From a5ef5133a333dc47b12558ec2e422c7b6d589f15 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Thu, 29 Nov 2018 15:13:03 -0800 Subject: [PATCH 001/337] Reorganize source code in preparation to move into aspnet/AspNetCore Prior to reorganization, this source code was found in https://github.com/aspnet/Razor/tree/dotnet/aspnetcore-tooling@582f3f867eeb8fca00e6b328faf7665c9a98476c \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/33b287d4a46d71b1162f16af74ab8e8a6cffd3e8 --- .../src/CSharpIdentifier.cs | 71 + .../src/ExtensionInitializer.cs | 29 + .../src/IInjectTargetExtension.cs | 12 + .../IViewComponentTagHelperTargetExtension.cs | 12 + .../src/InjectDirective.cs | 124 + .../src/InjectIntermediateNode.cs | 59 + .../src/InjectTargetExtension.cs | 44 + .../src/LegacySectionTargetExtension.cs | 32 + ...ore.Mvc.Razor.Extensions.Version1_X.csproj | 21 + .../src/ModelDirective.cs | 145 + .../src/ModelExpressionPass.cs | 85 + .../src/MvcImportProjectFeature.cs | 89 + .../src/MvcRazorTemplateEngine.cs | 60 + .../src/MvcViewDocumentClassifierPass.cs | 71 + .../src/Properties/AssemblyInfo.cs | 11 + .../src/Properties/Resources.Designer.cs | 254 + .../ViewComponentResources.Designer.cs | 100 + .../src/RazorExtensions.cs | 117 + .../src/RazorExtensionsDiagnosticFactory.cs | 103 + .../src/Resources.resx | 168 + .../src/TagHelperDescriptorExtensions.cs | 37 + .../src/ViewComponentResources.resx | 135 + .../src/ViewComponentTagHelperConventions.cs | 10 + ...ViewComponentTagHelperDescriptorFactory.cs | 269 + ...iewComponentTagHelperDescriptorProvider.cs | 72 + .../ViewComponentTagHelperIntermediateNode.cs | 59 + .../src/ViewComponentTagHelperMetadata.cs | 14 + .../src/ViewComponentTagHelperPass.cs | 203 + .../ViewComponentTagHelperTargetExtension.cs | 183 + .../src/ViewComponentTypeVisitor.cs | 86 + .../src/ViewComponentTypes.cs | 35 + .../test/InjectDirectiveTest.cs | 225 + .../test/InjectTargetExtensionTest.cs | 68 + .../CodeGenerationIntegrationTest.cs | 370 + .../test/LegacySectionTargetExtensionTest.cs | 46 + ...vc.Razor.Extensions.Version1_X.Test.csproj | 51 + .../test/ModelDirectiveTest.cs | 343 + .../test/ModelExpressionPassTest.cs | 208 + .../test/MvcImportProjectFeatureTest.cs | 76 + .../test/MvcRazorTemplateEngineTest.cs | 92 + .../test/MvcShim.cs | 45 + .../test/MvcViewDocumentClassifierPassTest.cs | 264 + .../test/Properties/AssemblyInfo.cs | 6 + .../test/SourceMappingsSerializer.cs | 54 + .../test/TagHelperDescriptorExtensionsTest.cs | 82 + .../Basic.cshtml | 8 + .../Basic_DesignTime.codegen.cs | 71 + .../Basic_DesignTime.ir.txt | 62 + .../Basic_DesignTime.mappings.txt | 34 + .../Basic_Runtime.codegen.cs | 92 + .../Basic_Runtime.ir.txt | 72 + .../IncompleteDirectives.cshtml | 8 + ...IncompleteDirectives_DesignTime.codegen.cs | 63 + ...pleteDirectives_DesignTime.diagnostics.txt | 6 + .../IncompleteDirectives_DesignTime.ir.txt | 64 + ...completeDirectives_DesignTime.mappings.txt | 30 + .../IncompleteDirectives_Runtime.codegen.cs | 51 + ...completeDirectives_Runtime.diagnostics.txt | 6 + .../IncompleteDirectives_Runtime.ir.txt | 58 + .../InheritsViewModel.cshtml | 2 + .../InheritsViewModel_DesignTime.codegen.cs | 56 + .../InheritsViewModel_DesignTime.ir.txt | 37 + .../InheritsViewModel_DesignTime.mappings.txt | 10 + .../InheritsViewModel_Runtime.codegen.cs | 33 + .../InheritsViewModel_Runtime.ir.txt | 16 + .../InheritsWithViewImports.cshtml | 1 + ...eritsWithViewImports_DesignTime.codegen.cs | 48 + .../InheritsWithViewImports_DesignTime.ir.txt | 37 + ...itsWithViewImports_DesignTime.mappings.txt | 5 + ...InheritsWithViewImports_Runtime.codegen.cs | 33 + .../InheritsWithViewImports_Runtime.ir.txt | 16 + .../Inject.cshtml | 1 + .../InjectWithModel.cshtml | 3 + .../InjectWithModel_DesignTime.codegen.cs | 82 + .../InjectWithModel_DesignTime.ir.txt | 41 + .../InjectWithModel_DesignTime.mappings.txt | 25 + .../InjectWithModel_Runtime.codegen.cs | 35 + .../InjectWithModel_Runtime.ir.txt | 17 + .../InjectWithSemicolon.cshtml | 5 + .../InjectWithSemicolon_DesignTime.codegen.cs | 118 + .../InjectWithSemicolon_DesignTime.ir.txt | 47 + ...njectWithSemicolon_DesignTime.mappings.txt | 45 + .../InjectWithSemicolon_Runtime.codegen.cs | 39 + .../InjectWithSemicolon_Runtime.ir.txt | 19 + .../Inject_DesignTime.codegen.cs | 58 + .../Inject_DesignTime.ir.txt | 38 + .../Inject_DesignTime.mappings.txt | 10 + .../Inject_Runtime.codegen.cs | 35 + .../Inject_Runtime.ir.txt | 17 + .../InvalidNamespaceAtEOF.cshtml | 1 + ...nvalidNamespaceAtEOF_DesignTime.codegen.cs | 40 + ...dNamespaceAtEOF_DesignTime.diagnostics.txt | 1 + .../InvalidNamespaceAtEOF_DesignTime.ir.txt | 37 + ...alidNamespaceAtEOF_DesignTime.mappings.txt | 0 .../InvalidNamespaceAtEOF_Runtime.codegen.cs | 36 + ...alidNamespaceAtEOF_Runtime.diagnostics.txt | 1 + .../InvalidNamespaceAtEOF_Runtime.ir.txt | 22 + .../Model.cshtml | 1 + .../ModelExpressionTagHelper.cshtml | 6 + ...lExpressionTagHelper_DesignTime.codegen.cs | 69 + ...ModelExpressionTagHelper_DesignTime.ir.txt | 66 + ...xpressionTagHelper_DesignTime.mappings.txt | 20 + ...odelExpressionTagHelper_Runtime.codegen.cs | 104 + .../ModelExpressionTagHelper_Runtime.ir.txt | 69 + .../Model_DesignTime.codegen.cs | 48 + .../Model_DesignTime.ir.txt | 36 + .../Model_DesignTime.mappings.txt | 5 + .../Model_Runtime.codegen.cs | 33 + .../Model_Runtime.ir.txt | 16 + .../MultipleModels.cshtml | 2 + .../MultipleModels_DesignTime.codegen.cs | 56 + .../MultipleModels_DesignTime.diagnostics.txt | 1 + .../MultipleModels_DesignTime.ir.txt | 39 + .../MultipleModels_DesignTime.mappings.txt | 10 + .../Sections.cshtml | 14 + .../Sections_DesignTime.codegen.cs | 80 + .../Sections_DesignTime.ir.txt | 71 + .../Sections_DesignTime.mappings.txt | 29 + .../ViewComponentTagHelper.cshtml | 6 + ...ewComponentTagHelper_DesignTime.codegen.cs | 84 + .../ViewComponentTagHelper_DesignTime.ir.txt | 57 + ...ComponentTagHelper_DesignTime.mappings.txt | 19 + .../ViewComponentTagHelper_Runtime.codegen.cs | 110 + .../ViewComponentTagHelper_Runtime.ir.txt | 43 + .../_ViewImports.cshtml | 1 + .../_ViewImports_DesignTime.codegen.cs | 58 + .../_ViewImports_DesignTime.ir.txt | 38 + .../_ViewImports_DesignTime.mappings.txt | 10 + .../_ViewImports_Runtime.codegen.cs | 35 + .../_ViewImports_Runtime.ir.txt | 17 + ...ComponentTagHelperDescriptorFactoryTest.cs | 343 + ...omponentTagHelperDescriptorProviderTest.cs | 71 + .../test/ViewComponentTagHelperPassTest.cs | 275 + ...ewComponentTagHelperTargetExtensionTest.cs | 120 + .../test/ViewComponentTypeVisitorTest.cs | 202 + .../test/xunit.runner.json | 4 + .../src/AssemblyAttributeInjectionPass.cs | 102 + .../src/CSharpIdentifier.cs | 71 + .../src/ExtensionInitializer.cs | 15 + .../src/IInjectTargetExtension.cs | 12 + .../IViewComponentTagHelperTargetExtension.cs | 12 + .../src/InjectDirective.cs | 124 + .../src/InjectIntermediateNode.cs | 58 + .../src/InjectTargetExtension.cs | 44 + .../src/InstrumentationPass.cs | 125 + ...ore.Mvc.Razor.Extensions.Version2_X.csproj | 20 + .../src/ModelDirective.cs | 152 + .../src/ModelExpressionPass.cs | 85 + .../src/MvcImportProjectFeature.cs | 91 + .../src/MvcViewDocumentClassifierPass.cs | 71 + .../src/NamespaceDirective.cs | 204 + .../src/PageDirective.cs | 121 + .../src/PagesPropertyInjectionPass.cs | 57 + .../src/Properties/AssemblyInfo.cs | 12 + .../src/Properties/Resources.Designer.cs | 338 + .../ViewComponentResources.Designer.cs | 100 + .../src/RazorExtensions.cs | 48 + .../src/RazorExtensionsDiagnosticFactory.cs | 131 + .../src/RazorPageDocumentClassifierPass.cs | 164 + .../src/Resources.resx | 186 + .../src/TagHelperDescriptorExtensions.cs | 37 + .../src/ViewComponentResources.resx | 135 + .../src/ViewComponentTagHelperConventions.cs | 10 + ...ViewComponentTagHelperDescriptorFactory.cs | 284 + ...iewComponentTagHelperDescriptorProvider.cs | 72 + .../ViewComponentTagHelperIntermediateNode.cs | 59 + .../src/ViewComponentTagHelperMetadata.cs | 14 + .../src/ViewComponentTagHelperPass.cs | 203 + .../ViewComponentTagHelperTargetExtension.cs | 183 + .../src/ViewComponentTypeVisitor.cs | 88 + .../src/ViewComponentTypes.cs | 35 + .../src/baseline.netcore.json | 1180 ++ .../src/baseline.netframework.json | 982 + .../AssemblyAttributeInjectionPassTest.cs | 444 + .../test/InjectDirectiveTest.cs | 225 + .../test/InjectTargetExtensionTest.cs | 68 + .../test/InstrumentationPassTest.cs | 348 + .../CodeGenerationIntegrationTest.cs | 961 + .../InstrumentationPassIntegrationTest.cs | 92 + ...vc.Razor.Extensions.Version2_X.Test.csproj | 52 + .../test/ModelDirectiveTest.cs | 343 + .../test/ModelExpressionPassTest.cs | 208 + .../test/MvcImportProjectFeatureTest.cs | 76 + .../test/MvcShim.cs | 45 + .../test/MvcViewDocumentClassifierPassTest.cs | 264 + .../test/NamespaceDirectiveTest.cs | 352 + .../test/PageDirectiveTest.cs | 148 + .../test/Properties/AssemblyInfo.cs | 6 + .../RazorPageDocumentClassifierPassTest.cs | 417 + .../test/SourceMappingsSerializer.cs | 54 + .../test/TagHelperDescriptorExtensionsTest.cs | 82 + .../Basic.cshtml | 8 + .../Basic_DesignTime.codegen.cs | 71 + .../Basic_DesignTime.ir.txt | 64 + .../Basic_DesignTime.mappings.txt | 34 + .../Basic_Runtime.codegen.cs | 95 + .../Basic_Runtime.ir.txt | 76 + .../IncompleteDirectives.cshtml | 15 + ...IncompleteDirectives_DesignTime.codegen.cs | 71 + ...pleteDirectives_DesignTime.diagnostics.txt | 12 + .../IncompleteDirectives_DesignTime.ir.txt | 84 + ...completeDirectives_DesignTime.mappings.txt | 40 + .../IncompleteDirectives_Runtime.codegen.cs | 65 + ...completeDirectives_Runtime.diagnostics.txt | 12 + .../IncompleteDirectives_Runtime.ir.txt | 95 + .../InheritsViewModel.cshtml | 2 + .../InheritsViewModel_DesignTime.codegen.cs | 56 + .../InheritsViewModel_DesignTime.ir.txt | 39 + .../InheritsViewModel_DesignTime.mappings.txt | 10 + .../InheritsViewModel_Runtime.codegen.cs | 36 + .../InheritsViewModel_Runtime.ir.txt | 20 + .../InheritsWithViewImports.cshtml | 2 + ...eritsWithViewImports_DesignTime.codegen.cs | 50 + .../InheritsWithViewImports_DesignTime.ir.txt | 43 + ...itsWithViewImports_DesignTime.mappings.txt | 5 + ...InheritsWithViewImports_Runtime.codegen.cs | 39 + .../InheritsWithViewImports_Runtime.ir.txt | 25 + .../Inject.cshtml | 1 + .../InjectWithModel.cshtml | 3 + .../InjectWithModel_DesignTime.codegen.cs | 82 + .../InjectWithModel_DesignTime.ir.txt | 43 + .../InjectWithModel_DesignTime.mappings.txt | 25 + .../InjectWithModel_Runtime.codegen.cs | 38 + .../InjectWithModel_Runtime.ir.txt | 21 + .../InjectWithSemicolon.cshtml | 5 + .../InjectWithSemicolon_DesignTime.codegen.cs | 118 + .../InjectWithSemicolon_DesignTime.ir.txt | 49 + ...njectWithSemicolon_DesignTime.mappings.txt | 45 + .../InjectWithSemicolon_Runtime.codegen.cs | 42 + .../InjectWithSemicolon_Runtime.ir.txt | 23 + .../Inject_DesignTime.codegen.cs | 58 + .../Inject_DesignTime.ir.txt | 40 + .../Inject_DesignTime.mappings.txt | 10 + .../Inject_Runtime.codegen.cs | 38 + .../Inject_Runtime.ir.txt | 21 + .../InvalidNamespaceAtEOF.cshtml | 1 + ...nvalidNamespaceAtEOF_DesignTime.codegen.cs | 40 + ...dNamespaceAtEOF_DesignTime.diagnostics.txt | 1 + .../InvalidNamespaceAtEOF_DesignTime.ir.txt | 40 + ...alidNamespaceAtEOF_DesignTime.mappings.txt | 0 .../InvalidNamespaceAtEOF_Runtime.codegen.cs | 39 + ...alidNamespaceAtEOF_Runtime.diagnostics.txt | 1 + .../InvalidNamespaceAtEOF_Runtime.ir.txt | 27 + .../MalformedPageDirective.cshtml | 4 + ...lformedPageDirective_DesignTime.codegen.cs | 42 + ...edPageDirective_DesignTime.diagnostics.txt | 1 + .../MalformedPageDirective_DesignTime.ir.txt | 51 + ...ormedPageDirective_DesignTime.mappings.txt | 0 .../MalformedPageDirective_Runtime.codegen.cs | 41 + ...ormedPageDirective_Runtime.diagnostics.txt | 1 + .../MalformedPageDirective_Runtime.ir.txt | 38 + .../Model.cshtml | 1 + .../ModelExpressionTagHelper.cshtml | 6 + ...lExpressionTagHelper_DesignTime.codegen.cs | 69 + ...ModelExpressionTagHelper_DesignTime.ir.txt | 68 + ...xpressionTagHelper_DesignTime.mappings.txt | 20 + ...odelExpressionTagHelper_Runtime.codegen.cs | 107 + .../ModelExpressionTagHelper_Runtime.ir.txt | 73 + .../Model_DesignTime.codegen.cs | 48 + .../Model_DesignTime.ir.txt | 38 + .../Model_DesignTime.mappings.txt | 5 + .../Model_Runtime.codegen.cs | 36 + .../Model_Runtime.ir.txt | 20 + .../MultipleModels.cshtml | 2 + .../MultipleModels_DesignTime.codegen.cs | 56 + .../MultipleModels_DesignTime.diagnostics.txt | 1 + .../MultipleModels_DesignTime.ir.txt | 41 + .../MultipleModels_DesignTime.mappings.txt | 10 + .../PageWithNamespace.cshtml | 3 + .../PageWithNamespace_DesignTime.codegen.cs | 50 + .../PageWithNamespace_DesignTime.ir.txt | 47 + .../PageWithNamespace_DesignTime.mappings.txt | 5 + .../PageWithNamespace_Runtime.codegen.cs | 41 + .../PageWithNamespace_Runtime.ir.txt | 33 + ...RazorPageWithNoLeadingPageDirective.cshtml | 2 + ...LeadingPageDirective_DesignTime.codegen.cs | 42 + ...ngPageDirective_DesignTime.diagnostics.txt | 1 + ...thNoLeadingPageDirective_DesignTime.ir.txt | 46 + ...adingPageDirective_DesignTime.mappings.txt | 0 ...hNoLeadingPageDirective_Runtime.codegen.cs | 41 + ...adingPageDirective_Runtime.diagnostics.txt | 1 + ...eWithNoLeadingPageDirective_Runtime.ir.txt | 33 + .../RazorPages.cshtml | 40 + .../RazorPagesWithRouteTemplate.cshtml | 13 + ...gesWithRouteTemplate_DesignTime.codegen.cs | 78 + ...orPagesWithRouteTemplate_DesignTime.ir.txt | 60 + ...sWithRouteTemplate_DesignTime.mappings.txt | 35 + ...rPagesWithRouteTemplate_Runtime.codegen.cs | 72 + ...RazorPagesWithRouteTemplate_Runtime.ir.txt | 61 + .../RazorPagesWithoutModel.cshtml | 36 + ...zorPagesWithoutModel_DesignTime.codegen.cs | 83 + .../RazorPagesWithoutModel_DesignTime.ir.txt | 143 + ...rPagesWithoutModel_DesignTime.mappings.txt | 46 + .../RazorPagesWithoutModel_Runtime.codegen.cs | 204 + .../RazorPagesWithoutModel_Runtime.ir.txt | 193 + .../RazorPages_DesignTime.codegen.cs | 94 + .../RazorPages_DesignTime.ir.txt | 144 + .../RazorPages_DesignTime.mappings.txt | 57 + .../RazorPages_Runtime.codegen.cs | 207 + .../RazorPages_Runtime.ir.txt | 193 + .../Sections.cshtml | 14 + .../Sections_DesignTime.codegen.cs | 80 + .../Sections_DesignTime.ir.txt | 73 + .../Sections_DesignTime.mappings.txt | 29 + .../Sections_Runtime.codegen.cs | 99 + .../Sections_Runtime.ir.txt | 77 + .../UsingDirectives.cshtml | 4 + .../UsingDirectives_DesignTime.codegen.cs | 59 + .../UsingDirectives_DesignTime.ir.txt | 46 + .../UsingDirectives_DesignTime.mappings.txt | 20 + .../UsingDirectives_Runtime.codegen.cs | 55 + .../UsingDirectives_Runtime.ir.txt | 23 + .../ViewComponentTagHelper.cshtml | 6 + ...ewComponentTagHelper_DesignTime.codegen.cs | 84 + .../ViewComponentTagHelper_DesignTime.ir.txt | 59 + ...ComponentTagHelper_DesignTime.mappings.txt | 19 + .../ViewComponentTagHelper_Runtime.codegen.cs | 112 + .../ViewComponentTagHelper_Runtime.ir.txt | 46 + .../ViewWithNamespace.cshtml | 2 + .../ViewWithNamespace_DesignTime.codegen.cs | 48 + .../ViewWithNamespace_DesignTime.ir.txt | 43 + .../ViewWithNamespace_DesignTime.mappings.txt | 5 + .../ViewWithNamespace_Runtime.codegen.cs | 39 + .../ViewWithNamespace_Runtime.ir.txt | 29 + .../_ViewImports.cshtml | 1 + .../_ViewImports_DesignTime.codegen.cs | 58 + .../_ViewImports_DesignTime.ir.txt | 40 + .../_ViewImports_DesignTime.mappings.txt | 10 + .../_ViewImports_Runtime.codegen.cs | 38 + .../_ViewImports_Runtime.ir.txt | 21 + .../BasicTest.codegen.cs | 118 + .../BasicTest.cshtml | 9 + .../BasicTest.ir.txt | 100 + ...ComponentTagHelperDescriptorFactoryTest.cs | 485 + ...omponentTagHelperDescriptorProviderTest.cs | 72 + .../test/ViewComponentTagHelperPassTest.cs | 275 + ...ewComponentTagHelperTargetExtensionTest.cs | 120 + .../test/ViewComponentTypeVisitorTest.cs | 202 + .../test/xunit.runner.json | 4 + .../src/AssemblyAttributeInjectionPass.cs | 102 + .../src/ExtensionInitializer.cs | 16 + .../src/IInjectTargetExtension.cs | 12 + .../IViewComponentTagHelperTargetExtension.cs | 12 + .../src/InjectDirective.cs | 131 + .../src/InjectIntermediateNode.cs | 58 + .../src/InjectTargetExtension.cs | 44 + ...oft.AspNetCore.Mvc.Razor.Extensions.csproj | 20 + .../src/ModelDirective.cs | 152 + .../src/ModelExpressionPass.cs | 85 + .../src/MvcImportProjectFeature.cs | 91 + .../src/MvcRazorTemplateEngine.cs | 62 + .../src/MvcViewDocumentClassifierPass.cs | 70 + .../src/NamespaceDirective.cs | 204 + .../src/PageDirective.cs | 121 + .../src/PagesPropertyInjectionPass.cs | 57 + .../src/Properties/AssemblyInfo.cs | 11 + .../src/Properties/Resources.Designer.cs | 338 + .../ViewComponentResources.Designer.cs | 100 + .../src/RazorExtensions.cs | 47 + .../src/RazorExtensionsDiagnosticFactory.cs | 131 + .../src/RazorPageDocumentClassifierPass.cs | 163 + .../src/Resources.resx | 186 + .../src/TagHelperDescriptorExtensions.cs | 37 + .../src/ViewComponentResources.resx | 135 + .../src/ViewComponentTagHelperConventions.cs | 10 + ...ViewComponentTagHelperDescriptorFactory.cs | 284 + ...iewComponentTagHelperDescriptorProvider.cs | 72 + .../ViewComponentTagHelperIntermediateNode.cs | 59 + .../src/ViewComponentTagHelperMetadata.cs | 14 + .../src/ViewComponentTagHelperPass.cs | 203 + .../ViewComponentTagHelperTargetExtension.cs | 183 + .../src/ViewComponentTypeVisitor.cs | 88 + .../src/ViewComponentTypes.cs | 35 + .../src/baseline.netcore.json | 1235 ++ .../src/baseline.netframework.json | 1023 + .../src/breakingchanges.netcore.json | 11 + .../src/breakingchanges.netframework.json | 11 + .../AssemblyAttributeInjectionPassTest.cs | 444 + .../test/InjectDirectiveTest.cs | 212 + .../test/InjectTargetExtensionTest.cs | 68 + .../CodeGenerationIntegrationTest.cs | 961 + ...spNetCore.Mvc.Razor.Extensions.Test.csproj | 51 + .../test/ModelDirectiveTest.cs | 343 + .../test/ModelExpressionPassTest.cs | 208 + .../test/MvcImportProjectFeatureTest.cs | 76 + .../test/MvcRazorTemplateEngineTest.cs | 94 + .../test/MvcShim.cs | 45 + .../test/MvcViewDocumentClassifierPassTest.cs | 264 + .../test/NamespaceDirectiveTest.cs | 352 + .../test/PageDirectiveTest.cs | 148 + .../test/Properties/AssemblyInfo.cs | 6 + .../RazorPageDocumentClassifierPassTest.cs | 417 + .../test/SourceMappingsSerializer.cs | 54 + .../test/TagHelperDescriptorExtensionsTest.cs | 82 + .../Basic.cshtml | 8 + .../Basic_DesignTime.codegen.cs | 71 + .../Basic_DesignTime.ir.txt | 64 + .../Basic_DesignTime.mappings.txt | 34 + .../Basic_Runtime.codegen.cs | 81 + .../Basic_Runtime.ir.txt | 48 + .../IncompleteDirectives.cshtml | 15 + ...IncompleteDirectives_DesignTime.codegen.cs | 71 + ...pleteDirectives_DesignTime.diagnostics.txt | 12 + .../IncompleteDirectives_DesignTime.ir.txt | 84 + ...completeDirectives_DesignTime.mappings.txt | 40 + .../IncompleteDirectives_Runtime.codegen.cs | 47 + ...completeDirectives_Runtime.diagnostics.txt | 12 + .../IncompleteDirectives_Runtime.ir.txt | 59 + .../InheritsViewModel.cshtml | 2 + .../InheritsViewModel_DesignTime.codegen.cs | 56 + .../InheritsViewModel_DesignTime.ir.txt | 39 + .../InheritsViewModel_DesignTime.mappings.txt | 10 + .../InheritsViewModel_Runtime.codegen.cs | 36 + .../InheritsViewModel_Runtime.ir.txt | 20 + .../InheritsWithViewImports.cshtml | 2 + ...eritsWithViewImports_DesignTime.codegen.cs | 50 + .../InheritsWithViewImports_DesignTime.ir.txt | 43 + ...itsWithViewImports_DesignTime.mappings.txt | 5 + ...InheritsWithViewImports_Runtime.codegen.cs | 39 + .../InheritsWithViewImports_Runtime.ir.txt | 25 + .../Inject.cshtml | 1 + .../InjectWithModel.cshtml | 3 + .../InjectWithModel_DesignTime.codegen.cs | 82 + .../InjectWithModel_DesignTime.ir.txt | 43 + .../InjectWithModel_DesignTime.mappings.txt | 25 + .../InjectWithModel_Runtime.codegen.cs | 38 + .../InjectWithModel_Runtime.ir.txt | 21 + .../InjectWithSemicolon.cshtml | 5 + .../InjectWithSemicolon_DesignTime.codegen.cs | 118 + .../InjectWithSemicolon_DesignTime.ir.txt | 49 + ...njectWithSemicolon_DesignTime.mappings.txt | 45 + .../InjectWithSemicolon_Runtime.codegen.cs | 42 + .../InjectWithSemicolon_Runtime.ir.txt | 23 + .../Inject_DesignTime.codegen.cs | 58 + .../Inject_DesignTime.ir.txt | 40 + .../Inject_DesignTime.mappings.txt | 10 + .../Inject_Runtime.codegen.cs | 38 + .../Inject_Runtime.ir.txt | 21 + .../InvalidNamespaceAtEOF.cshtml | 1 + ...nvalidNamespaceAtEOF_DesignTime.codegen.cs | 40 + ...dNamespaceAtEOF_DesignTime.diagnostics.txt | 1 + .../InvalidNamespaceAtEOF_DesignTime.ir.txt | 40 + ...alidNamespaceAtEOF_DesignTime.mappings.txt | 0 .../InvalidNamespaceAtEOF_Runtime.codegen.cs | 37 + ...alidNamespaceAtEOF_Runtime.diagnostics.txt | 1 + .../InvalidNamespaceAtEOF_Runtime.ir.txt | 23 + .../MalformedPageDirective.cshtml | 4 + ...lformedPageDirective_DesignTime.codegen.cs | 42 + ...edPageDirective_DesignTime.diagnostics.txt | 1 + .../MalformedPageDirective_DesignTime.ir.txt | 51 + ...ormedPageDirective_DesignTime.mappings.txt | 0 .../MalformedPageDirective_Runtime.codegen.cs | 39 + ...ormedPageDirective_Runtime.diagnostics.txt | 1 + .../MalformedPageDirective_Runtime.ir.txt | 34 + .../Model.cshtml | 1 + .../ModelExpressionTagHelper.cshtml | 6 + ...lExpressionTagHelper_DesignTime.codegen.cs | 69 + ...ModelExpressionTagHelper_DesignTime.ir.txt | 68 + ...xpressionTagHelper_DesignTime.mappings.txt | 20 + ...odelExpressionTagHelper_Runtime.codegen.cs | 95 + .../ModelExpressionTagHelper_Runtime.ir.txt | 49 + .../Model_DesignTime.codegen.cs | 48 + .../Model_DesignTime.ir.txt | 38 + .../Model_DesignTime.mappings.txt | 5 + .../Model_Runtime.codegen.cs | 36 + .../Model_Runtime.ir.txt | 20 + .../MultipleModels.cshtml | 2 + .../MultipleModels_DesignTime.codegen.cs | 56 + .../MultipleModels_DesignTime.diagnostics.txt | 1 + .../MultipleModels_DesignTime.ir.txt | 41 + .../MultipleModels_DesignTime.mappings.txt | 10 + .../PageWithNamespace.cshtml | 3 + .../PageWithNamespace_DesignTime.codegen.cs | 50 + .../PageWithNamespace_DesignTime.ir.txt | 47 + .../PageWithNamespace_DesignTime.mappings.txt | 5 + .../PageWithNamespace_Runtime.codegen.cs | 39 + .../PageWithNamespace_Runtime.ir.txt | 29 + ...RazorPageWithNoLeadingPageDirective.cshtml | 2 + ...LeadingPageDirective_DesignTime.codegen.cs | 42 + ...ngPageDirective_DesignTime.diagnostics.txt | 1 + ...thNoLeadingPageDirective_DesignTime.ir.txt | 46 + ...adingPageDirective_DesignTime.mappings.txt | 0 ...hNoLeadingPageDirective_Runtime.codegen.cs | 39 + ...adingPageDirective_Runtime.diagnostics.txt | 1 + ...eWithNoLeadingPageDirective_Runtime.ir.txt | 29 + .../RazorPages.cshtml | 40 + .../RazorPagesWithRouteTemplate.cshtml | 13 + ...gesWithRouteTemplate_DesignTime.codegen.cs | 78 + ...orPagesWithRouteTemplate_DesignTime.ir.txt | 60 + ...sWithRouteTemplate_DesignTime.mappings.txt | 35 + ...rPagesWithRouteTemplate_Runtime.codegen.cs | 62 + ...RazorPagesWithRouteTemplate_Runtime.ir.txt | 41 + .../RazorPagesWithoutModel.cshtml | 36 + ...zorPagesWithoutModel_DesignTime.codegen.cs | 83 + .../RazorPagesWithoutModel_DesignTime.ir.txt | 143 + ...rPagesWithoutModel_DesignTime.mappings.txt | 46 + .../RazorPagesWithoutModel_Runtime.codegen.cs | 166 + .../RazorPagesWithoutModel_Runtime.ir.txt | 117 + .../RazorPages_DesignTime.codegen.cs | 94 + .../RazorPages_DesignTime.ir.txt | 144 + .../RazorPages_DesignTime.mappings.txt | 57 + .../RazorPages_Runtime.codegen.cs | 169 + .../RazorPages_Runtime.ir.txt | 117 + .../Sections.cshtml | 14 + .../Sections_DesignTime.codegen.cs | 80 + .../Sections_DesignTime.ir.txt | 73 + .../Sections_DesignTime.mappings.txt | 29 + .../Sections_Runtime.codegen.cs | 87 + .../Sections_Runtime.ir.txt | 53 + .../UsingDirectives.cshtml | 4 + .../UsingDirectives_DesignTime.codegen.cs | 59 + .../UsingDirectives_DesignTime.ir.txt | 46 + .../UsingDirectives_DesignTime.mappings.txt | 20 + .../UsingDirectives_Runtime.codegen.cs | 55 + .../UsingDirectives_Runtime.ir.txt | 23 + .../ViewComponentTagHelper.cshtml | 6 + ...ewComponentTagHelper_DesignTime.codegen.cs | 84 + .../ViewComponentTagHelper_DesignTime.ir.txt | 59 + ...ComponentTagHelper_DesignTime.mappings.txt | 19 + .../ViewComponentTagHelper_Runtime.codegen.cs | 108 + .../ViewComponentTagHelper_Runtime.ir.txt | 38 + .../ViewWithNamespace.cshtml | 2 + .../ViewWithNamespace_DesignTime.codegen.cs | 48 + .../ViewWithNamespace_DesignTime.ir.txt | 43 + .../ViewWithNamespace_DesignTime.mappings.txt | 5 + .../ViewWithNamespace_Runtime.codegen.cs | 37 + .../ViewWithNamespace_Runtime.ir.txt | 25 + .../_ViewImports.cshtml | 1 + .../_ViewImports_DesignTime.codegen.cs | 58 + .../_ViewImports_DesignTime.ir.txt | 40 + .../_ViewImports_DesignTime.mappings.txt | 10 + .../_ViewImports_Runtime.codegen.cs | 38 + .../_ViewImports_Runtime.ir.txt | 21 + ...ComponentTagHelperDescriptorFactoryTest.cs | 485 + ...omponentTagHelperDescriptorProviderTest.cs | 72 + .../test/ViewComponentTagHelperPassTest.cs | 275 + ...ewComponentTagHelperTargetExtensionTest.cs | 120 + .../test/ViewComponentTypeVisitorTest.cs | 202 + .../test/xunit.runner.json | 4 + .../src/AllowedChildTagDescriptor.cs | 48 + .../src/AllowedChildTagDescriptorBuilder.cs | 17 + .../src/AllowedChildTagDescriptorComparer.cs | 71 + .../src/AssemblyExtension.cs | 55 + .../src/AttributeStructure.cs | 15 + .../src/BoundAttributeDescriptor.cs | 80 + .../src/BoundAttributeDescriptorBuilder.cs | 30 + ...undAttributeDescriptorBuilderExtensions.cs | 55 + .../src/BoundAttributeDescriptorComparer.cs | 83 + .../src/BoundAttributeDescriptorExtensions.cs | 53 + .../src/CSharpIdentifier.cs | 53 + .../src/Checksum.cs | 28 + .../src/ClassifiedSpanVisitor.cs | 312 + .../CodeGeneration/CodeRenderingContext.cs | 44 + .../src/CodeGeneration/CodeTarget.cs | 95 + .../src/CodeGeneration/CodeTargetBuilder.cs | 18 + .../src/CodeGeneration/CodeWriter.cs | 207 + .../CodeGeneration/CodeWriterExtensions.cs | 650 + .../DefaultCodeRenderingContext.cs | 213 + .../src/CodeGeneration/DefaultCodeTarget.cs | 54 + .../DefaultCodeTargetBuilder.cs | 30 + .../CodeGeneration/DefaultDocumentWriter.cs | 266 + .../CodeGeneration/DesignTimeNodeWriter.cs | 259 + .../src/CodeGeneration/DocumentWriter.cs | 46 + .../CodeGeneration/ICodeTargetExtension.cs | 9 + .../CodeGeneration/IntermediateNodeWriter.cs | 30 + .../LiteralRuntimeNodeWriter.cs | 10 + .../src/CodeGeneration/RuntimeNodeWriter.cs | 391 + ...TagHelperHtmlAttributeRuntimeNodeWriter.cs | 10 + .../TagHelperRenderingContext.cs | 40 + .../src/Components/CodeGenerationConstants.cs | 27 + .../ComponentDocumentClassifierPass.cs | 139 + .../src/Components/ComponentExtensions.cs | 22 + .../src/DefaultAllowedChildTagDescriptor.cs | 15 + ...DefaultAllowedChildTagDescriptorBuilder.cs | 77 + .../src/DefaultBoundAttributeDescriptor.cs | 43 + .../DefaultBoundAttributeDescriptorBuilder.cs | 209 + .../src/DefaultDirectiveSyntaxTreePass.cs | 66 + .../src/DefaultDocumentClassifierPass.cs | 49 + .../DefaultDocumentClassifierPassFeature.cs | 21 + .../src/DefaultImportProjectFeature.cs | 13 + .../src/DefaultRazorCSharpDocument.cs | 47 + .../src/DefaultRazorCSharpLoweringPhase.cs | 33 + .../src/DefaultRazorCodeDocument.cs | 33 + .../src/DefaultRazorCodeGenerationOptions.cs | 32 + ...efaultRazorCodeGenerationOptionsBuilder.cs | 51 + ...eGenerationOptionsFactoryProjectFeature.cs | 32 + ...efaultRazorCodeGenerationOptionsFeature.cs | 38 + .../src/DefaultRazorDiagnostic.cs | 84 + .../DefaultRazorDirectiveClassifierPhase.cs | 30 + .../src/DefaultRazorDirectiveFeature.cs | 30 + .../DefaultRazorDocumentClassifierPhase.cs | 30 + .../src/DefaultRazorEngine.cs | 55 + .../src/DefaultRazorEngineBuilder.cs | 37 + ...faultRazorIntermediateNodeLoweringPhase.cs | 1118 ++ .../src/DefaultRazorOptimizationPhase.cs | 30 + .../src/DefaultRazorParserOptions.cs | 35 + .../src/DefaultRazorParserOptionsBuilder.cs | 51 + ...RazorParserOptionsFactoryProjectFeature.cs | 32 + .../src/DefaultRazorParserOptionsFeature.cs | 40 + .../src/DefaultRazorParsingPhase.cs | 31 + .../src/DefaultRazorProjectEngine.cs | 195 + .../src/DefaultRazorProjectEngineBuilder.cs | 60 + .../src/DefaultRazorProjectFileSystem.cs | 86 + .../src/DefaultRazorProjectItem.cs | 39 + .../src/DefaultRazorSourceLineCollection.cs | 123 + .../src/DefaultRazorSyntaxTree.cs | 33 + .../src/DefaultRazorSyntaxTreePhase.cs | 30 + .../src/DefaultRazorTagHelperBinderPhase.cs | 192 + .../src/DefaultRazorTargetExtensionFeature.cs | 13 + .../src/DefaultRequiredAttributeDescriptor.cs | 24 + ...faultRequiredAttributeDescriptorBuilder.cs | 78 + .../src/DefaultTagHelperDescriptor.cs | 36 + .../src/DefaultTagHelperDescriptorBuilder.cs | 237 + .../src/DefaultTagMatchingRuleDescriptor.cs | 22 + ...DefaultTagMatchingRuleDescriptorBuilder.cs | 146 + .../src/DirectiveDescriptor.cs | 263 + .../DirectiveDescriptorBuilderExtensions.cs | 186 + .../src/DirectiveDescriptorComparer.cs | 49 + .../src/DirectiveKind.cs | 12 + .../src/DirectiveRemovalOptimizationPass.cs | 40 + .../src/DirectiveTokenDescriptor.cs | 50 + .../src/DirectiveTokenDescriptorComparer.cs | 44 + .../src/DirectiveTokenEditHandler.cs | 49 + .../src/DirectiveTokenKind.cs | 13 + .../src/DirectiveUsage.cs | 27 + .../src/DocumentClassifierPassBase.cs | 153 + .../src/EmptyProjectFileSystem.cs | 23 + .../DefaultMetadataIdentifierFeature.cs | 41 + .../DefaultTagHelperBodyIntermediateNode.cs | 74 + .../DefaultTagHelperCreateIntermediateNode.cs | 61 + ...DefaultTagHelperExecuteIntermediateNode.cs | 46 + ...tTagHelperHtmlAttributeIntermediateNode.cs | 84 + .../DefaultTagHelperOptimizationPass.cs | 259 + ...efaultTagHelperPropertyIntermediateNode.cs | 102 + ...DefaultTagHelperRuntimeIntermediateNode.cs | 46 + .../DefaultTagHelperTargetExtension.cs | 663 + .../DesignTimeDirectiveIntermediateNode.cs | 47 + .../src/Extensions/DesignTimeDirectivePass.cs | 82 + .../DesignTimeDirectiveTargetExtension.cs | 174 + .../src/Extensions/EliminateMethodBodyPass.cs | 71 + .../src/Extensions/FunctionsDirective.cs | 44 + .../src/Extensions/FunctionsDirectivePass.cs | 27 + .../IDefaultTagHelperTargetExtension.cs | 22 + .../IDesignTimeDirectiveTargetExtension.cs | 12 + .../IMetadataAttributeTargetExtension.cs | 16 + .../Extensions/IMetadataIdentifierFeature.cs | 10 + .../IPreallocatedAttributeTargetExtension.cs | 18 + .../src/Extensions/ISectionTargetExtension.cs | 12 + .../Extensions/ITemplateTargetExtension.cs | 12 + .../src/Extensions/InheritsDirective.cs | 46 + .../src/Extensions/InheritsDirectivePass.cs | 31 + .../src/Extensions/MetadataAttributePass.cs | 128 + .../MetadataAttributeTargetExtension.cs | 88 + .../PreallocatedAttributeTargetExtension.cs | 167 + ...catedTagHelperAttributeOptimizationPass.cs | 166 + ...dTagHelperHtmlAttributeIntermediateNode.cs | 55 + ...elperHtmlAttributeValueIntermediateNode.cs | 88 + ...ocatedTagHelperPropertyIntermediateNode.cs | 97 + ...dTagHelperPropertyValueIntermediateNode.cs | 64 + ...orCompiledItemAttributeIntermediateNode.cs | 59 + ...edItemMetadataAttributeIntermediateNode.cs | 65 + ...SourceChecksumAttributeIntermediateNode.cs | 52 + .../src/Extensions/SectionDirective.cs | 47 + .../src/Extensions/SectionDirectivePass.cs | 49 + .../src/Extensions/SectionIntermediateNode.cs | 55 + .../src/Extensions/SectionTargetExtension.cs | 43 + .../Extensions/TemplateIntermediateNode.cs | 46 + .../src/Extensions/TemplateTargetExtension.cs | 35 + .../src/HtmlConventions.cs | 44 + .../src/HtmlNodeOptimizationPass.cs | 32 + ...figureRazorCodeGenerationOptionsFeature.cs | 12 + .../IConfigureRazorParserOptionsFeature.cs | 12 + .../src/IDirectiveDescriptorBuilder.cs | 49 + .../src/IImportProjectFeature.cs | 12 + .../src/IRazorCSharpLoweringPhase.cs | 17 + ...eGenerationOptionsFactoryProjectFeature.cs | 12 + .../src/IRazorCodeGenerationOptionsFeature.cs | 13 + .../src/IRazorDirectiveClassifierPass.cs | 14 + .../src/IRazorDirectiveClassifierPhase.cs | 25 + .../src/IRazorDirectiveFeature.cs | 12 + .../src/IRazorDocumentClassifierPass.cs | 14 + .../src/IRazorDocumentClassifierPhase.cs | 28 + .../src/IRazorEngineBuilder.cs | 20 + .../src/IRazorEngineFeature.cs | 10 + .../src/IRazorEnginePhase.cs | 12 + .../src/IRazorFeature.cs | 9 + .../IRazorIntermediateNodeLoweringPhase.cs | 19 + .../src/IRazorOptimizationPass.cs | 14 + .../src/IRazorOptimizationPhase.cs | 24 + ...RazorParserOptionsFactoryProjectFeature.cs | 12 + .../src/IRazorParserOptionsFeature.cs | 13 + .../src/IRazorParsingPhase.cs | 9 + .../src/IRazorProjectEngineFeature.cs | 10 + .../src/IRazorSyntaxTreePass.cs | 13 + .../src/IRazorSyntaxTreePhase.cs | 10 + .../src/IRazorTagHelperBinderPhase.cs | 9 + .../src/IRazorTargetExtensionFeature.cs | 13 + .../src/ITagHelperDescriptorProvider.cs | 12 + .../src/ITagHelperFeature.cs | 12 + ...SharpCodeAttributeValueIntermediateNode.cs | 31 + .../CSharpCodeIntermediateNode.cs | 27 + ...xpressionAttributeValueIntermediateNode.cs | 31 + .../CSharpExpressionIntermediateNode.cs | 27 + .../ClassDeclarationIntermediateNode.cs | 45 + .../src/Intermediate/CommonAnnotations.cs | 21 + .../Intermediate/DebuggerDisplayFormatter.cs | 21 + .../DefaultRazorIntermediateNodeBuilder.cs | 102 + .../Intermediate/DirectiveIntermediateNode.cs | 32 + .../DirectiveTokenIntermediateNode.cs | 28 + .../Intermediate/DocumentIntermediateNode.cs | 36 + .../DocumentIntermediateNodeExtensions.cs | 99 + .../Intermediate/ExtensionIntermediateNode.cs | 41 + .../FieldDeclarationIntermediateNode.cs | 38 + .../HtmlAttributeIntermediateNode.cs | 37 + .../HtmlAttributeValueIntermediateNode.cs | 31 + .../HtmlContentIntermediateNode.cs | 27 + .../IExtensionIntermediateNodeVisitor.cs | 10 + .../src/Intermediate/InputDocumentKind.cs | 12 + .../src/Intermediate/IntermediateNode.cs | 71 + .../Intermediate/IntermediateNodeBuilder.cs | 34 + .../IntermediateNodeCollection.cs | 198 + .../IntermediateNodeExtensions.cs | 81 + .../Intermediate/IntermediateNodeFormatter.cs | 16 + .../IntermediateNodeFormatterBase.cs | 180 + .../Intermediate/IntermediateNodeReference.cs | 209 + .../Intermediate/IntermediateNodeVisitor.cs | 132 + .../Intermediate/IntermediateNodeWalker.cs | 40 + .../src/Intermediate/IntermediateToken.cs | 37 + .../MalformedDirectiveIntermediateNode.cs | 32 + .../MemberDeclarationIntermediateNode.cs | 9 + .../MethodDeclarationIntermediateNode.cs | 60 + .../src/Intermediate/MethodParameter.cs | 16 + .../NamespaceDeclarationIntermediateNode.cs | 31 + .../PropertyDeclarationIntermediateNode.cs | 29 + .../TagHelperBodyIntermediateNode.cs | 22 + .../TagHelperHtmlAttributeIntermediateNode.cs | 34 + .../Intermediate/TagHelperIntermediateNode.cs | 57 + .../TagHelperPropertyIntermediateNode.cs | 43 + .../src/Intermediate/TokenKind.cs | 12 + .../src/Intermediate/TypeParameter.cs | 10 + .../UsingDirectiveIntermediateNode.cs | 31 + .../src/IntermediateNodePassBase.cs | 45 + .../src/ItemCollection.cs | 124 + .../src/LargeTextSourceDocument.cs | 159 + .../src/Legacy/AcceptedCharactersInternal.cs | 22 + .../src/Legacy/AddImportChunkGenerator.cs | 35 + .../src/Legacy/AddTagHelperChunkGenerator.cs | 86 + .../src/Legacy/AutoCompleteEditHandler.cs | 70 + .../src/Legacy/BalancingModes.cs | 17 + .../src/Legacy/BlockKindInternal.cs | 24 + .../src/Legacy/CSharpCodeParser.cs | 2471 +++ .../src/Legacy/CSharpKeyword.cs | 88 + .../Legacy/CSharpLanguageCharacteristics.cs | 176 + .../src/Legacy/CSharpTokenizer.cs | 807 + .../src/Legacy/ClassifiedSpanInternal.cs | 27 + .../src/Legacy/CodeBlockEditHandler.cs | 127 + .../src/Legacy/DirectiveCSharpTokenizer.cs | 63 + .../src/Legacy/DirectiveHtmlTokenizer.cs | 57 + .../Legacy/DirectiveTokenChunkGenerator.cs | 50 + .../src/Legacy/DisposableAction.cs | 32 + .../src/Legacy/EditResult.cs | 19 + .../src/Legacy/ErrorSink.cs | 34 + .../src/Legacy/ExpressionChunkGenerator.cs | 28 + ...tDirectiveCSharpLanguageCharacteristics.cs | 18 + ...rstDirectiveHtmlLanguageCharacteristics.cs | 18 + .../src/Legacy/HtmlLanguageCharacteristics.cs | 128 + .../src/Legacy/HtmlMarkupParser.cs | 1951 ++ .../src/Legacy/HtmlTokenizer.cs | 296 + .../src/Legacy/ISpanChunkGenerator.cs | 9 + .../src/Legacy/ITextBuffer.cs | 13 + .../src/Legacy/ITextDocument.cs | 10 + .../src/Legacy/ITokenizer.cs | 12 + .../Legacy/ImplicitExpressionEditHandler.cs | 626 + .../src/Legacy/KnownTokenType.cs | 18 + .../src/Legacy/LanguageCharacteristics.cs | 108 + .../src/Legacy/LegacySyntaxNodeExtensions.cs | 248 + .../src/Legacy/LineTrackingStringBuffer.cs | 173 + .../Legacy/LiteralAttributeChunkGenerator.cs | 44 + .../src/Legacy/LocationTagged.cs | 89 + .../src/Legacy/MarkupChunkGenerator.cs | 13 + .../src/Legacy/ParserBase.cs | 15 + .../src/Legacy/ParserContext.cs | 112 + .../src/Legacy/ParserHelpers.cs | 104 + .../src/Legacy/PartialParseResultInternal.cs | 59 + .../src/Legacy/RazorParser.cs | 47 + .../src/Legacy/RazorSyntaxTreeExtensions.cs | 38 + .../Legacy/RemoveTagHelperChunkGenerator.cs | 86 + .../src/Legacy/SeekableTextReader.cs | 76 + .../src/Legacy/SourceLocationTracker.cs | 113 + .../src/Legacy/SpanChunkGenerator.cs | 33 + .../src/Legacy/SpanContext.cs | 52 + .../src/Legacy/SpanEditHandler.cs | 169 + .../src/Legacy/SpanKindInternal.cs | 15 + .../src/Legacy/StatementChunkGenerator.cs | 13 + .../src/Legacy/SyntaxConstants.cs | 32 + .../src/Legacy/TagHelperAttributeNode.cs | 29 + .../src/Legacy/TagHelperBlockRewriter.cs | 649 + .../src/Legacy/TagHelperDirectiveType.cs | 26 + .../src/Legacy/TagHelperParseTreeRewriter.cs | 727 + .../TagHelperPrefixDirectiveChunkGenerator.cs | 67 + .../src/Legacy/TagHelperSpanInternal.cs | 28 + .../src/Legacy/TextReaderExtensions.cs | 167 + .../src/Legacy/Tokenizer.cs | 445 + .../src/Legacy/TokenizerBackedParser.cs | 594 + .../src/Legacy/TokenizerView.cs | 40 + .../src/Legacy/WhiteSpaceRewriter.cs | 70 + ...Microsoft.AspNetCore.Razor.Language.csproj | 12 + .../src/NotFoundProjectItem.cs | 40 + .../src/Properties/AssemblyInfo.cs | 30 + .../src/Properties/Resources.Designer.cs | 1918 ++ ...ovideRazorExtensionInitializerAttribute.cs | 31 + .../src/RazorCSharpDocument.cs | 69 + .../src/RazorCodeDocument.cs | 56 + .../src/RazorCodeDocumentExtensions.cs | 222 + .../src/RazorCodeGenerationOptions.cs | 104 + .../src/RazorCodeGenerationOptionsBuilder.cs | 56 + .../src/RazorConfiguration.cs | 118 + .../src/RazorDiagnostic.cs | 64 + .../src/RazorDiagnosticCollection.cs | 191 + .../src/RazorDiagnosticDescriptor.cs | 65 + .../src/RazorDiagnosticFactory.cs | 785 + .../src/RazorDiagnosticSeverity.cs | 11 + .../src/RazorEngine.cs | 195 + .../src/RazorEngineBuilderExtensions.cs | 163 + .../src/RazorEngineFeatureBase.cs | 69 + .../src/RazorEnginePhaseBase.cs | 86 + .../src/RazorExtension.cs | 10 + .../src/RazorExtensionInitializer.cs | 10 + .../src/RazorLanguageVersion.cs | 138 + .../src/RazorParserFeatureFlags.cs | 57 + .../src/RazorParserOptions.cs | 66 + .../src/RazorParserOptionsBuilder.cs | 26 + .../src/RazorProject.cs | 138 + .../src/RazorProjectEngine.cs | 232 + .../src/RazorProjectEngineBuilder.cs | 20 + .../RazorProjectEngineBuilderExtensions.cs | 265 + .../src/RazorProjectEngineFeatureBase.cs | 31 + .../src/RazorProjectFileSystem.cs | 27 + .../src/RazorProjectItem.cs | 122 + .../src/RazorSourceDocument.cs | 294 + .../src/RazorSourceDocumentProperties.cs | 57 + .../src/RazorSourceLineCollection.cs | 14 + .../src/RazorSyntaxTree.cs | 71 + .../src/RazorTemplateEngine.cs | 241 + .../src/RazorTemplateEngineOptions.cs | 21 + .../src/RequiredAttributeDescriptor.cs | 96 + .../src/RequiredAttributeDescriptorBuilder.cs | 18 + .../RequiredAttributeDescriptorComparer.cs | 77 + .../src/Resources.resx | 545 + .../src/SourceChange.cs | 139 + .../src/SourceLocation.cs | 135 + .../src/SourceMapping.cs | 53 + .../src/SourceSpan.cs | 124 + .../src/StreamSourceDocument.cs | 119 + .../src/StringSourceDocument.cs | 105 + .../src/SuppressChecksumOptionsFeature.cs | 22 + .../src/Syntax/ArrayElement.cs | 58 + .../src/Syntax/ChildSyntaxList.cs | 710 + .../Syntax.xml.Internal.Generated.cs | 4264 +++++ .../Generated/Syntax.xml.Main.Generated.cs | 1246 ++ .../Generated/Syntax.xml.Syntax.Generated.cs | 3178 ++++ .../src/Syntax/GreenNode.cs | 583 + .../src/Syntax/GreenNodeExtensions.cs | 58 + .../InternalSyntax/RazorDirectiveSyntax.cs | 34 + .../Syntax/InternalSyntax/RazorSyntaxNode.cs | 27 + .../Syntax/InternalSyntax/SyntaxFactory.cs | 26 + .../src/Syntax/InternalSyntax/SyntaxList.cs | 428 + .../InternalSyntax/SyntaxListBuilder.cs | 201 + .../InternalSyntax/SyntaxListBuilderOfT.cs | 115 + .../Syntax/InternalSyntax/SyntaxListOfT.cs | 187 + .../Syntax/InternalSyntax/SyntaxListPool.cs | 100 + .../Syntax/InternalSyntax/SyntaxRewriter.cs | 56 + .../src/Syntax/InternalSyntax/SyntaxToken.cs | 226 + .../src/Syntax/InternalSyntax/SyntaxTrivia.cs | 100 + .../Syntax/InternalSyntax/SyntaxVisitor.cs | 60 + .../src/Syntax/MarkupElementRewriter.cs | 290 + ...MarkupMinimizedTagHelperAttributeSyntax.cs | 33 + .../Syntax/MarkupTagHelperAttributeSyntax.cs | 33 + .../Syntax/MarkupTagHelperElementSyntax.cs | 33 + .../src/Syntax/NodeFlags.cs | 21 + .../src/Syntax/ObjectPool.cs | 248 + .../src/Syntax/RazorDirectiveSyntax.cs | 33 + .../src/Syntax/RazorSyntaxNode.cs | 13 + .../src/Syntax/SpecializedCollections.cs | 169 + .../src/Syntax/Syntax.xml | 230 + .../src/Syntax/SyntaxAnnotation.cs | 93 + .../src/Syntax/SyntaxExtensions.cs | 53 + .../src/Syntax/SyntaxFactory.cs | 23 + .../src/Syntax/SyntaxKind.cs | 136 + .../src/Syntax/SyntaxList.cs | 123 + .../src/Syntax/SyntaxListBuilder.cs | 172 + .../src/Syntax/SyntaxListBuilderExtensions.cs | 29 + .../src/Syntax/SyntaxListBuilderOfT.cs | 93 + .../src/Syntax/SyntaxListOfT.cs | 606 + .../src/Syntax/SyntaxNode.Iterators.cs | 126 + .../src/Syntax/SyntaxNode.cs | 413 + .../src/Syntax/SyntaxNodeExtensions.cs | 339 + .../src/Syntax/SyntaxReplacer.cs | 207 + .../src/Syntax/SyntaxRewriter.cs | 148 + .../src/Syntax/SyntaxSerializer.cs | 304 + .../src/Syntax/SyntaxToken.cs | 105 + .../src/Syntax/SyntaxTrivia.cs | 59 + .../src/Syntax/SyntaxTriviaList.cs | 785 + .../src/Syntax/SyntaxTriviaListBuilder.cs | 138 + .../src/Syntax/SyntaxVisitor.cs | 70 + .../src/Syntax/SyntaxWalker.cs | 55 + .../src/Syntax/TextSpan.cs | 261 + .../src/TagHelperAttributeInfo.cs | 24 + .../src/TagHelperBinder.cs | 137 + .../src/TagHelperBinding.cs | 42 + .../src/TagHelperConventions.cs | 12 + .../src/TagHelperDescriptor.cs | 89 + .../src/TagHelperDescriptorBuilder.cs | 77 + .../TagHelperDescriptorBuilderExtensions.cs | 40 + .../src/TagHelperDescriptorComparer.cs | 155 + .../src/TagHelperDescriptorExtensions.cs | 42 + .../src/TagHelperDescriptorProviderContext.cs | 48 + .../src/TagHelperDocumentContext.cs | 46 + .../src/TagHelperInfo.cs | 24 + .../src/TagHelperMatchingConventions.cs | 186 + .../src/TagHelperMetadata.cs | 20 + .../src/TagHelperSpanVisitor.cs | 31 + .../src/TagMatchingRuleDescriptor.cs | 62 + .../src/TagMatchingRuleDescriptorBuilder.cs | 23 + .../src/TagMatchingRuleDescriptorComparer.cs | 77 + .../src/TagMode.cs | 26 + .../src/TagStructure.cs | 28 + .../src/VirtualRazorProjectFileSystem.cs | 215 + .../src/baseline.netcore.json | 15598 ++++++++++++++++ .../src/baseline.netframework.json | 13608 ++++++++++++++ .../src/breakingchanges.netcore.json | 15 + .../src/breakingchanges.netframework.json | 15 + .../src/Application.cs | 114 + .../src/CachingMetadataReference.cs | 32 + .../src/Client.cs | 200 + .../src/CommandBase.cs | 59 + .../src/CompilerHost.cs | 134 + .../src/CompositeRazorProjectFileSystem.cs | 46 + .../src/ConcurrentLruCache.cs | 207 + .../src/Connection.cs | 28 + .../src/ConnectionHost.cs | 148 + .../src/ConnectionResult.cs | 47 + .../src/DebugMode.cs | 27 + .../src/DefaultExtensionAssemblyLoader.cs | 241 + .../src/DefaultExtensionDependencyChecker.cs | 158 + .../src/DefaultRequestDispatcher.cs | 472 + .../src/DiscoverCommand.cs | 224 + .../src/EventBus.cs | 68 + .../src/ExtensionAssemblyLoader.cs | 16 + .../src/ExtensionDependencyChecker.cs | 12 + .../src/GenerateCommand.cs | 372 + .../src/Memory.cs | 13 + .../src/MetadataCache.cs | 86 + .../src/MetadataReaderExtensions.cs | 94 + .../Microsoft.AspNetCore.Razor.Tools.csproj | 45 + .../src/MutexName.cs | 22 + .../src/PipeName.cs | 60 + .../src/Program.cs | 53 + .../src/Properties/AssemblyInfo.cs | 9 + .../src/RequestDispatcher.cs | 29 + .../src/ServerCommand.cs | 188 + .../ServerProtocol/CompletedServerResponse.cs | 58 + .../MismatchedVersionServerResponse.cs | 17 + .../src/ServerProtocol/NativeMethods.cs | 89 + .../ServerProtocol/RejectedServerResponse.cs | 17 + .../src/ServerProtocol/RequestArgument.cs | 72 + .../src/ServerProtocol/ServerConnection.cs | 390 + .../src/ServerProtocol/ServerLogger.cs | 146 + .../src/ServerProtocol/ServerPaths.cs | 33 + .../src/ServerProtocol/ServerProtocol.cs | 70 + .../src/ServerProtocol/ServerRequest.cs | 216 + .../src/ServerProtocol/ServerResponse.cs | 132 + .../ServerProtocol/ShutdownServerResponse.cs | 30 + .../src/ShadowCopyManager.cs | 169 + .../src/ShutdownCommand.cs | 97 + .../CompositeRazorProjectFileSystemTest.cs | 81 + .../test/ConcurrentLruCacheTest.cs | 120 + .../DefaultExtensionAssemblyLoaderTest.cs | 128 + .../DefaultExtensionDependencyCheckerTest.cs | 111 + .../test/DefaultRequestDispatcherTest.cs | 572 + .../test/Infrastructure/ServerData.cs | 49 + .../test/Infrastructure/ServerStats.cs | 17 + .../test/Infrastructure/ServerUtilities.cs | 156 + .../test/Infrastructure/TestableEventBus.cs | 64 + .../test/LoaderTestResources.cs | 146 + .../test/MetadataCacheTest.cs | 103 + ...crosoft.AspNetCore.Razor.Tools.Test.csproj | 21 + .../test/MvcShim.cs | 45 + .../test/Properties/AssemblyInfo.cs | 6 + .../test/ServerCommandTest.cs | 119 + .../test/ServerLifecycleTest.cs | 291 + .../test/ServerProtocol/ServerProtocolTest.cs | 128 + .../test/TempDirectory.cs | 30 + .../TestDefaultExtensionAssemblyLoader.cs | 25 + .../src/AssemblyIdentityEqualityComparer.cs | 50 + .../src/CompilationTagHelperFeature.cs | 50 + .../ComponentTagHelperDescriptorProvider.cs | 132 + .../src/DefaultMetadataReferenceFeature.cs | 13 + .../src/DefaultTagHelperDescriptorFactory.cs | 439 + .../src/DefaultTagHelperDescriptorProvider.cs | 75 + .../src/FilePathComparer.cs | 30 + .../src/IMetadataReferenceFeature.cs | 13 + .../src/Microsoft.CodeAnalysis.Razor.csproj | 16 + .../src/Properties/AssemblyInfo.cs | 17 + .../src/Properties/Resources.Designer.cs | 142 + .../src/RazorDiagnosticFactory.cs | 175 + .../src/RazorLanguage.cs | 14 + .../src/RequiredAttributeParser.cs | 304 + .../src/Resources.resx | 144 + .../src/SourceSpanExtensions.cs | 16 + ...lperDescriptorProviderContextExtensions.cs | 31 + .../src/TagHelperTypeVisitor.cs | 51 + .../src/TagHelperTypes.cs | 39 + .../src/TextChangeExtensions.cs | 22 + .../src/TextSpanExtensions.cs | 16 + .../src/baseline.netcore.json | 360 + .../src/baseline.netframework.json | 349 + .../test/CompilationTagHelperFeatureTest.cs | 131 + .../DefaultTagHelperDescriptorFactoryTest.cs | 2382 +++ .../DefaultTagHelperDescriptorProviderTest.cs | 54 + .../Microsoft.CodeAnalysis.Razor.Test.csproj | 31 + .../TagHelperDescriptorFactoryTagHelpers.cs | 463 + .../test/TagHelperTypeVisitorTest.cs | 118 + .../test/xunit.runner.json | 4 + .../src/DotnetToolTask.cs | 274 + .../src/Microsoft.NET.Sdk.Razor.csproj | 96 + .../src/Microsoft.NET.Sdk.Razor.nuspec | 25 + .../src/RazorGenerate.cs | 155 + .../src/RazorTagHelper.cs | 133 + .../Microsoft.NET.Sdk.Razor/src/Sdk/Sdk.props | 25 + .../src/Sdk/Sdk.targets | 23 + .../src/baseline.netcore.json | 762 + .../src/baseline.netframework.json | 762 + ...osoft.NET.Sdk.Razor.CodeGeneration.targets | 180 + ...icrosoft.NET.Sdk.Razor.Compilation.targets | 182 + .../Microsoft.NET.Sdk.Razor.Component.targets | 285 + ...rosoft.NET.Sdk.Razor.Configuration.targets | 92 + ...Microsoft.NET.Sdk.Razor.DesignTime.targets | 60 + ...NET.Sdk.Razor.GenerateAssemblyInfo.targets | 185 + .../Microsoft.NET.Sdk.Razor.props | 17 + .../Rules/RazorConfiguration.xaml | 29 + .../netstandard2.0/Rules/RazorExtension.xaml | 37 + .../netstandard2.0/Rules/RazorGeneral.xaml | 36 + .../Rules/RazorGenerateWithTargetPath.xaml | 30 + .../Sdk.Razor.CurrentVersion.props | 86 + .../Sdk.Razor.CurrentVersion.targets | 722 + .../Microsoft.NET.Sdk.Razor.props | 17 + ...azor.CurrentVersion.MultiTargeting.targets | 22 + .../test/BuildVariables.cs | 41 + .../test/BuildVariables.cs.template | 15 + .../test/IntegrationTests/Assert.cs | 733 + .../BuildIncrementalismTest.cs | 360 + .../IntegrationTests/BuildIntegrationTest.cs | 684 + .../BuildIntrospectionTest.cs | 76 + .../IntegrationTests/BuildPerformanceTest.cs | 109 + .../BuildServerIntegrationTest.cs | 266 + .../BuildServerTestFixture.cs | 62 + .../BuildWithComponentsIntegrationTest.cs | 41 + .../ConfigurationMetadataIntegrationTest.cs | 71 + .../DesignTimeBuildIntegrationTest.cs | 68 + .../test/IntegrationTests/FIleThumbPrint.cs | 49 + .../InitializeTestProjectAttribute.cs | 54 + .../MSBuildIntegrationTestBase.cs | 173 + .../IntegrationTests/MSBuildProcessKind.cs | 14 + .../IntegrationTests/MSBuildProcessManager.cs | 152 + .../test/IntegrationTests/MSBuildResult.cs | 27 + .../IntegrationTests/PackIntegrationTest.cs | 180 + .../test/IntegrationTests/ProjectDirectory.cs | 187 + .../PublishIntegrationTest.cs | 446 + .../RazorCompileIntegrationTest.cs | 114 + .../RazorGenerateIntegrationTest.cs | 358 + .../test/Microsoft.NET.Sdk.Razor.Test.csproj | 54 + .../test/xunit.runner.json | 5 + .../TestCodeRenderingContext.cs | 99 + .../CompilationFailedException.cs | 58 + .../IntegrationTests/CompiledAssembly.cs | 24 + .../IntegrationTests/CompiledCSharpCode.cs | 21 + .../IntegrationTests/IntegrationTestBase.cs | 639 + .../IntermediateNodeSerializer.cs | 46 + .../IntermediateNodeVerifier.cs | 275 + .../IntermediateNodeWriter.cs | 306 + .../IntializeTestFileAttribute.cs | 28 + .../RazorDiagnosticSerializer.cs | 13 + .../SourceMappingsSerializer.cs | 48 + .../Intermediate/IntermediateNodeAssert.cs | 495 + .../ClassifiedSpanSerializer.cs | 22 + .../ClassifiedSpan/ClassifiedSpanVerifier.cs | 111 + .../ClassifiedSpan/ClassifiedSpanWriter.cs | 56 + .../Legacy/IntializeTestFileAttribute.cs | 36 + .../Language/Legacy/ParserTestBase.cs | 463 + .../Language/Legacy/SyntaxNodeSerializer.cs | 61 + .../Language/Legacy/SyntaxNodeVerifier.cs | 296 + .../Language/Legacy/SyntaxNodeWalker.cs | 37 + .../Language/Legacy/SyntaxNodeWriter.cs | 219 + .../TagHelperSpan/TagHelperSpanSerializer.cs | 22 + .../TagHelperSpan/TagHelperSpanVerifier.cs | 111 + .../TagHelperSpan/TagHelperSpanWriter.cs | 62 + .../Language/RazorEngineBuilderExtensions.cs | 71 + .../RazorProjectEngineBuilderExtensions.cs | 70 + .../Language/SyntaxTreeVerifier.cs | 46 + ...undAttributeDescriptorBuilderExtensions.cs | 123 + .../Language/TestFile.cs | 89 + .../Language/TestProject.cs | 28 + .../Language/TestRazorCodeDocument.cs | 27 + .../Language/TestRazorProjectFileSystem.cs | 41 + .../Language/TestRazorProjectItem.cs | 49 + .../Language/TestRazorSourceDocument.cs | 113 + ...redAttributeDescriptorBuilderExtensions.cs | 69 + ...estTagHelperDescriptorBuilderExtensions.cs | 122 + .../Language/TestTagHelperFeature.cs | 27 + ...MatchingRuleDescriptorBuilderExtensions.cs | 72 + ...rosoft.AspNetCore.Razor.Test.Common.csproj | 22 + .../Properties/AssemblyInfo.cs | 15 + .../TestCompilation.cs | 71 + ...NetCore.Razor.Test.MvcShim.ClassLib.csproj | 19 + .../HelperResult.cs | 22 + .../IRazorPage.cs | 31 + .../RazorInjectAttribute.cs | 14 + .../RazorPage.cs | 55 + .../RazorPageOfT.cs | 14 + .../RenderAsyncDelegate.cs | 10 + .../IHtmlHelperOfT.cs | 9 + .../IJsonHelper.cs | 10 + .../ViewContext.cs | 12 + .../IModelExpressionProvider.cs | 15 + .../ITempDataDictionary.cs | 9 + .../IViewContextAware.cs | 12 + .../ModelExpression.cs | 9 + .../ViewContextAttribute.cs | 11 + .../ViewDataDictionary.cs | 92 + .../ViewDataDictionaryOfT.cs | 7 + .../Microsoft.AspNetCore.Mvc/IUrlHelper.cs | 10 + .../IViewComponentHelper.cs | 16 + .../ViewComponentAttribute.cs | 11 + ...tCore.Razor.Test.MvcShim.Version1_X.csproj | 16 + .../xunit.runner.json | 3 + ...iledRazorAssemblyApplicationPartFactory.cs | 10 + .../ProvideApplicationPartFactoryAttribute.cs | 19 + .../RelatedAssemblyAttribute.cs | 15 + .../HelperResult.cs | 22 + .../RazorInjectAttribute.cs | 14 + .../RazorPage.cs | 48 + .../RazorPageBase.cs | 165 + .../RazorPageOfT.cs | 14 + .../RazorViewAttribute.cs | 27 + .../RenderAsyncDelegate.cs | 9 + .../Page.cs | 32 + .../PageContext.cs | 12 + .../PageModel.cs | 43 + .../RazorPageAttribute.cs | 19 + .../IHtmlHelperOfT.cs | 9 + .../IJsonHelper.cs | 10 + .../ViewContext.cs | 12 + .../IModelExpressionProvider.cs | 15 + .../ITempDataDictionary.cs | 9 + .../IViewContextAware.cs | 12 + .../ModelExpression.cs | 9 + .../ViewContextAttribute.cs | 11 + .../ViewDataDictionary.cs | 92 + .../ViewDataDictionaryOfT.cs | 7 + .../Microsoft.AspNetCore.Mvc/ActionResult.cs | 10 + .../Microsoft.AspNetCore.Mvc/IActionResult.cs | 9 + .../Microsoft.AspNetCore.Mvc/IUrlHelper.cs | 10 + .../IViewComponentHelper.cs | 16 + .../RedirectResult.cs | 10 + .../ViewComponentAttribute.cs | 11 + ...tCore.Razor.Test.MvcShim.Version2_X.csproj | 16 + .../xunit.runner.json | 3 + .../Component.cs | 16 + .../IComponent.cs | 9 + .../RenderTree/RenderTreeBuilder.cs | 9 + ...iledRazorAssemblyApplicationPartFactory.cs | 10 + .../ProvideApplicationPartFactoryAttribute.cs | 19 + .../RelatedAssemblyAttribute.cs | 15 + .../HelperResult.cs | 22 + .../RazorInjectAttribute.cs | 14 + .../RazorPage.cs | 48 + .../RazorPageBase.cs | 165 + .../RazorPageOfT.cs | 14 + .../RazorViewAttribute.cs | 27 + .../RenderAsyncDelegate.cs | 9 + .../Page.cs | 32 + .../PageContext.cs | 12 + .../PageModel.cs | 43 + .../RazorPageAttribute.cs | 19 + .../IHtmlHelperOfT.cs | 9 + .../IJsonHelper.cs | 10 + .../ViewContext.cs | 12 + .../IModelExpressionProvider.cs | 15 + .../ITempDataDictionary.cs | 9 + .../IViewContextAware.cs | 12 + .../ModelExpression.cs | 9 + .../ViewContextAttribute.cs | 11 + .../ViewDataDictionary.cs | 92 + .../ViewDataDictionaryOfT.cs | 7 + .../Microsoft.AspNetCore.Mvc/ActionResult.cs | 10 + .../Microsoft.AspNetCore.Mvc/IActionResult.cs | 9 + .../Microsoft.AspNetCore.Mvc/IUrlHelper.cs | 10 + .../IViewComponentHelper.cs | 16 + .../RedirectResult.cs | 10 + .../ViewComponentAttribute.cs | 11 + ...osoft.AspNetCore.Razor.Test.MvcShim.csproj | 16 + .../xunit.runner.json | 3 + .../AppWithP2PReference.csproj | 34 + .../Models/ErrorViewModel.cs | 11 + .../testassets/AppWithP2PReference/Program.cs | 13 + .../Views/Home/About.cshtml | 7 + .../Views/Home/Contact.cshtml | 17 + .../Views/Home/Index.cshtml | 108 + .../Views/Shared/Error.cshtml | 22 + .../Shared/_ValidationScriptsPartial.cshtml | 18 + .../Views/_ViewImports.cshtml | 3 + .../Views/_ViewStart.cshtml | 3 + .../test/testassets/ClassLibrary/Class1.cs | 7 + .../ClassLibrary/ClassLibrary.csproj | 40 + .../ClassLibrary/Views/Shared/_Layout.cshtml | 71 + .../ClassLibrary/Views/_ViewImports.cshtml | 2 + .../test/testassets/ClassLibrary2/Class2.cs | 13 + .../ClassLibrary2/ClassLibrary2.csproj | 39 + .../ClassLibrary2/Views/Shared/Index.cshtml | 2 + .../ClassLibrary2/Views/_ViewImports.cshtml | 2 + .../Areas/MyFeature/Pages/Page1.cshtml | 16 + .../Areas/MyFeature/Pages/Page1.cshtml.cs | 17 + .../ClassLibraryMvc21.csproj | 18 + .../test/testassets/Directory.Build.props | 35 + .../test/testassets/Directory.Build.targets | 9 + .../LargeProject/LargeProject.csproj | 31 + .../LargeProject/Views/Home/View000.cshtml | 71 + .../LargeProject/Views/Home/View001.cshtml | 7 + .../LargeProject/Views/Home/View002.cshtml | 108 + .../LargeProject/Views/Home/View003.cshtml | 17 + .../LargeProject/Views/Shared/_Layout.cshtml | 71 + .../Views/Shared/_ViewImports.cshtml | 2 + .../Views/Shared/_ViewStart.cshtml | 3 + .../LinkedDir/LinkedErrorFile.cshtml | 1 + .../testassets/LinkedDir/LinkedFile.cshtml | 1 + .../testassets/LinkedDir/LinkedFile2.cshtml | 1 + .../testassets/LinkedDir/LinkedFile3.cshtml | 1 + .../Models/ErrorViewModel.cs | 11 + .../MvcWithComponents.csproj | 31 + .../testassets/MvcWithComponents/Program.cs | 13 + .../MvcWithComponents/TestComponent.razor | 1 + .../MvcWithComponents/Views/Home/Index.cshtml | 5 + .../Views/Shared/NavMenu.razor | 2 + .../Views/_ViewImports.cshtml | 3 + .../MvcWithComponents/Views/_ViewStart.cshtml | 3 + .../RazorTest.Introspection.targets | 28 + .../SimpleMvc/Models/ErrorViewModel.cs | 11 + .../test/testassets/SimpleMvc/Program.cs | 13 + .../testassets/SimpleMvc/SimpleMvc.csproj | 31 + .../testassets/SimpleMvc/SimpleTagHelper.cs | 8 + .../SimpleMvc/Views/Home/About.cshtml | 7 + .../SimpleMvc/Views/Home/Contact.cshtml | 17 + .../SimpleMvc/Views/Home/Index.cshtml | 108 + .../SimpleMvc/Views/Shared/Error.cshtml | 22 + .../SimpleMvc/Views/Shared/_Layout.cshtml | 71 + .../Shared/_ValidationScriptsPartial.cshtml | 18 + .../SimpleMvc/Views/_ViewImports.cshtml | 3 + .../SimpleMvc/Views/_ViewStart.cshtml | 3 + .../testassets/SimpleMvc/wwwroot/css/site.css | 37 + .../SimpleMvc/wwwroot/js/SimpleMvc.js | 1 + .../SimpleMvc21/Models/ErrorViewModel.cs | 11 + .../test/testassets/SimpleMvc21/Program.cs | 13 + .../testassets/SimpleMvc21/SimpleMvc21.csproj | 31 + .../SimpleMvc21/Views/Home/About.cshtml | 7 + .../SimpleMvc21/Views/Home/Index.cshtml | 108 + .../SimpleMvc21/Views/Shared/_Layout.cshtml | 71 + .../Shared/_ValidationScriptsPartial.cshtml | 18 + .../SimpleMvc21/Views/_ViewImports.cshtml | 4 + .../SimpleMvc21/Views/_ViewStart.cshtml | 3 + .../SimpleMvcFSharp/Models/ErrorViewModel.fs | 8 + .../testassets/SimpleMvcFSharp/Program.fs | 11 + .../SimpleMvcFSharp/SimpleMvcFSharp.fsproj | 36 + .../SimpleMvcFSharp/Views/Home/About.cshtml | 7 + .../SimpleMvcFSharp/Views/_ViewImports.cshtml | 2 + .../Areas/Products/Pages/Index.cshtml | 107 + .../Areas/Products/Pages/_ViewImports.cshtml | 3 + .../Areas/Products/Pages/_ViewStart.cshtml | 3 + .../testassets/SimplePages/Pages/About.cshtml | 9 + .../SimplePages/Pages/About.cshtml.cs | 18 + .../SimplePages/Pages/Contact.cshtml | 19 + .../SimplePages/Pages/Contact.cshtml.cs | 18 + .../testassets/SimplePages/Pages/Index.cshtml | 108 + .../SimplePages/Pages/Index.cshtml.cs | 17 + .../SimplePages/Pages/_Layout.cshtml | 71 + .../SimplePages/Pages/_ViewImports.cshtml | 3 + .../SimplePages/Pages/_ViewStart.cshtml | 3 + .../test/testassets/SimplePages/Program.cs | 10 + .../testassets/SimplePages/SimplePages.csproj | 31 + .../RazorDiagnosticJsonConverter.cs | 66 + 1290 files changed, 153085 insertions(+) create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/CSharpIdentifier.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ExtensionInitializer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/IInjectTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/IViewComponentTagHelperTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/LegacySectionTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ModelDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ModelExpressionPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcImportProjectFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcRazorTemplateEngine.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcViewDocumentClassifierPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/Resources.Designer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/ViewComponentResources.Designer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/RazorExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/RazorExtensionsDiagnosticFactory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Resources.resx create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/TagHelperDescriptorExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentResources.resx create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperConventions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperDescriptorFactory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperDescriptorProvider.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperMetadata.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTypeVisitor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTypes.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/InjectDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/InjectTargetExtensionTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/LegacySectionTargetExtensionTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ModelDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ModelExpressionPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcImportProjectFeatureTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcRazorTemplateEngineTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcShim.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcViewDocumentClassifierPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/SourceMappingsSerializer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TagHelperDescriptorExtensionsTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperTargetExtensionTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTypeVisitorTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/xunit.runner.json create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/AssemblyAttributeInjectionPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/CSharpIdentifier.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ExtensionInitializer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/IInjectTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/IViewComponentTagHelperTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InstrumentationPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ModelDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ModelExpressionPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/MvcImportProjectFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/MvcViewDocumentClassifierPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/NamespaceDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/PageDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/PagesPropertyInjectionPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/Resources.Designer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/ViewComponentResources.Designer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorExtensionsDiagnosticFactory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorPageDocumentClassifierPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Resources.resx create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/TagHelperDescriptorExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentResources.resx create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperConventions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperDescriptorFactory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperDescriptorProvider.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperMetadata.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTypeVisitor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTypes.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/baseline.netcore.json create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/baseline.netframework.json create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/AssemblyAttributeInjectionPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InjectDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InjectTargetExtensionTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InstrumentationPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/InstrumentationPassIntegrationTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ModelDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ModelExpressionPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcImportProjectFeatureTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcShim.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcViewDocumentClassifierPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/NamespaceDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/PageDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/RazorPageDocumentClassifierPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/SourceMappingsSerializer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TagHelperDescriptorExtensionsTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperTargetExtensionTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTypeVisitorTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/xunit.runner.json create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/AssemblyAttributeInjectionPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ExtensionInitializer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/IInjectTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/IViewComponentTagHelperTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ModelDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ModelExpressionPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcImportProjectFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcRazorTemplateEngine.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcViewDocumentClassifierPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/NamespaceDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/PageDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/PagesPropertyInjectionPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/Resources.Designer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/ViewComponentResources.Designer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorExtensionsDiagnosticFactory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorPageDocumentClassifierPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Resources.resx create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/TagHelperDescriptorExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentResources.resx create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperConventions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorFactory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorProvider.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperMetadata.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTypeVisitor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTypes.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/baseline.netcore.json create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/baseline.netframework.json create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/breakingchanges.netcore.json create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/breakingchanges.netframework.json create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/AssemblyAttributeInjectionPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/InjectDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/InjectTargetExtensionTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/IntegrationTests/CodeGenerationIntegrationTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ModelDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ModelExpressionPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcImportProjectFeatureTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcRazorTemplateEngineTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcShim.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcViewDocumentClassifierPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/NamespaceDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/PageDirectiveTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/RazorPageDocumentClassifierPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/SourceMappingsSerializer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TagHelperDescriptorExtensionsTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorFactoryTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperPassTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperTargetExtensionTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTypeVisitorTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/xunit.runner.json create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptorComparer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/AssemblyExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/AttributeStructure.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilderExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CSharpIdentifier.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Checksum.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeRenderingContext.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeTarget.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeTargetBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeWriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeWriterExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeRenderingContext.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeTarget.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeTargetBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultDocumentWriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DesignTimeNodeWriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DocumentWriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/ICodeTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/IntermediateNodeWriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/LiteralRuntimeNodeWriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/RuntimeNodeWriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/TagHelperHtmlAttributeRuntimeNodeWriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/TagHelperRenderingContext.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/CodeGenerationConstants.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDocumentClassifierPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultAllowedChildTagDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultAllowedChildTagDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDirectiveSyntaxTreePass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDocumentClassifierPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDocumentClassifierPassFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultImportProjectFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCSharpDocument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCSharpLoweringPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeDocument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsFactoryProjectFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDiagnostic.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDirectiveClassifierPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDirectiveFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDocumentClassifierPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorEngine.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorEngineBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorOptimizationPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsFactoryProjectFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParsingPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngine.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngineBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectFileSystem.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectItem.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSourceLineCollection.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSyntaxTree.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSyntaxTreePhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperBinderPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTargetExtensionFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRequiredAttributeDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRequiredAttributeDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagMatchingRuleDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagMatchingRuleDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptorBuilderExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptorComparer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveKind.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveRemovalOptimizationPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenDescriptorComparer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenEditHandler.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenKind.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveUsage.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/DocumentClassifierPassBase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/EmptyProjectFileSystem.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultMetadataIdentifierFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperBodyIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperCreateIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperExecuteIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperHtmlAttributeIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperOptimizationPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperPropertyIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperRuntimeIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectiveIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectivePass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectiveTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/EliminateMethodBodyPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/FunctionsDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/FunctionsDirectivePass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IDefaultTagHelperTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IDesignTimeDirectiveTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IMetadataAttributeTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IMetadataIdentifierFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IPreallocatedAttributeTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/ISectionTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/ITemplateTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/InheritsDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/InheritsDirectivePass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/MetadataAttributePass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/MetadataAttributeTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedAttributeTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperAttributeOptimizationPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperHtmlAttributeIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperHtmlAttributeValueIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperPropertyIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperPropertyValueIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorCompiledItemAttributeIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorCompiledItemMetadataAttributeIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorSourceChecksumAttributeIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionDirective.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionDirectivePass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/TemplateIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/TemplateTargetExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/HtmlConventions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/HtmlNodeOptimizationPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IConfigureRazorCodeGenerationOptionsFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IConfigureRazorParserOptionsFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IDirectiveDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IImportProjectFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCSharpLoweringPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCodeGenerationOptionsFactoryProjectFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCodeGenerationOptionsFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveClassifierPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveClassifierPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDocumentClassifierPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDocumentClassifierPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEngineBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEngineFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEnginePhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorIntermediateNodeLoweringPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorOptimizationPass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorOptimizationPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParserOptionsFactoryProjectFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParserOptionsFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParsingPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorProjectEngineFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorSyntaxTreePass.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorSyntaxTreePhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorTagHelperBinderPhase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorTargetExtensionFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/ITagHelperDescriptorProvider.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/ITagHelperFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpCodeAttributeValueIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpCodeIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpExpressionAttributeValueIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpExpressionIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/ClassDeclarationIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CommonAnnotations.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DebuggerDisplayFormatter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DefaultRazorIntermediateNodeBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DirectiveIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DirectiveTokenIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DocumentIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DocumentIntermediateNodeExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/ExtensionIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/FieldDeclarationIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlAttributeIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlAttributeValueIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlContentIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IExtensionIntermediateNodeVisitor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/InputDocumentKind.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeCollection.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeFormatter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeFormatterBase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeReference.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeVisitor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeWalker.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateToken.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MalformedDirectiveIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MemberDeclarationIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MethodDeclarationIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MethodParameter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/NamespaceDeclarationIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/PropertyDeclarationIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperBodyIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperHtmlAttributeIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperPropertyIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TokenKind.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TypeParameter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/UsingDirectiveIntermediateNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/IntermediateNodePassBase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/ItemCollection.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/LargeTextSourceDocument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AcceptedCharactersInternal.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AddImportChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AddTagHelperChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AutoCompleteEditHandler.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/BalancingModes.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/BlockKindInternal.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpCodeParser.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpKeyword.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpLanguageCharacteristics.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpTokenizer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ClassifiedSpanInternal.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CodeBlockEditHandler.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveCSharpTokenizer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveHtmlTokenizer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveTokenChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DisposableAction.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/EditResult.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ErrorSink.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ExpressionChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/FirstDirectiveCSharpLanguageCharacteristics.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/FirstDirectiveHtmlLanguageCharacteristics.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlLanguageCharacteristics.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlTokenizer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ISpanChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ITextBuffer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ITextDocument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ITokenizer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ImplicitExpressionEditHandler.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/KnownTokenType.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/LanguageCharacteristics.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/LegacySyntaxNodeExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/LineTrackingStringBuffer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/LiteralAttributeChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/LocationTagged.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/MarkupChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ParserBase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ParserContext.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ParserHelpers.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/PartialParseResultInternal.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/RazorParser.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/RazorSyntaxTreeExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/RemoveTagHelperChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/SeekableTextReader.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/SourceLocationTracker.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/SpanChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/SpanContext.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/SpanEditHandler.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/SpanKindInternal.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/StatementChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/SyntaxConstants.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperAttributeNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperDirectiveType.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperPrefixDirectiveChunkGenerator.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperSpanInternal.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TextReaderExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/Tokenizer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TokenizerBackedParser.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TokenizerView.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/WhiteSpaceRewriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Microsoft.AspNetCore.Razor.Language.csproj create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/NotFoundProjectItem.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/Resources.Designer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/ProvideRazorExtensionInitializerAttribute.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCSharpDocument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeDocument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeDocumentExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptionsBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorConfiguration.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorDiagnostic.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorDiagnosticCollection.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorDiagnosticDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorDiagnosticFactory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorDiagnosticSeverity.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorEngine.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorEngineBuilderExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorEngineFeatureBase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorEnginePhaseBase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorExtension.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorExtensionInitializer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorLanguageVersion.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorParserFeatureFlags.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorParserOptions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorParserOptionsBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProject.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngine.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngineBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngineBuilderExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngineFeatureBase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectFileSystem.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectItem.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorSourceDocument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorSourceDocumentProperties.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorSourceLineCollection.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorSyntaxTree.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorTemplateEngine.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorTemplateEngineOptions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RequiredAttributeDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RequiredAttributeDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/RequiredAttributeDescriptorComparer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Resources.resx create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/SourceChange.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/SourceLocation.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/SourceMapping.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/SourceSpan.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/StreamSourceDocument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/StringSourceDocument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/SuppressChecksumOptionsFeature.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/ArrayElement.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/ChildSyntaxList.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Internal.Generated.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Main.Generated.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Syntax.Generated.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/GreenNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/GreenNodeExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/RazorDirectiveSyntax.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/RazorSyntaxNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxFactory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxList.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxListBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxListBuilderOfT.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxListOfT.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxListPool.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxRewriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxToken.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxTrivia.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/InternalSyntax/SyntaxVisitor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/MarkupElementRewriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/MarkupMinimizedTagHelperAttributeSyntax.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/MarkupTagHelperAttributeSyntax.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/MarkupTagHelperElementSyntax.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/NodeFlags.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/ObjectPool.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/RazorDirectiveSyntax.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/RazorSyntaxNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SpecializedCollections.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Syntax.xml create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxAnnotation.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxFactory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxKind.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxList.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxListBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxListBuilderExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxListBuilderOfT.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxListOfT.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNode.Iterators.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNodeExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxReplacer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxRewriter.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxSerializer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxToken.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxTrivia.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxTriviaList.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxTriviaListBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxVisitor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxWalker.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/TextSpan.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperAttributeInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperBinder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperBinding.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperConventions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorBuilderExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorComparer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorProviderContext.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDocumentContext.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperMatchingConventions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperMetadata.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperSpanVisitor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagMatchingRuleDescriptor.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagMatchingRuleDescriptorBuilder.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagMatchingRuleDescriptorComparer.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagMode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagStructure.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/VirtualRazorProjectFileSystem.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/baseline.netcore.json create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/baseline.netframework.json create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/breakingchanges.netcore.json create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/breakingchanges.netframework.json create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Application.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/CachingMetadataReference.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Client.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/CommandBase.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/CompilerHost.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/CompositeRazorProjectFileSystem.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ConcurrentLruCache.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Connection.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ConnectionHost.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ConnectionResult.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/DebugMode.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/DefaultExtensionAssemblyLoader.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/DefaultExtensionDependencyChecker.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/DefaultRequestDispatcher.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/DiscoverCommand.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/EventBus.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ExtensionAssemblyLoader.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ExtensionDependencyChecker.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/GenerateCommand.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Memory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/MetadataCache.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/MetadataReaderExtensions.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Microsoft.AspNetCore.Razor.Tools.csproj create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/MutexName.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/PipeName.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Program.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/RequestDispatcher.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerCommand.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/CompletedServerResponse.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/MismatchedVersionServerResponse.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/NativeMethods.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/RejectedServerResponse.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/RequestArgument.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/ServerConnection.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/ServerLogger.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/ServerPaths.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/ServerProtocol.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/ServerRequest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/ServerResponse.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ServerProtocol/ShutdownServerResponse.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ShadowCopyManager.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/src/ShutdownCommand.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/CompositeRazorProjectFileSystemTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/ConcurrentLruCacheTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/DefaultExtensionAssemblyLoaderTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/DefaultExtensionDependencyCheckerTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/DefaultRequestDispatcherTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Infrastructure/ServerData.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Infrastructure/ServerStats.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Infrastructure/ServerUtilities.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Infrastructure/TestableEventBus.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/LoaderTestResources.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/MetadataCacheTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Microsoft.AspNetCore.Razor.Tools.Test.csproj create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/MvcShim.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/ServerCommandTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/ServerLifecycleTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/ServerProtocol/ServerProtocolTest.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/TempDirectory.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Tools/test/TestDefaultExtensionAssemblyLoader.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/AssemblyIdentityEqualityComparer.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/CompilationTagHelperFeature.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultMetadataReferenceFeature.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorFactory.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorProvider.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/FilePathComparer.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/IMetadataReferenceFeature.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/Microsoft.CodeAnalysis.Razor.csproj create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/AssemblyInfo.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/Resources.Designer.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/RazorDiagnosticFactory.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/RazorLanguage.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/RequiredAttributeParser.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/Resources.resx create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/SourceSpanExtensions.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/TagHelperDescriptorProviderContextExtensions.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/TagHelperTypeVisitor.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/TagHelperTypes.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/TextChangeExtensions.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/TextSpanExtensions.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/baseline.netcore.json create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/src/baseline.netframework.json create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/test/CompilationTagHelperFeatureTest.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorFactoryTest.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/test/Microsoft.CodeAnalysis.Razor.Test.csproj create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/test/TagHelperDescriptorFactoryTagHelpers.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/test/TagHelperTypeVisitorTest.cs create mode 100644 src/Razor/Microsoft.CodeAnalysis.Razor/test/xunit.runner.json create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/DotnetToolTask.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.nuspec create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/RazorGenerate.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/RazorTagHelper.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/Sdk/Sdk.props create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/Sdk/Sdk.targets create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/baseline.netcore.json create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/baseline.netframework.json create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.CodeGeneration.targets create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Compilation.targets create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Configuration.targets create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.GenerateAssemblyInfo.targets create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.props create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorConfiguration.xaml create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorExtension.xaml create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorGeneral.xaml create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorGenerateWithTargetPath.xaml create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.props create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/buildMultiTargeting/Microsoft.NET.Sdk.Razor.props create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/src/buildMultiTargeting/Sdk.Razor.CurrentVersion.MultiTargeting.targets create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/BuildVariables.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/BuildVariables.cs.template create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/Assert.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildIncrementalismTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildIntegrationTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildIntrospectionTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildPerformanceTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerIntegrationTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerTestFixture.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildWithComponentsIntegrationTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/ConfigurationMetadataIntegrationTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/DesignTimeBuildIntegrationTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/FIleThumbPrint.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/InitializeTestProjectAttribute.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/MSBuildIntegrationTestBase.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/MSBuildProcessKind.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/MSBuildProcessManager.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/MSBuildResult.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/PackIntegrationTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/ProjectDirectory.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/PublishIntegrationTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/RazorCompileIntegrationTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/RazorGenerateIntegrationTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/Microsoft.NET.Sdk.Razor.Test.csproj create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/xunit.runner.json create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/CodeGeneration/TestCodeRenderingContext.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/CompilationFailedException.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/CompiledAssembly.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/CompiledCSharpCode.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/IntegrationTestBase.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/IntermediateNodeSerializer.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/IntermediateNodeVerifier.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/IntermediateNodeWriter.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/IntializeTestFileAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/RazorDiagnosticSerializer.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/SourceMappingsSerializer.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Intermediate/IntermediateNodeAssert.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ClassifiedSpan/ClassifiedSpanSerializer.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ClassifiedSpan/ClassifiedSpanVerifier.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ClassifiedSpan/ClassifiedSpanWriter.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/IntializeTestFileAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeSerializer.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeVerifier.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWalker.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWriter.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/TagHelperSpan/TagHelperSpanSerializer.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/TagHelperSpan/TagHelperSpanVerifier.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/TagHelperSpan/TagHelperSpanWriter.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/RazorEngineBuilderExtensions.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/RazorProjectEngineBuilderExtensions.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/SyntaxTreeVerifier.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestBoundAttributeDescriptorBuilderExtensions.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestFile.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestProject.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestRazorCodeDocument.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestRazorProjectFileSystem.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestRazorProjectItem.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestRazorSourceDocument.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestRequiredAttributeDescriptorBuilderExtensions.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperDescriptorBuilderExtensions.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperFeature.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagMatchingRuleDescriptorBuilderExtensions.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Microsoft.AspNetCore.Razor.Test.Common.csproj create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Properties/AssemblyInfo.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/TestCompilation.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib/Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.Razor/HelperResult.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.Razor/IRazorPage.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.Razor/RazorInjectAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.Razor/RazorPageOfT.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.Razor/RenderAsyncDelegate.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.Rendering/IHtmlHelperOfT.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.Rendering/IJsonHelper.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.Rendering/ViewContext.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.ViewFeatures/IModelExpressionProvider.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ITempDataDictionary.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.ViewFeatures/IViewContextAware.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ModelExpression.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewContextAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewDataDictionary.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewDataDictionaryOfT.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc/IUrlHelper.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc/IViewComponentHelper.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Mvc/ViewComponentAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X.csproj create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/xunit.runner.json create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ApplicationParts/CompiledRazorAssemblyApplicationPartFactory.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ApplicationParts/ProvideApplicationPartFactoryAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ApplicationParts/RelatedAssemblyAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Razor/HelperResult.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Razor/RazorInjectAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Razor/RazorPageBase.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Razor/RazorPageOfT.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Razor/RazorViewAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Razor/RenderAsyncDelegate.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.RazorPages/PageContext.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.RazorPages/RazorPageAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Rendering/IHtmlHelperOfT.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Rendering/IJsonHelper.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.Rendering/ViewContext.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ViewFeatures/IModelExpressionProvider.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ITempDataDictionary.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ViewFeatures/IViewContextAware.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ModelExpression.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewContextAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewDataDictionary.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewDataDictionaryOfT.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc/ActionResult.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc/IActionResult.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc/IUrlHelper.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc/IViewComponentHelper.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc/RedirectResult.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Mvc/ViewComponentAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X.csproj create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/xunit.runner.json create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Components/Component.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Components/IComponent.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Components/RenderTree/RenderTreeBuilder.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ApplicationParts/CompiledRazorAssemblyApplicationPartFactory.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ApplicationParts/ProvideApplicationPartFactoryAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ApplicationParts/RelatedAssemblyAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Razor/HelperResult.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Razor/RazorInjectAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Razor/RazorPageBase.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Razor/RazorPageOfT.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Razor/RazorViewAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Razor/RenderAsyncDelegate.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.RazorPages/PageContext.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.RazorPages/RazorPageAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Rendering/IHtmlHelperOfT.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Rendering/IJsonHelper.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.Rendering/ViewContext.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ViewFeatures/IModelExpressionProvider.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ViewFeatures/ITempDataDictionary.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ViewFeatures/IViewContextAware.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ViewFeatures/ModelExpression.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewContextAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewDataDictionary.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewDataDictionaryOfT.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc/ActionResult.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc/IActionResult.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc/IUrlHelper.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc/IViewComponentHelper.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc/RedirectResult.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc/ViewComponentAttribute.cs create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Razor.Test.MvcShim.csproj create mode 100644 src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/xunit.runner.json create mode 100644 src/Razor/test/testassets/AppWithP2PReference/AppWithP2PReference.csproj create mode 100644 src/Razor/test/testassets/AppWithP2PReference/Models/ErrorViewModel.cs create mode 100644 src/Razor/test/testassets/AppWithP2PReference/Program.cs create mode 100644 src/Razor/test/testassets/AppWithP2PReference/Views/Home/About.cshtml create mode 100644 src/Razor/test/testassets/AppWithP2PReference/Views/Home/Contact.cshtml create mode 100644 src/Razor/test/testassets/AppWithP2PReference/Views/Home/Index.cshtml create mode 100644 src/Razor/test/testassets/AppWithP2PReference/Views/Shared/Error.cshtml create mode 100644 src/Razor/test/testassets/AppWithP2PReference/Views/Shared/_ValidationScriptsPartial.cshtml create mode 100644 src/Razor/test/testassets/AppWithP2PReference/Views/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/AppWithP2PReference/Views/_ViewStart.cshtml create mode 100644 src/Razor/test/testassets/ClassLibrary/Class1.cs create mode 100644 src/Razor/test/testassets/ClassLibrary/ClassLibrary.csproj create mode 100644 src/Razor/test/testassets/ClassLibrary/Views/Shared/_Layout.cshtml create mode 100644 src/Razor/test/testassets/ClassLibrary/Views/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/ClassLibrary2/Class2.cs create mode 100644 src/Razor/test/testassets/ClassLibrary2/ClassLibrary2.csproj create mode 100644 src/Razor/test/testassets/ClassLibrary2/Views/Shared/Index.cshtml create mode 100644 src/Razor/test/testassets/ClassLibrary2/Views/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/ClassLibraryMvc21/Areas/MyFeature/Pages/Page1.cshtml create mode 100644 src/Razor/test/testassets/ClassLibraryMvc21/Areas/MyFeature/Pages/Page1.cshtml.cs create mode 100644 src/Razor/test/testassets/ClassLibraryMvc21/ClassLibraryMvc21.csproj create mode 100644 src/Razor/test/testassets/Directory.Build.props create mode 100644 src/Razor/test/testassets/Directory.Build.targets create mode 100644 src/Razor/test/testassets/LargeProject/LargeProject.csproj create mode 100644 src/Razor/test/testassets/LargeProject/Views/Home/View000.cshtml create mode 100644 src/Razor/test/testassets/LargeProject/Views/Home/View001.cshtml create mode 100644 src/Razor/test/testassets/LargeProject/Views/Home/View002.cshtml create mode 100644 src/Razor/test/testassets/LargeProject/Views/Home/View003.cshtml create mode 100644 src/Razor/test/testassets/LargeProject/Views/Shared/_Layout.cshtml create mode 100644 src/Razor/test/testassets/LargeProject/Views/Shared/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/LargeProject/Views/Shared/_ViewStart.cshtml create mode 100644 src/Razor/test/testassets/LinkedDir/LinkedErrorFile.cshtml create mode 100644 src/Razor/test/testassets/LinkedDir/LinkedFile.cshtml create mode 100644 src/Razor/test/testassets/LinkedDir/LinkedFile2.cshtml create mode 100644 src/Razor/test/testassets/LinkedDir/LinkedFile3.cshtml create mode 100644 src/Razor/test/testassets/MvcWithComponents/Models/ErrorViewModel.cs create mode 100644 src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj create mode 100644 src/Razor/test/testassets/MvcWithComponents/Program.cs create mode 100644 src/Razor/test/testassets/MvcWithComponents/TestComponent.razor create mode 100644 src/Razor/test/testassets/MvcWithComponents/Views/Home/Index.cshtml create mode 100644 src/Razor/test/testassets/MvcWithComponents/Views/Shared/NavMenu.razor create mode 100644 src/Razor/test/testassets/MvcWithComponents/Views/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/MvcWithComponents/Views/_ViewStart.cshtml create mode 100644 src/Razor/test/testassets/RazorTest.Introspection.targets create mode 100644 src/Razor/test/testassets/SimpleMvc/Models/ErrorViewModel.cs create mode 100644 src/Razor/test/testassets/SimpleMvc/Program.cs create mode 100644 src/Razor/test/testassets/SimpleMvc/SimpleMvc.csproj create mode 100644 src/Razor/test/testassets/SimpleMvc/SimpleTagHelper.cs create mode 100644 src/Razor/test/testassets/SimpleMvc/Views/Home/About.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc/Views/Home/Contact.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc/Views/Home/Index.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc/Views/Shared/Error.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc/Views/Shared/_Layout.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc/Views/Shared/_ValidationScriptsPartial.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc/Views/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc/Views/_ViewStart.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc/wwwroot/css/site.css create mode 100644 src/Razor/test/testassets/SimpleMvc/wwwroot/js/SimpleMvc.js create mode 100644 src/Razor/test/testassets/SimpleMvc21/Models/ErrorViewModel.cs create mode 100644 src/Razor/test/testassets/SimpleMvc21/Program.cs create mode 100644 src/Razor/test/testassets/SimpleMvc21/SimpleMvc21.csproj create mode 100644 src/Razor/test/testassets/SimpleMvc21/Views/Home/About.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc21/Views/Home/Index.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc21/Views/Shared/_Layout.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc21/Views/Shared/_ValidationScriptsPartial.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc21/Views/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvc21/Views/_ViewStart.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvcFSharp/Models/ErrorViewModel.fs create mode 100644 src/Razor/test/testassets/SimpleMvcFSharp/Program.fs create mode 100644 src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj create mode 100644 src/Razor/test/testassets/SimpleMvcFSharp/Views/Home/About.cshtml create mode 100644 src/Razor/test/testassets/SimpleMvcFSharp/Views/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Areas/Products/Pages/Index.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Areas/Products/Pages/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Areas/Products/Pages/_ViewStart.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Pages/About.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Pages/About.cshtml.cs create mode 100644 src/Razor/test/testassets/SimplePages/Pages/Contact.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Pages/Contact.cshtml.cs create mode 100644 src/Razor/test/testassets/SimplePages/Pages/Index.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Pages/Index.cshtml.cs create mode 100644 src/Razor/test/testassets/SimplePages/Pages/_Layout.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Pages/_ViewImports.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Pages/_ViewStart.cshtml create mode 100644 src/Razor/test/testassets/SimplePages/Program.cs create mode 100644 src/Razor/test/testassets/SimplePages/SimplePages.csproj create mode 100644 src/Shared/RazorShared/RazorDiagnosticJsonConverter.cs diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/CSharpIdentifier.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/CSharpIdentifier.cs new file mode 100644 index 0000000000..4e34345903 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/CSharpIdentifier.cs @@ -0,0 +1,71 @@ +// 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 System.Text; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + internal static class CSharpIdentifier + { + private const string CshtmlExtension = ".cshtml"; + + public static string GetClassNameFromPath(string path) + { + if (string.IsNullOrEmpty(path)) + { + return path; + } + + if (path.EndsWith(CshtmlExtension, StringComparison.OrdinalIgnoreCase)) + { + path = path.Substring(0, path.Length - CshtmlExtension.Length); + } + + return SanitizeClassName(path); + } + + // CSharp Spec §2.4.2 + private static bool IsIdentifierStart(char character) + { + return char.IsLetter(character) || + character == '_' || + CharUnicodeInfo.GetUnicodeCategory(character) == UnicodeCategory.LetterNumber; + } + + public static bool IsIdentifierPart(char character) + { + return char.IsDigit(character) || + IsIdentifierStart(character) || + IsIdentifierPartByUnicodeCategory(character); + } + + private static bool IsIdentifierPartByUnicodeCategory(char character) + { + var category = CharUnicodeInfo.GetUnicodeCategory(character); + + return category == UnicodeCategory.NonSpacingMark || // Mn + category == UnicodeCategory.SpacingCombiningMark || // Mc + category == UnicodeCategory.ConnectorPunctuation || // Pc + category == UnicodeCategory.Format; // Cf + } + + public static string SanitizeClassName(string inputName) + { + if (!IsIdentifierStart(inputName[0]) && IsIdentifierPart(inputName[0])) + { + inputName = "_" + inputName; + } + + var builder = new StringBuilder(inputName.Length); + for (var i = 0; i < inputName.Length; i++) + { + var ch = inputName[i]; + builder.Append(IsIdentifierPart(ch) ? ch : '_'); + } + + return builder.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ExtensionInitializer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ExtensionInitializer.cs new file mode 100644 index 0000000000..51f16b552f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ExtensionInitializer.cs @@ -0,0 +1,29 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + internal class ExtensionInitializer : RazorExtensionInitializer + { + public override void Initialize(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + if (builder.Configuration.ConfigurationName == "MVC-1.0") + { + RazorExtensions.Register(builder); + } + else if (builder.Configuration.ConfigurationName == "MVC-1.1") + { + RazorExtensions.Register(builder); + RazorExtensions.RegisterViewComponentTagHelpers(builder); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/IInjectTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/IInjectTargetExtension.cs new file mode 100644 index 0000000000..781932ba8c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/IInjectTargetExtension.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public interface IInjectTargetExtension : ICodeTargetExtension + { + void WriteInjectProperty(CodeRenderingContext context, InjectIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/IViewComponentTagHelperTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/IViewComponentTagHelperTargetExtension.cs new file mode 100644 index 0000000000..45a0d581a5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/IViewComponentTagHelperTargetExtension.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public interface IViewComponentTagHelperTargetExtension : ICodeTargetExtension + { + void WriteViewComponentTagHelper(CodeRenderingContext context, ViewComponentTagHelperIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectDirective.cs new file mode 100644 index 0000000000..f5ea583121 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectDirective.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 System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public static class InjectDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "inject", + DirectiveKind.SingleLine, + builder => + { + builder + .AddTypeToken(Resources.InjectDirective_TypeToken_Name, Resources.InjectDirective_TypeToken_Description) + .AddMemberToken(Resources.InjectDirective_MemberToken_Name, Resources.InjectDirective_MemberToken_Description); + + builder.Usage = DirectiveUsage.FileScopedMultipleOccurring; + builder.Description = Resources.InjectDirective_Description; + }); + + public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + builder.AddTargetExtension(new InjectTargetExtension()); + return builder; + } + + internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + // Runs after the @model and @namespace directives + public override int Order => 10; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var visitor = new Visitor(); + visitor.Visit(documentNode); + var modelType = ModelDirective.GetModelType(documentNode); + + var properties = new HashSet(StringComparer.Ordinal); + + for (var i = visitor.Directives.Count - 1; i >= 0; i--) + { + var directive = visitor.Directives[i]; + var tokens = directive.Tokens.ToArray(); + if (tokens.Length < 2) + { + continue; + } + + var typeName = tokens[0].Content; + var memberName = tokens[1].Content; + + if (!properties.Add(memberName)) + { + continue; + } + + typeName = typeName.Replace("", "<" + modelType + ">"); + + var injectNode = new InjectIntermediateNode() + { + TypeName = typeName, + MemberName = memberName, + }; + + visitor.Class.Children.Add(injectNode); + } + } + } + + private class Visitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Class { get; private set; } + + public IList Directives { get; } = new List(); + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (Class == null) + { + Class = node; + } + + base.VisitClassDeclaration(node); + } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + Directives.Add(node); + } + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static IRazorEngineBuilder Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + builder.AddTargetExtension(new InjectTargetExtension()); + return builder; + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectIntermediateNode.cs new file mode 100644 index 0000000000..8325c2b7a1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectIntermediateNode.cs @@ -0,0 +1,59 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class InjectIntermediateNode : ExtensionIntermediateNode + { + public string TypeName { get; set; } + + public string MemberName { get; set; } + + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteInjectProperty(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(MemberName); + + formatter.WriteProperty(nameof(MemberName), MemberName); + formatter.WriteProperty(nameof(TypeName), TypeName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectTargetExtension.cs new file mode 100644 index 0000000000..23effb4081 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/InjectTargetExtension.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 System; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class InjectTargetExtension : IInjectTargetExtension + { + private const string RazorInjectAttribute = "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]"; + + public void WriteInjectProperty(CodeRenderingContext context, InjectIntermediateNode node) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + var property = $"public {node.TypeName} {node.MemberName} {{ get; private set; }}"; + + if (node.Source.HasValue) + { + using (context.CodeWriter.BuildLinePragma(node.Source.Value)) + { + context.CodeWriter + .WriteLine(RazorInjectAttribute) + .WriteLine(property); + } + } + else + { + context.CodeWriter + .WriteLine(RazorInjectAttribute) + .WriteLine(property); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/LegacySectionTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/LegacySectionTargetExtension.cs new file mode 100644 index 0000000000..52698cdfe8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/LegacySectionTargetExtension.cs @@ -0,0 +1,32 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal class LegacySectionTargetExtension : ISectionTargetExtension + { + private static readonly string DefaultWriterName = "__razor_section_writer"; + + public static readonly string DefaultSectionMethodName = "DefineSection"; + + public string SectionMethodName { get; set; } = DefaultSectionMethodName; + + public void WriteSection(CodeRenderingContext context, SectionIntermediateNode node) + { + context.CodeWriter + .WriteStartMethodInvocation(SectionMethodName) + .Write("\"") + .Write(node.SectionName) + .Write("\", "); + + using (context.CodeWriter.BuildAsyncLambda(DefaultWriterName)) + { + context.RenderChildren(node); + } + + context.CodeWriter.WriteEndMethodInvocation(endLine: true); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj new file mode 100644 index 0000000000..0d61d12b26 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj @@ -0,0 +1,21 @@ + + + + ASP.NET Core design time hosting infrastructure for the Razor view engine. + netstandard2.0 + $(PackageTags);aspnetcoremvc + false + + + + + Shared\CodeWriterExtensions.cs + + + + + + + + + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ModelDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ModelDirective.cs new file mode 100644 index 0000000000..c16f46153f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ModelDirective.cs @@ -0,0 +1,145 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public static class ModelDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "model", + DirectiveKind.SingleLine, + builder => + { + builder.AddTypeToken(Resources.ModelDirective_TypeToken_Name, Resources.ModelDirective_TypeToken_Description); + builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; + builder.Description = Resources.ModelDirective_Description; + }); + + public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + return builder; + } + + public static string GetModelType(DocumentIntermediateNode document) + { + if (document == null) + { + throw new ArgumentNullException(nameof(document)); + } + + var visitor = new Visitor(); + return GetModelType(document, visitor); + } + + private static string GetModelType(DocumentIntermediateNode document, Visitor visitor) + { + visitor.Visit(document); + + for (var i = visitor.ModelDirectives.Count - 1; i >= 0; i--) + { + var directive = visitor.ModelDirectives[i]; + + var tokens = directive.Tokens.ToArray(); + if (tokens.Length >= 1) + { + return tokens[0].Content; + } + } + + return "dynamic"; + } + + internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + // Runs after the @inherits directive + public override int Order => 5; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var visitor = new Visitor(); + var modelType = GetModelType(documentNode, visitor); + + if (documentNode.Options.DesignTime) + { + // Alias the TModel token to a known type. + // This allows design time compilation to succeed for Razor files where the token isn't replaced. + var typeName = $"global::{typeof(object).FullName}"; + var usingNode = new UsingDirectiveIntermediateNode() + { + Content = $"TModel = {typeName}" + }; + + visitor.Namespace?.Children.Insert(0, usingNode); + } + + var baseType = visitor.Class?.BaseType?.Replace("", "<" + modelType + ">"); + visitor.Class.BaseType = baseType; + } + } + + private class Visitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Namespace { get; private set; } + + public ClassDeclarationIntermediateNode Class { get; private set; } + + public IList ModelDirectives { get; } = new List(); + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + if (Namespace == null) + { + Namespace = node; + } + + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (Class == null) + { + Class = node; + } + + base.VisitClassDeclaration(node); + } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + ModelDirectives.Add(node); + } + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static IRazorEngineBuilder Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + return builder; + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ModelExpressionPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ModelExpressionPass.cs new file mode 100644 index 0000000000..c943afe5bc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ModelExpressionPass.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; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class ModelExpressionPass : IntermediateNodePassBase, IRazorOptimizationPass + { + private const string ModelExpressionTypeName = "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression"; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var visitor = new Visitor(); + visitor.Visit(documentNode); + } + + private class Visitor : IntermediateNodeWalker + { + public List TagHelpers { get; } = new List(); + + public override void VisitTagHelperProperty(TagHelperPropertyIntermediateNode node) + { + if (string.Equals(node.BoundAttribute.TypeName, ModelExpressionTypeName, StringComparison.Ordinal) || + (node.IsIndexerNameMatch && + string.Equals(node.BoundAttribute.IndexerTypeName, ModelExpressionTypeName, StringComparison.Ordinal))) + { + var expression = new CSharpExpressionIntermediateNode(); + + expression.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = "ModelExpressionProvider.CreateModelExpression(ViewData, __model => ", + }); + + if (node.Children.Count == 1 && node.Children[0] is IntermediateToken token && token.IsCSharp) + { + // A 'simple' expression will look like __model => __model.Foo + + expression.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = "__model." + }); + + expression.Children.Add(token); + } + else + { + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is CSharpExpressionIntermediateNode nestedExpression) + { + for (var j = 0; j < nestedExpression.Children.Count; j++) + { + if (nestedExpression.Children[j] is IntermediateToken cSharpToken && + cSharpToken.IsCSharp) + { + expression.Children.Add(cSharpToken); + } + } + + continue; + } + } + } + + expression.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = ")", + }); + + node.Children.Clear(); + + node.Children.Add(expression); + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcImportProjectFeature.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcImportProjectFeature.cs new file mode 100644 index 0000000000..254c57c1c4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcImportProjectFeature.cs @@ -0,0 +1,89 @@ +// 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.IO; +using System.Linq; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + internal class MvcImportProjectFeature : RazorProjectEngineFeatureBase, IImportProjectFeature + { + private const string ImportsFileName = "_ViewImports.cshtml"; + + public IReadOnlyList GetImports(RazorProjectItem projectItem) + { + if (projectItem == null) + { + throw new ArgumentNullException(nameof(projectItem)); + } + + var imports = new List(); + AddDefaultDirectivesImport(imports); + + // We add hierarchical imports second so any default directive imports can be overridden. + AddHierarchicalImports(projectItem, imports); + + return imports; + } + + // Internal for testing + internal static void AddDefaultDirectivesImport(List imports) + { + imports.Add(DefaultDirectivesProjectItem.Instance); + } + + // Internal for testing + internal void AddHierarchicalImports(RazorProjectItem projectItem, List imports) + { + // We want items in descending order. FindHierarchicalItems returns items in ascending order. + var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(projectItem.FilePath, ImportsFileName).Reverse(); + imports.AddRange(importProjectItems); + } + + private class DefaultDirectivesProjectItem : RazorProjectItem + { + private readonly byte[] _defaultImportBytes; + + private DefaultDirectivesProjectItem() + { + var preamble = Encoding.UTF8.GetPreamble(); + var content = @" +@using System +@using System.Collections.Generic +@using System.Linq +@using System.Threading.Tasks +@using Microsoft.AspNetCore.Mvc +@using Microsoft.AspNetCore.Mvc.Rendering +@using Microsoft.AspNetCore.Mvc.ViewFeatures +@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html +@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json +@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component +@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url +@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider +@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor +"; + var contentBytes = Encoding.UTF8.GetBytes(content); + + _defaultImportBytes = new byte[preamble.Length + contentBytes.Length]; + preamble.CopyTo(_defaultImportBytes, 0); + contentBytes.CopyTo(_defaultImportBytes, preamble.Length); + } + + public override string BasePath => null; + + public override string FilePath => null; + + public override string PhysicalPath => null; + + public override bool Exists => true; + + public static DefaultDirectivesProjectItem Instance { get; } = new DefaultDirectivesProjectItem(); + + public override Stream Read() => new MemoryStream(_defaultImportBytes); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcRazorTemplateEngine.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcRazorTemplateEngine.cs new file mode 100644 index 0000000000..497d173e4e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcRazorTemplateEngine.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 System.IO; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + /// + /// A for Mvc Razor views. + /// + public class MvcRazorTemplateEngine : RazorTemplateEngine + { + /// + /// Initializes a new instance of . + /// + /// The . + /// The . + public MvcRazorTemplateEngine( + RazorEngine engine, + RazorProject project) + : base(engine, project) + { + Options.ImportsFileName = "_ViewImports.cshtml"; + Options.DefaultImports = GetDefaultImports(); + } + + public override RazorCodeDocument CreateCodeDocument(RazorProjectItem projectItem) + { + return base.CreateCodeDocument(projectItem); + } + + // Internal for testing. + internal static RazorSourceDocument GetDefaultImports() + { + using (var stream = new MemoryStream()) + using (var writer = new StreamWriter(stream, Encoding.UTF8)) + { + writer.WriteLine("@using System"); + writer.WriteLine("@using System.Collections.Generic"); + writer.WriteLine("@using System.Linq"); + writer.WriteLine("@using System.Threading.Tasks"); + writer.WriteLine("@using Microsoft.AspNetCore.Mvc"); + writer.WriteLine("@using Microsoft.AspNetCore.Mvc.Rendering"); + writer.WriteLine("@using Microsoft.AspNetCore.Mvc.ViewFeatures"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider"); + writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor"); + writer.Flush(); + + stream.Position = 0; + return RazorSourceDocument.ReadFrom(stream, fileName: null, encoding: Encoding.UTF8); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcViewDocumentClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcViewDocumentClassifierPass.cs new file mode 100644 index 0000000000..b4a5c930f6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/MvcViewDocumentClassifierPass.cs @@ -0,0 +1,71 @@ +// 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.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class MvcViewDocumentClassifierPass : DocumentClassifierPassBase + { + public static readonly string MvcViewDocumentKind = "mvc.1.0.view"; + + protected override string DocumentKind => MvcViewDocumentKind; + + protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) => true; + + protected override void OnDocumentStructureCreated( + RazorCodeDocument codeDocument, + NamespaceDeclarationIntermediateNode @namespace, + ClassDeclarationIntermediateNode @class, + MethodDeclarationIntermediateNode method) + { + base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method); + + @namespace.Content = "AspNetCore"; + + var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath; + if (string.IsNullOrEmpty(filePath)) + { + // It's possible for a Razor document to not have a file path. + // Eg. When we try to generate code for an in memory document like default imports. + var checksum = BytesToString(codeDocument.Source.GetChecksum()); + @class.ClassName = $"AspNetCore_{checksum}"; + } + else + { + @class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath); + } + + @class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage"; + @class.Modifiers.Clear(); + @class.Modifiers.Add("public"); + + method.MethodName = "ExecuteAsync"; + method.Modifiers.Clear(); + method.Modifiers.Add("public"); + method.Modifiers.Add("async"); + method.Modifiers.Add("override"); + method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}"; + } + + private static string BytesToString(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException(nameof(bytes)); + } + + var result = new StringBuilder(bytes.Length); + for (var i = 0; i < bytes.Length; i++) + { + // The x2 format means lowercase hex, where each byte is a 2-character string. + result.Append(bytes[i].ToString("x2")); + } + + return result.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..8233c62607 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/AssemblyInfo.cs @@ -0,0 +1,11 @@ +// 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; +using Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X; +using Microsoft.AspNetCore.Razor.Language; + +[assembly: ProvideRazorExtensionInitializer("MVC-1.0", typeof(ExtensionInitializer))] +[assembly: ProvideRazorExtensionInitializer("MVC-1.1", typeof(ExtensionInitializer))] + +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/Resources.Designer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..917bbe18ce --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/Resources.Designer.cs @@ -0,0 +1,254 @@ +// +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class Resources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Resources", typeof(Resources).GetTypeInfo().Assembly); + + /// + /// Value cannot be null or empty. + /// + internal static string ArgumentCannotBeNullOrEmpy + { + get => GetString("ArgumentCannotBeNullOrEmpy"); + } + + /// + /// Value cannot be null or empty. + /// + internal static string FormatArgumentCannotBeNullOrEmpy() + => GetString("ArgumentCannotBeNullOrEmpy"); + + /// + /// Inject a service from the application's service container into a property. + /// + internal static string InjectDirective_Description + { + get => GetString("InjectDirective_Description"); + } + + /// + /// Inject a service from the application's service container into a property. + /// + internal static string FormatInjectDirective_Description() + => GetString("InjectDirective_Description"); + + /// + /// The name of the property. + /// + internal static string InjectDirective_MemberToken_Description + { + get => GetString("InjectDirective_MemberToken_Description"); + } + + /// + /// The name of the property. + /// + internal static string FormatInjectDirective_MemberToken_Description() + => GetString("InjectDirective_MemberToken_Description"); + + /// + /// PropertyName + /// + internal static string InjectDirective_MemberToken_Name + { + get => GetString("InjectDirective_MemberToken_Name"); + } + + /// + /// PropertyName + /// + internal static string FormatInjectDirective_MemberToken_Name() + => GetString("InjectDirective_MemberToken_Name"); + + /// + /// The type of the service to inject. + /// + internal static string InjectDirective_TypeToken_Description + { + get => GetString("InjectDirective_TypeToken_Description"); + } + + /// + /// The type of the service to inject. + /// + internal static string FormatInjectDirective_TypeToken_Description() + => GetString("InjectDirective_TypeToken_Description"); + + /// + /// TypeName + /// + internal static string InjectDirective_TypeToken_Name + { + get => GetString("InjectDirective_TypeToken_Name"); + } + + /// + /// TypeName + /// + internal static string FormatInjectDirective_TypeToken_Name() + => GetString("InjectDirective_TypeToken_Name"); + + /// + /// Specify the view or page model for the page. + /// + internal static string ModelDirective_Description + { + get => GetString("ModelDirective_Description"); + } + + /// + /// Specify the view or page model for the page. + /// + internal static string FormatModelDirective_Description() + => GetString("ModelDirective_Description"); + + /// + /// The model type. + /// + internal static string ModelDirective_TypeToken_Description + { + get => GetString("ModelDirective_TypeToken_Description"); + } + + /// + /// The model type. + /// + internal static string FormatModelDirective_TypeToken_Description() + => GetString("ModelDirective_TypeToken_Description"); + + /// + /// TypeName + /// + internal static string ModelDirective_TypeToken_Name + { + get => GetString("ModelDirective_TypeToken_Name"); + } + + /// + /// TypeName + /// + internal static string FormatModelDirective_TypeToken_Name() + => GetString("ModelDirective_TypeToken_Name"); + + /// + /// The 'inherits' keyword is not allowed when a '{0}' keyword is used. + /// + internal static string MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword + { + get => GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword"); + } + + /// + /// The 'inherits' keyword is not allowed when a '{0}' keyword is used. + /// + internal static string FormatMvcRazorCodeParser_CannotHaveModelAndInheritsKeyword(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword"), p0); + + /// + /// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'. + /// + internal static string MvcRazorCodeParser_InjectDirectivePropertyNameRequired + { + get => GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired"); + } + + /// + /// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'. + /// + internal static string FormatMvcRazorCodeParser_InjectDirectivePropertyNameRequired(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired"), p0); + + /// + /// The '{0}' keyword must be followed by a type name on the same line. + /// + internal static string MvcRazorCodeParser_KeywordMustBeFollowedByTypeName + { + get => GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName"); + } + + /// + /// The '{0}' keyword must be followed by a type name on the same line. + /// + internal static string FormatMvcRazorCodeParser_KeywordMustBeFollowedByTypeName(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName"), p0); + + /// + /// Only one '{0}' statement is allowed in a file. + /// + internal static string MvcRazorCodeParser_OnlyOneModelStatementIsAllowed + { + get => GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed"); + } + + /// + /// Only one '{0}' statement is allowed in a file. + /// + internal static string FormatMvcRazorCodeParser_OnlyOneModelStatementIsAllowed(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed"), p0); + + /// + /// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'. + /// + internal static string MvcRazorParser_InvalidPropertyType + { + get => GetString("MvcRazorParser_InvalidPropertyType"); + } + + /// + /// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'. + /// + internal static string FormatMvcRazorParser_InvalidPropertyType(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorParser_InvalidPropertyType"), p0, p1, p2); + + /// + /// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file. + /// + internal static string PageDirectiveCannotBeImported + { + get => GetString("PageDirectiveCannotBeImported"); + } + + /// + /// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file. + /// + internal static string FormatPageDirectiveCannotBeImported(object p0, object p1) + => string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveCannotBeImported"), p0, p1); + + /// + /// Runtime code generation for Mvc 1.x is not supported. + /// + internal static string RuntimeCodeGenerationNotSupported + { + get => GetString("RuntimeCodeGenerationNotSupported"); + } + + /// + /// Runtime code generation for Mvc 1.x is not supported. + /// + internal static string FormatRuntimeCodeGenerationNotSupported() + => GetString("RuntimeCodeGenerationNotSupported"); + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/ViewComponentResources.Designer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/ViewComponentResources.Designer.cs new file mode 100644 index 0000000000..58228a720f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Properties/ViewComponentResources.Designer.cs @@ -0,0 +1,100 @@ +// +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class ViewComponentResources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.ViewComponentResources", typeof(ViewComponentResources).GetTypeInfo().Assembly); + + /// + /// View component '{0}' must have exactly one public method named '{1}' or '{2}'. + /// + internal static string ViewComponent_AmbiguousMethods + { + get => GetString("ViewComponent_AmbiguousMethods"); + } + + /// + /// View component '{0}' must have exactly one public method named '{1}' or '{2}'. + /// + internal static string FormatViewComponent_AmbiguousMethods(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AmbiguousMethods"), p0, p1, p2); + + /// + /// Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;. + /// + internal static string ViewComponent_AsyncMethod_ShouldReturnTask + { + get => GetString("ViewComponent_AsyncMethod_ShouldReturnTask"); + } + + /// + /// Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;. + /// + internal static string FormatViewComponent_AsyncMethod_ShouldReturnTask(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AsyncMethod_ShouldReturnTask"), p0, p1, p2); + + /// + /// Could not find an '{0}' or '{1}' method for the view component '{2}'. + /// + internal static string ViewComponent_CannotFindMethod + { + get => GetString("ViewComponent_CannotFindMethod"); + } + + /// + /// Could not find an '{0}' or '{1}' method for the view component '{2}'. + /// + internal static string FormatViewComponent_CannotFindMethod(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_CannotFindMethod"), p0, p1, p2); + + /// + /// Method '{0}' of view component '{1}' cannot return a {2}. + /// + internal static string ViewComponent_SyncMethod_CannotReturnTask + { + get => GetString("ViewComponent_SyncMethod_CannotReturnTask"); + } + + /// + /// Method '{0}' of view component '{1}' cannot return a {2}. + /// + internal static string FormatViewComponent_SyncMethod_CannotReturnTask(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_CannotReturnTask"), p0, p1, p2); + + /// + /// Method '{0}' of view component '{1}' should be declared to return a value. + /// + internal static string ViewComponent_SyncMethod_ShouldReturnValue + { + get => GetString("ViewComponent_SyncMethod_ShouldReturnValue"); + } + + /// + /// Method '{0}' of view component '{1}' should be declared to return a value. + /// + internal static string FormatViewComponent_SyncMethod_ShouldReturnValue(object p0, object p1) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_ShouldReturnValue"), p0, p1); + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/RazorExtensions.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/RazorExtensions.cs new file mode 100644 index 0000000000..55e8929457 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/RazorExtensions.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 System; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.CodeAnalysis.Razor; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public static class RazorExtensions + { + public static void Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + InjectDirective.Register(builder); + ModelDirective.Register(builder); + + InheritsDirective.Register(builder); + + builder.Features.Add(new DefaultTagHelperDescriptorProvider()); + + // Register section directive with the 1.x compatible target extension. + builder.AddDirective(SectionDirective.Directive); + builder.Features.Add(new SectionDirectivePass()); + builder.AddTargetExtension(new LegacySectionTargetExtension()); + + builder.AddTargetExtension(new TemplateTargetExtension() + { + TemplateTypeName = "global::Microsoft.AspNetCore.Mvc.Razor.HelperResult", + }); + + builder.Features.Add(new ModelExpressionPass()); + builder.Features.Add(new MvcViewDocumentClassifierPass()); + + builder.SetImportFeature(new MvcImportProjectFeature()); + } + + public static void RegisterViewComponentTagHelpers(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Features.Add(new ViewComponentTagHelperDescriptorProvider()); + + builder.Features.Add(new ViewComponentTagHelperPass()); + builder.AddTargetExtension(new ViewComponentTagHelperTargetExtension()); + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static void Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + EnsureDesignTime(builder); + + InjectDirective.Register(builder); + ModelDirective.Register(builder); + + FunctionsDirective.Register(builder); + InheritsDirective.Register(builder); + + builder.Features.Add(new DefaultTagHelperDescriptorProvider()); + + // Register section directive with the 1.x compatible target extension. + builder.AddDirective(SectionDirective.Directive); + builder.Features.Add(new SectionDirectivePass()); + builder.AddTargetExtension(new LegacySectionTargetExtension()); + + builder.AddTargetExtension(new TemplateTargetExtension() + { + TemplateTypeName = "global::Microsoft.AspNetCore.Mvc.Razor.HelperResult", + }); + + builder.Features.Add(new ModelExpressionPass()); + builder.Features.Add(new MvcViewDocumentClassifierPass()); + } + + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static void RegisterViewComponentTagHelpers(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + EnsureDesignTime(builder); + + builder.Features.Add(new ViewComponentTagHelperDescriptorProvider()); + builder.Features.Add(new ViewComponentTagHelperPass()); + builder.AddTargetExtension(new ViewComponentTagHelperTargetExtension()); + } + +#pragma warning disable CS0618 // Type or member is obsolete + private static void EnsureDesignTime(IRazorEngineBuilder builder) +#pragma warning restore CS0618 // Type or member is obsolete + { + if (builder.DesignTime) + { + return; + } + + throw new NotSupportedException(Resources.RuntimeCodeGenerationNotSupported); + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/RazorExtensionsDiagnosticFactory.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/RazorExtensionsDiagnosticFactory.cs new file mode 100644 index 0000000000..af883af3d4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/RazorExtensionsDiagnosticFactory.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 System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + internal class RazorExtensionsDiagnosticFactory + { + private const string DiagnosticPrefix = "RZ"; + + internal static readonly RazorDiagnosticDescriptor ViewComponent_CannotFindMethod = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3900", + () => ViewComponentResources.ViewComponent_CannotFindMethod, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_CannotFindMethod(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_CannotFindMethod, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.SyncMethodName, + ViewComponentTypes.AsyncMethodName, + tagHelperType); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_AmbiguousMethods = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3901", + () => ViewComponentResources.ViewComponent_AmbiguousMethods, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_AmbiguousMethods(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_AmbiguousMethods, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + tagHelperType, + ViewComponentTypes.SyncMethodName, + ViewComponentTypes.AsyncMethodName); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_AsyncMethod_ShouldReturnTask = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3902", + () => ViewComponentResources.ViewComponent_AsyncMethod_ShouldReturnTask, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_AsyncMethod_ShouldReturnTask(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_AsyncMethod_ShouldReturnTask, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.AsyncMethodName, + tagHelperType, + nameof(Task)); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_ShouldReturnValue = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3903", + () => ViewComponentResources.ViewComponent_SyncMethod_ShouldReturnValue, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_SyncMethod_ShouldReturnValue(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_SyncMethod_ShouldReturnValue, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.SyncMethodName, + tagHelperType); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_CannotReturnTask = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3904", + () => ViewComponentResources.ViewComponent_SyncMethod_CannotReturnTask, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_SyncMethod_CannotReturnTask(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_SyncMethod_CannotReturnTask, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.SyncMethodName, + tagHelperType, + nameof(Task)); + + return diagnostic; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Resources.resx b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Resources.resx new file mode 100644 index 0000000000..6754c87c52 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Resources.resx @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Value cannot be null or empty. + + + Inject a service from the application's service container into a property. + + + The name of the property. + + + PropertyName + + + The type of the service to inject. + + + TypeName + + + Specify the view or page model for the page. + + + The model type. + + + TypeName + + + The 'inherits' keyword is not allowed when a '{0}' keyword is used. + + + A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'. + + + The '{0}' keyword must be followed by a type name on the same line. + + + Only one '{0}' statement is allowed in a file. + + + Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'. + + + The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file. + + + Runtime code generation for Mvc 1.x is not supported. + + \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/TagHelperDescriptorExtensions.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/TagHelperDescriptorExtensions.cs new file mode 100644 index 0000000000..b455fc7423 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/TagHelperDescriptorExtensions.cs @@ -0,0 +1,37 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public static class TagHelperDescriptorExtensions + { + /// + /// Indicates whether a represents a view component. + /// + /// The to check. + /// Whether a represents a view component. + public static bool IsViewComponentKind(this TagHelperDescriptor tagHelper) + { + if (tagHelper == null) + { + throw new ArgumentNullException(nameof(tagHelper)); + } + + return string.Equals(ViewComponentTagHelperConventions.Kind, tagHelper.Kind, StringComparison.Ordinal); + } + + public static string GetViewComponentName(this TagHelperDescriptor tagHelper) + { + if (tagHelper == null) + { + throw new ArgumentNullException(nameof(tagHelper)); + } + + tagHelper.Metadata.TryGetValue(ViewComponentTagHelperMetadata.Name, out var result); + return result; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentResources.resx b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentResources.resx new file mode 100644 index 0000000000..d6aad4ff3f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentResources.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + View component '{0}' must have exactly one public method named '{1}' or '{2}'. + + + Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;. + + + Could not find an '{0}' or '{1}' method for the view component '{2}'. + + + Method '{0}' of view component '{1}' cannot return a {2}. + + + Method '{0}' of view component '{1}' should be declared to return a value. + + \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperConventions.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperConventions.cs new file mode 100644 index 0000000000..f02d874dc5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperConventions.cs @@ -0,0 +1,10 @@ +// 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.Mvc.Razor.Extensions.Version1_X +{ + public static class ViewComponentTagHelperConventions + { + public static readonly string Kind = "MVC.ViewComponent"; + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperDescriptorFactory.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperDescriptorFactory.cs new file mode 100644 index 0000000000..68966e734c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperDescriptorFactory.cs @@ -0,0 +1,269 @@ +// 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.Collections.Immutable; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + internal class ViewComponentTagHelperDescriptorFactory + { + private readonly INamedTypeSymbol _viewComponentAttributeSymbol; + private readonly INamedTypeSymbol _genericTaskSymbol; + private readonly INamedTypeSymbol _taskSymbol; + private readonly INamedTypeSymbol _iDictionarySymbol; + + private static readonly SymbolDisplayFormat FullNameTypeDisplayFormat = + SymbolDisplayFormat.FullyQualifiedFormat + .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted) + .WithMiscellaneousOptions(SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions & (~SymbolDisplayMiscellaneousOptions.UseSpecialTypes)); + + private static readonly IReadOnlyDictionary PrimitiveDisplayTypeNameLookups = new Dictionary(StringComparer.Ordinal) + { + [typeof(byte).FullName] = "byte", + [typeof(sbyte).FullName] = "sbyte", + [typeof(int).FullName] = "int", + [typeof(uint).FullName] = "uint", + [typeof(short).FullName] = "short", + [typeof(ushort).FullName] = "ushort", + [typeof(long).FullName] = "long", + [typeof(ulong).FullName] = "ulong", + [typeof(float).FullName] = "float", + [typeof(double).FullName] = "double", + [typeof(char).FullName] = "char", + [typeof(bool).FullName] = "bool", + [typeof(object).FullName] = "object", + [typeof(string).FullName] = "string", + [typeof(decimal).FullName] = "decimal", + }; + + public ViewComponentTagHelperDescriptorFactory(Compilation compilation) + { + _viewComponentAttributeSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute); + _genericTaskSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.GenericTask); + _taskSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.Task); + _iDictionarySymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.IDictionary); + } + + public virtual TagHelperDescriptor CreateDescriptor(INamedTypeSymbol type) + { + var assemblyName = type.ContainingAssembly.Name; + var shortName = GetShortName(type); + var tagName = $"vc:{HtmlConventions.ToHtmlCase(shortName)}"; + var typeName = $"__Generated__{shortName}ViewComponentTagHelper"; + var displayName = shortName + "ViewComponentTagHelper"; + var descriptorBuilder = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, typeName, assemblyName); + descriptorBuilder.SetTypeName(typeName); + descriptorBuilder.DisplayName = displayName; + + if (TryFindInvokeMethod(type, out var method, out var diagnostic)) + { + var methodParameters = method.Parameters; + descriptorBuilder.TagMatchingRule(ruleBuilder => + { + ruleBuilder.TagName = tagName; + AddRequiredAttributes(methodParameters, ruleBuilder); + }); + + AddBoundAttributes(methodParameters, displayName, descriptorBuilder); + } + else + { + descriptorBuilder.Diagnostics.Add(diagnostic); + } + + descriptorBuilder.Metadata[ViewComponentTagHelperMetadata.Name] = shortName; + + var descriptor = descriptorBuilder.Build(); + return descriptor; + } + + private bool TryFindInvokeMethod(INamedTypeSymbol type, out IMethodSymbol method, out RazorDiagnostic diagnostic) + { + var methods = type.GetMembers() + .OfType() + .Where(m => + m.DeclaredAccessibility == Accessibility.Public && + (string.Equals(m.Name, ViewComponentTypes.AsyncMethodName, StringComparison.Ordinal) || + string.Equals(m.Name, ViewComponentTypes.SyncMethodName, StringComparison.Ordinal))) + .ToArray(); + + if (methods.Length == 0) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_CannotFindMethod(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + else if (methods.Length > 1) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_AmbiguousMethods(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + + var selectedMethod = methods[0]; + var returnType = selectedMethod.ReturnType as INamedTypeSymbol; + if (string.Equals(selectedMethod.Name, ViewComponentTypes.AsyncMethodName, StringComparison.Ordinal)) + { + // Will invoke asynchronously. Method must not return Task or Task. + if (returnType == _taskSymbol) + { + // This is ok. + } + else if (returnType.IsGenericType && returnType.ConstructedFrom == _genericTaskSymbol) + { + // This is ok. + } + else + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_AsyncMethod_ShouldReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + } + else + { + // Will invoke synchronously. Method must not return void, Task or Task. + if (returnType.SpecialType == SpecialType.System_Void) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_ShouldReturnValue(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + else if (returnType == _taskSymbol) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_CannotReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + else if (returnType.IsGenericType && returnType.ConstructedFrom == _genericTaskSymbol) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_CannotReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + } + + method = selectedMethod; + diagnostic = null; + return true; + } + + private void AddRequiredAttributes(ImmutableArray methodParameters, TagMatchingRuleDescriptorBuilder builder) + { + foreach (var parameter in methodParameters) + { + if (GetIndexerValueTypeName(parameter) == null) + { + // Set required attributes only for non-indexer attributes. Indexer attributes can't be required attributes + // because there are two ways of setting values for the attribute. + builder.Attribute(attributeBuilder => + { + var lowerKebabName = HtmlConventions.ToHtmlCase(parameter.Name); + attributeBuilder.Name =lowerKebabName; + }); + } + } + } + + private void AddBoundAttributes(ImmutableArray methodParameters, string containingDisplayName, TagHelperDescriptorBuilder builder) + { + foreach (var parameter in methodParameters) + { + var lowerKebabName = HtmlConventions.ToHtmlCase(parameter.Name); + var typeName = parameter.Type.ToDisplayString(FullNameTypeDisplayFormat); + + if (!PrimitiveDisplayTypeNameLookups.TryGetValue(typeName, out var simpleName)) + { + simpleName = typeName; + } + + builder.BindAttribute(attributeBuilder => + { + attributeBuilder.Name = lowerKebabName; + attributeBuilder.TypeName = typeName; + attributeBuilder.DisplayName = $"{simpleName} {containingDisplayName}.{parameter.Name}"; + attributeBuilder.SetPropertyName(parameter.Name); + + if (parameter.Type.TypeKind == TypeKind.Enum) + { + attributeBuilder.IsEnum = true; + } + else + { + var dictionaryValueType = GetIndexerValueTypeName(parameter); + if (dictionaryValueType != null) + { + attributeBuilder.AsDictionary(lowerKebabName + "-", dictionaryValueType); + } + } + }); + } + } + + private string GetIndexerValueTypeName(IParameterSymbol parameter) + { + INamedTypeSymbol dictionaryType; + if ((parameter.Type as INamedTypeSymbol)?.ConstructedFrom == _iDictionarySymbol) + { + dictionaryType = (INamedTypeSymbol)parameter.Type; + } + else if (parameter.Type.AllInterfaces.Any(s => s.ConstructedFrom == _iDictionarySymbol)) + { + dictionaryType = parameter.Type.AllInterfaces.First(s => s.ConstructedFrom == _iDictionarySymbol); + } + else + { + dictionaryType = null; + } + + if (dictionaryType == null || dictionaryType.TypeArguments[0].SpecialType != SpecialType.System_String) + { + return null; + } + + var type = dictionaryType.TypeArguments[1]; + var typeName = type.ToDisplayString(FullNameTypeDisplayFormat); + + return typeName; + } + + private string GetShortName(INamedTypeSymbol componentType) + { + var viewComponentAttribute = componentType.GetAttributes().Where(a => a.AttributeClass == _viewComponentAttributeSymbol).FirstOrDefault(); + var name = viewComponentAttribute + ?.NamedArguments + .Where(namedArgument => string.Equals(namedArgument.Key, ViewComponentTypes.ViewComponent.Name, StringComparison.Ordinal)) + .FirstOrDefault() + .Value + .Value as string; + + if (!string.IsNullOrEmpty(name)) + { + var separatorIndex = name.LastIndexOf('.'); + if (separatorIndex >= 0) + { + return name.Substring(separatorIndex + 1); + } + else + { + return name; + } + } + + // Get name by convention + if (componentType.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix, StringComparison.OrdinalIgnoreCase)) + { + return componentType.Name.Substring(0, componentType.Name.Length - ViewComponentTypes.ViewComponentSuffix.Length); + } + else + { + return componentType.Name; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperDescriptorProvider.cs new file mode 100644 index 0000000000..318994ec0e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperDescriptorProvider.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.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Razor; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public sealed class ViewComponentTagHelperDescriptorProvider : RazorEngineFeatureBase, ITagHelperDescriptorProvider + { + public int Order { get; set; } + + public void Execute(TagHelperDescriptorProviderContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var compilation = context.GetCompilation(); + if (compilation == null) + { + // No compilation, nothing to do. + return; + } + + var vcAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute); + var nonVCAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.NonViewComponentAttribute); + if (vcAttribute == null || vcAttribute.TypeKind == TypeKind.Error) + { + // Could not find attributes we care about in the compilation. Nothing to do. + return; + } + + var types = new List(); + var visitor = new ViewComponentTypeVisitor(vcAttribute, nonVCAttribute, types); + + // We always visit the global namespace. + visitor.Visit(compilation.Assembly.GlobalNamespace); + + foreach (var reference in compilation.References) + { + if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly) + { + if (IsTagHelperAssembly(assembly)) + { + visitor.Visit(assembly.GlobalNamespace); + } + } + } + + var factory = new ViewComponentTagHelperDescriptorFactory(compilation); + for (var i = 0; i < types.Count; i++) + { + var descriptor = factory.CreateDescriptor(types[i]); + + if (descriptor != null) + { + context.Results.Add(descriptor); + } + } + } + + private bool IsTagHelperAssembly(IAssemblySymbol assembly) + { + return assembly.Name != null && !assembly.Name.StartsWith("System.", StringComparison.Ordinal); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperIntermediateNode.cs new file mode 100644 index 0000000000..b1399ffbea --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperIntermediateNode.cs @@ -0,0 +1,59 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public sealed class ViewComponentTagHelperIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = IntermediateNodeCollection.ReadOnly; + + public string ClassName { get; set; } + + public TagHelperDescriptor TagHelper { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteViewComponentTagHelper(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(ClassName); + + formatter.WriteProperty(nameof(ClassName), ClassName); + formatter.WriteProperty(nameof(TagHelper), TagHelper?.DisplayName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperMetadata.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperMetadata.cs new file mode 100644 index 0000000000..1718829c39 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperMetadata.cs @@ -0,0 +1,14 @@ +// 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.Mvc.Razor.Extensions.Version1_X +{ + public static class ViewComponentTagHelperMetadata + { + /// + /// The key in a containing + /// the short name of a view component. + /// + public static readonly string Name = "MVC.ViewComponent.Name"; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperPass.cs new file mode 100644 index 0000000000..ba9938a123 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperPass.cs @@ -0,0 +1,203 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class ViewComponentTagHelperPass : IntermediateNodePassBase, IRazorOptimizationPass + { + // Run after the default taghelper pass + public override int Order => IntermediateNodePassBase.DefaultFeatureOrder + 2000; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var @namespace = documentNode.FindPrimaryNamespace(); + var @class = documentNode.FindPrimaryClass(); + if (@namespace == null || @class == null) + { + // Nothing to do, bail. We can't function without the standard structure. + return; + } + + var context = new Context(@namespace, @class); + + // For each VCTH *usage* we need to rewrite the tag helper node to use the tag helper runtime to construct + // and set properties on the the correct field, and using the name of the type we will generate. + var nodes = documentNode.FindDescendantNodes(); + for (var i = 0; i < nodes.Count; i++) + { + var node = nodes[i]; + foreach (var tagHelper in node.TagHelpers) + { + RewriteUsage(context, node, tagHelper); + } + } + + // Then for each VCTH *definition* that we've seen we need to generate the class that implements + // ITagHelper and the field that will hold it. + foreach (var tagHelper in context.TagHelpers) + { + AddField(context, tagHelper); + AddTagHelperClass(context, tagHelper); + } + } + + private void RewriteUsage(Context context, TagHelperIntermediateNode node, TagHelperDescriptor tagHelper) + { + if (!tagHelper.IsViewComponentKind()) + { + return; + } + + context.Add(tagHelper); + + // Now we need to insert a create node using the default tag helper runtime. This is similar to + // code in DefaultTagHelperOptimizationPass. + // + // Find the body node. + var i = 0; + while (i < node.Children.Count && node.Children[i] is TagHelperBodyIntermediateNode) + { + i++; + } + while (i < node.Children.Count && node.Children[i] is DefaultTagHelperBodyIntermediateNode) + { + i++; + } + + // Now find the last create node. + while (i < node.Children.Count && node.Children[i] is DefaultTagHelperCreateIntermediateNode) + { + i++; + } + + // Now i has the right insertion point. + node.Children.Insert(i, new DefaultTagHelperCreateIntermediateNode() + { + FieldName = context.GetFieldName(tagHelper), + TagHelper = tagHelper, + TypeName = context.GetFullyQualifiedName(tagHelper), + }); + + // Now we need to rewrite any set property nodes to use the default runtime. + for (i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode && + propertyNode.TagHelper == tagHelper) + { + // This is a set property for this VCTH - we need to replace it with a node + // that will use our field and property name. + node.Children[i] = new DefaultTagHelperPropertyIntermediateNode(propertyNode) + { + FieldName = context.GetFieldName(tagHelper), + PropertyName = propertyNode.BoundAttribute.GetPropertyName(), + }; + } + } + } + + private void AddField(Context context, TagHelperDescriptor tagHelper) + { + // We need to insert a node for the field that will hold the tag helper. We've already generated a field name + // at this time and use it for all uses of the same tag helper type. + // + // We also want to preserve the ordering of the nodes for testability. So insert at the end of any existing + // field nodes. + var i = 0; + while (i < context.Class.Children.Count && context.Class.Children[i] is DefaultTagHelperRuntimeIntermediateNode) + { + i++; + } + + while (i < context.Class.Children.Count && context.Class.Children[i] is FieldDeclarationIntermediateNode) + { + i++; + } + + context.Class.Children.Insert(i, new FieldDeclarationIntermediateNode() + { + Annotations = + { + { CommonAnnotations.DefaultTagHelperExtension.TagHelperField, bool.TrueString }, + }, + Modifiers = + { + "private", + }, + FieldName = context.GetFieldName(tagHelper), + FieldType = "global::" + context.GetFullyQualifiedName(tagHelper), + }); + } + + private void AddTagHelperClass(Context context, TagHelperDescriptor tagHelper) + { + var node = new ViewComponentTagHelperIntermediateNode() + { + ClassName = context.GetClassName(tagHelper), + TagHelper = tagHelper + }; + + context.Class.Children.Add(node); + } + + private struct Context + { + private Dictionary _tagHelpers; + + public Context(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class) + { + Namespace = @namespace; + Class = @class; + + _tagHelpers = new Dictionary(); + } + + public ClassDeclarationIntermediateNode Class { get; } + + public NamespaceDeclarationIntermediateNode Namespace { get; } + + + public IEnumerable TagHelpers => _tagHelpers.Keys; + + public bool Add(TagHelperDescriptor tagHelper) + { + if (_tagHelpers.ContainsKey(tagHelper)) + { + return false; + } + + var className = $"__Generated__{tagHelper.GetViewComponentName()}ViewComponentTagHelper"; + var fullyQualifiedName = $"{Namespace.Content}.{Class.ClassName}.{className}"; + var fieldName = GenerateFieldName(tagHelper); + + _tagHelpers.Add(tagHelper, (className, fullyQualifiedName, fieldName)); + + return true; + } + + public string GetClassName(TagHelperDescriptor taghelper) + { + return _tagHelpers[taghelper].className; + } + + public string GetFullyQualifiedName(TagHelperDescriptor taghelper) + { + return _tagHelpers[taghelper].fullyQualifiedName; + } + + public string GetFieldName(TagHelperDescriptor taghelper) + { + return _tagHelpers[taghelper].fieldName; + } + + private static string GenerateFieldName(TagHelperDescriptor tagHelper) + { + return $"__{tagHelper.GetViewComponentName()}ViewComponentTagHelper"; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperTargetExtension.cs new file mode 100644 index 0000000000..eb426d0607 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTagHelperTargetExtension.cs @@ -0,0 +1,183 @@ +// 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.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + internal class ViewComponentTagHelperTargetExtension : IViewComponentTagHelperTargetExtension + { + private static readonly string[] PublicModifiers = new[] { "public" }; + + public string TagHelperTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelper"; + + public string ViewComponentHelperTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.IViewComponentHelper"; + + public string ViewComponentHelperVariableName { get; set; } = "_helper"; + + public string ViewComponentInvokeMethodName { get; set; } = "InvokeAsync"; + + public string HtmlAttributeNotBoundAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute"; + + public string ViewContextAttributeTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute"; + + public string ViewContextTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext"; + + public string ViewContextPropertyName { get; set; } = "ViewContext"; + + public string HtmlTargetElementAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute"; + + public string TagHelperProcessMethodName { get; set; } = "ProcessAsync"; + + public string TagHelperContextTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext"; + + public string TagHelperContextVariableName { get; set; } = "context"; + + public string TagHelperOutputTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput"; + + public string TagHelperOutputVariableName { get; set; } = "output"; + + public string TagHelperOutputTagNamePropertyName { get; set; } = "TagName"; + + public string TagHelperOutputContentPropertyName { get; set; } = "Content"; + + public string TagHelperContentSetMethodName { get; set; } = "SetHtmlContent"; + + public string TagHelperContentVariableName { get; set; } = "content"; + + public string IViewContextAwareTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware"; + + public string IViewContextAwareContextualizeMethodName { get; set; } = "Contextualize"; + + public void WriteViewComponentTagHelper(CodeRenderingContext context, ViewComponentTagHelperIntermediateNode node) + { + // Add target element. + WriteTargetElementString(context.CodeWriter, node.TagHelper); + + // Initialize declaration. + using (context.CodeWriter.BuildClassDeclaration( + PublicModifiers, + node.ClassName, + TagHelperTypeName, + interfaces: null, + typeParameters: null)) + { + // Add view component helper. + context.CodeWriter.WriteVariableDeclaration( + $"private readonly {ViewComponentHelperTypeName}", + ViewComponentHelperVariableName, + value: null); + + // Add constructor. + WriteConstructorString(context.CodeWriter, node.ClassName); + + // Add attributes. + WriteAttributeDeclarations(context.CodeWriter, node.TagHelper); + + // Add process method. + WriteProcessMethodString(context.CodeWriter, node.TagHelper); + } + } + + private void WriteConstructorString(CodeWriter writer, string className) + { + writer.Write("public ") + .Write(className) + .Write("(") + .Write($"{ViewComponentHelperTypeName} helper") + .WriteLine(")"); + using (writer.BuildScope()) + { + writer.WriteStartAssignment(ViewComponentHelperVariableName) + .Write("helper") + .WriteLine(";"); + } + } + + private void WriteAttributeDeclarations(CodeWriter writer, TagHelperDescriptor tagHelper) + { + writer.Write("[") + .Write(HtmlAttributeNotBoundAttributeTypeName) + .WriteParameterSeparator() + .Write(ViewContextAttributeTypeName) + .WriteLine("]"); + + writer.WriteAutoPropertyDeclaration( + PublicModifiers, + ViewContextTypeName, + ViewContextPropertyName); + + foreach (var attribute in tagHelper.BoundAttributes) + { + writer.WriteAutoPropertyDeclaration( + PublicModifiers, + attribute.TypeName, + attribute.GetPropertyName()); + + if (attribute.IndexerTypeName != null) + { + writer.Write(" = ") + .WriteStartNewObject(attribute.TypeName) + .WriteEndMethodInvocation(); + } + } + } + + private void WriteProcessMethodString(CodeWriter writer, TagHelperDescriptor tagHelper) + { + using (writer.BuildMethodDeclaration( + $"public override async", + $"global::{typeof(Task).FullName}", + TagHelperProcessMethodName, + new Dictionary() + { + { TagHelperContextTypeName, TagHelperContextVariableName }, + { TagHelperOutputTypeName, TagHelperOutputVariableName } + })) + { + writer.WriteInstanceMethodInvocation( + $"({ViewComponentHelperVariableName} as {IViewContextAwareTypeName})?", + IViewContextAwareContextualizeMethodName, + new[] { ViewContextPropertyName }); + + var methodParameters = GetMethodParameters(tagHelper); + writer.Write("var ") + .WriteStartAssignment(TagHelperContentVariableName) + .WriteInstanceMethodInvocation($"await {ViewComponentHelperVariableName}", ViewComponentInvokeMethodName, methodParameters); + writer.WriteStartAssignment($"{TagHelperOutputVariableName}.{TagHelperOutputTagNamePropertyName}") + .WriteLine("null;"); + writer.WriteInstanceMethodInvocation( + $"{TagHelperOutputVariableName}.{TagHelperOutputContentPropertyName}", + TagHelperContentSetMethodName, + new[] { TagHelperContentVariableName }); + } + } + + private string[] GetMethodParameters(TagHelperDescriptor tagHelper) + { + var propertyNames = tagHelper.BoundAttributes.Select(attribute => attribute.GetPropertyName()); + var joinedPropertyNames = string.Join(", ", propertyNames); + var parametersString = $"new {{ { joinedPropertyNames } }}"; + var viewComponentName = tagHelper.GetViewComponentName(); + var methodParameters = new[] { $"\"{viewComponentName}\"", parametersString }; + return methodParameters; + } + + private void WriteTargetElementString(CodeWriter writer, TagHelperDescriptor tagHelper) + { + Debug.Assert(tagHelper.TagMatchingRules.Count() == 1); + + var rule = tagHelper.TagMatchingRules.First(); + + writer.Write("[") + .WriteStartMethodInvocation(HtmlTargetElementAttributeTypeName) + .WriteStringLiteral(rule.TagName) + .WriteLine(")]"); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTypeVisitor.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTypeVisitor.cs new file mode 100644 index 0000000000..db0912087a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTypeVisitor.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; +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + internal class ViewComponentTypeVisitor : SymbolVisitor + { + private static readonly Version SupportedVCTHMvcVersion = new Version(1, 1); + + private readonly INamedTypeSymbol _viewComponentAttribute; + private readonly INamedTypeSymbol _nonViewComponentAttribute; + private readonly List _results; + + public ViewComponentTypeVisitor( + INamedTypeSymbol viewComponentAttribute, + INamedTypeSymbol nonViewComponentAttribute, + List results) + { + _viewComponentAttribute = viewComponentAttribute; + _nonViewComponentAttribute = nonViewComponentAttribute; + _results = results; + } + + public override void VisitNamedType(INamedTypeSymbol symbol) + { + if (IsViewComponent(symbol)) + { + _results.Add(symbol); + } + + if (symbol.DeclaredAccessibility != Accessibility.Public) + { + return; + } + + foreach (var member in symbol.GetTypeMembers()) + { + Visit(member); + } + } + + public override void VisitNamespace(INamespaceSymbol symbol) + { + foreach (var member in symbol.GetMembers()) + { + Visit(member); + } + } + + internal bool IsViewComponent(INamedTypeSymbol symbol) + { + if (symbol.DeclaredAccessibility != Accessibility.Public || + symbol.IsAbstract || + symbol.IsGenericType || + AttributeIsDefined(symbol, _nonViewComponentAttribute)) + { + return false; + } + + return symbol.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix) || + AttributeIsDefined(symbol, _viewComponentAttribute); + } + + private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol queryAttribute) + { + if (type == null || queryAttribute == null) + { + return false; + } + + var attribute = type.GetAttributes().Where(a => a.AttributeClass == queryAttribute).FirstOrDefault(); + + if (attribute != null) + { + return true; + } + + return AttributeIsDefined(type.BaseType, queryAttribute); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTypes.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTypes.cs new file mode 100644 index 0000000000..e9d8f598f8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/ViewComponentTypes.cs @@ -0,0 +1,35 @@ +// 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.Mvc.Razor.Extensions.Version1_X +{ + internal static class ViewComponentTypes + { + public const string Assembly = "Microsoft.AspNetCore.Mvc.ViewFeatures"; + + public static readonly Version AssemblyVersion = new Version(1, 1, 0, 0); + + public const string ViewComponentSuffix = "ViewComponent"; + + public const string ViewComponentAttribute = "Microsoft.AspNetCore.Mvc.ViewComponentAttribute"; + + public const string NonViewComponentAttribute = "Microsoft.AspNetCore.Mvc.NonViewComponentAttribute"; + + public const string GenericTask = "System.Threading.Tasks.Task`1"; + + public const string Task = "System.Threading.Tasks.Task"; + + public const string IDictionary = "System.Collections.Generic.IDictionary`2"; + + public const string AsyncMethodName = "InvokeAsync"; + + public const string SyncMethodName = "Invoke"; + + public static class ViewComponent + { + public const string Name = "Name"; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/InjectDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/InjectDirectiveTest.cs new file mode 100644 index 0000000000..a5579d645a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/InjectDirectiveTest.cs @@ -0,0 +1,225 @@ +// 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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class InjectDirectiveTest + { + [Fact] + public void InjectDirectivePass_Execute_DefinesProperty() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_DedupesPropertiesByName() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +@inject PropertyType2 PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType2", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_ExpandsTModel_WithDynamic() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_ExpandsTModel_WithModelTypeFirst() + { + // Arrange + var codeDocument = CreateDocument(@" +@model ModelType +@inject PropertyType PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_ExpandsTModel_WithModelType() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +@model ModelType +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + private RazorCodeDocument CreateDocument(string content) + { + var source = RazorSourceDocument.Create(content, "test.cshtml"); + return RazorCodeDocument.Create(source); + } + + private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node) + { + var visitor = new ClassNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private RazorEngine CreateEngine() + { + return RazorProjectEngine.Create(b => + { + // Notice we're not registering the InjectDirective.Pass here so we can run it on demand. + b.AddDirective(InjectDirective.Directive); + b.AddDirective(ModelDirective.Directive); + }).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 IRazorDocumentClassifierPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + + private string GetCSharpContent(IntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + var child = node.Children[i] as IntermediateToken; + if (child.Kind == TokenKind.CSharp) + { + builder.Append(child.Content); + } + } + + return builder.ToString(); + } + + private class ClassNodeVisitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Node { get; set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Node = node; + } + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/InjectTargetExtensionTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/InjectTargetExtensionTest.cs new file mode 100644 index 0000000000..fcc8b1123c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/InjectTargetExtensionTest.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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class InjectTargetExtensionTest + { + [Fact] + public void InjectDirectiveTargetExtension_WritesProperty() + { + // Arrange + var context = TestCodeRenderingContext.CreateRuntime(); + var target = new InjectTargetExtension(); + var node = new InjectIntermediateNode() + { + TypeName = "PropertyType", + MemberName = "PropertyName", + }; + + // Act + target.WriteInjectProperty(context, node); + + // Assert + Assert.Equal( + "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine + + "public PropertyType PropertyName { get; private set; }" + Environment.NewLine, + context.CodeWriter.GenerateCode()); + } + + [Fact] + public void InjectDirectiveTargetExtension_WritesPropertyWithLinePragma_WhenSourceIsSet() + { + // Arrange + var context = TestCodeRenderingContext.CreateRuntime(); + var target = new InjectTargetExtension(); + var node = new InjectIntermediateNode() + { + TypeName = "PropertyType", + MemberName = "PropertyName", + Source = new SourceSpan( + filePath: "test-path", + absoluteIndex: 0, + lineIndex: 1, + characterIndex: 1, + length: 10) + }; + + // Act + target.WriteInjectProperty(context, node); + + // Assert + Assert.Equal( + "#line 2 \"test-path\"" + Environment.NewLine + + "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine + + "public PropertyType PropertyName { get; private set; }" + Environment.NewLine + Environment.NewLine + + "#line default" + Environment.NewLine + + "#line hidden" + Environment.NewLine, + context.CodeWriter.GenerateCode()); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs new file mode 100644 index 0000000000..bb605fed72 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs @@ -0,0 +1,370 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.IntegrationTests; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.CodeAnalysis.CSharp; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.IntegrationTests +{ + public class CodeGenerationIntegrationTest : IntegrationTestBase + { + private readonly static CSharpCompilation DefaultBaseCompilation = MvcShim.BaseCompilation.WithAssemblyName("AppCode"); + + public CodeGenerationIntegrationTest() + : base(generateBaselines: null) + { + Configuration = RazorConfiguration.Create( + RazorLanguageVersion.Version_1_1, + "MVC-1.1", + new[] { new AssemblyExtension("MVC-1.1", typeof(ExtensionInitializer).Assembly) }); + } + + protected override CSharpCompilation BaseCompilation => DefaultBaseCompilation; + + protected override RazorConfiguration Configuration { get; } + + [Fact] + public void InvalidNamespaceAtEOF_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ1007", Assert.Single(diagnotics).Id); + } + + [Fact] + public void IncompleteDirectives_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyService +{ + public string Html { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + // We expect this test to generate a bunch of errors. + Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + } + + [Fact] + public void InheritsViewModel_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Razor; + +public class MyBasePageForViews : RazorPage +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} +public class MyModel +{ + +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void InheritsWithViewImports_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Razor; + +public class MyBasePageForViews : RazorPage +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} + +public class MyModel +{ + +}"); + + AddProjectItemFromText(@"@inherits MyBasePageForViews"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Basic_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Sections_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void _ViewImports_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Inject_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyApp +{ + public string MyProperty { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void InjectWithModel_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyService +{ + public string Html { get; set; } +} + +public class MyApp +{ + public string MyProperty { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void InjectWithSemicolon_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyApp +{ + public string MyProperty { get; set; } +} + +public class MyService +{ + public string Html { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Model_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void MultipleModels_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class ThisShouldBeGenerated +{ + +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ2001", Assert.Single(diagnotics).Id); + } + + [Fact] + public void ModelExpressionTagHelper_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void ViewComponentTagHelper_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class TestViewComponent +{{ + public string Invoke(string firstName) + {{ + return firstName; + }} +}} + +[{typeof(HtmlTargetElementAttribute).FullName}] +public class AllTagHelper : {typeof(TagHelper).FullName} +{{ + public string Bar {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/LegacySectionTargetExtensionTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/LegacySectionTargetExtensionTest.cs new file mode 100644 index 0000000000..bef1d0718f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/LegacySectionTargetExtensionTest.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 Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public class LegacySectionTargetExtensionTest + { + [Fact] + public void WriteSection_WritesSectionCode_DesignTime() + { + // Arrange + var node = new SectionIntermediateNode() + { + Children = + { + new CSharpExpressionIntermediateNode(), + }, + SectionName = "MySection" + }; + + var extension = new LegacySectionTargetExtension() + { + 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/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj new file mode 100644 index 0000000000..808b0f3eea --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj @@ -0,0 +1,51 @@ + + + + $(StandardTestTfms) + true + $(DefaultItemExcludes);TestFiles\** + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + Content + PreserveNewest + Build + + + + + + + + + + + + + + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ModelDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ModelDirectiveTest.cs new file mode 100644 index 0000000000..cc6cf53097 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ModelDirectiveTest.cs @@ -0,0 +1,343 @@ +// 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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class ModelDirectiveTest + { + [Fact] + public void ModelDirective_GetModelType_GetsTypeFromFirstWellFormedDirective() + { + // Arrange + var codeDocument = CreateDocument(@" +@model Type1 +@model Type2 +@model +"); + + var engine = CreateEngine(); + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = ModelDirective.GetModelType(irDocument); + + // Assert + Assert.Equal("Type1", result); + } + + [Fact] + public void ModelDirective_GetModelType_DefaultsToDynamic() + { + // Arrange + var codeDocument = CreateDocument(@" "); + + var engine = CreateEngine(); + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = ModelDirective.GetModelType(irDocument); + + // Assert + Assert.Equal("dynamic", result); + } + + [Fact] + public void ModelDirectivePass_Execute_ReplacesTModelInBaseType() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +@model Type1 +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_Execute_ReplacesTModelInBaseType_DifferentOrdering() + { + // Arrange + var codeDocument = CreateDocument(@" +@model Type1 +@inherits BaseType +@model Type2 +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_Execute_NoOpWithoutTModel() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +@model Type1 +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_Execute_ReplacesTModelInBaseType_DefaultDynamic() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_DesignTime_AddsTModelUsingDirective() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +"); + + var engine = CreateDesignTimeEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + + var @namespace = FindNamespaceNode(irDocument); + var usingNode = Assert.IsType(@namespace.Children[0]); + Assert.Equal($"TModel = global::{typeof(object).FullName}", usingNode.Content); + } + + [Fact] + public void ModelDirectivePass_DesignTime_WithModel_AddsTModelUsingDirective() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +@model SomeType +"); + + var engine = CreateDesignTimeEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + + var @namespace = FindNamespaceNode(irDocument); + var usingNode = Assert.IsType(@namespace.Children[0]); + Assert.Equal($"TModel = global::System.Object", usingNode.Content); + } + + private RazorCodeDocument CreateDocument(string content) + { + var source = RazorSourceDocument.Create(content, "test.cshtml"); + return RazorCodeDocument.Create(source); + } + + private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node) + { + var visitor = new ClassNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private NamespaceDeclarationIntermediateNode FindNamespaceNode(IntermediateNode node) + { + var visitor = new NamespaceNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private RazorEngine CreateEngine() + { + return CreateEngineCore(); + } + + private RazorEngine CreateDesignTimeEngine() + { + return CreateEngineCore(designTime: true); + } + + private RazorEngine CreateEngineCore(bool designTime = false) + { + return RazorProjectEngine.Create(b => + { + // Notice we're not registering the ModelDirective.Pass here so we can run it on demand. + b.AddDirective(ModelDirective.Directive); + + // There's some special interaction with the inherits directive + InheritsDirective.Register(b); + + b.Features.Add(new DesignTimeOptionsFeature(designTime)); + }).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 IRazorDocumentClassifierPhase) + { + break; + } + } + + // InheritsDirectivePass needs to run before ModelDirective. + var pass = new InheritsDirectivePass() + { + Engine = engine + }; + pass.Execute(codeDocument, codeDocument.GetDocumentIntermediateNode()); + + return codeDocument.GetDocumentIntermediateNode(); + } + + private string GetCSharpContent(IntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + var child = node.Children[i] as IntermediateToken; + if (child.Kind == TokenKind.CSharp) + { + builder.Append(child.Content); + } + } + + return builder.ToString(); + } + + private class ClassNodeVisitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Node { get; set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Node = node; + } + } + + private class NamespaceNodeVisitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Node { get; set; } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + Node = node; + } + } + + 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); + } + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ModelExpressionPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ModelExpressionPassTest.cs new file mode 100644 index 0000000000..30f27ffcbb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ModelExpressionPassTest.cs @@ -0,0 +1,208 @@ +// 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 System.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class ModelExpressionPassTest + { + [Fact] + public void ModelExpressionPass_NonModelExpressionProperty_Ignored() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BoundAttributeDescriptor(attribute => + attribute + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => + rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ModelExpressionPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + var setProperty = tagHelper.Children.OfType().Single(); + + var token = Assert.IsType(Assert.Single(setProperty.Children)); + Assert.True(token.IsCSharp); + Assert.Equal("17", token.Content); + } + + [Fact] + public void ModelExpressionPass_ModelExpressionProperty_SimpleExpression() + { + // Arrange + + // Using \r\n here because we verify line mappings + var codeDocument = CreateDocument( + "@addTagHelper TestTagHelper, TestAssembly\r\n

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BoundAttributeDescriptor(attribute => + attribute + .Name("Foo") + .TypeName("Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression")) + .TagMatchingRuleDescriptor(rule => + rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ModelExpressionPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + var setProperty = tagHelper.Children.OfType().Single(); + + var expression = Assert.IsType(Assert.Single(setProperty.Children)); + Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Bar)", GetCSharpContent(expression)); + + var originalNode = Assert.IsType(expression.Children[2]); + Assert.Equal(TokenKind.CSharp, originalNode.Kind); + Assert.Equal("Bar", originalNode.Content); + Assert.Equal(new SourceSpan("test.cshtml", 51, 1, 8, 3), originalNode.Source.Value); + } + + [Fact] + public void ModelExpressionPass_ModelExpressionProperty_ComplexExpression() + { + // Arrange + + // Using \r\n here because we verify line mappings + var codeDocument = CreateDocument( + "@addTagHelper TestTagHelper, TestAssembly\r\n

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BoundAttributeDescriptor(attribute => + attribute + .Name("Foo") + .TypeName("Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression")) + .TagMatchingRuleDescriptor(rule => + rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ModelExpressionPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + var setProperty = tagHelper.Children.OfType().Single(); + + var expression = Assert.IsType(Assert.Single(setProperty.Children)); + Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => Bar)", GetCSharpContent(expression)); + + var originalNode = Assert.IsType(expression.Children[1]); + Assert.Equal(TokenKind.CSharp, originalNode.Kind); + Assert.Equal("Bar", originalNode.Content); + Assert.Equal(new SourceSpan("test.cshtml", 52, 1, 9, 3), originalNode.Source.Value); + } + + 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 string GetCSharpContent(IntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + var child = node.Children[i] as IntermediateToken; + if (child.Kind == TokenKind.CSharp) + { + builder.Append(child.Content); + } + } + + return builder.ToString(); + } + + private class TagHelperNodeVisitor : IntermediateNodeWalker + { + public TagHelperIntermediateNode Node { get; set; } + + public override void VisitTagHelper(TagHelperIntermediateNode node) + { + Node = node; + } + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcImportProjectFeatureTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcImportProjectFeatureTest.cs new file mode 100644 index 0000000000..e53046ed5a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcImportProjectFeatureTest.cs @@ -0,0 +1,76 @@ +// 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; +using Moq; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class MvcImportProjectFeatureTest + { + [Fact] + public void AddDefaultDirectivesImport_AddsSingleDynamicImport() + { + // Arrange + var imports = new List(); + + // Act + MvcImportProjectFeature.AddDefaultDirectivesImport(imports); + + // Assert + var import = Assert.Single(imports); + Assert.Null(import.FilePath); + } + + [Fact] + public void AddHierarchicalImports_AddsViewImportSourceDocumentsOnDisk() + { + // Arrange + var imports = new List(); + var projectItem = new TestRazorProjectItem("/Contact/Index.cshtml"); + var testFileSystem = new TestRazorProjectFileSystem(new[] + { + new TestRazorProjectItem("/Index.cshtml"), + new TestRazorProjectItem("/_ViewImports.cshtml"), + new TestRazorProjectItem("/Contact/_ViewImports.cshtml"), + projectItem, + }); + var mvcImportFeature = new MvcImportProjectFeature() + { + ProjectEngine = Mock.Of(projectEngine => projectEngine.FileSystem == testFileSystem) + }; + + // Act + mvcImportFeature.AddHierarchicalImports(projectItem, imports); + + // Assert + Assert.Collection(imports, + import => Assert.Equal("/_ViewImports.cshtml", import.FilePath), + import => Assert.Equal("/Contact/_ViewImports.cshtml", import.FilePath)); + } + + [Fact] + public void AddHierarchicalImports_AddsViewImportSourceDocumentsNotOnDisk() + { + // Arrange + var imports = new List(); + var projectItem = new TestRazorProjectItem("/Pages/Contact/Index.cshtml"); + var testFileSystem = new TestRazorProjectFileSystem(new[] { projectItem }); + var mvcImportFeature = new MvcImportProjectFeature() + { + ProjectEngine = Mock.Of(projectEngine => projectEngine.FileSystem == testFileSystem) + }; + + // Act + mvcImportFeature.AddHierarchicalImports(projectItem, imports); + + // Assert + Assert.Collection(imports, + import => Assert.Equal("/_ViewImports.cshtml", import.FilePath), + import => Assert.Equal("/Pages/_ViewImports.cshtml", import.FilePath), + import => Assert.Equal("/Pages/Contact/_ViewImports.cshtml", import.FilePath)); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcRazorTemplateEngineTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcRazorTemplateEngineTest.cs new file mode 100644 index 0000000000..45186848ae --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcRazorTemplateEngineTest.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 System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class MvcRazorTemplateEngineTest + { + [Fact] + public void GetDefaultImports_IncludesDefaultImports() + { + // Arrange + var expectedImports = new[] + { + "@using System", + "@using System.Collections.Generic", + "@using System.Linq", + "@using System.Threading.Tasks", + "@using Microsoft.AspNetCore.Mvc", + "@using Microsoft.AspNetCore.Mvc.Rendering", + "@using Microsoft.AspNetCore.Mvc.ViewFeatures", + }; + var mvcRazorTemplateEngine = new MvcRazorTemplateEngine( + RazorProjectEngine.Create().Engine, + new TestRazorProjectFileSystem()); + + // Act + var imports = mvcRazorTemplateEngine.Options.DefaultImports; + + // Assert + var importContent = GetContent(imports) + .Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .Where(line => line.StartsWith("@using")); + Assert.Equal(expectedImports, importContent); + } + + [Fact] + public void GetDefaultImports_IncludesDefaulInjects() + { + // Arrange + var expectedImports = new[] + { + "@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html", + "@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json", + "@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component", + "@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url", + "@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider", + }; + var mvcRazorTemplateEngine = new MvcRazorTemplateEngine( + RazorProjectEngine.Create().Engine, + new TestRazorProjectFileSystem()); + + // Act + var imports = mvcRazorTemplateEngine.Options.DefaultImports; + + // Assert + var importContent = GetContent(imports) + .Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .Where(line => line.StartsWith("@inject")); + Assert.Equal(expectedImports, importContent); + } + + [Fact] + public void GetDefaultImports_IncludesDefaultTagHelpers() + { + // Arrange + var mvcRazorTemplateEngine = new MvcRazorTemplateEngine( + RazorProjectEngine.Create().Engine, + new TestRazorProjectFileSystem()); + + // Act + var imports = mvcRazorTemplateEngine.Options.DefaultImports; + + // Assert + var importContent = GetContent(imports) + .Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .Where(line => line.StartsWith("@addTagHelper")); + Assert.Contains("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor", importContent); + } + + private string GetContent(RazorSourceDocument imports) + { + var contentChars = new char[imports.Length]; + imports.CopyTo(0, contentChars, 0, imports.Length); + return new string(contentChars); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcShim.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcShim.cs new file mode 100644 index 0000000000..a50560e593 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcShim.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 System.IO; +using System.Reflection; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + internal static class MvcShim + { + public static readonly string AssemblyName = "Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X"; + + private static Assembly _assembly; + private static CSharpCompilation _baseCompilation; + + public static Assembly Assembly + { + get + { + if (_assembly == null) + { + var filePath = Path.Combine(Directory.GetCurrentDirectory(), AssemblyName + ".dll"); + _assembly = Assembly.LoadFrom(filePath); + } + + return _assembly; + } + } + + public static CSharpCompilation BaseCompilation + { + get + { + if (_baseCompilation == null) + { + _baseCompilation = TestCompilation.Create(Assembly); + } + + return _baseCompilation; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcViewDocumentClassifierPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcViewDocumentClassifierPassTest.cs new file mode 100644 index 0000000000..663aff4518 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/MvcViewDocumentClassifierPassTest.cs @@ -0,0 +1,264 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class MvcViewDocumentClassifierPassTest + { + [Fact] + public void MvcViewDocumentClassifierPass_SetsDocumentKind() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("mvc.1.0.view", irDocument.DocumentKind); + } + + [Fact] + public void MvcViewDocumentClassifierPass_NoOpsIfDocumentKindIsAlreadySet() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + irDocument.DocumentKind = "some-value"; + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("some-value", irDocument.DocumentKind); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SetsNamespace() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("AspNetCore", visitor.Namespace.Content); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("Test", visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_NullFilePath_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("AspNetCore_d9f877a857a7e9928eac04d09a59f25967624155", visitor.Class.ClassName); + } + + [Theory] + [InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")] + [InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")] + public void MvcViewDocumentClassifierPass_UsesRelativePathToGenerateTypeName(string relativePath, string expected) + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: relativePath); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal(expected, visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_UsesAbsolutePath_IfRelativePathIsNotSet() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x::\application\Views\Home\Index.cshtml", relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("x___application_Views_Home_Index", visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SanitizesClassName() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x:\Test.cshtml", relativePath: "path.with+invalid-chars"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("path_with_invalid_chars", visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SetsUpExecuteAsyncMethod() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("ExecuteAsync", visitor.Method.MethodName); + Assert.Equal("global::System.Threading.Tasks.Task", visitor.Method.ReturnType); + Assert.Equal(new[] { "public", "async", "override" }, visitor.Method.Modifiers); + } + + private static RazorProjectEngine CreateProjectEngine() => RazorProjectEngine.Create(); + + private static DocumentIntermediateNode CreateIRDocument(RazorProjectEngine engine, RazorCodeDocument codeDocument) + { + for (var i = 0; i < engine.Phases.Count; i++) + { + var phase = engine.Phases[i]; + phase.Execute(codeDocument); + + if (phase is IRazorIntermediateNodeLoweringPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + + private class Visitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Namespace { get; private set; } + + public ClassDeclarationIntermediateNode Class { get; private set; } + + public MethodDeclarationIntermediateNode Method { get; private set; } + + public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node) + { + Method = node; + } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + Namespace = node; + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Class = node; + base.VisitClassDeclaration(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..3337ebeac2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/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/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/SourceMappingsSerializer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/SourceMappingsSerializer.cs new file mode 100644 index 0000000000..c081118d86 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/SourceMappingsSerializer.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 System; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public static class SourceMappingsSerializer + { + public static string Serialize(RazorCSharpDocument csharpDocument, RazorSourceDocument sourceDocument) + { + var builder = new StringBuilder(); + var sourceFilePath = sourceDocument.FilePath; + var charBuffer = new char[sourceDocument.Length]; + sourceDocument.CopyTo(0, charBuffer, 0, sourceDocument.Length); + var sourceContent = new string(charBuffer); + + for (var i = 0; i < csharpDocument.SourceMappings.Count; i++) + { + var sourceMapping = csharpDocument.SourceMappings[i]; + if (!string.Equals(sourceMapping.OriginalSpan.FilePath, sourceFilePath, StringComparison.Ordinal)) + { + continue; + } + + builder.Append("Source Location: "); + AppendMappingLocation(builder, sourceMapping.OriginalSpan, sourceContent); + + builder.Append("Generated Location: "); + AppendMappingLocation(builder, sourceMapping.GeneratedSpan, csharpDocument.GeneratedCode); + + builder.AppendLine(); + } + + return builder.ToString(); + } + + private static void AppendMappingLocation(StringBuilder builder, SourceSpan location, string content) + { + builder + .AppendLine(location.ToString()) + .Append("|"); + + for (var i = 0; i < location.Length; i++) + { + builder.Append(content[location.AbsoluteIndex + i]); + } + + builder.AppendLine("|"); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TagHelperDescriptorExtensionsTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TagHelperDescriptorExtensionsTest.cs new file mode 100644 index 0000000000..f080719b5a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TagHelperDescriptorExtensionsTest.cs @@ -0,0 +1,82 @@ +// 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; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class TagHelperDescriptorExtensionsTest + { + [Fact] + public void IsViewComponentKind_ReturnsFalse_ForNonVCTHDescriptor() + { + // Arrange + var tagHelper = CreateTagHelperDescriptor(); + + // Act + var result = tagHelper.IsViewComponentKind(); + + // Assert + Assert.False(result); + } + + [Fact] + public void IsViewComponentKind_ReturnsTrue_ForVCTHDescriptor() + { + // Arrange + var tagHelper = CreateViewComponentTagHelperDescriptor(); + + // Act + var result = tagHelper.IsViewComponentKind(); + + // Assert + Assert.True(result); + } + + [Fact] + public void GetViewComponentName_ReturnsNull_ForNonVCTHDescriptor() + { + //Arrange + var tagHelper = CreateTagHelperDescriptor(); + + // Act + var result = tagHelper.GetViewComponentName(); + + // Assert + Assert.Null(result); + } + + [Fact] + public void GetViewComponentName_ReturnsName_ForVCTHDescriptor() + { + // Arrange + var tagHelper = CreateViewComponentTagHelperDescriptor("ViewComponentName"); + + // Act + var result = tagHelper.GetViewComponentName(); + + // Assert + Assert.Equal("ViewComponentName", result); + } + + private static TagHelperDescriptor CreateTagHelperDescriptor() + { + var tagHelper = TagHelperDescriptorBuilder.Create("TypeName", "AssemblyName") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name")) + .Build(); + + return tagHelper; + } + + private static TagHelperDescriptor CreateViewComponentTagHelperDescriptor(string name = "ViewComponentName") + { + var tagHelper = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TypeName", "AssemblyName") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, name) + .Build(); + + return tagHelper; + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml new file mode 100644 index 0000000000..a20b20dae8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml @@ -0,0 +1,8 @@ +

+ Hello world + @string.Format("{0}", "Hello") +
+@{ + var cls = "foo"; +} +

diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs new file mode 100644 index 0000000000..d39b64c26d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs @@ -0,0 +1,71 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + __o = this.ToString(); + +#line default +#line hidden +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" +__o = string.Format("{0}", "Hello"); + +#line default +#line hidden +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + + var cls = "foo"; + +#line default +#line hidden +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + if(cls != null) { + +#line default +#line hidden +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + __o = cls; + +#line default +#line hidden +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + } + +#line default +#line hidden + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt new file mode 100644 index 0000000000..24d84bf975 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt @@ -0,0 +1,62 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (0:0,0 [4] Basic.cshtml) + IntermediateToken - (0:0,0 [4] Basic.cshtml) - Html -

+ IntermediateToken - (30:0,30 [23] Basic.cshtml) - Html - \n Hello world\n + CSharpExpression - (54:2,5 [29] Basic.cshtml) + IntermediateToken - (54:2,5 [29] Basic.cshtml) - CSharp - string.Format("{0}", "Hello") + HtmlContent - (83:2,34 [10] Basic.cshtml) + IntermediateToken - (83:2,34 [2] Basic.cshtml) - Html - \n + IntermediateToken - (85:3,0 [6] Basic.cshtml) - Html -
+ IntermediateToken - (91:3,6 [2] Basic.cshtml) - Html - \n + CSharpCode - (95:4,2 [25] Basic.cshtml) + IntermediateToken - (95:4,2 [25] Basic.cshtml) - CSharp - \n var cls = "foo";\n + HtmlContent - (123:7,0 [2] Basic.cshtml) + IntermediateToken - (123:7,0 [2] Basic.cshtml) - Html -

+ IntermediateToken - (162:7,39 [2] Basic.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt new file mode 100644 index 0000000000..372b49cb6f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt @@ -0,0 +1,34 @@ +Source Location: (13:0,13 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|this.ToString()| +Generated Location: (1030:26,13 [15] ) +|this.ToString()| + +Source Location: (54:2,5 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|string.Format("{0}", "Hello")| +Generated Location: (1166:31,6 [29] ) +|string.Format("{0}", "Hello")| + +Source Location: (95:4,2 [25] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +| + var cls = "foo"; +| +Generated Location: (1312:36,2 [25] ) +| + var cls = "foo"; +| + +Source Location: (134:7,11 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|if(cls != null) { | +Generated Location: (1460:42,11 [18] ) +|if(cls != null) { | + +Source Location: (153:7,30 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|cls| +Generated Location: (1622:47,30 [3] ) +|cls| + +Source Location: (156:7,33 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +| }| +Generated Location: (1773:52,33 [2] ) +| }| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs new file mode 100644 index 0000000000..b8ce28e05f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs @@ -0,0 +1,92 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "4120ddad9d4353ed260e0585fe71080d78ff8ab3" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(0, 4, true); + WriteLiteral("

+ IntermediateToken - (30:0,30 [19] Basic.cshtml) - Html - \n Hello world\n + IntermediateToken - (49:2,0 [4] Basic.cshtml) - Html - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(54, 29, false); + CSharpExpression - (54:2,5 [29] Basic.cshtml) + IntermediateToken - (54:2,5 [29] Basic.cshtml) - CSharp - string.Format("{0}", "Hello") + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(83, 10, true); + HtmlContent - (83:2,34 [10] Basic.cshtml) + IntermediateToken - (83:2,34 [2] Basic.cshtml) - Html - \n + IntermediateToken - (85:3,0 [6] Basic.cshtml) - Html -
+ IntermediateToken - (91:3,6 [2] Basic.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - (95:4,2 [25] Basic.cshtml) + IntermediateToken - (95:4,2 [25] Basic.cshtml) - CSharp - \n var cls = "foo";\n + CSharpCode - + IntermediateToken - - CSharp - BeginContext(123, 2, true); + HtmlContent - (123:7,0 [2] Basic.cshtml) + IntermediateToken - (123:7,0 [2] Basic.cshtml) - Html -

+ IntermediateToken - (162:7,39 [2] Basic.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml new file mode 100644 index 0000000000..ecc90de2d6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml @@ -0,0 +1,8 @@ +@* These test files validate that end-to-end, incomplete directives don't throw. *@ + +@model +@model + +@inject +@inject +@inject MyService diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs new file mode 100644 index 0000000000..9fdc70a98b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs @@ -0,0 +1,63 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..3542c13c86 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt @@ -0,0 +1,6 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(3,7): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ2001: The 'model' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,8): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(6,8): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,9): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,26): Error RZ1015: The 'inject' directive expects an identifier. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt new file mode 100644 index 0000000000..3a6d24fc1e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt @@ -0,0 +1,64 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (93:2,6 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (102:3,7 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (113:5,7 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (123:6,8 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (133:7,8 [17] IncompleteDirectives.cshtml) - MyService + DirectiveToken - (150:7,25 [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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) + IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (87:2,0 [6] IncompleteDirectives.cshtml) - model + DirectiveToken - (93:2,6 [0] IncompleteDirectives.cshtml) - + HtmlContent - (93:2,6 [2] IncompleteDirectives.cshtml) + IntermediateToken - (93:2,6 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (95:3,0 [7] IncompleteDirectives.cshtml) - model + DirectiveToken - (102:3,7 [0] IncompleteDirectives.cshtml) - + HtmlContent - (102:3,7 [4] IncompleteDirectives.cshtml) + IntermediateToken - (102:3,7 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (106:5,0 [7] IncompleteDirectives.cshtml) - inject + DirectiveToken - (113:5,7 [0] IncompleteDirectives.cshtml) - + HtmlContent - (113:5,7 [2] IncompleteDirectives.cshtml) + IntermediateToken - (113:5,7 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (115:6,0 [8] IncompleteDirectives.cshtml) - inject + DirectiveToken - (123:6,8 [0] IncompleteDirectives.cshtml) - + HtmlContent - (123:6,8 [2] IncompleteDirectives.cshtml) + IntermediateToken - (123:6,8 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (125:7,0 [25] IncompleteDirectives.cshtml) - inject + DirectiveToken - (133:7,8 [17] IncompleteDirectives.cshtml) - MyService + DirectiveToken - (150:7,25 [0] IncompleteDirectives.cshtml) - + HtmlContent - (150:7,25 [2] IncompleteDirectives.cshtml) + IntermediateToken - (150:7,25 [2] IncompleteDirectives.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt new file mode 100644 index 0000000000..cb37b8b1a0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt @@ -0,0 +1,30 @@ +Source Location: (93:2,6 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (680:18,0 [0] ) +|| + +Source Location: (102:3,7 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (733:21,0 [0] ) +|| + +Source Location: (113:5,7 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (786:24,0 [0] ) +|| + +Source Location: (123:6,8 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (839:27,0 [0] ) +|| + +Source Location: (133:7,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|MyService| +Generated Location: (988:31,0 [17] ) +|MyService| + +Source Location: (150:7,25 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (1141:38,0 [0] ) +|| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs new file mode 100644 index 0000000000..e9170ae11c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs @@ -0,0 +1,51 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "844eb91b909a14b78feddd5e6866563b5a75e021" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(83, 4, true); + WriteLiteral("\r\n\r\n"); + EndContext(); + BeginContext(93, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(102, 4, true); + WriteLiteral("\r\n\r\n"); + EndContext(); + BeginContext(113, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(123, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(150, 2, true); + WriteLiteral("\r\n"); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt new file mode 100644 index 0000000000..72a8fa589b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt @@ -0,0 +1,6 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(3,7): Error RZ9999: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ9999: The 'model' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,8): Error RZ9999: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(6,8): Error RZ9999: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,9): Error RZ9999: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,26): Error RZ9999: The 'inject' directive expects an identifier. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt new file mode 100644 index 0000000000..8bb3264f43 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt @@ -0,0 +1,58 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(83, 4, true); + HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) + IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (87:2,0 [6] IncompleteDirectives.cshtml) - model + CSharpCode - + IntermediateToken - - CSharp - BeginContext(93, 2, true); + HtmlContent - (93:2,6 [2] IncompleteDirectives.cshtml) + IntermediateToken - (93:2,6 [2] IncompleteDirectives.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (95:3,0 [7] IncompleteDirectives.cshtml) - model + CSharpCode - + IntermediateToken - - CSharp - BeginContext(102, 4, true); + HtmlContent - (102:3,7 [4] IncompleteDirectives.cshtml) + IntermediateToken - (102:3,7 [4] IncompleteDirectives.cshtml) - Html - \n\n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (106:5,0 [7] IncompleteDirectives.cshtml) - inject + CSharpCode - + IntermediateToken - - CSharp - BeginContext(113, 2, true); + HtmlContent - (113:5,7 [2] IncompleteDirectives.cshtml) + IntermediateToken - (113:5,7 [2] IncompleteDirectives.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (115:6,0 [8] IncompleteDirectives.cshtml) - inject + CSharpCode - + IntermediateToken - - CSharp - BeginContext(123, 2, true); + HtmlContent - (123:6,8 [2] IncompleteDirectives.cshtml) + IntermediateToken - (123:6,8 [2] IncompleteDirectives.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (125:7,0 [25] IncompleteDirectives.cshtml) - inject + DirectiveToken - (133:7,8 [17] IncompleteDirectives.cshtml) - MyService + CSharpCode - + IntermediateToken - - CSharp - BeginContext(150, 2, true); + HtmlContent - (150:7,25 [2] IncompleteDirectives.cshtml) + IntermediateToken - (150:7,25 [2] IncompleteDirectives.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml new file mode 100644 index 0000000000..38efd570da --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml @@ -0,0 +1,2 @@ +@inherits MyBasePageForViews +@model MyModel diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs new file mode 100644 index 0000000000..7cdbaf3326 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs @@ -0,0 +1,56 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel : MyBasePageForViews + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" +MyBasePageForViews __typeHelper = default(MyBasePageForViews); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt new file mode 100644 index 0000000000..cc189604db --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt @@ -0,0 +1,37 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel - MyBasePageForViews - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (10:0,10 [26] InheritsViewModel.cshtml) - MyBasePageForViews + DirectiveToken - (45:1,7 [7] InheritsViewModel.cshtml) - MyModel + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt new file mode 100644 index 0000000000..6a313a909d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (10:0,10 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml) +|MyBasePageForViews| +Generated Location: (740:19,0 [26] ) +|MyBasePageForViews| + +Source Location: (45:1,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml) +|MyModel| +Generated Location: (1004:27,0 [7] ) +|MyModel| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs new file mode 100644 index 0000000000..af9db74379 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs @@ -0,0 +1,33 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "91cf923452a86b2906083cb0236d6d5b3bc528ef" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel_cshtml : MyBasePageForViews + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt new file mode 100644 index 0000000000..b18e254c9f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt @@ -0,0 +1,16 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel_cshtml - MyBasePageForViews - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml new file mode 100644 index 0000000000..c735e2e429 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml @@ -0,0 +1 @@ +@model MyModel diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs new file mode 100644 index 0000000000..0ca023f56a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs @@ -0,0 +1,48 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports : MyBasePageForViews + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt new file mode 100644 index 0000000000..db2a73f64d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt @@ -0,0 +1,37 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyBasePageForViews - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (10:0,10 [26] TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml) - MyBasePageForViews + DirectiveToken - (7:0,7 [7] InheritsWithViewImports.cshtml) - MyModel + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt new file mode 100644 index 0000000000..9ee5bceaa0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml) +|MyModel| +Generated Location: (752:19,0 [7] ) +|MyModel| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs new file mode 100644 index 0000000000..5ede728cf8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs @@ -0,0 +1,33 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "cf2e52e7d1326775fe4ece983a7f8ee1f62235a0" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports_cshtml : MyBasePageForViews + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt new file mode 100644 index 0000000000..0f47fce86b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt @@ -0,0 +1,16 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports_cshtml - MyBasePageForViews - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml new file mode 100644 index 0000000000..0aa749dd3f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml @@ -0,0 +1 @@ +@inject MyApp MyPropertyName diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml new file mode 100644 index 0000000000..d699f1e754 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml @@ -0,0 +1,3 @@ +@model MyModel +@inject MyApp MyPropertyName +@inject MyService Html diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs new file mode 100644 index 0000000000..2120622373 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs @@ -0,0 +1,82 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +global::System.Object MyPropertyName = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +global::System.Object Html = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt new file mode 100644 index 0000000000..8ff03ba4e9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt @@ -0,0 +1,41 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [7] InjectWithModel.cshtml) - MyModel + DirectiveToken - (24:1,8 [5] InjectWithModel.cshtml) - MyApp + DirectiveToken - (30:1,14 [14] InjectWithModel.cshtml) - MyPropertyName + DirectiveToken - (54:2,8 [17] InjectWithModel.cshtml) - MyService + DirectiveToken - (72:2,26 [4] InjectWithModel.cshtml) - Html + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt new file mode 100644 index 0000000000..c4838ff64d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt @@ -0,0 +1,25 @@ +Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyModel| +Generated Location: (766:19,0 [7] ) +|MyModel| + +Source Location: (24:1,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyApp| +Generated Location: (990:27,0 [5] ) +|MyApp| + +Source Location: (30:1,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyPropertyName| +Generated Location: (1232:35,22 [14] ) +|MyPropertyName| + +Source Location: (54:2,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyService| +Generated Location: (1438:43,0 [17] ) +|MyService| + +Source Location: (72:2,26 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|Html| +Generated Location: (1704:51,22 [4] ) +|Html| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs new file mode 100644 index 0000000000..c3846121e1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs @@ -0,0 +1,35 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "a039b7091118c718dc3023b6ac58d9645cb58e59" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt new file mode 100644 index 0000000000..2e1c3deb3e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt @@ -0,0 +1,17 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml new file mode 100644 index 0000000000..8cd61913e4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml @@ -0,0 +1,5 @@ +@model MyModel +@inject MyApp MyPropertyName; +@inject MyService Html; +@inject MyApp MyPropertyName2 ; +@inject MyService Html2 ; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs new file mode 100644 index 0000000000..ea95a4e7eb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs @@ -0,0 +1,118 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object MyPropertyName = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object Html = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object MyPropertyName2 = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object Html2 = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt new file mode 100644 index 0000000000..2b470e7180 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt @@ -0,0 +1,47 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [7] InjectWithSemicolon.cshtml) - MyModel + DirectiveToken - (24:1,8 [5] InjectWithSemicolon.cshtml) - MyApp + DirectiveToken - (30:1,14 [14] InjectWithSemicolon.cshtml) - MyPropertyName + DirectiveToken - (58:2,8 [17] InjectWithSemicolon.cshtml) - MyService + DirectiveToken - (76:2,26 [4] InjectWithSemicolon.cshtml) - Html + DirectiveToken - (93:3,8 [5] InjectWithSemicolon.cshtml) - MyApp + DirectiveToken - (99:3,14 [15] InjectWithSemicolon.cshtml) - MyPropertyName2 + DirectiveToken - (129:4,8 [17] InjectWithSemicolon.cshtml) - MyService + DirectiveToken - (147:4,26 [5] InjectWithSemicolon.cshtml) - Html2 + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt new file mode 100644 index 0000000000..6a90f75f3e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt @@ -0,0 +1,45 @@ +Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyModel| +Generated Location: (774:19,0 [7] ) +|MyModel| + +Source Location: (24:1,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyApp| +Generated Location: (1002:27,0 [5] ) +|MyApp| + +Source Location: (30:1,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyPropertyName| +Generated Location: (1248:35,22 [14] ) +|MyPropertyName| + +Source Location: (58:2,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyService| +Generated Location: (1458:43,0 [17] ) +|MyService| + +Source Location: (76:2,26 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|Html| +Generated Location: (1728:51,22 [4] ) +|Html| + +Source Location: (93:3,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyApp| +Generated Location: (1928:59,0 [5] ) +|MyApp| + +Source Location: (99:3,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyPropertyName2| +Generated Location: (2174:67,22 [15] ) +|MyPropertyName2| + +Source Location: (129:4,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyService| +Generated Location: (2385:75,0 [17] ) +|MyService| + +Source Location: (147:4,26 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|Html2| +Generated Location: (2655:83,22 [5] ) +|Html2| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs new file mode 100644 index 0000000000..4dd7659e08 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs @@ -0,0 +1,39 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5010aab35d235175dab517f8018e41aee9a2ac7f" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt new file mode 100644 index 0000000000..b624d6b15c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt @@ -0,0 +1,19 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs new file mode 100644 index 0000000000..7b2f4fedc6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs @@ -0,0 +1,58 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml" +global::System.Object MyPropertyName = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt new file mode 100644 index 0000000000..2fed4fbe5a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt @@ -0,0 +1,38 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (8:0,8 [5] Inject.cshtml) - MyApp + DirectiveToken - (14:0,14 [14] Inject.cshtml) - MyPropertyName + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt new file mode 100644 index 0000000000..10ed356ecf --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (8:0,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml) +|MyApp| +Generated Location: (748:19,0 [5] ) +|MyApp| + +Source Location: (14:0,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml) +|MyPropertyName| +Generated Location: (981:27,22 [14] ) +|MyPropertyName| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs new file mode 100644 index 0000000000..941237e909 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs @@ -0,0 +1,35 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "c711078454f5b0e8d2cb77d9cb7fa88cca32b884" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt new file mode 100644 index 0000000000..32a3c51ac7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt @@ -0,0 +1,17 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml new file mode 100644 index 0000000000..6dfb72bc31 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml @@ -0,0 +1 @@ +@namespace Test. \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs new file mode 100644 index 0000000000..d99c176c52 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..c3add1daa9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml(1,2): Error RZ1007: "namespace" is a reserved word and cannot be used in implicit expressions. An explicit expression ("@()") must be used. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt new file mode 100644 index 0000000000..f34fe8f4a0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt @@ -0,0 +1,37 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (10:0,10 [6] InvalidNamespaceAtEOF.cshtml) + IntermediateToken - (10:0,10 [6] InvalidNamespaceAtEOF.cshtml) - Html - Test. + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs new file mode 100644 index 0000000000..d292eeebcc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs @@ -0,0 +1,36 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "de132bd3e2a46a0d2ec953a168427c01e5829cde" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(10, 6, true); + WriteLiteral(" Test."); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt new file mode 100644 index 0000000000..cfbf688e18 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml(1,2): Error RZ9999: "namespace" is a reserved word and cannot be used in implicit expressions. An explicit expression ("@()") must be used. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt new file mode 100644 index 0000000000..fb0bab7833 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt @@ -0,0 +1,22 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(10, 6, true); + HtmlContent - (10:0,10 [6] InvalidNamespaceAtEOF.cshtml) + IntermediateToken - (10:0,10 [6] InvalidNamespaceAtEOF.cshtml) - Html - Test. + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml new file mode 100644 index 0000000000..4b73b2dc53 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml @@ -0,0 +1 @@ +@model System.Collections.IEnumerable diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml new file mode 100644 index 0000000000..c488b1e443 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml @@ -0,0 +1,6 @@ +@model DateTime + +@addTagHelper "InputTestTagHelper, AppCode" + + + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs new file mode 100644 index 0000000000..82441cd663 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs @@ -0,0 +1,69 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +DateTime __typeHelper = default(DateTime); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +global::System.Object __typeHelper = "InputTestTagHelper, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + __InputTestTagHelper = CreateTagHelper(); +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + __InputTestTagHelper = CreateTagHelper(); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => Model); + +#line default +#line hidden + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt new file mode 100644 index 0000000000..1ecd121c63 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt @@ -0,0 +1,66 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [8] ModelExpressionTagHelper.cshtml) - DateTime + DirectiveToken - (33:2,14 [29] ModelExpressionTagHelper.cshtml) - "InputTestTagHelper, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (17:1,0 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (17:1,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n + HtmlContent - (62:2,43 [4] ModelExpressionTagHelper.cshtml) + IntermediateToken - (62:2,43 [4] ModelExpressionTagHelper.cshtml) - Html - \n\n + TagHelper - (66:4,0 [25] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (91:4,25 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (91:4,25 [2] ModelExpressionTagHelper.cshtml) - Html - \n + TagHelper - (93:5,0 [27] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - (111:5,18 [5] ModelExpressionTagHelper.cshtml) - CSharp - Model + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (120:5,27 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (120:5,27 [2] ModelExpressionTagHelper.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt new file mode 100644 index 0000000000..63a7d6ccc1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt @@ -0,0 +1,20 @@ +Source Location: (7:0,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|DateTime| +Generated Location: (851:20,0 [8] ) +|DateTime| + +Source Location: (33:2,14 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|"InputTestTagHelper, AppCode"| +Generated Location: (1123:28,37 [29] ) +|"InputTestTagHelper, AppCode"| + +Source Location: (83:4,17 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|Date| +Generated Location: (1802:44,102 [4] ) +|Date| + +Source Location: (111:5,18 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|Model| +Generated Location: (2118:50,94 [5] ) +|Model| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs new file mode 100644 index 0000000000..8fb69e52ed --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs @@ -0,0 +1,104 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "0906a816db301fe624bbe5a96c4b3013071ea492" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(17, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(64, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(66, 25, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => { + } + ); + __InputTestTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTestTagHelper); +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("for", __InputTestTagHelper.For, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(91, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(93, 27, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => { + } + ); + __InputTestTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTestTagHelper); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => Model); + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("for", __InputTestTagHelper.For, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(120, 2, true); + WriteLiteral("\r\n"); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt new file mode 100644 index 0000000000..b336b645b0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt @@ -0,0 +1,69 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(17, 2, true); + HtmlContent - (17:1,0 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (17:1,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(64, 2, true); + HtmlContent - (64:3,0 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (64:3,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(66, 25, false); + TagHelper - (66:4,0 [25] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(91, 2, true); + HtmlContent - (91:4,25 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (91:4,25 [2] ModelExpressionTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(93, 27, false); + TagHelper - (93:5,0 [27] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - (111:5,18 [5] ModelExpressionTagHelper.cshtml) - CSharp - Model + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(120, 2, true); + HtmlContent - (120:5,27 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (120:5,27 [2] ModelExpressionTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs new file mode 100644 index 0000000000..63c2a52c6f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs @@ -0,0 +1,48 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml" +System.Collections.IEnumerable __typeHelper = default(System.Collections.IEnumerable); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt new file mode 100644 index 0000000000..c18b0cd554 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt @@ -0,0 +1,36 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [30] Model.cshtml) - System.Collections.IEnumerable + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt new file mode 100644 index 0000000000..7d84cf754d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (7:0,7 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml) +|System.Collections.IEnumerable| +Generated Location: (769:19,0 [30] ) +|System.Collections.IEnumerable| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs new file mode 100644 index 0000000000..cd4f57b409 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs @@ -0,0 +1,33 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "31c5b047a450ac9f6dc4116626667d26bfb657ba" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt new file mode 100644 index 0000000000..3f8d705381 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt @@ -0,0 +1,16 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml new file mode 100644 index 0000000000..350f93b776 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml @@ -0,0 +1,2 @@ +@model ThisShouldBeGenerated +@model System.Collections.IEnumerable diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs new file mode 100644 index 0000000000..e8f705cef7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs @@ -0,0 +1,56 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MultipleModels : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml" +ThisShouldBeGenerated __typeHelper = default(ThisShouldBeGenerated); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml" +System.Collections.IEnumerable __typeHelper = default(System.Collections.IEnumerable); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..2fe8233c66 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml(2,1): Error RZ2001: The 'model' directive may only occur once per document. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt new file mode 100644 index 0000000000..a1ef9941e3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt @@ -0,0 +1,39 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MultipleModels - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [21] MultipleModels.cshtml) - ThisShouldBeGenerated + DirectiveToken - (37:1,7 [30] MultipleModels.cshtml) - System.Collections.IEnumerable + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (30:1,0 [39] MultipleModels.cshtml) - model + DirectiveToken - (37:1,7 [30] MultipleModels.cshtml) - System.Collections.IEnumerable + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt new file mode 100644 index 0000000000..79d7e257c7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (7:0,7 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml) +|ThisShouldBeGenerated| +Generated Location: (778:19,0 [21] ) +|ThisShouldBeGenerated| + +Source Location: (37:1,7 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml) +|System.Collections.IEnumerable| +Generated Location: (1029:27,0 [30] ) +|System.Collections.IEnumerable| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml new file mode 100644 index 0000000000..7438788ff4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml @@ -0,0 +1,14 @@ +@model DateTime + +@addTagHelper "InputTestTagHelper, AppCode" + +@{ + Layout = "_SectionTestLayout.cshtml"; +} + +

Some body
+ +@section Section1 { +
This is in Section 1
+ +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs new file mode 100644 index 0000000000..3ca46af8a7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs @@ -0,0 +1,80 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +DateTime __typeHelper = default(DateTime); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +global::System.Object __typeHelper = "InputTestTagHelper, AppCode"; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +global::System.Object Section1 = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" + + Layout = "_SectionTestLayout.cshtml"; + +#line default +#line hidden + DefineSection("Section1", async(__razor_section_writer) => { + __InputTestTagHelper = CreateTagHelper(); +#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + } + ); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt new file mode 100644 index 0000000000..515e48bee6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt @@ -0,0 +1,71 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [8] Sections.cshtml) - DateTime + DirectiveToken - (33:2,14 [29] Sections.cshtml) - "InputTestTagHelper, AppCode" + DirectiveToken - (152:10,9 [8] Sections.cshtml) - Section1 + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (17:1,0 [2] Sections.cshtml) + IntermediateToken - (17:1,0 [2] Sections.cshtml) - Html - \n + HtmlContent - (62:2,43 [4] Sections.cshtml) + IntermediateToken - (62:2,43 [4] Sections.cshtml) - Html - \n\n + CSharpCode - (68:4,2 [46] Sections.cshtml) + IntermediateToken - (68:4,2 [46] Sections.cshtml) - CSharp - \n Layout = "_SectionTestLayout.cshtml";\n + HtmlContent - (117:7,0 [26] Sections.cshtml) + IntermediateToken - (117:7,0 [2] Sections.cshtml) - Html - \n + IntermediateToken - (119:8,0 [5] Sections.cshtml) - Html -
+ IntermediateToken - (124:8,5 [9] Sections.cshtml) - Html - Some body + IntermediateToken - (133:8,14 [6] Sections.cshtml) - Html -
+ IntermediateToken - (139:8,20 [4] Sections.cshtml) - Html - \n\n + Section - - Section1 + HtmlContent - (162:10,19 [43] Sections.cshtml) + IntermediateToken - (162:10,19 [6] Sections.cshtml) - Html - \n + IntermediateToken - (168:11,4 [5] Sections.cshtml) - Html -
+ IntermediateToken - (173:11,9 [20] Sections.cshtml) - Html - This is in Section 1 + IntermediateToken - (193:11,29 [6] Sections.cshtml) - Html -
+ IntermediateToken - (199:11,35 [6] Sections.cshtml) - Html - \n + TagHelper - (205:12,4 [25] Sections.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (222:12,21 [4] Sections.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (222:12,21 [4] Sections.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (230:12,29 [2] Sections.cshtml) + IntermediateToken - (230:12,29 [2] Sections.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt new file mode 100644 index 0000000000..1cc991810c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt @@ -0,0 +1,29 @@ +Source Location: (7:0,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|DateTime| +Generated Location: (819:20,0 [8] ) +|DateTime| + +Source Location: (33:2,14 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|"InputTestTagHelper, AppCode"| +Generated Location: (1075:28,37 [29] ) +|"InputTestTagHelper, AppCode"| + +Source Location: (152:10,9 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|Section1| +Generated Location: (1305:36,22 [8] ) +|Section1| + +Source Location: (68:4,2 [46] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +| + Layout = "_SectionTestLayout.cshtml"; +| +Generated Location: (1771:51,2 [46] ) +| + Layout = "_SectionTestLayout.cshtml"; +| + +Source Location: (222:12,21 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|Date| +Generated Location: (2196:59,102 [4] ) +|Date| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml new file mode 100644 index 0000000000..0430ccfc69 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml @@ -0,0 +1,6 @@ +@addTagHelper "*, AppCode" +@{ + var foo = "Hello"; +} + + \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs new file mode 100644 index 0000000000..b6196f6651 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs @@ -0,0 +1,84 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::AllTagHelper __AllTagHelper; + private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper __TestViewComponentTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" +global::System.Object __typeHelper = "*, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + + var foo = "Hello"; + +#line default +#line hidden + __AllTagHelper = CreateTagHelper(); + __TestViewComponentTagHelper = CreateTagHelper(); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + __o = foo; + +#line default +#line hidden + __TestViewComponentTagHelper.firstName = string.Empty; + __AllTagHelper.Bar = " World"; + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("vc:test")] + public class __Generated__TestViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper + { + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TestViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.String firstName { get; set; } + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync("Test", new { firstName }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } + } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt new file mode 100644 index 0000000000..328b11876d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt @@ -0,0 +1,57 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::AllTagHelper - __AllTagHelper + FieldDeclaration - - private - global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper - __TestViewComponentTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (14:0,14 [12] ViewComponentTagHelper.cshtml) - "*, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (26:0,26 [2] ViewComponentTagHelper.cshtml) + IntermediateToken - (26:0,26 [2] ViewComponentTagHelper.cshtml) - Html - \n + CSharpCode - (30:1,2 [26] ViewComponentTagHelper.cshtml) + IntermediateToken - (30:1,2 [26] ViewComponentTagHelper.cshtml) - CSharp - \n var foo = "Hello";\n + HtmlContent - (59:4,0 [2] ViewComponentTagHelper.cshtml) + IntermediateToken - (59:4,0 [2] ViewComponentTagHelper.cshtml) - Html - \n + TagHelper - (61:5,0 [50] ViewComponentTagHelper.cshtml) - vc:test - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - AllTagHelper + DefaultTagHelperCreate - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper + DefaultTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - string TestViewComponentTagHelper.firstName - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - (83:5,22 [3] ViewComponentTagHelper.cshtml) + IntermediateToken - (83:5,22 [3] ViewComponentTagHelper.cshtml) - CSharp - foo + DefaultTagHelperProperty - (93:5,32 [6] ViewComponentTagHelper.cshtml) - bar - string AllTagHelper.Bar - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (93:5,32 [6] ViewComponentTagHelper.cshtml) + IntermediateToken - (93:5,32 [6] ViewComponentTagHelper.cshtml) - Html - World + DefaultTagHelperExecute - + Inject - + Inject - + Inject - + Inject - + Inject - + ViewComponentTagHelper - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt new file mode 100644 index 0000000000..9c5fd32efb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt @@ -0,0 +1,19 @@ +Source Location: (14:0,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) +|"*, AppCode"| +Generated Location: (1057:21,37 [12] ) +|"*, AppCode"| + +Source Location: (30:1,2 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) +| + var foo = "Hello"; +| +Generated Location: (1534:36,2 [26] ) +| + var foo = "Hello"; +| + +Source Location: (83:5,22 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) +|foo| +Generated Location: (1985:44,22 [3] ) +|foo| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs new file mode 100644 index 0000000000..2c85bf513c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs @@ -0,0 +1,110 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "6a0ad3c59f3a87877c36928472f0508bd40cdd8c" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper __TestViewComponentTagHelper; + private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("bar", " 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::AllTagHelper __AllTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + + var foo = "Hello"; + +#line default +#line hidden + BeginContext(59, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(61, 50, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("vc:test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + } + ); + __AllTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__AllTagHelper); + __TestViewComponentTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__TestViewComponentTagHelper); + BeginWriteTagHelperAttribute(); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + WriteLiteral(foo); + +#line default +#line hidden + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __TestViewComponentTagHelper.firstName = __tagHelperStringValueBuffer; + __tagHelperExecutionContext.AddTagHelperAttribute("first-name", __TestViewComponentTagHelper.firstName, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); + __AllTagHelper.Bar = (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(); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("vc:test")] +public class __Generated__TestViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper +{ + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TestViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.String firstName { get; set; } + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync("Test", new { firstName }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } +} + + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt new file mode 100644 index 0000000000..a1678711eb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt @@ -0,0 +1,43 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + FieldDeclaration - - private - global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper - __TestViewComponentTagHelper + PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - bar - World - HtmlAttributeValueStyle.DoubleQuotes + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::AllTagHelper - __AllTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - (30:1,2 [26] ViewComponentTagHelper.cshtml) + IntermediateToken - (30:1,2 [26] ViewComponentTagHelper.cshtml) - CSharp - \n var foo = "Hello";\n + CSharpCode - + IntermediateToken - - CSharp - BeginContext(59, 2, true); + HtmlContent - (59:4,0 [2] ViewComponentTagHelper.cshtml) + IntermediateToken - (59:4,0 [2] ViewComponentTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(61, 50, false); + TagHelper - (61:5,0 [50] ViewComponentTagHelper.cshtml) - vc:test - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - AllTagHelper + DefaultTagHelperCreate - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper + DefaultTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - string TestViewComponentTagHelper.firstName - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - (83:5,22 [3] ViewComponentTagHelper.cshtml) + IntermediateToken - (83:5,22 [3] ViewComponentTagHelper.cshtml) - CSharp - foo + PreallocatedTagHelperProperty - (93:5,32 [6] ViewComponentTagHelper.cshtml) - __tagHelperAttribute_0 - bar - Bar + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("vc:test")]\npublic class __Generated__TestViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper\n{\n private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null;\n public __Generated__TestViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper)\n {\n _helper = helper;\n }\n [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute]\n public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; }\n public System.String firstName { get; set; }\n public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output)\n {\n (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext);\n var content = await _helper.InvokeAsync("Test", new { firstName });\n output.TagName = null;\n output.Content.SetHtmlContent(content);\n }\n}\n diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml new file mode 100644 index 0000000000..f4e110d289 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml @@ -0,0 +1 @@ +@inject IHtmlHelper Helper \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs new file mode 100644 index 0000000000..1f60d924cc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs @@ -0,0 +1,58 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml" +IHtmlHelper __typeHelper = default(IHtmlHelper); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml" +global::System.Object Helper = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public IHtmlHelper Helper { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt new file mode 100644 index 0000000000..f75113d4b6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt @@ -0,0 +1,38 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (8:0,8 [19] _ViewImports.cshtml) - IHtmlHelper + DirectiveToken - (28:0,28 [6] _ViewImports.cshtml) - Helper + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt new file mode 100644 index 0000000000..dc03ca32da --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (8:0,8 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml) +|IHtmlHelper| +Generated Location: (760:19,0 [19] ) +|IHtmlHelper| + +Source Location: (28:0,28 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml) +|Helper| +Generated Location: (1027:27,22 [6] ) +|Helper| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs new file mode 100644 index 0000000000..2400a20b50 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs @@ -0,0 +1,35 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "e57bbc3e746e8b13b4c33d8df0e022bd397d8caa" +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public IHtmlHelper Helper { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt new file mode 100644 index 0000000000..3703d64a46 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt @@ -0,0 +1,17 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs new file mode 100644 index 0000000000..d88f379542 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs @@ -0,0 +1,343 @@ +// 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.Reflection; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class ViewComponentTagHelperDescriptorFactoryTest + { + private static readonly Assembly _assembly = typeof(ViewComponentTagHelperDescriptorFactoryTest).GetTypeInfo().Assembly; + + [Fact] + public void CreateDescriptor_UnderstandsStringParameters() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(StringParameterViewComponent).FullName); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__StringParameterViewComponentTagHelper", + typeof(StringParameterViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__StringParameterViewComponentTagHelper") + .DisplayName("StringParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:string-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("foo")) + .RequireAttributeDescriptor(attribute => attribute.Name("bar"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("foo") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("bar") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "StringParameter") + .Build(); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_UnderstandsVariousParameterTypes() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(VariousParameterViewComponent).FullName); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__VariousParameterViewComponentTagHelper", + typeof(VariousParameterViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__VariousParameterViewComponentTagHelper") + .DisplayName("VariousParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:various-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("test-enum")) + .RequireAttributeDescriptor(attribute => attribute.Name("test-string")) + .RequireAttributeDescriptor(attribute => attribute.Name("baz"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("test-enum") + .PropertyName("testEnum") + .TypeName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum)) + .AsEnum() + .DisplayName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum) + " VariousParameterViewComponentTagHelper.testEnum")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("test-string") + .PropertyName("testString") + .TypeName(typeof(string).FullName) + .DisplayName("string VariousParameterViewComponentTagHelper.testString")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("baz") + .PropertyName("baz") + .TypeName(typeof(int).FullName) + .DisplayName("int VariousParameterViewComponentTagHelper.baz")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "VariousParameter") + .Build(); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_UnderstandsGenericParameters() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(GenericParameterViewComponent).FullName); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__GenericParameterViewComponentTagHelper", + typeof(GenericParameterViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__GenericParameterViewComponentTagHelper") + .DisplayName("GenericParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:generic-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("foo"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("Foo") + .TypeName("System.Collections.Generic.List") + .DisplayName("System.Collections.Generic.List GenericParameterViewComponentTagHelper.Foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("Bar") + .TypeName("System.Collections.Generic.Dictionary") + .AsDictionaryAttribute("bar-", typeof(int).FullName) + .DisplayName("System.Collections.Generic.Dictionary GenericParameterViewComponentTagHelper.Bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "GenericParameter") + .Build(); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_AddsDiagnostic_ForViewComponentWithNoInvokeMethod() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(ViewComponentWithoutInvokeMethod).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_CannotFindMethod.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_UnderstandsGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Empty(descriptor.GetAllDiagnostics()); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_UnderstandsNonGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithNonGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Empty(descriptor.GetAllDiagnostics()); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_DoesNotUnderstandVoid() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithString).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_AsyncMethod_ShouldReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_DoesNotUnderstandString() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithString).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_AsyncMethod_ShouldReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvoke_DoesNotUnderstandVoid() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncViewComponentWithVoid).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_SyncMethod_ShouldReturnValue.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvoke_DoesNotUnderstandNonGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncViewComponentWithNonGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_SyncMethod_CannotReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvoke_DoesNotUnderstandGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncViewComponentWithGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_SyncMethod_CannotReturnTask.Id, diagnostic.Id); + } + } + + public class StringParameterViewComponent + { + public string Invoke(string foo, string bar) => null; + } + + public class VariousParameterViewComponent + { + public string Invoke(TestEnum testEnum, string testString, int baz = 5) => null; + + public enum TestEnum + { + A = 1, + B = 2, + C = 3 + } + } + + public class GenericParameterViewComponent + { + public string Invoke(List Foo, Dictionary Bar) => null; + } + + public class ViewComponentWithoutInvokeMethod + { + } + + public class AsyncViewComponentWithGenericTask + { + public Task InvokeAsync() => null; + } + + public class AsyncViewComponentWithNonGenericTask + { + public Task InvokeAsync() => null; + } + + public class AsyncViewComponentWithVoid + { + public void InvokeAsync() { } + } + + public class AsyncViewComponentWithString + { + public string InvokeAsync() => null; + } + + public class SyncViewComponentWithVoid + { + public void Invoke() { } + } + + public class SyncViewComponentWithNonGenericTask + { + public Task Invoke() => null; + } + + public class SyncViewComponentWithGenericTask + { + public Task Invoke() => null; + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs new file mode 100644 index 0000000000..7ddd76d9fc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs @@ -0,0 +1,71 @@ +// 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 System.Reflection; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Razor; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + // This is just a basic integration test. There are detailed tests for the VCTH visitor and descriptor factory. + public class ViewComponentTagHelperDescriptorProviderTest + { + [Fact] + public void DescriptorProvider_FindsVCTH() + { + // Arrange + var code = @" + public class StringParameterViewComponent + { + public string Invoke(string foo, string bar) => null; + } +"; + + var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code)); + + var context = TagHelperDescriptorProviderContext.Create(); + context.SetCompilation(compilation); + + var provider = new ViewComponentTagHelperDescriptorProvider() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__StringParameterViewComponentTagHelper", + TestCompilation.AssemblyName) + .TypeName("__Generated__StringParameterViewComponentTagHelper") + .DisplayName("StringParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:string-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("foo")) + .RequireAttributeDescriptor(attribute => attribute.Name("bar"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("foo") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("bar") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "StringParameter") + .Build(); + + // Act + provider.Execute(context); + + // Assert + Assert.Single(context.Results, d => TagHelperDescriptorComparer.CaseSensitive.Equals(d, expectedDescriptor)); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperPassTest.cs new file mode 100644 index 0000000000..befa9d011c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperPassTest.cs @@ -0,0 +1,275 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class ViewComponentTagHelperPassTest + { + [Fact] + public void ViewComponentTagHelperPass_Execute_IgnoresRegularTagHelper() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .TypeName("TestTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.Equal(3, @class.Children.Count); // No class node created for a VCTH + for (var i = 0; i < @class.Children.Count; i++) + { + Assert.IsNotType(@class.Children[i]); + } + } + + [Fact] + public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Int32") + .PropertyName("Foo")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + var vcthFullName = "AspNetCore.test.__Generated__TagCloudViewComponentTagHelper"; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + Assert.Equal(vcthFullName, Assert.IsType(tagHelper.Children[1]).TypeName); + Assert.Equal("Foo", Assert.IsType(tagHelper.Children[2]).PropertyName); + + + var @class = FindClassNode(irDocument); + Assert.Equal(4, @class.Children.Count); + + Assert.IsType(@class.Children.Last()); + } + + [Fact] + public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_WithIndexer() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Collections.Generic.Dictionary") + .PropertyName("Tags") + .AsDictionaryAttribute("foo-", "System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + var vcthFullName = "AspNetCore.test.__Generated__TagCloudViewComponentTagHelper"; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + Assert.Equal(vcthFullName, Assert.IsType(tagHelper.Children[1]).TypeName); + Assert.IsType(tagHelper.Children[2]); + + var @class = FindClassNode(irDocument); + Assert.Equal(4, @class.Children.Count); + + Assert.IsType(@class.Children[3]); + } + + [Fact] + public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_Nested() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper *, TestAssembly +

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("PTestTagHelper", "TestAssembly") + .TypeName("PTestTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .PropertyName("Foo") + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p")) + .Build(), + TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .PropertyName("Foo") + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + var vcthFullName = "AspNetCore.test.__Generated__TagCloudViewComponentTagHelper"; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var outerTagHelper = FindTagHelperNode(irDocument); + Assert.Equal("PTestTagHelper", Assert.IsType(outerTagHelper.Children[1]).TypeName); + Assert.Equal("Foo", Assert.IsType(outerTagHelper.Children[2]).PropertyName); + + var vcth = FindTagHelperNode(outerTagHelper.Children[0]); + Assert.Equal(vcthFullName, Assert.IsType(vcth.Children[1]).TypeName); + Assert.Equal("Foo", Assert.IsType(vcth.Children[2]).PropertyName); + + + var @class = FindClassNode(irDocument); + Assert.Equal(5, @class.Children.Count); + + Assert.IsType(@class.Children.Last()); + } + + 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 MvcViewDocumentClassifierPass()); + + 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; + } + } + + // We also expect the default tag helper pass to run first. + var documentNode = codeDocument.GetDocumentIntermediateNode(); + + var defaultTagHelperPass = engine.Features.OfType().Single(); + defaultTagHelperPass.Execute(codeDocument, documentNode); + + return codeDocument.GetDocumentIntermediateNode(); + } + + private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node) + { + var visitor = new ClassDeclarationNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private TagHelperIntermediateNode FindTagHelperNode(IntermediateNode node) + { + var visitor = new TagHelperNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private class ClassDeclarationNodeVisitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Node { get; set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Node = node; + } + } + + private class TagHelperNodeVisitor : IntermediateNodeWalker + { + public TagHelperIntermediateNode Node { get; set; } + + public override void VisitTagHelper(TagHelperIntermediateNode node) + { + Node = node; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperTargetExtensionTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperTargetExtensionTest.cs new file mode 100644 index 0000000000..2e3c476a36 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperTargetExtensionTest.cs @@ -0,0 +1,120 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class ViewComponentTagHelperTargetExtensionTest + { + [Fact] + public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper() + { + // Arrange + var tagHelper = TagHelperDescriptorBuilder + .Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Int32") + .PropertyName("Foo")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build(); + + var extension = new ViewComponentTagHelperTargetExtension(); + var context = TestCodeRenderingContext.CreateRuntime(); + var node = new ViewComponentTagHelperIntermediateNode() + { + ClassName = "__Generated__TagCloudViewComponentTagHelper", + TagHelper = tagHelper + }; + + // Act + extension.WriteViewComponentTagHelper(context, node); + + // Assert + var csharp = context.CodeWriter.GenerateCode(); + Assert.Equal( + @"[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute(""tagcloud"")] +public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper +{ + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TagCloudViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.Int32 Foo { get; set; } + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync(""TagCloud"", new { Foo }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } +} +", + csharp, + ignoreLineEndingDifferences: true); + } + + [Fact] + public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper_WithIndexer() + { + // Arrange + var tagHelper = TagHelperDescriptorBuilder + .Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Collections.Generic.Dictionary") + .PropertyName("Tags") + .AsDictionaryAttribute("foo-", "System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build(); + + var extension = new ViewComponentTagHelperTargetExtension(); + var context = TestCodeRenderingContext.CreateRuntime(); + var node = new ViewComponentTagHelperIntermediateNode() + { + ClassName = "__Generated__TagCloudViewComponentTagHelper", + TagHelper = tagHelper + }; + + // Act + extension.WriteViewComponentTagHelper(context, node); + + // Assert + var csharp = context.CodeWriter.GenerateCode(); + Assert.Equal( + @"[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute(""tagcloud"")] +public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper +{ + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TagCloudViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.Collections.Generic.Dictionary Tags { get; set; } + = new System.Collections.Generic.Dictionary(); + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync(""TagCloud"", new { Tags }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } +} +", + csharp, + ignoreLineEndingDifferences: true); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTypeVisitorTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTypeVisitorTest.cs new file mode 100644 index 0000000000..96d879756c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTypeVisitorTest.cs @@ -0,0 +1,202 @@ +// 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; +using Microsoft.CodeAnalysis; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X +{ + public class ViewComponentTypeVisitorTest + { + private static readonly Assembly _assembly = typeof(ViewComponentTypeVisitorTest).GetTypeInfo().Assembly; + + private static Compilation Compilation { get; } = TestCompilation.Create(_assembly); + + // In practice MVC will provide a marker attribute for ViewComponents. To prevent a circular reference between MVC and Razor + // we can use a test class as a marker. + private static INamedTypeSymbol TestViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestViewComponentAttribute).FullName); + private static INamedTypeSymbol TestNonViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestNonViewComponentAttribute).FullName); + + [Fact] + public void IsViewComponent_PlainViewComponent_ReturnsTrue() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_PlainViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.True(isViewComponent); + } + + [Fact] + public void IsViewComponent_DecoratedViewComponent_ReturnsTrue() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_DecoratedVC).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.True(isViewComponent); + } + + [Fact] + public void IsViewComponent_InheritedViewComponent_ReturnsTrue() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_InheritedVC).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.True(isViewComponent); + } + + [Fact] + public void IsViewComponent_AbstractViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_AbstractViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_GenericViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_GenericViewComponent<>).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_InternalViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InternalViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_DecoratedNonViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_DecoratedViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_InheritedNonViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InheritedViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + public abstract class Invalid_AbstractViewComponent + { + } + + public class Invalid_GenericViewComponent + { + } + + internal class Invalid_InternalViewComponent + { + } + + public class Valid_PlainViewComponent + { + } + + [TestViewComponent] + public class Valid_DecoratedVC + { + } + + public class Valid_InheritedVC : Valid_DecoratedVC + { + } + + [TestNonViewComponent] + public class Invalid_DecoratedViewComponent + { + } + + [TestViewComponent] + public class Invalid_InheritedViewComponent : Invalid_DecoratedViewComponent + { + } + + public class TestViewComponentAttribute : Attribute + { + } + + public class TestNonViewComponentAttribute : Attribute + { + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/xunit.runner.json b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/xunit.runner.json new file mode 100644 index 0000000000..fcf172c8fc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "methodDisplay": "method", + "shadowCopy": false +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/AssemblyAttributeInjectionPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/AssemblyAttributeInjectionPass.cs new file mode 100644 index 0000000000..021c61c368 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/AssemblyAttributeInjectionPass.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.Diagnostics; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class AssemblyAttributeInjectionPass : IntermediateNodePassBase, IRazorOptimizationPass + { + private const string RazorViewAttribute = "global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute"; + private const string RazorPageAttribute = "global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute"; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.Options.DesignTime) + { + return; + } + + var @namespace = documentNode.FindPrimaryNamespace(); + if (@namespace == null || string.IsNullOrEmpty(@namespace.Content)) + { + // No namespace node or it's incomplete. Skip. + return; + } + + var @class = documentNode.FindPrimaryClass(); + if (@class == null || string.IsNullOrEmpty(@class.ClassName)) + { + // No class node or it's incomplete. Skip. + return; + } + + var generatedTypeName = $"{@namespace.Content}.{@class.ClassName}"; + + // The MVC attributes require a relative path to be specified so that we can make a view engine path. + // We can't use a rooted path because we don't know what the project root is. + // + // If we can't sanitize the path, we'll just set it to null and let is blow up at runtime - we don't + // want to create noise if this code has to run in some unanticipated scenario. + var escapedPath = MakeVerbatimStringLiteral(ConvertToViewEnginePath(codeDocument.Source.RelativePath)); + + string attribute; + if (documentNode.DocumentKind == MvcViewDocumentClassifierPass.MvcViewDocumentKind) + { + attribute = $"[assembly:{RazorViewAttribute}({escapedPath}, typeof({generatedTypeName}))]"; + } + else if (documentNode.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind && + PageDirective.TryGetPageDirective(documentNode, out var pageDirective)) + { + var escapedRoutePrefix = MakeVerbatimStringLiteral(pageDirective.RouteTemplate); + attribute = $"[assembly:{RazorPageAttribute}({escapedPath}, typeof({generatedTypeName}), {escapedRoutePrefix})]"; + } + else + { + return; + } + + var index = documentNode.Children.IndexOf(@namespace); + Debug.Assert(index >= 0); + + var pageAttribute = new CSharpCodeIntermediateNode(); + pageAttribute.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = attribute, + }); + + documentNode.Children.Insert(index, pageAttribute); + } + + private static string MakeVerbatimStringLiteral(string value) + { + if (value == null) + { + return "null"; + } + + value = value.Replace("\"", "\"\""); + return $"@\"{value}\""; + } + + private static string ConvertToViewEnginePath(string relativePath) + { + if (string.IsNullOrEmpty(relativePath)) + { + return null; + } + + // Checking for both / and \ because a \ will become a /. + if (!relativePath.StartsWith("/") && !relativePath.StartsWith("\\")) + { + relativePath = "/" + relativePath; + } + + relativePath = relativePath.Replace('\\', '/'); + return relativePath; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/CSharpIdentifier.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/CSharpIdentifier.cs new file mode 100644 index 0000000000..77a5e8f54e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/CSharpIdentifier.cs @@ -0,0 +1,71 @@ +// 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 System.Text; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + internal static class CSharpIdentifier + { + private const string CshtmlExtension = ".cshtml"; + + public static string GetClassNameFromPath(string path) + { + if (string.IsNullOrEmpty(path)) + { + return path; + } + + if (path.EndsWith(CshtmlExtension, StringComparison.OrdinalIgnoreCase)) + { + path = path.Substring(0, path.Length - CshtmlExtension.Length); + } + + return SanitizeClassName(path); + } + + // CSharp Spec §2.4.2 + private static bool IsIdentifierStart(char character) + { + return char.IsLetter(character) || + character == '_' || + CharUnicodeInfo.GetUnicodeCategory(character) == UnicodeCategory.LetterNumber; + } + + public static bool IsIdentifierPart(char character) + { + return char.IsDigit(character) || + IsIdentifierStart(character) || + IsIdentifierPartByUnicodeCategory(character); + } + + private static bool IsIdentifierPartByUnicodeCategory(char character) + { + var category = CharUnicodeInfo.GetUnicodeCategory(character); + + return category == UnicodeCategory.NonSpacingMark || // Mn + category == UnicodeCategory.SpacingCombiningMark || // Mc + category == UnicodeCategory.ConnectorPunctuation || // Pc + category == UnicodeCategory.Format; // Cf + } + + public static string SanitizeClassName(string inputName) + { + if (!IsIdentifierStart(inputName[0]) && IsIdentifierPart(inputName[0])) + { + inputName = "_" + inputName; + } + + var builder = new StringBuilder(inputName.Length); + for (var i = 0; i < inputName.Length; i++) + { + var ch = inputName[i]; + builder.Append(IsIdentifierPart(ch) ? ch : '_'); + } + + return builder.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ExtensionInitializer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ExtensionInitializer.cs new file mode 100644 index 0000000000..03d05f7f9b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ExtensionInitializer.cs @@ -0,0 +1,15 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + internal class ExtensionInitializer : RazorExtensionInitializer + { + public override void Initialize(RazorProjectEngineBuilder builder) + { + RazorExtensions.Register(builder); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/IInjectTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/IInjectTargetExtension.cs new file mode 100644 index 0000000000..c334e23c2b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/IInjectTargetExtension.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public interface IInjectTargetExtension : ICodeTargetExtension + { + void WriteInjectProperty(CodeRenderingContext context, InjectIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/IViewComponentTagHelperTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/IViewComponentTagHelperTargetExtension.cs new file mode 100644 index 0000000000..f3e07a2b75 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/IViewComponentTagHelperTargetExtension.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public interface IViewComponentTagHelperTargetExtension : ICodeTargetExtension + { + void WriteViewComponentTagHelper(CodeRenderingContext context, ViewComponentTagHelperIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectDirective.cs new file mode 100644 index 0000000000..9442aaf641 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectDirective.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 System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public static class InjectDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "inject", + DirectiveKind.SingleLine, + builder => + { + builder + .AddTypeToken(Resources.InjectDirective_TypeToken_Name, Resources.InjectDirective_TypeToken_Description) + .AddMemberToken(Resources.InjectDirective_MemberToken_Name, Resources.InjectDirective_MemberToken_Description); + + builder.Usage = DirectiveUsage.FileScopedMultipleOccurring; + builder.Description = Resources.InjectDirective_Description; + }); + + public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + builder.AddTargetExtension(new InjectTargetExtension()); + return builder; + } + + internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + // Runs after the @model and @namespace directives + public override int Order => 10; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var visitor = new Visitor(); + visitor.Visit(documentNode); + var modelType = ModelDirective.GetModelType(documentNode); + + var properties = new HashSet(StringComparer.Ordinal); + + for (var i = visitor.Directives.Count - 1; i >= 0; i--) + { + var directive = visitor.Directives[i]; + var tokens = directive.Tokens.ToArray(); + if (tokens.Length < 2) + { + continue; + } + + var typeName = tokens[0].Content; + var memberName = tokens[1].Content; + + if (!properties.Add(memberName)) + { + continue; + } + + typeName = typeName.Replace("", "<" + modelType + ">"); + + var injectNode = new InjectIntermediateNode() + { + TypeName = typeName, + MemberName = memberName, + }; + + visitor.Class.Children.Add(injectNode); + } + } + } + + private class Visitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Class { get; private set; } + + public IList Directives { get; } = new List(); + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (Class == null) + { + Class = node; + } + + base.VisitClassDeclaration(node); + } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + Directives.Add(node); + } + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static IRazorEngineBuilder Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + builder.AddTargetExtension(new InjectTargetExtension()); + return builder; + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectIntermediateNode.cs new file mode 100644 index 0000000000..4e3603f40d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectIntermediateNode.cs @@ -0,0 +1,58 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class InjectIntermediateNode : ExtensionIntermediateNode + { + public string TypeName { get; set; } + + public string MemberName { get; set; } + + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteInjectProperty(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(MemberName); + + formatter.WriteProperty(nameof(MemberName), MemberName); + formatter.WriteProperty(nameof(TypeName), TypeName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectTargetExtension.cs new file mode 100644 index 0000000000..1660b84d6d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InjectTargetExtension.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 System; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class InjectTargetExtension : IInjectTargetExtension + { + private const string RazorInjectAttribute = "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]"; + + public void WriteInjectProperty(CodeRenderingContext context, InjectIntermediateNode node) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + var property = $"public {node.TypeName} {node.MemberName} {{ get; private set; }}"; + + if (node.Source.HasValue) + { + using (context.CodeWriter.BuildLinePragma(node.Source.Value)) + { + context.CodeWriter + .WriteLine(RazorInjectAttribute) + .WriteLine(property); + } + } + else + { + context.CodeWriter + .WriteLine(RazorInjectAttribute) + .WriteLine(property); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InstrumentationPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InstrumentationPass.cs new file mode 100644 index 0000000000..f82ed32e45 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/InstrumentationPass.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.Collections.Generic; +using System.Globalization; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class InstrumentationPass : IntermediateNodePassBase, IRazorOptimizationPass + { + public override int Order => DefaultFeatureOrder; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.Options.DesignTime) + { + return; + } + + var walker = new Visitor(); + walker.VisitDocument(documentNode); + + for (var i = 0; i < walker.Items.Count; i++) + { + var node = walker.Items[i]; + + AddInstrumentation(node); + } + } + + private static void AddInstrumentation(InstrumentationItem item) + { + var beginContextMethodName = "BeginContext"; // ORIGINAL: BeginContextMethodName + var endContextMethodName = "EndContext"; // ORIGINAL: EndContextMethodName + + var beginNode = new CSharpCodeIntermediateNode(); + beginNode.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = string.Format("{0}({1}, {2}, {3});", + beginContextMethodName, + item.Source.AbsoluteIndex.ToString(CultureInfo.InvariantCulture), + item.Source.Length.ToString(CultureInfo.InvariantCulture), + item.IsLiteral ? "true" : "false") + }); + + var endNode = new CSharpCodeIntermediateNode(); + endNode.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = string.Format("{0}();", endContextMethodName) + }); + + var nodeIndex = item.Parent.Children.IndexOf(item.Node); + item.Parent.Children.Insert(nodeIndex, beginNode); + item.Parent.Children.Insert(nodeIndex + 2, endNode); + } + + private struct InstrumentationItem + { + public InstrumentationItem(IntermediateNode node, IntermediateNode parent, bool isLiteral, SourceSpan source) + { + Node = node; + Parent = parent; + IsLiteral = isLiteral; + Source = source; + } + + public IntermediateNode Node { get; } + + public IntermediateNode Parent { get; } + + public bool IsLiteral { get; } + + public SourceSpan Source { get; } + } + + private class Visitor : IntermediateNodeWalker + { + public List Items { get; } = new List(); + + public override void VisitHtml(HtmlContentIntermediateNode node) + { + if (node.Source != null) + { + Items.Add(new InstrumentationItem(node, Parent, isLiteral: true, source: node.Source.Value)); + } + + VisitDefault(node); + } + + public override void VisitCSharpExpression(CSharpExpressionIntermediateNode node) + { + if (node.Source != null) + { + Items.Add(new InstrumentationItem(node, Parent, isLiteral: false, source: node.Source.Value)); + } + + VisitDefault(node); + } + + public override void VisitTagHelper(TagHelperIntermediateNode node) + { + if (node.Source != null) + { + Items.Add(new InstrumentationItem(node, Parent, isLiteral: false, source: node.Source.Value)); + } + + // Inside a tag helper we only want to visit inside of the body (skip all of the attributes and properties). + for (var i = 0; i < node.Children.Count; i++) + { + var child = node.Children[i]; + if (child is TagHelperBodyIntermediateNode || + child is DefaultTagHelperBodyIntermediateNode) + { + VisitDefault(child); + } + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj new file mode 100644 index 0000000000..e77d4c3837 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj @@ -0,0 +1,20 @@ + + + + ASP.NET Core design time hosting infrastructure for the Razor view engine. + netstandard2.0 + $(PackageTags);aspnetcoremvc + + + + + Shared\CodeWriterExtensions.cs + + + + + + + + + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ModelDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ModelDirective.cs new file mode 100644 index 0000000000..cf80df5f68 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ModelDirective.cs @@ -0,0 +1,152 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public static class ModelDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "model", + DirectiveKind.SingleLine, + builder => + { + builder.AddTypeToken(Resources.ModelDirective_TypeToken_Name, Resources.ModelDirective_TypeToken_Description); + builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; + builder.Description = Resources.ModelDirective_Description; + }); + + public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + return builder; + } + + public static string GetModelType(DocumentIntermediateNode document) + { + if (document == null) + { + throw new ArgumentNullException(nameof(document)); + } + + var visitor = new Visitor(); + return GetModelType(document, visitor); + } + + private static string GetModelType(DocumentIntermediateNode document, Visitor visitor) + { + visitor.Visit(document); + + for (var i = visitor.ModelDirectives.Count - 1; i >= 0; i--) + { + var directive = visitor.ModelDirectives[i]; + + var tokens = directive.Tokens.ToArray(); + if (tokens.Length >= 1) + { + return tokens[0].Content; + } + } + + if (document.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind) + { + return visitor.Class.ClassName; + } + else + { + return "dynamic"; + } + } + + internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + // Runs after the @inherits directive + public override int Order => 5; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var visitor = new Visitor(); + var modelType = GetModelType(documentNode, visitor); + + if (documentNode.Options.DesignTime) + { + // Alias the TModel token to a known type. + // This allows design time compilation to succeed for Razor files where the token isn't replaced. + var typeName = $"global::{typeof(object).FullName}"; + var usingNode = new UsingDirectiveIntermediateNode() + { + Content = $"TModel = {typeName}" + }; + + visitor.Namespace?.Children.Insert(0, usingNode); + } + + var baseType = visitor.Class?.BaseType?.Replace("", "<" + modelType + ">"); + visitor.Class.BaseType = baseType; + } + } + + private class Visitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Namespace { get; private set; } + + public ClassDeclarationIntermediateNode Class { get; private set; } + + public IList ModelDirectives { get; } = new List(); + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + if (Namespace == null) + { + Namespace = node; + } + + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (Class == null) + { + Class = node; + } + + base.VisitClassDeclaration(node); + } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + ModelDirectives.Add(node); + } + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static IRazorEngineBuilder Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + return builder; + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ModelExpressionPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ModelExpressionPass.cs new file mode 100644 index 0000000000..ef8e8fb181 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ModelExpressionPass.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; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class ModelExpressionPass : IntermediateNodePassBase, IRazorOptimizationPass + { + private const string ModelExpressionTypeName = "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression"; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var visitor = new Visitor(); + visitor.Visit(documentNode); + } + + private class Visitor : IntermediateNodeWalker + { + public List TagHelpers { get; } = new List(); + + public override void VisitTagHelperProperty(TagHelperPropertyIntermediateNode node) + { + if (string.Equals(node.BoundAttribute.TypeName, ModelExpressionTypeName, StringComparison.Ordinal) || + (node.IsIndexerNameMatch && + string.Equals(node.BoundAttribute.IndexerTypeName, ModelExpressionTypeName, StringComparison.Ordinal))) + { + var expression = new CSharpExpressionIntermediateNode(); + + expression.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = "ModelExpressionProvider.CreateModelExpression(ViewData, __model => ", + }); + + if (node.Children.Count == 1 && node.Children[0] is IntermediateToken token && token.IsCSharp) + { + // A 'simple' expression will look like __model => __model.Foo + + expression.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = "__model." + }); + + expression.Children.Add(token); + } + else + { + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is CSharpExpressionIntermediateNode nestedExpression) + { + for (var j = 0; j < nestedExpression.Children.Count; j++) + { + if (nestedExpression.Children[j] is IntermediateToken cSharpToken && + cSharpToken.IsCSharp) + { + expression.Children.Add(cSharpToken); + } + } + + continue; + } + } + } + + expression.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = ")", + }); + + node.Children.Clear(); + + node.Children.Add(expression); + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/MvcImportProjectFeature.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/MvcImportProjectFeature.cs new file mode 100644 index 0000000000..c25cb0d063 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/MvcImportProjectFeature.cs @@ -0,0 +1,91 @@ +// 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.IO; +using System.Linq; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + internal class MvcImportProjectFeature : RazorProjectEngineFeatureBase, IImportProjectFeature + { + private const string ImportsFileName = "_ViewImports.cshtml"; + + public IReadOnlyList GetImports(RazorProjectItem projectItem) + { + if (projectItem == null) + { + throw new ArgumentNullException(nameof(projectItem)); + } + + var imports = new List(); + AddDefaultDirectivesImport(imports); + + // We add hierarchical imports second so any default directive imports can be overridden. + AddHierarchicalImports(projectItem, imports); + + return imports; + } + + // Internal for testing + internal static void AddDefaultDirectivesImport(List imports) + { + imports.Add(DefaultDirectivesProjectItem.Instance); + } + + // Internal for testing + internal void AddHierarchicalImports(RazorProjectItem projectItem, List imports) + { + // We want items in descending order. FindHierarchicalItems returns items in ascending order. + var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(projectItem.FilePath, ImportsFileName).Reverse(); + imports.AddRange(importProjectItems); + } + + private class DefaultDirectivesProjectItem : RazorProjectItem + { + private readonly byte[] _defaultImportBytes; + + private DefaultDirectivesProjectItem() + { + var preamble = Encoding.UTF8.GetPreamble(); + var content = @" +@using System +@using System.Collections.Generic +@using System.Linq +@using System.Threading.Tasks +@using Microsoft.AspNetCore.Mvc +@using Microsoft.AspNetCore.Mvc.Rendering +@using Microsoft.AspNetCore.Mvc.ViewFeatures +@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html +@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json +@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component +@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url +@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider +@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor +@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor +@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor +"; + var contentBytes = Encoding.UTF8.GetBytes(content); + + _defaultImportBytes = new byte[preamble.Length + contentBytes.Length]; + preamble.CopyTo(_defaultImportBytes, 0); + contentBytes.CopyTo(_defaultImportBytes, preamble.Length); + } + + public override string BasePath => null; + + public override string FilePath => null; + + public override string PhysicalPath => null; + + public override bool Exists => true; + + public static DefaultDirectivesProjectItem Instance { get; } = new DefaultDirectivesProjectItem(); + + public override Stream Read() => new MemoryStream(_defaultImportBytes); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/MvcViewDocumentClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/MvcViewDocumentClassifierPass.cs new file mode 100644 index 0000000000..7ec6a1360e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/MvcViewDocumentClassifierPass.cs @@ -0,0 +1,71 @@ +// 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.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class MvcViewDocumentClassifierPass : DocumentClassifierPassBase + { + public static readonly string MvcViewDocumentKind = "mvc.1.0.view"; + + protected override string DocumentKind => MvcViewDocumentKind; + + protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) => true; + + protected override void OnDocumentStructureCreated( + RazorCodeDocument codeDocument, + NamespaceDeclarationIntermediateNode @namespace, + ClassDeclarationIntermediateNode @class, + MethodDeclarationIntermediateNode method) + { + base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method); + + @namespace.Content = "AspNetCore"; + + var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath; + if (string.IsNullOrEmpty(filePath)) + { + // It's possible for a Razor document to not have a file path. + // Eg. When we try to generate code for an in memory document like default imports. + var checksum = BytesToString(codeDocument.Source.GetChecksum()); + @class.ClassName = $"AspNetCore_{checksum}"; + } + else + { + @class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath); + } + + @class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage"; + @class.Modifiers.Clear(); + @class.Modifiers.Add("public"); + + method.MethodName = "ExecuteAsync"; + method.Modifiers.Clear(); + method.Modifiers.Add("public"); + method.Modifiers.Add("async"); + method.Modifiers.Add("override"); + method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}"; + } + + private static string BytesToString(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException(nameof(bytes)); + } + + var result = new StringBuilder(bytes.Length); + for (var i = 0; i < bytes.Length; i++) + { + // The x2 format means lowercase hex, where each byte is a 2-character string. + result.Append(bytes[i].ToString("x2")); + } + + return result.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/NamespaceDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/NamespaceDirective.cs new file mode 100644 index 0000000000..de05d354b1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/NamespaceDirective.cs @@ -0,0 +1,204 @@ +// 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 System.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public static class NamespaceDirective + { + private static readonly char[] Separators = new char[] { '\\', '/' }; + + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "namespace", + DirectiveKind.SingleLine, + builder => + { + builder.AddNamespaceToken( + Resources.NamespaceDirective_NamespaceToken_Name, + Resources.NamespaceDirective_NamespaceToken_Description); + builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; + builder.Description = Resources.NamespaceDirective_Description; + }); + + public static void Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + } + + // internal for testing + internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind && + documentNode.DocumentKind != MvcViewDocumentClassifierPass.MvcViewDocumentKind) + { + // Not a page. Skip. + return; + } + + var visitor = new Visitor(); + visitor.Visit(documentNode); + + var directive = visitor.LastNamespaceDirective; + if (directive == null) + { + // No namespace set. Skip. + return; + } + + var @namespace = visitor.FirstNamespace; + if (@namespace == null) + { + // No namespace node. Skip. + return; + } + + @namespace.Content = GetNamespace(codeDocument.Source.FilePath, directive); + } + } + + // internal for testing. + // + // This code does a best-effort attempt to compute a namespace 'suffix' - the path difference between + // where the @namespace directive appears and where the current document is on disk. + // + // In the event that these two source either don't have FileNames set or don't follow a coherent hierarchy, + // we will just use the namespace verbatim. + internal static string GetNamespace(string source, DirectiveIntermediateNode directive) + { + var directiveSource = NormalizeDirectory(directive.Source?.FilePath); + + var baseNamespace = directive.Tokens.FirstOrDefault()?.Content; + if (string.IsNullOrEmpty(baseNamespace)) + { + // The namespace directive was incomplete. + return string.Empty; + } + + if (string.IsNullOrEmpty(source) || directiveSource == null) + { + // No sources, can't compute a suffix. + return baseNamespace; + } + + // We're specifically using OrdinalIgnoreCase here because Razor treats all paths as case-insensitive. + if (!source.StartsWith(directiveSource, StringComparison.OrdinalIgnoreCase) || + source.Length <= directiveSource.Length) + { + // The imports are not from the directory hierarchy, can't compute a suffix. + return baseNamespace; + } + + // OK so that this point we know that the 'imports' file containing this directive is in the directory + // hierarchy of this soure file. This is the case where we can append a suffix to the baseNamespace. + // + // Everything so far has just been defensiveness on our part. + + var builder = new StringBuilder(baseNamespace); + + var segments = source.Substring(directiveSource.Length).Split(Separators); + + // Skip the last segment because it's the FileName. + for (var i = 0; i < segments.Length - 1; i++) + { + builder.Append('.'); + builder.Append(CSharpIdentifier.SanitizeClassName(segments[i])); + } + + return builder.ToString(); + } + + // We want to normalize the path of the file containing the '@namespace' directive to just the containing + // directory with a trailing separator. + // + // Not using Path.GetDirectoryName here because it doesn't meet these requirements, and we want to handle + // both 'view engine' style paths and absolute paths. + // + // We also don't normalize the separators here. We expect that all documents are using a consistent style of path. + // + // If we can't normalize the path, we just return null so it will be ignored. + private static string NormalizeDirectory(string path) + { + if (string.IsNullOrEmpty(path)) + { + return null; + } + + var lastSeparator = path.LastIndexOfAny(Separators); + if (lastSeparator == -1) + { + return null; + } + + // Includes the separator + return path.Substring(0, lastSeparator + 1); + } + + private class Visitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode FirstClass { get; private set; } + + public NamespaceDeclarationIntermediateNode FirstNamespace { get; private set; } + + // We want the last one, so get them all and then . + public DirectiveIntermediateNode LastNamespaceDirective { get; private set; } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + if (FirstNamespace == null) + { + FirstNamespace = node; + } + + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (FirstClass == null) + { + FirstClass = node; + } + + base.VisitClassDeclaration(node); + } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + LastNamespaceDirective = node; + } + + base.VisitDirective(node); + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static void Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/PageDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/PageDirective.cs new file mode 100644 index 0000000000..9b483f9b9f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/PageDirective.cs @@ -0,0 +1,121 @@ +// 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.Diagnostics; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class PageDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "page", + DirectiveKind.SingleLine, + builder => + { + builder.AddOptionalStringToken(Resources.PageDirective_RouteToken_Name, Resources.PageDirective_RouteToken_Description); + builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; + builder.Description = Resources.PageDirective_Description; + }); + + private PageDirective(string routeTemplate, IntermediateNode directiveNode) + { + RouteTemplate = routeTemplate; + DirectiveNode = directiveNode; + } + + public string RouteTemplate { get; } + + public IntermediateNode DirectiveNode { get; } + + public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + return builder; + } + + public static bool TryGetPageDirective(DocumentIntermediateNode documentNode, out PageDirective pageDirective) + { + var visitor = new Visitor(); + for (var i = 0; i < documentNode.Children.Count; i++) + { + visitor.Visit(documentNode.Children[i]); + } + + if (visitor.DirectiveTokens == null) + { + pageDirective = null; + return false; + } + + var tokens = visitor.DirectiveTokens.ToList(); + string routeTemplate = null; + if (tokens.Count > 0) + { + routeTemplate = TrimQuotes(tokens[0].Content); + } + + pageDirective = new PageDirective(routeTemplate, visitor.DirectiveNode); + return true; + } + + private static string TrimQuotes(string content) + { + // Tokens aren't captured if they're malformed. Therefore, this method will + // always be called with a valid token content. + Debug.Assert(content.Length >= 2); + Debug.Assert(content.StartsWith("\"", StringComparison.Ordinal)); + Debug.Assert(content.EndsWith("\"", StringComparison.Ordinal)); + + return content.Substring(1, content.Length - 2); + } + + private class Visitor : IntermediateNodeWalker + { + public IntermediateNode DirectiveNode { get; private set; } + + public IEnumerable DirectiveTokens { get; private set; } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + DirectiveNode = node; + DirectiveTokens = node.Tokens; + } + } + + public override void VisitMalformedDirective(MalformedDirectiveIntermediateNode node) + { + if (DirectiveTokens == null && node.Directive == Directive) + { + DirectiveNode = node; + DirectiveTokens = node.Tokens; + } + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static IRazorEngineBuilder Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + return builder; + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/PagesPropertyInjectionPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/PagesPropertyInjectionPass.cs new file mode 100644 index 0000000000..4010c1903b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/PagesPropertyInjectionPass.cs @@ -0,0 +1,57 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class PagesPropertyInjectionPass : IntermediateNodePassBase, IRazorOptimizationPass + { + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind) + { + return; + } + + var modelType = ModelDirective.GetModelType(documentNode); + var visitor = new Visitor(); + visitor.Visit(documentNode); + + var @class = visitor.Class; + + var viewDataType = $"global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<{modelType}>"; + var vddProperty = new CSharpCodeIntermediateNode(); + vddProperty.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = $"public {viewDataType} ViewData => ({viewDataType})PageContext?.ViewData;", + }); + @class.Children.Add(vddProperty); + + var modelProperty = new CSharpCodeIntermediateNode(); + modelProperty.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = $"public {modelType} Model => ViewData.Model;", + }); + @class.Children.Add(modelProperty); + } + + private class Visitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Class { get; private set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (Class == null) + { + Class = node; + } + + base.VisitClassDeclaration(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..a7a402e09a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/AssemblyInfo.cs @@ -0,0 +1,12 @@ +// 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; +using Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X; +using Microsoft.AspNetCore.Razor.Language; + +[assembly: ProvideRazorExtensionInitializer("MVC-2.0", typeof(ExtensionInitializer))] +[assembly: ProvideRazorExtensionInitializer("MVC-2.1", typeof(ExtensionInitializer))] + +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] +[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/Resources.Designer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..ec4883803c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/Resources.Designer.cs @@ -0,0 +1,338 @@ +// +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class Resources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Resources", typeof(Resources).GetTypeInfo().Assembly); + + /// + /// Value cannot be null or empty. + /// + internal static string ArgumentCannotBeNullOrEmpty + { + get => GetString("ArgumentCannotBeNullOrEmpty"); + } + + /// + /// Value cannot be null or empty. + /// + internal static string FormatArgumentCannotBeNullOrEmpty() + => GetString("ArgumentCannotBeNullOrEmpty"); + + /// + /// Inject a service from the application's service container into a property. + /// + internal static string InjectDirective_Description + { + get => GetString("InjectDirective_Description"); + } + + /// + /// Inject a service from the application's service container into a property. + /// + internal static string FormatInjectDirective_Description() + => GetString("InjectDirective_Description"); + + /// + /// The name of the property. + /// + internal static string InjectDirective_MemberToken_Description + { + get => GetString("InjectDirective_MemberToken_Description"); + } + + /// + /// The name of the property. + /// + internal static string FormatInjectDirective_MemberToken_Description() + => GetString("InjectDirective_MemberToken_Description"); + + /// + /// PropertyName + /// + internal static string InjectDirective_MemberToken_Name + { + get => GetString("InjectDirective_MemberToken_Name"); + } + + /// + /// PropertyName + /// + internal static string FormatInjectDirective_MemberToken_Name() + => GetString("InjectDirective_MemberToken_Name"); + + /// + /// The type of the service to inject. + /// + internal static string InjectDirective_TypeToken_Description + { + get => GetString("InjectDirective_TypeToken_Description"); + } + + /// + /// The type of the service to inject. + /// + internal static string FormatInjectDirective_TypeToken_Description() + => GetString("InjectDirective_TypeToken_Description"); + + /// + /// TypeName + /// + internal static string InjectDirective_TypeToken_Name + { + get => GetString("InjectDirective_TypeToken_Name"); + } + + /// + /// TypeName + /// + internal static string FormatInjectDirective_TypeToken_Name() + => GetString("InjectDirective_TypeToken_Name"); + + /// + /// Specify the view or page model for the page. + /// + internal static string ModelDirective_Description + { + get => GetString("ModelDirective_Description"); + } + + /// + /// Specify the view or page model for the page. + /// + internal static string FormatModelDirective_Description() + => GetString("ModelDirective_Description"); + + /// + /// The model type. + /// + internal static string ModelDirective_TypeToken_Description + { + get => GetString("ModelDirective_TypeToken_Description"); + } + + /// + /// The model type. + /// + internal static string FormatModelDirective_TypeToken_Description() + => GetString("ModelDirective_TypeToken_Description"); + + /// + /// TypeName + /// + internal static string ModelDirective_TypeToken_Name + { + get => GetString("ModelDirective_TypeToken_Name"); + } + + /// + /// TypeName + /// + internal static string FormatModelDirective_TypeToken_Name() + => GetString("ModelDirective_TypeToken_Name"); + + /// + /// The 'inherits' keyword is not allowed when a '{0}' keyword is used. + /// + internal static string MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword + { + get => GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword"); + } + + /// + /// The 'inherits' keyword is not allowed when a '{0}' keyword is used. + /// + internal static string FormatMvcRazorCodeParser_CannotHaveModelAndInheritsKeyword(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword"), p0); + + /// + /// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'. + /// + internal static string MvcRazorCodeParser_InjectDirectivePropertyNameRequired + { + get => GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired"); + } + + /// + /// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'. + /// + internal static string FormatMvcRazorCodeParser_InjectDirectivePropertyNameRequired(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired"), p0); + + /// + /// The '{0}' keyword must be followed by a type name on the same line. + /// + internal static string MvcRazorCodeParser_KeywordMustBeFollowedByTypeName + { + get => GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName"); + } + + /// + /// The '{0}' keyword must be followed by a type name on the same line. + /// + internal static string FormatMvcRazorCodeParser_KeywordMustBeFollowedByTypeName(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName"), p0); + + /// + /// Only one '{0}' statement is allowed in a file. + /// + internal static string MvcRazorCodeParser_OnlyOneModelStatementIsAllowed + { + get => GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed"); + } + + /// + /// Only one '{0}' statement is allowed in a file. + /// + internal static string FormatMvcRazorCodeParser_OnlyOneModelStatementIsAllowed(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed"), p0); + + /// + /// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'. + /// + internal static string MvcRazorParser_InvalidPropertyType + { + get => GetString("MvcRazorParser_InvalidPropertyType"); + } + + /// + /// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'. + /// + internal static string FormatMvcRazorParser_InvalidPropertyType(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorParser_InvalidPropertyType"), p0, p1, p2); + + /// + /// Specify the base namespace for the page. + /// + internal static string NamespaceDirective_Description + { + get => GetString("NamespaceDirective_Description"); + } + + /// + /// Specify the base namespace for the page. + /// + internal static string FormatNamespaceDirective_Description() + => GetString("NamespaceDirective_Description"); + + /// + /// The namespace for the page. + /// + internal static string NamespaceDirective_NamespaceToken_Description + { + get => GetString("NamespaceDirective_NamespaceToken_Description"); + } + + /// + /// The namespace for the page. + /// + internal static string FormatNamespaceDirective_NamespaceToken_Description() + => GetString("NamespaceDirective_NamespaceToken_Description"); + + /// + /// Namespace + /// + internal static string NamespaceDirective_NamespaceToken_Name + { + get => GetString("NamespaceDirective_NamespaceToken_Name"); + } + + /// + /// Namespace + /// + internal static string FormatNamespaceDirective_NamespaceToken_Name() + => GetString("NamespaceDirective_NamespaceToken_Name"); + + /// + /// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file. + /// + internal static string PageDirectiveCannotBeImported + { + get => GetString("PageDirectiveCannotBeImported"); + } + + /// + /// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file. + /// + internal static string FormatPageDirectiveCannotBeImported(object p0, object p1) + => string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveCannotBeImported"), p0, p1); + + /// + /// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive. + /// + internal static string PageDirectiveMustExistAtTheTopOfFile + { + get => GetString("PageDirectiveMustExistAtTheTopOfFile"); + } + + /// + /// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive. + /// + internal static string FormatPageDirectiveMustExistAtTheTopOfFile(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveMustExistAtTheTopOfFile"), p0); + + /// + /// Mark the page as a Razor Page. + /// + internal static string PageDirective_Description + { + get => GetString("PageDirective_Description"); + } + + /// + /// Mark the page as a Razor Page. + /// + internal static string FormatPageDirective_Description() + => GetString("PageDirective_Description"); + + /// + /// An optional route template for the page. + /// + internal static string PageDirective_RouteToken_Description + { + get => GetString("PageDirective_RouteToken_Description"); + } + + /// + /// An optional route template for the page. + /// + internal static string FormatPageDirective_RouteToken_Description() + => GetString("PageDirective_RouteToken_Description"); + + /// + /// RouteTemplate + /// + internal static string PageDirective_RouteToken_Name + { + get => GetString("PageDirective_RouteToken_Name"); + } + + /// + /// RouteTemplate + /// + internal static string FormatPageDirective_RouteToken_Name() + => GetString("PageDirective_RouteToken_Name"); + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/ViewComponentResources.Designer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/ViewComponentResources.Designer.cs new file mode 100644 index 0000000000..3309adf1c7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Properties/ViewComponentResources.Designer.cs @@ -0,0 +1,100 @@ +// +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class ViewComponentResources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentResources", typeof(ViewComponentResources).GetTypeInfo().Assembly); + + /// + /// View component '{0}' must have exactly one public method named '{1}' or '{2}'. + /// + internal static string ViewComponent_AmbiguousMethods + { + get => GetString("ViewComponent_AmbiguousMethods"); + } + + /// + /// View component '{0}' must have exactly one public method named '{1}' or '{2}'. + /// + internal static string FormatViewComponent_AmbiguousMethods(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AmbiguousMethods"), p0, p1, p2); + + /// + /// Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;. + /// + internal static string ViewComponent_AsyncMethod_ShouldReturnTask + { + get => GetString("ViewComponent_AsyncMethod_ShouldReturnTask"); + } + + /// + /// Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;. + /// + internal static string FormatViewComponent_AsyncMethod_ShouldReturnTask(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AsyncMethod_ShouldReturnTask"), p0, p1, p2); + + /// + /// Could not find an '{0}' or '{1}' method for the view component '{2}'. + /// + internal static string ViewComponent_CannotFindMethod + { + get => GetString("ViewComponent_CannotFindMethod"); + } + + /// + /// Could not find an '{0}' or '{1}' method for the view component '{2}'. + /// + internal static string FormatViewComponent_CannotFindMethod(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_CannotFindMethod"), p0, p1, p2); + + /// + /// Method '{0}' of view component '{1}' cannot return a {2}. + /// + internal static string ViewComponent_SyncMethod_CannotReturnTask + { + get => GetString("ViewComponent_SyncMethod_CannotReturnTask"); + } + + /// + /// Method '{0}' of view component '{1}' cannot return a {2}. + /// + internal static string FormatViewComponent_SyncMethod_CannotReturnTask(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_CannotReturnTask"), p0, p1, p2); + + /// + /// Method '{0}' of view component '{1}' should be declared to return a value. + /// + internal static string ViewComponent_SyncMethod_ShouldReturnValue + { + get => GetString("ViewComponent_SyncMethod_ShouldReturnValue"); + } + + /// + /// Method '{0}' of view component '{1}' should be declared to return a value. + /// + internal static string FormatViewComponent_SyncMethod_ShouldReturnValue(object p0, object p1) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_ShouldReturnValue"), p0, p1); + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorExtensions.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorExtensions.cs new file mode 100644 index 0000000000..69cf7e2055 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorExtensions.cs @@ -0,0 +1,48 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.CodeAnalysis.Razor; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public static class RazorExtensions + { + public static void Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + InjectDirective.Register(builder); + ModelDirective.Register(builder); + NamespaceDirective.Register(builder); + PageDirective.Register(builder); + + InheritsDirective.Register(builder); + SectionDirective.Register(builder); + + builder.Features.Add(new DefaultTagHelperDescriptorProvider()); + builder.Features.Add(new ViewComponentTagHelperDescriptorProvider()); + + builder.AddTargetExtension(new ViewComponentTagHelperTargetExtension()); + builder.AddTargetExtension(new TemplateTargetExtension() + { + TemplateTypeName = "global::Microsoft.AspNetCore.Mvc.Razor.HelperResult", + }); + + builder.Features.Add(new ModelExpressionPass()); + builder.Features.Add(new PagesPropertyInjectionPass()); + builder.Features.Add(new ViewComponentTagHelperPass()); + builder.Features.Add(new RazorPageDocumentClassifierPass()); + builder.Features.Add(new MvcViewDocumentClassifierPass()); + builder.Features.Add(new AssemblyAttributeInjectionPass()); + builder.Features.Add(new InstrumentationPass()); + + builder.SetImportFeature(new MvcImportProjectFeature()); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorExtensionsDiagnosticFactory.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorExtensionsDiagnosticFactory.cs new file mode 100644 index 0000000000..05a01d38a9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorExtensionsDiagnosticFactory.cs @@ -0,0 +1,131 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + internal class RazorExtensionsDiagnosticFactory + { + private const string DiagnosticPrefix = "RZ"; + + internal static readonly RazorDiagnosticDescriptor ViewComponent_CannotFindMethod = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3900", + () => ViewComponentResources.ViewComponent_CannotFindMethod, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_CannotFindMethod(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_CannotFindMethod, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.SyncMethodName, + ViewComponentTypes.AsyncMethodName, + tagHelperType); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_AmbiguousMethods = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3901", + () => ViewComponentResources.ViewComponent_AmbiguousMethods, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_AmbiguousMethods(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_AmbiguousMethods, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + tagHelperType, + ViewComponentTypes.SyncMethodName, + ViewComponentTypes.AsyncMethodName); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_AsyncMethod_ShouldReturnTask = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3902", + () => ViewComponentResources.ViewComponent_AsyncMethod_ShouldReturnTask, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_AsyncMethod_ShouldReturnTask(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_AsyncMethod_ShouldReturnTask, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.AsyncMethodName, + tagHelperType, + nameof(Task)); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_ShouldReturnValue = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3903", + () => ViewComponentResources.ViewComponent_SyncMethod_ShouldReturnValue, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_SyncMethod_ShouldReturnValue(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_SyncMethod_ShouldReturnValue, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.SyncMethodName, + tagHelperType); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_CannotReturnTask = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3904", + () => ViewComponentResources.ViewComponent_SyncMethod_CannotReturnTask, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_SyncMethod_CannotReturnTask(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_SyncMethod_CannotReturnTask, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.SyncMethodName, + tagHelperType, + nameof(Task)); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor PageDirective_CannotBeImported = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3905", + () => Resources.PageDirectiveCannotBeImported, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreatePageDirective_CannotBeImported(SourceSpan source) + { + var fileName = Path.GetFileName(source.FilePath); + var diagnostic = RazorDiagnostic.Create(PageDirective_CannotBeImported, source, PageDirective.Directive.Directive, fileName); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor PageDirective_MustExistAtTheTopOfFile = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3906", + () => Resources.PageDirectiveMustExistAtTheTopOfFile, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreatePageDirective_MustExistAtTheTopOfFile(SourceSpan source) + { + var fileName = Path.GetFileName(source.FilePath); + var diagnostic = RazorDiagnostic.Create(PageDirective_MustExistAtTheTopOfFile, source, PageDirective.Directive.Directive); + + return diagnostic; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorPageDocumentClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorPageDocumentClassifierPass.cs new file mode 100644 index 0000000000..a5de7d0783 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/RazorPageDocumentClassifierPass.cs @@ -0,0 +1,164 @@ +// 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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class RazorPageDocumentClassifierPass : DocumentClassifierPassBase + { + public static readonly string RazorPageDocumentKind = "mvc.1.0.razor-page"; + public static readonly string RouteTemplateKey = "RouteTemplate"; + + private static readonly RazorProjectEngine LeadingDirectiveParsingEngine = RazorProjectEngine.Create( + RazorConfiguration.Default, + RazorProjectFileSystem.Create("/"), + builder => + { + for (var i = builder.Phases.Count - 1; i >= 0; i--) + { + var phase = builder.Phases[i]; + builder.Phases.RemoveAt(i); + if (phase is IRazorDocumentClassifierPhase) + { + break; + } + } + + RazorExtensions.Register(builder); + builder.Features.Add(new LeadingDirectiveParserOptionsFeature()); + }); + + protected override string DocumentKind => RazorPageDocumentKind; + + protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + return PageDirective.TryGetPageDirective(documentNode, out var pageDirective); + } + + protected override void OnDocumentStructureCreated( + RazorCodeDocument codeDocument, + NamespaceDeclarationIntermediateNode @namespace, + ClassDeclarationIntermediateNode @class, + MethodDeclarationIntermediateNode method) + { + base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method); + + @namespace.Content = "AspNetCore"; + + @class.BaseType = "global::Microsoft.AspNetCore.Mvc.RazorPages.Page"; + + var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath; + if (string.IsNullOrEmpty(filePath)) + { + // It's possible for a Razor document to not have a file path. + // Eg. When we try to generate code for an in memory document like default imports. + var checksum = BytesToString(codeDocument.Source.GetChecksum()); + @class.ClassName = $"AspNetCore_{checksum}"; + } + else + { + @class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath); + } + + @class.Modifiers.Clear(); + @class.Modifiers.Add("public"); + + method.MethodName = "ExecuteAsync"; + method.Modifiers.Clear(); + method.Modifiers.Add("public"); + method.Modifiers.Add("async"); + method.Modifiers.Add("override"); + method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}"; + + var document = codeDocument.GetDocumentIntermediateNode(); + PageDirective.TryGetPageDirective(document, out var pageDirective); + + EnsureValidPageDirective(codeDocument, pageDirective); + + AddRouteTemplateMetadataAttribute(@namespace, @class, pageDirective); + } + + private static void AddRouteTemplateMetadataAttribute(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class, PageDirective pageDirective) + { + if (string.IsNullOrEmpty(pageDirective.RouteTemplate)) + { + return; + } + + var classIndex = @namespace.Children.IndexOf(@class); + if (classIndex == -1) + { + return; + } + + var metadataAttributeNode = new RazorCompiledItemMetadataAttributeIntermediateNode + { + Key = RouteTemplateKey, + Value = pageDirective.RouteTemplate, + }; + // Metadata attributes need to be inserted right before the class declaration. + @namespace.Children.Insert(classIndex, metadataAttributeNode); + } + + private void EnsureValidPageDirective(RazorCodeDocument codeDocument, PageDirective pageDirective) + { + Debug.Assert(pageDirective != null); + + if (pageDirective.DirectiveNode.IsImported()) + { + pageDirective.DirectiveNode.Diagnostics.Add( + RazorExtensionsDiagnosticFactory.CreatePageDirective_CannotBeImported(pageDirective.DirectiveNode.Source.Value)); + } + else + { + // The document contains a page directive and it is not imported. + // We now want to make sure this page directive exists at the top of the file. + // We are going to do that by re-parsing the document until the very first line that is not Razor comment + // or whitespace. We then make sure the page directive still exists in the re-parsed IR tree. + var leadingDirectiveCodeDocument = RazorCodeDocument.Create(codeDocument.Source); + LeadingDirectiveParsingEngine.Engine.Process(leadingDirectiveCodeDocument); + + var leadingDirectiveDocumentNode = leadingDirectiveCodeDocument.GetDocumentIntermediateNode(); + if (!PageDirective.TryGetPageDirective(leadingDirectiveDocumentNode, out var _)) + { + // The page directive is not the leading directive. Add an error. + pageDirective.DirectiveNode.Diagnostics.Add( + RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(pageDirective.DirectiveNode.Source.Value)); + } + } + } + + private class LeadingDirectiveParserOptionsFeature : RazorEngineFeatureBase, IConfigureRazorParserOptionsFeature + { + public int Order { get; } + + public void Configure(RazorParserOptionsBuilder options) + { + options.ParseLeadingDirectives = true; + } + } + + private static string BytesToString(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException(nameof(bytes)); + } + + var result = new StringBuilder(bytes.Length); + for (var i = 0; i < bytes.Length; i++) + { + // The x2 format means lowercase hex, where each byte is a 2-character string. + result.Append(bytes[i].ToString("x2")); + } + + return result.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Resources.resx b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Resources.resx new file mode 100644 index 0000000000..474537197e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Resources.resx @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Value cannot be null or empty. + + + Inject a service from the application's service container into a property. + + + The name of the property. + + + PropertyName + + + The type of the service to inject. + + + TypeName + + + Specify the view or page model for the page. + + + The model type. + + + TypeName + + + The 'inherits' keyword is not allowed when a '{0}' keyword is used. + + + A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'. + + + The '{0}' keyword must be followed by a type name on the same line. + + + Only one '{0}' statement is allowed in a file. + + + Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'. + + + Specify the base namespace for the page. + + + The namespace for the page. + + + Namespace + + + The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file. + + + The '@{0}' directive must precede all other elements defined in a Razor file. + + + Mark the page as a Razor Page. + + + An optional route template for the page. + + + RouteTemplate + + \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/TagHelperDescriptorExtensions.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/TagHelperDescriptorExtensions.cs new file mode 100644 index 0000000000..b7bd72ec70 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/TagHelperDescriptorExtensions.cs @@ -0,0 +1,37 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public static class TagHelperDescriptorExtensions + { + /// + /// Indicates whether a represents a view component. + /// + /// The to check. + /// Whether a represents a view component. + public static bool IsViewComponentKind(this TagHelperDescriptor tagHelper) + { + if (tagHelper == null) + { + throw new ArgumentNullException(nameof(tagHelper)); + } + + return string.Equals(ViewComponentTagHelperConventions.Kind, tagHelper.Kind, StringComparison.Ordinal); + } + + public static string GetViewComponentName(this TagHelperDescriptor tagHelper) + { + if (tagHelper == null) + { + throw new ArgumentNullException(nameof(tagHelper)); + } + + tagHelper.Metadata.TryGetValue(ViewComponentTagHelperMetadata.Name, out var result); + return result; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentResources.resx b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentResources.resx new file mode 100644 index 0000000000..d6aad4ff3f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentResources.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + View component '{0}' must have exactly one public method named '{1}' or '{2}'. + + + Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;. + + + Could not find an '{0}' or '{1}' method for the view component '{2}'. + + + Method '{0}' of view component '{1}' cannot return a {2}. + + + Method '{0}' of view component '{1}' should be declared to return a value. + + \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperConventions.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperConventions.cs new file mode 100644 index 0000000000..30e8d1c36f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperConventions.cs @@ -0,0 +1,10 @@ +// 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.Mvc.Razor.Extensions.Version2_X +{ + public static class ViewComponentTagHelperConventions + { + public static readonly string Kind = "MVC.ViewComponent"; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperDescriptorFactory.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperDescriptorFactory.cs new file mode 100644 index 0000000000..0b1221af72 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperDescriptorFactory.cs @@ -0,0 +1,284 @@ +// 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.Collections.Immutable; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + internal class ViewComponentTagHelperDescriptorFactory + { + private readonly INamedTypeSymbol _viewComponentAttributeSymbol; + private readonly INamedTypeSymbol _genericTaskSymbol; + private readonly INamedTypeSymbol _taskSymbol; + private readonly INamedTypeSymbol _iDictionarySymbol; + + private static readonly SymbolDisplayFormat FullNameTypeDisplayFormat = + SymbolDisplayFormat.FullyQualifiedFormat + .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted) + .WithMiscellaneousOptions(SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions & (~SymbolDisplayMiscellaneousOptions.UseSpecialTypes)); + + private static readonly IReadOnlyDictionary PrimitiveDisplayTypeNameLookups = new Dictionary(StringComparer.Ordinal) + { + [typeof(byte).FullName] = "byte", + [typeof(sbyte).FullName] = "sbyte", + [typeof(int).FullName] = "int", + [typeof(uint).FullName] = "uint", + [typeof(short).FullName] = "short", + [typeof(ushort).FullName] = "ushort", + [typeof(long).FullName] = "long", + [typeof(ulong).FullName] = "ulong", + [typeof(float).FullName] = "float", + [typeof(double).FullName] = "double", + [typeof(char).FullName] = "char", + [typeof(bool).FullName] = "bool", + [typeof(object).FullName] = "object", + [typeof(string).FullName] = "string", + [typeof(decimal).FullName] = "decimal", + }; + + public ViewComponentTagHelperDescriptorFactory(Compilation compilation) + { + _viewComponentAttributeSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute); + _genericTaskSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.GenericTask); + _taskSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.Task); + _iDictionarySymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.IDictionary); + } + + public virtual TagHelperDescriptor CreateDescriptor(INamedTypeSymbol type) + { + var assemblyName = type.ContainingAssembly.Name; + var shortName = GetShortName(type); + var tagName = $"vc:{HtmlConventions.ToHtmlCase(shortName)}"; + var typeName = $"__Generated__{shortName}ViewComponentTagHelper"; + var displayName = shortName + "ViewComponentTagHelper"; + var descriptorBuilder = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, typeName, assemblyName); + descriptorBuilder.SetTypeName(typeName); + descriptorBuilder.DisplayName = displayName; + + if (TryFindInvokeMethod(type, out var method, out var diagnostic)) + { + var methodParameters = method.Parameters; + descriptorBuilder.TagMatchingRule(ruleBuilder => + { + ruleBuilder.TagName = tagName; + AddRequiredAttributes(methodParameters, ruleBuilder); + }); + + AddBoundAttributes(methodParameters, displayName, descriptorBuilder); + } + else + { + descriptorBuilder.Diagnostics.Add(diagnostic); + } + + descriptorBuilder.Metadata[ViewComponentTagHelperMetadata.Name] = shortName; + + var descriptor = descriptorBuilder.Build(); + return descriptor; + } + + private bool TryFindInvokeMethod(INamedTypeSymbol type, out IMethodSymbol method, out RazorDiagnostic diagnostic) + { + var methods = GetInvokeMethods(type); + + if (methods.Count == 0) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_CannotFindMethod(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + else if (methods.Count > 1) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_AmbiguousMethods(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + + var selectedMethod = methods[0]; + var returnType = selectedMethod.ReturnType as INamedTypeSymbol; + if (string.Equals(selectedMethod.Name, ViewComponentTypes.AsyncMethodName, StringComparison.Ordinal)) + { + // Will invoke asynchronously. Method must not return Task or Task. + if (returnType == _taskSymbol) + { + // This is ok. + } + else if (returnType.IsGenericType && returnType.ConstructedFrom == _genericTaskSymbol) + { + // This is ok. + } + else + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_AsyncMethod_ShouldReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + } + else + { + // Will invoke synchronously. Method must not return void, Task or Task. + if (returnType.SpecialType == SpecialType.System_Void) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_ShouldReturnValue(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + else if (returnType == _taskSymbol) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_CannotReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + else if (returnType.IsGenericType && returnType.ConstructedFrom == _genericTaskSymbol) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_CannotReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + } + + method = selectedMethod; + diagnostic = null; + return true; + } + + private static IReadOnlyList GetInvokeMethods(INamedTypeSymbol type) + { + var methods = new List(); + while (type != null) + { + var currentTypeMethods = type.GetMembers() + .OfType() + .Where(m => + m.DeclaredAccessibility == Accessibility.Public && + !m.IsStatic && + (string.Equals(m.Name, ViewComponentTypes.AsyncMethodName, StringComparison.Ordinal) || + string.Equals(m.Name, ViewComponentTypes.SyncMethodName, StringComparison.Ordinal))); + + methods.AddRange(currentTypeMethods); + + type = type.BaseType; + } + + return methods; + } + + private void AddRequiredAttributes(ImmutableArray methodParameters, TagMatchingRuleDescriptorBuilder builder) + { + foreach (var parameter in methodParameters) + { + if (GetIndexerValueTypeName(parameter) == null) + { + // Set required attributes only for non-indexer attributes. Indexer attributes can't be required attributes + // because there are two ways of setting values for the attribute. + builder.Attribute(attributeBuilder => + { + var lowerKebabName = HtmlConventions.ToHtmlCase(parameter.Name); + attributeBuilder.Name = lowerKebabName; + }); + } + } + } + + private void AddBoundAttributes(ImmutableArray methodParameters, string containingDisplayName, TagHelperDescriptorBuilder builder) + { + foreach (var parameter in methodParameters) + { + var lowerKebabName = HtmlConventions.ToHtmlCase(parameter.Name); + var typeName = parameter.Type.ToDisplayString(FullNameTypeDisplayFormat); + + if (!PrimitiveDisplayTypeNameLookups.TryGetValue(typeName, out var simpleName)) + { + simpleName = typeName; + } + + builder.BindAttribute(attributeBuilder => + { + attributeBuilder.Name = lowerKebabName; + attributeBuilder.TypeName = typeName; + attributeBuilder.DisplayName = $"{simpleName} {containingDisplayName}.{parameter.Name}"; + attributeBuilder.SetPropertyName(parameter.Name); + + if (parameter.Type.TypeKind == TypeKind.Enum) + { + attributeBuilder.IsEnum = true; + } + else + { + var dictionaryValueType = GetIndexerValueTypeName(parameter); + if (dictionaryValueType != null) + { + attributeBuilder.AsDictionary(lowerKebabName + "-", dictionaryValueType); + } + } + }); + } + } + + private string GetIndexerValueTypeName(IParameterSymbol parameter) + { + INamedTypeSymbol dictionaryType; + if ((parameter.Type as INamedTypeSymbol)?.ConstructedFrom == _iDictionarySymbol) + { + dictionaryType = (INamedTypeSymbol)parameter.Type; + } + else if (parameter.Type.AllInterfaces.Any(s => s.ConstructedFrom == _iDictionarySymbol)) + { + dictionaryType = parameter.Type.AllInterfaces.First(s => s.ConstructedFrom == _iDictionarySymbol); + } + else + { + dictionaryType = null; + } + + if (dictionaryType == null || dictionaryType.TypeArguments[0].SpecialType != SpecialType.System_String) + { + return null; + } + + var type = dictionaryType.TypeArguments[1]; + var typeName = type.ToDisplayString(FullNameTypeDisplayFormat); + + return typeName; + } + + private string GetShortName(INamedTypeSymbol componentType) + { + var viewComponentAttribute = componentType.GetAttributes().Where(a => a.AttributeClass == _viewComponentAttributeSymbol).FirstOrDefault(); + var name = viewComponentAttribute + ?.NamedArguments + .Where(namedArgument => string.Equals(namedArgument.Key, ViewComponentTypes.ViewComponent.Name, StringComparison.Ordinal)) + .FirstOrDefault() + .Value + .Value as string; + + if (!string.IsNullOrEmpty(name)) + { + var separatorIndex = name.LastIndexOf('.'); + if (separatorIndex >= 0) + { + return name.Substring(separatorIndex + 1); + } + else + { + return name; + } + } + + // Get name by convention + if (componentType.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix, StringComparison.OrdinalIgnoreCase)) + { + return componentType.Name.Substring(0, componentType.Name.Length - ViewComponentTypes.ViewComponentSuffix.Length); + } + else + { + return componentType.Name; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperDescriptorProvider.cs new file mode 100644 index 0000000000..4806acc806 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperDescriptorProvider.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.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Razor; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public sealed class ViewComponentTagHelperDescriptorProvider : RazorEngineFeatureBase, ITagHelperDescriptorProvider + { + public int Order { get; set; } + + public void Execute(TagHelperDescriptorProviderContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var compilation = context.GetCompilation(); + if (compilation == null) + { + // No compilation, nothing to do. + return; + } + + var vcAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute); + var nonVCAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.NonViewComponentAttribute); + if (vcAttribute == null || vcAttribute.TypeKind == TypeKind.Error) + { + // Could not find attributes we care about in the compilation. Nothing to do. + return; + } + + var types = new List(); + var visitor = new ViewComponentTypeVisitor(vcAttribute, nonVCAttribute, types); + + // We always visit the global namespace. + visitor.Visit(compilation.Assembly.GlobalNamespace); + + foreach (var reference in compilation.References) + { + if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly) + { + if (IsTagHelperAssembly(assembly)) + { + visitor.Visit(assembly.GlobalNamespace); + } + } + } + + var factory = new ViewComponentTagHelperDescriptorFactory(compilation); + for (var i = 0; i < types.Count; i++) + { + var descriptor = factory.CreateDescriptor(types[i]); + + if (descriptor != null) + { + context.Results.Add(descriptor); + } + } + } + + private bool IsTagHelperAssembly(IAssemblySymbol assembly) + { + return assembly.Name != null && !assembly.Name.StartsWith("System.", StringComparison.Ordinal); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperIntermediateNode.cs new file mode 100644 index 0000000000..a42b88416b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperIntermediateNode.cs @@ -0,0 +1,59 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public sealed class ViewComponentTagHelperIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = IntermediateNodeCollection.ReadOnly; + + public string ClassName { get; set; } + + public TagHelperDescriptor TagHelper { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteViewComponentTagHelper(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(ClassName); + + formatter.WriteProperty(nameof(ClassName), ClassName); + formatter.WriteProperty(nameof(TagHelper), TagHelper?.DisplayName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperMetadata.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperMetadata.cs new file mode 100644 index 0000000000..ad77c7a29e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperMetadata.cs @@ -0,0 +1,14 @@ +// 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.Mvc.Razor.Extensions.Version2_X +{ + public static class ViewComponentTagHelperMetadata + { + /// + /// The key in a containing + /// the short name of a view component. + /// + public static readonly string Name = "MVC.ViewComponent.Name"; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperPass.cs new file mode 100644 index 0000000000..f5c37eb13b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperPass.cs @@ -0,0 +1,203 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class ViewComponentTagHelperPass : IntermediateNodePassBase, IRazorOptimizationPass + { + // Run after the default taghelper pass + public override int Order => IntermediateNodePassBase.DefaultFeatureOrder + 2000; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var @namespace = documentNode.FindPrimaryNamespace(); + var @class = documentNode.FindPrimaryClass(); + if (@namespace == null || @class == null) + { + // Nothing to do, bail. We can't function without the standard structure. + return; + } + + var context = new Context(@namespace, @class); + + // For each VCTH *usage* we need to rewrite the tag helper node to use the tag helper runtime to construct + // and set properties on the the correct field, and using the name of the type we will generate. + var nodes = documentNode.FindDescendantNodes(); + for (var i = 0; i < nodes.Count; i++) + { + var node = nodes[i]; + foreach (var tagHelper in node.TagHelpers) + { + RewriteUsage(context, node, tagHelper); + } + } + + // Then for each VCTH *definition* that we've seen we need to generate the class that implements + // ITagHelper and the field that will hold it. + foreach (var tagHelper in context.TagHelpers) + { + AddField(context, tagHelper); + AddTagHelperClass(context, tagHelper); + } + } + + private void RewriteUsage(Context context, TagHelperIntermediateNode node, TagHelperDescriptor tagHelper) + { + if (!tagHelper.IsViewComponentKind()) + { + return; + } + + context.Add(tagHelper); + + // Now we need to insert a create node using the default tag helper runtime. This is similar to + // code in DefaultTagHelperOptimizationPass. + // + // Find the body node. + var i = 0; + while (i < node.Children.Count && node.Children[i] is TagHelperBodyIntermediateNode) + { + i++; + } + while (i < node.Children.Count && node.Children[i] is DefaultTagHelperBodyIntermediateNode) + { + i++; + } + + // Now find the last create node. + while (i < node.Children.Count && node.Children[i] is DefaultTagHelperCreateIntermediateNode) + { + i++; + } + + // Now i has the right insertion point. + node.Children.Insert(i, new DefaultTagHelperCreateIntermediateNode() + { + FieldName = context.GetFieldName(tagHelper), + TagHelper = tagHelper, + TypeName = context.GetFullyQualifiedName(tagHelper), + }); + + // Now we need to rewrite any set property nodes to use the default runtime. + for (i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode && + propertyNode.TagHelper == tagHelper) + { + // This is a set property for this VCTH - we need to replace it with a node + // that will use our field and property name. + node.Children[i] = new DefaultTagHelperPropertyIntermediateNode(propertyNode) + { + FieldName = context.GetFieldName(tagHelper), + PropertyName = propertyNode.BoundAttribute.GetPropertyName(), + }; + } + } + } + + private void AddField(Context context, TagHelperDescriptor tagHelper) + { + // We need to insert a node for the field that will hold the tag helper. We've already generated a field name + // at this time and use it for all uses of the same tag helper type. + // + // We also want to preserve the ordering of the nodes for testability. So insert at the end of any existing + // field nodes. + var i = 0; + while (i < context.Class.Children.Count && context.Class.Children[i] is DefaultTagHelperRuntimeIntermediateNode) + { + i++; + } + + while (i < context.Class.Children.Count && context.Class.Children[i] is FieldDeclarationIntermediateNode) + { + i++; + } + + context.Class.Children.Insert(i, new FieldDeclarationIntermediateNode() + { + Annotations = + { + { CommonAnnotations.DefaultTagHelperExtension.TagHelperField, bool.TrueString }, + }, + Modifiers = + { + "private", + }, + FieldName = context.GetFieldName(tagHelper), + FieldType = "global::" + context.GetFullyQualifiedName(tagHelper), + }); + } + + private void AddTagHelperClass(Context context, TagHelperDescriptor tagHelper) + { + var node = new ViewComponentTagHelperIntermediateNode() + { + ClassName = context.GetClassName(tagHelper), + TagHelper = tagHelper + }; + + context.Class.Children.Add(node); + } + + private struct Context + { + private Dictionary _tagHelpers; + + public Context(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class) + { + Namespace = @namespace; + Class = @class; + + _tagHelpers = new Dictionary(); + } + + public ClassDeclarationIntermediateNode Class { get; } + + public NamespaceDeclarationIntermediateNode Namespace { get; } + + + public IEnumerable TagHelpers => _tagHelpers.Keys; + + public bool Add(TagHelperDescriptor tagHelper) + { + if (_tagHelpers.ContainsKey(tagHelper)) + { + return false; + } + + var className = $"__Generated__{tagHelper.GetViewComponentName()}ViewComponentTagHelper"; + var fullyQualifiedName = $"{Namespace.Content}.{Class.ClassName}.{className}"; + var fieldName = GenerateFieldName(tagHelper); + + _tagHelpers.Add(tagHelper, (className, fullyQualifiedName, fieldName)); + + return true; + } + + public string GetClassName(TagHelperDescriptor taghelper) + { + return _tagHelpers[taghelper].className; + } + + public string GetFullyQualifiedName(TagHelperDescriptor taghelper) + { + return _tagHelpers[taghelper].fullyQualifiedName; + } + + public string GetFieldName(TagHelperDescriptor taghelper) + { + return _tagHelpers[taghelper].fieldName; + } + + private static string GenerateFieldName(TagHelperDescriptor tagHelper) + { + return $"__{tagHelper.GetViewComponentName()}ViewComponentTagHelper"; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperTargetExtension.cs new file mode 100644 index 0000000000..a56e86fdca --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTagHelperTargetExtension.cs @@ -0,0 +1,183 @@ +// 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.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + internal class ViewComponentTagHelperTargetExtension : IViewComponentTagHelperTargetExtension + { + private static readonly string[] PublicModifiers = new[] { "public" }; + + public string TagHelperTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelper"; + + public string ViewComponentHelperTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.IViewComponentHelper"; + + public string ViewComponentHelperVariableName { get; set; } = "_helper"; + + public string ViewComponentInvokeMethodName { get; set; } = "InvokeAsync"; + + public string HtmlAttributeNotBoundAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute"; + + public string ViewContextAttributeTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute"; + + public string ViewContextTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext"; + + public string ViewContextPropertyName { get; set; } = "ViewContext"; + + public string HtmlTargetElementAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute"; + + public string TagHelperProcessMethodName { get; set; } = "ProcessAsync"; + + public string TagHelperContextTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext"; + + public string TagHelperContextVariableName { get; set; } = "context"; + + public string TagHelperOutputTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput"; + + public string TagHelperOutputVariableName { get; set; } = "output"; + + public string TagHelperOutputTagNamePropertyName { get; set; } = "TagName"; + + public string TagHelperOutputContentPropertyName { get; set; } = "Content"; + + public string TagHelperContentSetMethodName { get; set; } = "SetHtmlContent"; + + public string TagHelperContentVariableName { get; set; } = "content"; + + public string IViewContextAwareTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware"; + + public string IViewContextAwareContextualizeMethodName { get; set; } = "Contextualize"; + + public void WriteViewComponentTagHelper(CodeRenderingContext context, ViewComponentTagHelperIntermediateNode node) + { + // Add target element. + WriteTargetElementString(context.CodeWriter, node.TagHelper); + + // Initialize declaration. + using (context.CodeWriter.BuildClassDeclaration( + PublicModifiers, + node.ClassName, + TagHelperTypeName, + interfaces: null, + typeParameters: null)) + { + // Add view component helper. + context.CodeWriter.WriteVariableDeclaration( + $"private readonly {ViewComponentHelperTypeName}", + ViewComponentHelperVariableName, + value: null); + + // Add constructor. + WriteConstructorString(context.CodeWriter, node.ClassName); + + // Add attributes. + WriteAttributeDeclarations(context.CodeWriter, node.TagHelper); + + // Add process method. + WriteProcessMethodString(context.CodeWriter, node.TagHelper); + } + } + + private void WriteConstructorString(CodeWriter writer, string className) + { + writer.Write("public ") + .Write(className) + .Write("(") + .Write($"{ViewComponentHelperTypeName} helper") + .WriteLine(")"); + using (writer.BuildScope()) + { + writer.WriteStartAssignment(ViewComponentHelperVariableName) + .Write("helper") + .WriteLine(";"); + } + } + + private void WriteAttributeDeclarations(CodeWriter writer, TagHelperDescriptor tagHelper) + { + writer.Write("[") + .Write(HtmlAttributeNotBoundAttributeTypeName) + .WriteParameterSeparator() + .Write(ViewContextAttributeTypeName) + .WriteLine("]"); + + writer.WriteAutoPropertyDeclaration( + PublicModifiers, + ViewContextTypeName, + ViewContextPropertyName); + + foreach (var attribute in tagHelper.BoundAttributes) + { + writer.WriteAutoPropertyDeclaration( + PublicModifiers, + attribute.TypeName, + attribute.GetPropertyName()); + + if (attribute.IndexerTypeName != null) + { + writer.Write(" = ") + .WriteStartNewObject(attribute.TypeName) + .WriteEndMethodInvocation(); + } + } + } + + private void WriteProcessMethodString(CodeWriter writer, TagHelperDescriptor tagHelper) + { + using (writer.BuildMethodDeclaration( + $"public override async", + $"global::{typeof(Task).FullName}", + TagHelperProcessMethodName, + new Dictionary() + { + { TagHelperContextTypeName, TagHelperContextVariableName }, + { TagHelperOutputTypeName, TagHelperOutputVariableName } + })) + { + writer.WriteInstanceMethodInvocation( + $"({ViewComponentHelperVariableName} as {IViewContextAwareTypeName})?", + IViewContextAwareContextualizeMethodName, + new[] { ViewContextPropertyName }); + + var methodParameters = GetMethodParameters(tagHelper); + writer.Write("var ") + .WriteStartAssignment(TagHelperContentVariableName) + .WriteInstanceMethodInvocation($"await {ViewComponentHelperVariableName}", ViewComponentInvokeMethodName, methodParameters); + writer.WriteStartAssignment($"{TagHelperOutputVariableName}.{TagHelperOutputTagNamePropertyName}") + .WriteLine("null;"); + writer.WriteInstanceMethodInvocation( + $"{TagHelperOutputVariableName}.{TagHelperOutputContentPropertyName}", + TagHelperContentSetMethodName, + new[] { TagHelperContentVariableName }); + } + } + + private string[] GetMethodParameters(TagHelperDescriptor tagHelper) + { + var propertyNames = tagHelper.BoundAttributes.Select(attribute => attribute.GetPropertyName()); + var joinedPropertyNames = string.Join(", ", propertyNames); + var parametersString = $"new {{ { joinedPropertyNames } }}"; + var viewComponentName = tagHelper.GetViewComponentName(); + var methodParameters = new[] { $"\"{viewComponentName}\"", parametersString }; + return methodParameters; + } + + private void WriteTargetElementString(CodeWriter writer, TagHelperDescriptor tagHelper) + { + Debug.Assert(tagHelper.TagMatchingRules.Count() == 1); + + var rule = tagHelper.TagMatchingRules.First(); + + writer.Write("[") + .WriteStartMethodInvocation(HtmlTargetElementAttributeTypeName) + .WriteStringLiteral(rule.TagName) + .WriteLine(")]"); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTypeVisitor.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTypeVisitor.cs new file mode 100644 index 0000000000..01eb3fffaa --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTypeVisitor.cs @@ -0,0 +1,88 @@ +// 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.CodeAnalysis; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + internal class ViewComponentTypeVisitor : SymbolVisitor + { + private readonly INamedTypeSymbol _viewComponentAttribute; + private readonly INamedTypeSymbol _nonViewComponentAttribute; + private readonly List _results; + + public ViewComponentTypeVisitor( + INamedTypeSymbol viewComponentAttribute, + INamedTypeSymbol nonViewComponentAttribute, + List results) + { + _viewComponentAttribute = viewComponentAttribute; + _nonViewComponentAttribute = nonViewComponentAttribute; + _results = results; + } + + public override void VisitNamedType(INamedTypeSymbol symbol) + { + if (IsViewComponent(symbol)) + { + _results.Add(symbol); + } + + if (symbol.DeclaredAccessibility != Accessibility.Public) + { + return; + } + + foreach (var member in symbol.GetTypeMembers()) + { + Visit(member); + } + } + + public override void VisitNamespace(INamespaceSymbol symbol) + { + foreach (var member in symbol.GetMembers()) + { + Visit(member); + } + } + + internal bool IsViewComponent(INamedTypeSymbol symbol) + { + if (_viewComponentAttribute == null) + { + return false; + } + + if (symbol.DeclaredAccessibility != Accessibility.Public || + symbol.IsAbstract || + symbol.IsGenericType || + AttributeIsDefined(symbol, _nonViewComponentAttribute)) + { + return false; + } + + return symbol.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix) || + AttributeIsDefined(symbol, _viewComponentAttribute); + } + + private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol queryAttribute) + { + if (type == null || queryAttribute == null) + { + return false; + } + + var attribute = type.GetAttributes().Where(a => a.AttributeClass == queryAttribute).FirstOrDefault(); + + if (attribute != null) + { + return true; + } + + return AttributeIsDefined(type.BaseType, queryAttribute); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTypes.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTypes.cs new file mode 100644 index 0000000000..cd7e2771be --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/ViewComponentTypes.cs @@ -0,0 +1,35 @@ +// 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.Mvc.Razor.Extensions.Version2_X +{ + internal static class ViewComponentTypes + { + public const string Assembly = "Microsoft.AspNetCore.Mvc.ViewFeatures"; + + public static readonly Version AssemblyVersion = new Version(1, 1, 0, 0); + + public const string ViewComponentSuffix = "ViewComponent"; + + public const string ViewComponentAttribute = "Microsoft.AspNetCore.Mvc.ViewComponentAttribute"; + + public const string NonViewComponentAttribute = "Microsoft.AspNetCore.Mvc.NonViewComponentAttribute"; + + public const string GenericTask = "System.Threading.Tasks.Task`1"; + + public const string Task = "System.Threading.Tasks.Task"; + + public const string IDictionary = "System.Collections.Generic.IDictionary`2"; + + public const string AsyncMethodName = "InvokeAsync"; + + public const string SyncMethodName = "Invoke"; + + public static class ViewComponent + { + public const string Name = "Name"; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/baseline.netcore.json b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/baseline.netcore.json new file mode 100644 index 0000000000..87b3d074f3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/baseline.netcore.json @@ -0,0 +1,1180 @@ +{ + "AssemblyIdentity": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "Types": [ + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.AssemblyAttributeInjectionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IInjectTargetExtension", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.CodeGeneration.ICodeTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteInjectProperty", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectIntermediateNode" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectIntermediateNode", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.Intermediate.ExtensionIntermediateNode", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_TypeName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_TypeName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_MemberName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_MemberName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_Children", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeCollection", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Accept", + "Parameters": [ + { + "Name": "visitor", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeVisitor" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "WriteNode", + "Parameters": [ + { + "Name": "target", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeTarget" + }, + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectTargetExtension", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IInjectTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteInjectProperty", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IInjectTargetExtension", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InstrumentationPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Virtual": true, + "Override": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IViewComponentTagHelperTargetExtension", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.CodeGeneration.ICodeTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteViewComponentTagHelper", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperIntermediateNode" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ModelDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetModelType", + "Parameters": [ + { + "Name": "document", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.String", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ModelExpressionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.MvcViewDocumentClassifierPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_DocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "IsMatch", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Boolean", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "OnDocumentStructureCreated", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "namespace", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode" + }, + { + "Name": "class", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode" + }, + { + "Name": "method", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "MvcViewDocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.NamespaceDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.PageDirective", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_RouteTemplate", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_DirectiveNode", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNode", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "TryGetPageDirective", + "Parameters": [ + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + }, + { + "Name": "pageDirective", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.PageDirective", + "Direction": "Out" + } + ], + "ReturnType": "System.Boolean", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.PagesPropertyInjectionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.RazorExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.RazorPageDocumentClassifierPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_DocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "IsMatch", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Boolean", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "OnDocumentStructureCreated", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "namespace", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode" + }, + { + "Name": "class", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode" + }, + { + "Name": "method", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "RazorPageDocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "RouteTemplateKey", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.TagHelperDescriptorExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "IsViewComponentKind", + "Parameters": [ + { + "Name": "tagHelper", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.Boolean", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetViewComponentName", + "Parameters": [ + { + "Name": "tagHelper", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.String", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperConventions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Kind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperDescriptorProvider", + "Visibility": "Public", + "Kind": "Class", + "Sealed": true, + "BaseType": "Microsoft.AspNetCore.Razor.Language.RazorEngineFeatureBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_Order", + "Parameters": [ + { + "Name": "value", + "Type": "System.Int32" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Execute", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptorProviderContext" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperIntermediateNode", + "Visibility": "Public", + "Kind": "Class", + "Sealed": true, + "BaseType": "Microsoft.AspNetCore.Razor.Language.Intermediate.ExtensionIntermediateNode", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_Children", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeCollection", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_ClassName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_ClassName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_TagHelper", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_TagHelper", + "Parameters": [ + { + "Name": "value", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Accept", + "Parameters": [ + { + "Name": "visitor", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeVisitor" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "WriteNode", + "Parameters": [ + { + "Name": "target", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeTarget" + }, + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperMetadata", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Name", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Virtual": true, + "Override": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriterExtensions+CSharpCodeWritingScope", + "Visibility": "Public", + "Kind": "Struct", + "Sealed": true, + "ImplementedInterfaces": [ + "System.IDisposable" + ], + "Members": [ + { + "Kind": "Method", + "Name": "Dispose", + "Parameters": [], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "System.IDisposable", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "writer", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriter" + }, + { + "Name": "tabSize", + "Type": "System.Int32", + "DefaultValue": "4" + }, + { + "Name": "autoSpace", + "Type": "System.Boolean", + "DefaultValue": "True" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTypes+ViewComponent", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Name", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "Visibility": "Public", + "GenericParameter": [], + "Constant": true, + "Literal": "\"Name\"" + } + ], + "GenericParameters": [] + } + ] +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/baseline.netframework.json b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/baseline.netframework.json new file mode 100644 index 0000000000..9386496226 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/baseline.netframework.json @@ -0,0 +1,982 @@ +{ + "AssemblyIdentity": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "Types": [ + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.AssemblyAttributeInjectionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IInjectTargetExtension", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.CodeGeneration.ICodeTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteInjectProperty", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectIntermediateNode" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectIntermediateNode", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.Intermediate.ExtensionIntermediateNode", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_TypeName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_TypeName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_MemberName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_MemberName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_Children", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeCollection", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Accept", + "Parameters": [ + { + "Name": "visitor", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeVisitor" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "WriteNode", + "Parameters": [ + { + "Name": "target", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeTarget" + }, + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectTargetExtension", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IInjectTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteInjectProperty", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IInjectTargetExtension", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InstrumentationPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Virtual": true, + "Override": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ModelDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetModelType", + "Parameters": [ + { + "Name": "document", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.String", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ModelExpressionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.MvcViewDocumentClassifierPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_DocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "IsMatch", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Boolean", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "OnDocumentStructureCreated", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "namespace", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode" + }, + { + "Name": "class", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode" + }, + { + "Name": "method", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "MvcViewDocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.NamespaceDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.PageDirective", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_RouteTemplate", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_DirectiveNode", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNode", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "TryGetPageDirective", + "Parameters": [ + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + }, + { + "Name": "pageDirective", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.PageDirective", + "Direction": "Out" + } + ], + "ReturnType": "System.Boolean", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.PagesPropertyInjectionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.RazorExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.RazorPageDocumentClassifierPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_DocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "IsMatch", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Boolean", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "OnDocumentStructureCreated", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "namespace", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode" + }, + { + "Name": "class", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode" + }, + { + "Name": "method", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "RazorPageDocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.TagHelperDescriptorExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "IsViewComponentKind", + "Parameters": [ + { + "Name": "tagHelper", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.Boolean", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetViewComponentName", + "Parameters": [ + { + "Name": "tagHelper", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.String", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperConventions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Kind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperDescriptorProvider", + "Visibility": "Public", + "Kind": "Class", + "Sealed": true, + "BaseType": "Microsoft.AspNetCore.Razor.Language.RazorEngineFeatureBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_Order", + "Parameters": [ + { + "Name": "value", + "Type": "System.Int32" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Execute", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptorProviderContext" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperMetadata", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Name", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Virtual": true, + "Override": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriterExtensions+CSharpCodeWritingScope", + "Visibility": "Public", + "Kind": "Struct", + "Sealed": true, + "ImplementedInterfaces": [ + "System.IDisposable" + ], + "Members": [ + { + "Kind": "Method", + "Name": "Dispose", + "Parameters": [], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "System.IDisposable", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "writer", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriter" + }, + { + "Name": "tabSize", + "Type": "System.Int32", + "DefaultValue": "4" + }, + { + "Name": "autoSpace", + "Type": "System.Boolean", + "DefaultValue": "True" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTypes+ViewComponent", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Name", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "Visibility": "Public", + "GenericParameter": [], + "Constant": true, + "Literal": "\"Name\"" + } + ], + "GenericParameters": [] + } + ] +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/AssemblyAttributeInjectionPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/AssemblyAttributeInjectionPassTest.cs new file mode 100644 index 0000000000..4dbe6c72b4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/AssemblyAttributeInjectionPassTest.cs @@ -0,0 +1,444 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class AssemblyAttributeInjectionPassTest + { + [Fact] + public void Execute_NoOps_IfNamespaceNodeIsMissing() + { + // Arrange + var irDocument = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Empty(irDocument.Children); + } + + [Fact] + public void Execute_NoOps_IfNamespaceNodeHasEmptyContent() + { + // Arrange + var irDocument = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = string.Empty }; + @namespace.Annotations[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace; + builder.Push(@namespace); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_NoOps_IfClassNameNodeIsMissing() + { + // Arrange + var irDocument = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "SomeNamespace" }; + builder.Push(@namespace); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Collection( + irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_NoOps_IfClassNameIsEmpty() + { + // Arrange + var irDocument = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace, + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_NoOps_IfDocumentIsNotViewOrPage() + { + // Arrange + var irDocument = new DocumentIntermediateNode + { + DocumentKind = "Default", + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "SomeNamespace" }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Collection( + irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_NoOps_ForDesignTime() + { + // Arrange + var irDocument = new DocumentIntermediateNode + { + DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, + Options = RazorCodeGenerationOptions.CreateDesignTimeDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection( + irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_AddsRazorViewAttribute_ToViews() + { + // Arrange + var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/Views/Index.cshtml\", typeof(SomeNamespace.SomeName))]"; + var irDocument = new DocumentIntermediateNode + { + DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => + { + var csharpCode = Assert.IsType(node); + var token = Assert.IsType(Assert.Single(csharpCode.Children)); + Assert.Equal(TokenKind.CSharp, token.Kind); + Assert.Equal(expectedAttribute, token.Content); + }, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_EscapesViewPathWhenAddingAttributeToViews() + { + // Arrange + var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/test/\"\"Index.cshtml\", typeof(SomeNamespace.SomeName))]"; + var irDocument = new DocumentIntermediateNode + { + DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "\\test\\\"Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => + { + var csharpCode = Assert.IsType(node); + var token = Assert.IsType(Assert.Single(csharpCode.Children)); + Assert.Equal(TokenKind.CSharp, token.Kind); + Assert.Equal(expectedAttribute, token.Content); + }, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_AddsRazorPagettribute_ToPage() + { + // Arrange + var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@\"/Views/Index.cshtml\", typeof(SomeNamespace.SomeName), null)]"; + var irDocument = new DocumentIntermediateNode + { + DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind, + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var pageDirective = new DirectiveIntermediateNode + { + Directive = PageDirective.Directive, + }; + builder.Add(pageDirective); + + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => Assert.Same(pageDirective, node), + node => + { + var csharpCode = Assert.IsType(node); + var token = Assert.IsType(Assert.Single(csharpCode.Children)); + Assert.Equal(TokenKind.CSharp, token.Kind); + Assert.Equal(expectedAttribute, token.Content); + }, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_EscapesViewPathAndRouteWhenAddingAttributeToPage() + { + // Arrange + var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/test/\"\"Index.cshtml\", typeof(SomeNamespace.SomeName))]"; + var irDocument = new DocumentIntermediateNode + { + DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "test\\\"Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => + { + var csharpCode = Assert.IsType(node); + var token = Assert.IsType(Assert.Single(csharpCode.Children)); + Assert.Equal(TokenKind.CSharp, token.Kind); + Assert.Equal(expectedAttribute, token.Content); + }, + node => Assert.Same(@namespace, node)); + } + + 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 IRazorDocumentClassifierPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InjectDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InjectDirectiveTest.cs new file mode 100644 index 0000000000..ff128921c9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InjectDirectiveTest.cs @@ -0,0 +1,225 @@ +// 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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class InjectDirectiveTest + { + [Fact] + public void InjectDirectivePass_Execute_DefinesProperty() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_DedupesPropertiesByName() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +@inject PropertyType2 PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType2", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_ExpandsTModel_WithDynamic() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_ExpandsTModel_WithModelTypeFirst() + { + // Arrange + var codeDocument = CreateDocument(@" +@model ModelType +@inject PropertyType PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_ExpandsTModel_WithModelType() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +@model ModelType +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + private RazorCodeDocument CreateDocument(string content) + { + var source = RazorSourceDocument.Create(content, "test.cshtml"); + return RazorCodeDocument.Create(source); + } + + private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node) + { + var visitor = new ClassNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private RazorEngine CreateEngine() + { + return RazorProjectEngine.Create(b => + { + // Notice we're not registering the InjectDirective.Pass here so we can run it on demand. + b.AddDirective(InjectDirective.Directive); + b.AddDirective(ModelDirective.Directive); + }).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 IRazorDocumentClassifierPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + + private string GetCSharpContent(IntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + var child = node.Children[i] as IntermediateToken; + if (child.Kind == TokenKind.CSharp) + { + builder.Append(child.Content); + } + } + + return builder.ToString(); + } + + private class ClassNodeVisitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Node { get; set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Node = node; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InjectTargetExtensionTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InjectTargetExtensionTest.cs new file mode 100644 index 0000000000..71b2ec20ce --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InjectTargetExtensionTest.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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class InjectTargetExtensionTest + { + [Fact] + public void InjectDirectiveTargetExtension_WritesProperty() + { + // Arrange + var context = TestCodeRenderingContext.CreateRuntime(); + var target = new InjectTargetExtension(); + var node = new InjectIntermediateNode() + { + TypeName = "PropertyType", + MemberName = "PropertyName", + }; + + // Act + target.WriteInjectProperty(context, node); + + // Assert + Assert.Equal( + "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine + + "public PropertyType PropertyName { get; private set; }" + Environment.NewLine, + context.CodeWriter.GenerateCode()); + } + + [Fact] + public void InjectDirectiveTargetExtension_WritesPropertyWithLinePragma_WhenSourceIsSet() + { + // Arrange + var context = TestCodeRenderingContext.CreateRuntime(); + var target = new InjectTargetExtension(); + var node = new InjectIntermediateNode() + { + TypeName = "PropertyType", + MemberName = "PropertyName", + Source = new SourceSpan( + filePath: "test-path", + absoluteIndex: 0, + lineIndex: 1, + characterIndex: 1, + length: 10) + }; + + // Act + target.WriteInjectProperty(context, node); + + // Assert + Assert.Equal( + "#line 2 \"test-path\"" + Environment.NewLine + + "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine + + "public PropertyType PropertyName { get; private set; }" + Environment.NewLine + Environment.NewLine + + "#line default" + Environment.NewLine + + "#line hidden" + Environment.NewLine, + context.CodeWriter.GenerateCode()); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InstrumentationPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InstrumentationPassTest.cs new file mode 100644 index 0000000000..e1bd402e26 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InstrumentationPassTest.cs @@ -0,0 +1,348 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; +using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class InstrumentationPassTest + { + [Fact] + public void InstrumentationPass_NoOps_ForDesignTime() + { + // Arrange + var document = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDesignTimeDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(document); + builder.Push(new HtmlContentIntermediateNode()); + builder.Add(new IntermediateToken() + { + Content = "Hi", + Kind = TokenKind.Html, + }); + builder.Pop(); + + var pass = new InstrumentationPass() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), document); + + // Assert + Children( + document, + n => IntermediateNodeAssert.Html("Hi", n)); + } + + [Fact] + public void InstrumentationPass_InstrumentsHtml() + { + // Arrange + var document = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(document); + + builder.Push(new HtmlContentIntermediateNode() + { + Source = CreateSource(1), + }); + builder.Add(new IntermediateToken() + { + Content = "Hi", + Kind = TokenKind.Html, + Source = CreateSource(1) + }); + builder.Pop(); + + var pass = new InstrumentationPass() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), document); + + // Assert + Children( + document, + n => BeginInstrumentation("1, 1, true", n), + n => IntermediateNodeAssert.Html("Hi", n), + n => EndInstrumentation(n)); + } + + [Fact] + public void InstrumentationPass_SkipsHtml_WithoutLocation() + { + // Arrange + var document = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(document); + builder.Push(new HtmlContentIntermediateNode()); + builder.Add(new IntermediateToken() + { + Content = "Hi", + Kind = TokenKind.Html, + }); + builder.Pop(); + + var pass = new InstrumentationPass() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), document); + + // Assert + Children( + document, + n => IntermediateNodeAssert.Html("Hi", n)); + } + + [Fact] + public void InstrumentationPass_InstrumentsCSharpExpression() + { + // Arrange + var document = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(document); + builder.Push(new CSharpExpressionIntermediateNode() + { + Source = CreateSource(2), + }); + builder.Add(new IntermediateToken() + { + Content = "Hi", + Kind = TokenKind.CSharp, + }); + + var pass = new InstrumentationPass() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), document); + + // Assert + Children( + document, + n => BeginInstrumentation("2, 2, false", n), + n => CSharpExpression("Hi", n), + n => EndInstrumentation(n)); + } + + [Fact] + public void InstrumentationPass_SkipsCSharpExpression_WithoutLocation() + { + // Arrange + var document = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(document); + builder.Push(new CSharpExpressionIntermediateNode()); + builder.Add(new IntermediateToken() + { + Content = "Hi", + Kind = TokenKind.CSharp, + }); + + var pass = new InstrumentationPass() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), document); + + // Assert + Children( + document, + n => CSharpExpression("Hi", n)); + } + + [Fact] + public void InstrumentationPass_SkipsCSharpExpression_InsideTagHelperAttribute() + { + // Arrange + var document = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(document); + builder.Push(new TagHelperIntermediateNode()); + + builder.Push(new TagHelperHtmlAttributeIntermediateNode()); + + builder.Push(new CSharpExpressionIntermediateNode() + { + Source = CreateSource(5) + }); + + builder.Add(new IntermediateToken() + { + Content = "Hi", + Kind = TokenKind.CSharp, + }); + + var pass = new InstrumentationPass() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), document); + + // Assert + Children( + document, + n => + { + Assert.IsType(n); + Children( + n, + c => + { + Assert.IsType(c); + Children( + c, + s => CSharpExpression("Hi", s)); + }); + }); + } + + [Fact] + public void InstrumentationPass_SkipsCSharpExpression_InsideTagHelperProperty() + { + // Arrange + var document = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(document); + builder.Push(new TagHelperIntermediateNode()); + + builder.Push(new TagHelperPropertyIntermediateNode()); + + builder.Push(new CSharpExpressionIntermediateNode() + { + Source = CreateSource(5) + }); + + builder.Add(new IntermediateToken() + { + Content = "Hi", + Kind = TokenKind.CSharp, + }); + + var pass = new InstrumentationPass() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), document); + + // Assert + Children( + document, + n => + { + Assert.IsType(n); + Children( + n, + c => + { + Assert.IsType(c); + Children( + c, + s => CSharpExpression("Hi", s)); + }); + }); + } + + [Fact] + public void InstrumentationPass_InstrumentsTagHelper() + { + // Arrange + var document = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(document); + builder.Add(new TagHelperIntermediateNode() + { + Source = CreateSource(3), + }); + + var pass = new InstrumentationPass() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), document); + + // Assert + Children( + document, + n => BeginInstrumentation("3, 3, false", n), + n => Assert.IsType(n), + n => EndInstrumentation(n)); + } + + [Fact] + public void InstrumentationPass_SkipsTagHelper_WithoutLocation() + { + // Arrange + var document = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(document); + builder.Push(new TagHelperIntermediateNode()); + + var pass = new InstrumentationPass() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), document); + + // Assert + Children( + document, + n => Assert.IsType(n)); + } + + private SourceSpan CreateSource(int number) + { + // The actual source span doesn't really matter, we just want to see the values used. + return new SourceSpan(new SourceLocation(number, number, number), number); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs new file mode 100644 index 0000000000..1ff7ec5794 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs @@ -0,0 +1,961 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.IntegrationTests; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IntegrationTests +{ + public class CodeGenerationIntegrationTest : IntegrationTestBase + { + private readonly static CSharpCompilation DefaultBaseCompilation = MvcShim.BaseCompilation.WithAssemblyName("AppCode"); + + public CodeGenerationIntegrationTest() + : base(generateBaselines: null) + { + Configuration = RazorConfiguration.Create( + RazorLanguageVersion.Version_2_0, + "MVC-2.1", + new[] { new AssemblyExtension("MVC-2.1", typeof(ExtensionInitializer).Assembly) }); + } + + protected override CSharpCompilation BaseCompilation => DefaultBaseCompilation; + + protected override RazorConfiguration Configuration { get; } + + #region Runtime + + [Fact] + public void UsingDirectives_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false, throwOnFailure: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + var diagnostics = compiled.Compilation.GetDiagnostics().Where(d => d.Severity >= DiagnosticSeverity.Warning); + Assert.Equal("The using directive for 'System' appeared previously in this namespace", Assert.Single(diagnostics).GetMessage()); + } + + [Fact] + public void InvalidNamespaceAtEOF_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ1014", Assert.Single(diagnotics).Id); + } + + [Fact] + public void IncompleteDirectives_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyService +{ + public string Html { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + // We expect this test to generate a bunch of errors. + Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + } + + [Fact] + public void InheritsViewModel_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Razor; + +public class MyBasePageForViews : RazorPage +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} +public class MyModel +{ + +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void InheritsWithViewImports_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.RazorPages; + +public abstract class MyPageModel : Page +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} + +public class MyModel +{ + +}"); + AddProjectItemFromText(@"@inherits MyPageModel"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void MalformedPageDirective_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ1016", Assert.Single(diagnotics).Id); + } + + [Fact] + public void Basic_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void Sections_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void _ViewImports_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void Inject_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyApp +{ + public string MyProperty { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void InjectWithModel_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyService +{ + public string Html { get; set; } +} + +public class MyApp +{ + public string MyProperty { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void InjectWithSemicolon_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyApp +{ + public string MyProperty { get; set; } +} + +public class MyService +{ + public string Html { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void Model_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void ModelExpressionTagHelper_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void RazorPages_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class DivTagHelper : {typeof(TagHelper).FullName} +{{ + +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void RazorPagesWithRouteTemplate_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void RazorPagesWithoutModel_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class DivTagHelper : {typeof(TagHelper).FullName} +{{ + +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void PageWithNamespace_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void ViewWithNamespace_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void ViewComponentTagHelper_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class TestViewComponent +{{ + public string Invoke(string firstName) + {{ + return firstName; + }} +}} + +[{typeof(HtmlTargetElementAttribute).FullName}] +public class AllTagHelper : {typeof(TagHelper).FullName} +{{ + public string Bar {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void RazorPageWithNoLeadingPageDirective_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ3906", Assert.Single(diagnotics).Id); + } + #endregion + + #region DesignTime + + [Fact] + public void UsingDirectives_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true, throwOnFailure: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnostics = compiled.Compilation.GetDiagnostics().Where(d => d.Severity >= DiagnosticSeverity.Warning); + Assert.Equal("The using directive for 'System' appeared previously in this namespace", Assert.Single(diagnostics).GetMessage()); + } + + [Fact] + public void InvalidNamespaceAtEOF_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ1014", Assert.Single(diagnotics).Id); + } + + [Fact] + public void IncompleteDirectives_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyService +{ + public string Html { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + // We expect this test to generate a bunch of errors. + Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + } + + [Fact] + public void InheritsViewModel_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Razor; + +public class MyBasePageForViews : RazorPage +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} +public class MyModel +{ + +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void InheritsWithViewImports_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.RazorPages; + +public abstract class MyPageModel : Page +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} + +public class MyModel +{ + +}"); + + AddProjectItemFromText(@"@inherits MyPageModel"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void MalformedPageDirective_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ1016", Assert.Single(diagnotics).Id); + } + + [Fact] + public void Basic_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Sections_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void _ViewImports_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Inject_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyApp +{ + public string MyProperty { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void InjectWithModel_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyService +{ + public string Html { get; set; } +} + +public class MyApp +{ + public string MyProperty { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void InjectWithSemicolon_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyApp +{ + public string MyProperty { get; set; } +} + +public class MyService +{ + public string Html { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Model_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void MultipleModels_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class ThisShouldBeGenerated +{ + +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ2001", Assert.Single(diagnotics).Id); + } + + [Fact] + public void ModelExpressionTagHelper_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void RazorPages_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class DivTagHelper : {typeof(TagHelper).FullName} +{{ + +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void RazorPagesWithRouteTemplate_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void RazorPagesWithoutModel_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class DivTagHelper : {typeof(TagHelper).FullName} +{{ + +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void PageWithNamespace_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void ViewWithNamespace_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void ViewComponentTagHelper_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class TestViewComponent +{{ + public string Invoke(string firstName) + {{ + return firstName; + }} +}} + +[{typeof(HtmlTargetElementAttribute).FullName}] +public class AllTagHelper : {typeof(TagHelper).FullName} +{{ + public string Bar {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void RazorPageWithNoLeadingPageDirective_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ3906", Assert.Single(diagnotics).Id); + } + + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/InstrumentationPassIntegrationTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/InstrumentationPassIntegrationTest.cs new file mode 100644 index 0000000000..604100a335 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/InstrumentationPassIntegrationTest.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 System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.IntegrationTests; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IntegrationTests +{ + public class InstrumentationPassIntegrationTest : IntegrationTestBase + { + [Fact] + public void BasicTest() + { + // 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[] + { + builder => builder + .Name("value") + .PropertyName("FooProp") + .TypeName("System.String"), // Gets preallocated + builder => builder + .Name("date") + .PropertyName("BarProp") + .TypeName("System.DateTime"), // Doesn't get preallocated + }) + }; + + var engine = CreateProjectEngine(b => + { + b.AddTagHelpers(descriptors); + b.Features.Add(new InstrumentationPass()); + + // This test includes templates + b.AddTargetExtension(new TemplateTargetExtension()); + }); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var document = engine.Process(projectItem); + + // Assert + AssertDocumentNodeMatchesBaseline(document.GetDocumentIntermediateNode()); + + var csharpDocument = document.GetCSharpDocument(); + AssertCSharpDocumentMatchesBaseline(csharpDocument); + Assert.Empty(csharpDocument.Diagnostics); + } + + private static TagHelperDescriptor CreateTagHelperDescriptor( + string tagName, + string typeName, + string assemblyName, + IEnumerable> 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/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj new file mode 100644 index 0000000000..0fd06dcdfd --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj @@ -0,0 +1,52 @@ + + + + $(StandardTestTfms) + true + $(DefaultItemExcludes);TestFiles\** + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + Content + PreserveNewest + Build + + + + + + + + + + + + + + + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ModelDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ModelDirectiveTest.cs new file mode 100644 index 0000000000..eedc94d581 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ModelDirectiveTest.cs @@ -0,0 +1,343 @@ +// 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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class ModelDirectiveTest + { + [Fact] + public void ModelDirective_GetModelType_GetsTypeFromFirstWellFormedDirective() + { + // Arrange + var codeDocument = CreateDocument(@" +@model Type1 +@model Type2 +@model +"); + + var engine = CreateEngine(); + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = ModelDirective.GetModelType(irDocument); + + // Assert + Assert.Equal("Type1", result); + } + + [Fact] + public void ModelDirective_GetModelType_DefaultsToDynamic() + { + // Arrange + var codeDocument = CreateDocument(@" "); + + var engine = CreateEngine(); + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = ModelDirective.GetModelType(irDocument); + + // Assert + Assert.Equal("dynamic", result); + } + + [Fact] + public void ModelDirectivePass_Execute_ReplacesTModelInBaseType() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +@model Type1 +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_Execute_ReplacesTModelInBaseType_DifferentOrdering() + { + // Arrange + var codeDocument = CreateDocument(@" +@model Type1 +@inherits BaseType +@model Type2 +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_Execute_NoOpWithoutTModel() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +@model Type1 +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_Execute_ReplacesTModelInBaseType_DefaultDynamic() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_DesignTime_AddsTModelUsingDirective() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +"); + + var engine = CreateDesignTimeEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + + var @namespace = FindNamespaceNode(irDocument); + var usingNode = Assert.IsType(@namespace.Children[0]); + Assert.Equal($"TModel = global::{typeof(object).FullName}", usingNode.Content); + } + + [Fact] + public void ModelDirectivePass_DesignTime_WithModel_AddsTModelUsingDirective() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +@model SomeType +"); + + var engine = CreateDesignTimeEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + + var @namespace = FindNamespaceNode(irDocument); + var usingNode = Assert.IsType(@namespace.Children[0]); + Assert.Equal($"TModel = global::System.Object", usingNode.Content); + } + + private RazorCodeDocument CreateDocument(string content) + { + var source = RazorSourceDocument.Create(content, "test.cshtml"); + return RazorCodeDocument.Create(source); + } + + private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node) + { + var visitor = new ClassNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private NamespaceDeclarationIntermediateNode FindNamespaceNode(IntermediateNode node) + { + var visitor = new NamespaceNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private RazorEngine CreateEngine() + { + return CreateEngineCore(); + } + + private RazorEngine CreateDesignTimeEngine() + { + return CreateEngineCore(designTime: true); + } + + private RazorEngine CreateEngineCore(bool designTime = false) + { + return RazorProjectEngine.Create(b => + { + // Notice we're not registering the ModelDirective.Pass here so we can run it on demand. + b.AddDirective(ModelDirective.Directive); + + // There's some special interaction with the inherits directive + InheritsDirective.Register(b); + + b.Features.Add(new DesignTimeOptionsFeature(designTime)); + }).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 IRazorDocumentClassifierPhase) + { + break; + } + } + + // InheritsDirectivePass needs to run before ModelDirective. + var pass = new InheritsDirectivePass() + { + Engine = engine + }; + pass.Execute(codeDocument, codeDocument.GetDocumentIntermediateNode()); + + return codeDocument.GetDocumentIntermediateNode(); + } + + private string GetCSharpContent(IntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + var child = node.Children[i] as IntermediateToken; + if (child.Kind == TokenKind.CSharp) + { + builder.Append(child.Content); + } + } + + return builder.ToString(); + } + + private class ClassNodeVisitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Node { get; set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Node = node; + } + } + + private class NamespaceNodeVisitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Node { get; set; } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + Node = node; + } + } + + 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/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ModelExpressionPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ModelExpressionPassTest.cs new file mode 100644 index 0000000000..d18984c900 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ModelExpressionPassTest.cs @@ -0,0 +1,208 @@ +// 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 System.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class ModelExpressionPassTest + { + [Fact] + public void ModelExpressionPass_NonModelExpressionProperty_Ignored() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BoundAttributeDescriptor(attribute => + attribute + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => + rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ModelExpressionPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + var setProperty = tagHelper.Children.OfType().Single(); + + var token = Assert.IsType(Assert.Single(setProperty.Children)); + Assert.True(token.IsCSharp); + Assert.Equal("17", token.Content); + } + + [Fact] + public void ModelExpressionPass_ModelExpressionProperty_SimpleExpression() + { + // Arrange + + // Using \r\n here because we verify line mappings + var codeDocument = CreateDocument( + "@addTagHelper TestTagHelper, TestAssembly\r\n

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BoundAttributeDescriptor(attribute => + attribute + .Name("Foo") + .TypeName("Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression")) + .TagMatchingRuleDescriptor(rule => + rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ModelExpressionPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + var setProperty = tagHelper.Children.OfType().Single(); + + var expression = Assert.IsType(Assert.Single(setProperty.Children)); + Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Bar)", GetCSharpContent(expression)); + + var originalNode = Assert.IsType(expression.Children[2]); + Assert.Equal(TokenKind.CSharp, originalNode.Kind); + Assert.Equal("Bar", originalNode.Content); + Assert.Equal(new SourceSpan("test.cshtml", 51, 1, 8, 3), originalNode.Source.Value); + } + + [Fact] + public void ModelExpressionPass_ModelExpressionProperty_ComplexExpression() + { + // Arrange + + // Using \r\n here because we verify line mappings + var codeDocument = CreateDocument( + "@addTagHelper TestTagHelper, TestAssembly\r\n

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BoundAttributeDescriptor(attribute => + attribute + .Name("Foo") + .TypeName("Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression")) + .TagMatchingRuleDescriptor(rule => + rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ModelExpressionPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + var setProperty = tagHelper.Children.OfType().Single(); + + var expression = Assert.IsType(Assert.Single(setProperty.Children)); + Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => Bar)", GetCSharpContent(expression)); + + var originalNode = Assert.IsType(expression.Children[1]); + Assert.Equal(TokenKind.CSharp, originalNode.Kind); + Assert.Equal("Bar", originalNode.Content); + Assert.Equal(new SourceSpan("test.cshtml", 52, 1, 9, 3), originalNode.Source.Value); + } + + 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 string GetCSharpContent(IntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + var child = node.Children[i] as IntermediateToken; + if (child.Kind == TokenKind.CSharp) + { + builder.Append(child.Content); + } + } + + return builder.ToString(); + } + + private class TagHelperNodeVisitor : IntermediateNodeWalker + { + public TagHelperIntermediateNode Node { get; set; } + + public override void VisitTagHelper(TagHelperIntermediateNode node) + { + Node = node; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcImportProjectFeatureTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcImportProjectFeatureTest.cs new file mode 100644 index 0000000000..13c686adf9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcImportProjectFeatureTest.cs @@ -0,0 +1,76 @@ +// 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; +using Moq; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class MvcImportProjectFeatureTest + { + [Fact] + public void AddDefaultDirectivesImport_AddsSingleDynamicImport() + { + // Arrange + var imports = new List(); + + // Act + MvcImportProjectFeature.AddDefaultDirectivesImport(imports); + + // Assert + var import = Assert.Single(imports); + Assert.Null(import.FilePath); + } + + [Fact] + public void AddHierarchicalImports_AddsViewImportSourceDocumentsOnDisk() + { + // Arrange + var imports = new List(); + var projectItem = new TestRazorProjectItem("/Contact/Index.cshtml"); + var testFileSystem = new TestRazorProjectFileSystem(new[] + { + new TestRazorProjectItem("/Index.cshtml"), + new TestRazorProjectItem("/_ViewImports.cshtml"), + new TestRazorProjectItem("/Contact/_ViewImports.cshtml"), + projectItem, + }); + var mvcImportFeature = new MvcImportProjectFeature() + { + ProjectEngine = Mock.Of(projectEngine => projectEngine.FileSystem == testFileSystem) + }; + + // Act + mvcImportFeature.AddHierarchicalImports(projectItem, imports); + + // Assert + Assert.Collection(imports, + import => Assert.Equal("/_ViewImports.cshtml", import.FilePath), + import => Assert.Equal("/Contact/_ViewImports.cshtml", import.FilePath)); + } + + [Fact] + public void AddHierarchicalImports_AddsViewImportSourceDocumentsNotOnDisk() + { + // Arrange + var imports = new List(); + var projectItem = new TestRazorProjectItem("/Pages/Contact/Index.cshtml"); + var testFileSystem = new TestRazorProjectFileSystem(new[] { projectItem }); + var mvcImportFeature = new MvcImportProjectFeature() + { + ProjectEngine = Mock.Of(projectEngine => projectEngine.FileSystem == testFileSystem) + }; + + // Act + mvcImportFeature.AddHierarchicalImports(projectItem, imports); + + // Assert + Assert.Collection(imports, + import => Assert.Equal("/_ViewImports.cshtml", import.FilePath), + import => Assert.Equal("/Pages/_ViewImports.cshtml", import.FilePath), + import => Assert.Equal("/Pages/Contact/_ViewImports.cshtml", import.FilePath)); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcShim.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcShim.cs new file mode 100644 index 0000000000..acbdea28f3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcShim.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 System.IO; +using System.Reflection; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + internal static class MvcShim + { + public static readonly string AssemblyName = "Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X"; + + private static Assembly _assembly; + private static CSharpCompilation _baseCompilation; + + public static Assembly Assembly + { + get + { + if (_assembly == null) + { + var filePath = Path.Combine(Directory.GetCurrentDirectory(), AssemblyName + ".dll"); + _assembly = Assembly.LoadFrom(filePath); + } + + return _assembly; + } + } + + public static CSharpCompilation BaseCompilation + { + get + { + if (_baseCompilation == null) + { + _baseCompilation = TestCompilation.Create(Assembly); + } + + return _baseCompilation; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcViewDocumentClassifierPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcViewDocumentClassifierPassTest.cs new file mode 100644 index 0000000000..2d437c158d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/MvcViewDocumentClassifierPassTest.cs @@ -0,0 +1,264 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class MvcViewDocumentClassifierPassTest + { + [Fact] + public void MvcViewDocumentClassifierPass_SetsDocumentKind() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("mvc.1.0.view", irDocument.DocumentKind); + } + + [Fact] + public void MvcViewDocumentClassifierPass_NoOpsIfDocumentKindIsAlreadySet() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + irDocument.DocumentKind = "some-value"; + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("some-value", irDocument.DocumentKind); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SetsNamespace() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("AspNetCore", visitor.Namespace.Content); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("Test", visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_NullFilePath_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("AspNetCore_d9f877a857a7e9928eac04d09a59f25967624155", visitor.Class.ClassName); + } + + [Theory] + [InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")] + [InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")] + public void MvcViewDocumentClassifierPass_UsesRelativePathToGenerateTypeName(string relativePath, string expected) + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: relativePath); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal(expected, visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_UsesAbsolutePath_IfRelativePathIsNotSet() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x::\application\Views\Home\Index.cshtml", relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("x___application_Views_Home_Index", visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SanitizesClassName() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x:\Test.cshtml", relativePath: "path.with+invalid-chars"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("path_with_invalid_chars", visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SetsUpExecuteAsyncMethod() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("ExecuteAsync", visitor.Method.MethodName); + Assert.Equal("global::System.Threading.Tasks.Task", visitor.Method.ReturnType); + Assert.Equal(new[] { "public", "async", "override" }, visitor.Method.Modifiers); + } + + private static RazorProjectEngine CreateProjectEngine() => RazorProjectEngine.Create(); + + private static DocumentIntermediateNode CreateIRDocument(RazorProjectEngine projectEngine, RazorCodeDocument codeDocument) + { + for (var i = 0; i < projectEngine.Phases.Count; i++) + { + var phase = projectEngine.Phases[i]; + phase.Execute(codeDocument); + + if (phase is IRazorIntermediateNodeLoweringPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + + private class Visitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Namespace { get; private set; } + + public ClassDeclarationIntermediateNode Class { get; private set; } + + public MethodDeclarationIntermediateNode Method { get; private set; } + + public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node) + { + Method = node; + } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + Namespace = node; + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Class = node; + base.VisitClassDeclaration(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/NamespaceDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/NamespaceDirectiveTest.cs new file mode 100644 index 0000000000..8e5d76c678 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/NamespaceDirectiveTest.cs @@ -0,0 +1,352 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Moq; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class NamespaceDirectiveTest + { + [Fact] + public void GetNamespace_IncompleteDirective_UsesEmptyNamespace() + { + // Arrange + var source = "c:\\foo\\bar\\bleh.cshtml"; + var imports = "c:\\foo\\baz\\bleh.cshtml"; + var node = new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + + // Act + var @namespace = NamespaceDirective.GetNamespace(source, node); + + // Assert + Assert.Equal(string.Empty, @namespace); + } + + [Fact] + public void GetNamespace_EmptyDirective_UsesEmptyNamespace() + { + // Arrange + var source = "c:\\foo\\bar\\bleh.cshtml"; + var imports = "c:\\foo\\baz\\bleh.cshtml"; + var node = new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + node.Children.Add(new DirectiveTokenIntermediateNode() { Content = string.Empty }); + + // Act + var @namespace = NamespaceDirective.GetNamespace(source, node); + + // Assert + Assert.Equal(string.Empty, @namespace); + } + + // When we don't have a relationship between the source file and the imports file + // we will just use the namespace on the node directly. + [Theory] + [InlineData((string)null, (string)null)] + [InlineData("", "")] + [InlineData(null, "/foo/bar")] + [InlineData("/foo/baz", "/foo/bar/bleh")] + [InlineData("/foo.cshtml", "/foo/bar.cshtml")] + [InlineData("c:\\foo.cshtml", "d:\\foo\\bar.cshtml")] + [InlineData("c:\\foo\\bar\\bleh.cshtml", "c:\\foo\\baz\\bleh.cshtml")] + public void GetNamespace_ForNonRelatedFiles_UsesNamespaceVerbatim(string source, string imports) + { + // Arrange + var node = new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + + node.Children.Add(new DirectiveTokenIntermediateNode() { Content = "Base" }); + + // Act + var @namespace = NamespaceDirective.GetNamespace(source, node); + + // Assert + Assert.Equal("Base", @namespace); + } + + [Theory] + [InlineData("/foo.cshtml", "/_ViewImports.cshtml", "Base")] + [InlineData("/foo/bar.cshtml", "/_ViewImports.cshtml", "Base.foo")] + [InlineData("/foo/bar/baz.cshtml", "/_ViewImports.cshtml", "Base.foo.bar")] + [InlineData("/foo/bar/baz.cshtml", "/foo/_ViewImports.cshtml", "Base.bar")] + [InlineData("/Foo/bar/baz.cshtml", "/foo/_ViewImports.cshtml", "Base.bar")] + [InlineData("c:\\foo.cshtml", "c:\\_ViewImports.cshtml", "Base")] + [InlineData("c:\\foo\\bar.cshtml", "c:\\_ViewImports.cshtml", "Base.foo")] + [InlineData("c:\\foo\\bar\\baz.cshtml", "c:\\_ViewImports.cshtml", "Base.foo.bar")] + [InlineData("c:\\foo\\bar\\baz.cshtml", "c:\\foo\\_ViewImports.cshtml", "Base.bar")] + [InlineData("c:\\Foo\\bar\\baz.cshtml", "c:\\foo\\_ViewImports.cshtml", "Base.bar")] + public void GetNamespace_ForRelatedFiles_ComputesNamespaceWithSuffix(string source, string imports, string expected) + { + // Arrange + var node = new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + + node.Children.Add(new DirectiveTokenIntermediateNode() { Content = "Base" }); + + // Act + var @namespace = NamespaceDirective.GetNamespace(source, node); + + // Assert + Assert.Equal(expected, @namespace); + } + + // This is the case where a _ViewImports sets the namespace. + [Fact] + public void Pass_SetsNamespace_ComputedFromImports() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account.Manage", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + // This is the case where the source file sets the namespace. + [Fact] + public void Pass_SetsNamespace_ComputedFromSource() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + // This will be ignored. + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "ignored" }); + builder.Pop(); + + // This will be used. + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/Manage/AddUser.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account.Manage" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account.Manage", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + // Handles cases where invalid characters appears in FileNames. Note that we don't sanitize the part of + // the namespace that you put in an import, just the file-based-suffix. Garbage in, garbage out. + [Fact] + public void Pass_SetsNamespace_SanitizesClassAndNamespace() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage-Info/Add+User.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account.Manage_Info", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + // This is the case where the source file sets the namespace. + [Fact] + public void Pass_SetsNamespace_ComputedFromSource_ForView() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + // This will be ignored. + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "ignored" }); + builder.Pop(); + + // This will be used. + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/Manage/AddUser.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account.Manage" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account.Manage", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + // This handles an error case where we can't determine the relationship between the + // imports and the source. + [Fact] + public void Pass_SetsNamespace_VerbatimFromImports() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(null, 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + [Fact] + public void Pass_DoesNothing_ForUnknownDocumentKind() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(null, 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = null; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("default", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/PageDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/PageDirectiveTest.cs new file mode 100644 index 0000000000..1bdb156298 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/PageDirectiveTest.cs @@ -0,0 +1,148 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class PageDirectiveTest + { + [Fact] + public void TryGetPageDirective_ReturnsTrue_IfPageIsMalformed() + { + // Arrange + var content = "@page \"some-route-template\" Invalid"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Equal("some-route-template", pageDirective.RouteTemplate); + Assert.NotNull(pageDirective.DirectiveNode); + } + + [Fact] + public void TryGetPageDirective_ReturnsTrue_IfPageIsImported() + { + // Arrange + var content = "Hello world"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var importDocument = RazorSourceDocument.Create("@page", "imports.cshtml"); + var codeDocument = RazorCodeDocument.Create(sourceDocument, new[] { importDocument }); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Null(pageDirective.RouteTemplate); + } + + [Fact] + public void TryGetPageDirective_ReturnsFalse_IfPageDoesNotHaveDirective() + { + // Arrange + var content = "Hello world"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.False(result); + Assert.Null(pageDirective); + } + + [Fact] + public void TryGetPageDirective_ReturnsTrue_IfPageDoesStartWithDirective() + { + // Arrange + var content = "Hello @page"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Null(pageDirective.RouteTemplate); + Assert.NotNull(pageDirective.DirectiveNode); + } + + [Fact] + public void TryGetPageDirective_ReturnsTrue_IfContentHasDirective() + { + // Arrange + var content = "@page"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Null(pageDirective.RouteTemplate); + } + + [Fact] + public void TryGetPageDirective_ParsesRouteTemplate() + { + // Arrange + var content = "@page \"some-route-template\""; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Equal("some-route-template", pageDirective.RouteTemplate); + } + + private RazorEngine CreateEngine() + { + return RazorProjectEngine.Create(b => + { + PageDirective.Register(b); + }).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 IRazorDocumentClassifierPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..3337ebeac2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/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/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/RazorPageDocumentClassifierPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/RazorPageDocumentClassifierPassTest.cs new file mode 100644 index 0000000000..74acfa0c13 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/RazorPageDocumentClassifierPassTest.cs @@ -0,0 +1,417 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class RazorPageDocumentClassifierPassTest + { + [Fact] + public void RazorPageDocumentClassifierPass_LogsErrorForImportedPageDirectives() + { + // Arrange + var sourceSpan = new SourceSpan("import.cshtml", 0, 0, 0, 5); + var expectedDiagnostic = RazorExtensionsDiagnosticFactory.CreatePageDirective_CannotBeImported(sourceSpan); + var importDocument = RazorSourceDocument.Create("@page", "import.cshtml"); + var sourceDocument = RazorSourceDocument.Create("

Hello World

", "main.cshtml"); + var codeDocument = RazorCodeDocument.Create(sourceDocument, new[] { importDocument }); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive); + var directive = Assert.Single(pageDirectives); + var diagnostic = Assert.Single(directive.Node.Diagnostics); + Assert.Equal(expectedDiagnostic, diagnostic); + } + + [Fact] + public void RazorPageDocumentClassifierPass_LogsErrorIfDirectiveNotAtTopOfFile() + { + // Arrange + var sourceSpan = new SourceSpan( + "Test.cshtml", + absoluteIndex: 14 + Environment.NewLine.Length * 2, + lineIndex: 2, + characterIndex: 0, + length: 5 + Environment.NewLine.Length); + + var expectedDiagnostic = RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(sourceSpan); + var content = @" +@somethingelse +@page +"; + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive); + var directive = Assert.Single(pageDirectives); + var diagnostic = Assert.Single(directive.Node.Diagnostics); + Assert.Equal(expectedDiagnostic, diagnostic); + } + + [Fact] + public void RazorPageDocumentClassifierPass_DoesNotLogErrorIfCommentAndWhitespaceBeforeDirective() + { + // Arrange + var content = @" +@* some comment *@ + +@page +"; + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive); + var directive = Assert.Single(pageDirectives); + Assert.Empty(directive.Node.Diagnostics); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SetsDocumentKind() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("mvc.1.0.razor-page", irDocument.DocumentKind); + } + + [Fact] + public void RazorPageDocumentClassifierPass_NoOpsIfDocumentKindIsAlreadySet() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + irDocument.DocumentKind = "some-value"; + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("some-value", irDocument.DocumentKind); + } + + [Fact] + public void RazorPageDocumentClassifierPass_NoOpsIfPageDirectiveIsMalformed() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page+1", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + irDocument.DocumentKind = "some-value"; + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("some-value", irDocument.DocumentKind); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SetsNamespace() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("AspNetCore", visitor.Namespace.Content); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.RazorPages.Page", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("Test", visitor.Class.ClassName); + } + + [Fact] + public void RazorPageDocumentClassifierPass_NullFilePath_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.RazorPages.Page", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("AspNetCore_74fbaab062bb228ed1ab09c5ff8d6ed2417320e2", visitor.Class.ClassName); + } + + [Theory] + [InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")] + [InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")] + public void RazorPageDocumentClassifierPass_UsesRelativePathToGenerateTypeName(string relativePath, string expected) + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: relativePath); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal(expected, visitor.Class.ClassName); + } + + [Fact] + public void RazorPageDocumentClassifierPass_UsesAbsolutePath_IfRelativePathIsNotSet() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x::\application\Views\Home\Index.cshtml", relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("x___application_Views_Home_Index", visitor.Class.ClassName); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SanitizesClassName() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x:\Test.cshtml", relativePath: "path.with+invalid-chars"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("path_with_invalid_chars", visitor.Class.ClassName); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SetsUpExecuteAsyncMethod() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("ExecuteAsync", visitor.Method.MethodName); + Assert.Equal("global::System.Threading.Tasks.Task", visitor.Method.ReturnType); + Assert.Equal(new[] { "public", "async", "override" }, visitor.Method.Modifiers); + } + + [Fact] + public void RazorPageDocumentClassifierPass_AddsRouteTemplateMetadata() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page \"some-route\"", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + var attributeNode = Assert.IsType(visitor.ExtensionNode); + Assert.Equal("RouteTemplate", attributeNode.Key); + Assert.Equal("some-route", attributeNode.Value); + } + + private static RazorEngine CreateEngine() + { + return RazorProjectEngine.Create(b => + { + PageDirective.Register(b); + }).Engine; + } + + private static 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 IRazorIntermediateNodeLoweringPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + + private class Visitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Namespace { get; private set; } + + public ClassDeclarationIntermediateNode Class { get; private set; } + + public MethodDeclarationIntermediateNode Method { get; private set; } + + public ExtensionIntermediateNode ExtensionNode { get; private set; } + + public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node) + { + Method = node; + } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + Namespace = node; + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Class = node; + base.VisitClassDeclaration(node); + } + + public override void VisitExtension(ExtensionIntermediateNode node) + { + ExtensionNode = node; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/SourceMappingsSerializer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/SourceMappingsSerializer.cs new file mode 100644 index 0000000000..8c63fd7444 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/SourceMappingsSerializer.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 System; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public static class SourceMappingsSerializer + { + public static string Serialize(RazorCSharpDocument csharpDocument, RazorSourceDocument sourceDocument) + { + var builder = new StringBuilder(); + var sourceFilePath = sourceDocument.FilePath; + var charBuffer = new char[sourceDocument.Length]; + sourceDocument.CopyTo(0, charBuffer, 0, sourceDocument.Length); + var sourceContent = new string(charBuffer); + + for (var i = 0; i < csharpDocument.SourceMappings.Count; i++) + { + var sourceMapping = csharpDocument.SourceMappings[i]; + if (!string.Equals(sourceMapping.OriginalSpan.FilePath, sourceFilePath, StringComparison.Ordinal)) + { + continue; + } + + builder.Append("Source Location: "); + AppendMappingLocation(builder, sourceMapping.OriginalSpan, sourceContent); + + builder.Append("Generated Location: "); + AppendMappingLocation(builder, sourceMapping.GeneratedSpan, csharpDocument.GeneratedCode); + + builder.AppendLine(); + } + + return builder.ToString(); + } + + private static void AppendMappingLocation(StringBuilder builder, SourceSpan location, string content) + { + builder + .AppendLine(location.ToString()) + .Append("|"); + + for (var i = 0; i < location.Length; i++) + { + builder.Append(content[location.AbsoluteIndex + i]); + } + + builder.AppendLine("|"); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TagHelperDescriptorExtensionsTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TagHelperDescriptorExtensionsTest.cs new file mode 100644 index 0000000000..af0b983b55 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TagHelperDescriptorExtensionsTest.cs @@ -0,0 +1,82 @@ +// 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; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class TagHelperDescriptorExtensionsTest + { + [Fact] + public void IsViewComponentKind_ReturnsFalse_ForNonVCTHDescriptor() + { + // Arrange + var tagHelper = CreateTagHelperDescriptor(); + + // Act + var result = tagHelper.IsViewComponentKind(); + + // Assert + Assert.False(result); + } + + [Fact] + public void IsViewComponentKind_ReturnsTrue_ForVCTHDescriptor() + { + // Arrange + var tagHelper = CreateViewComponentTagHelperDescriptor(); + + // Act + var result = tagHelper.IsViewComponentKind(); + + // Assert + Assert.True(result); + } + + [Fact] + public void GetViewComponentName_ReturnsNull_ForNonVCTHDescriptor() + { + //Arrange + var tagHelper = CreateTagHelperDescriptor(); + + // Act + var result = tagHelper.GetViewComponentName(); + + // Assert + Assert.Null(result); + } + + [Fact] + public void GetViewComponentName_ReturnsName_ForVCTHDescriptor() + { + // Arrange + var tagHelper = CreateViewComponentTagHelperDescriptor("ViewComponentName"); + + // Act + var result = tagHelper.GetViewComponentName(); + + // Assert + Assert.Equal("ViewComponentName", result); + } + + private static TagHelperDescriptor CreateTagHelperDescriptor() + { + var tagHelper = TagHelperDescriptorBuilder.Create("TypeName", "AssemblyName") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name")) + .Build(); + + return tagHelper; + } + + private static TagHelperDescriptor CreateViewComponentTagHelperDescriptor(string name = "ViewComponentName") + { + var tagHelper = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TypeName", "AssemblyName") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, name) + .Build(); + + return tagHelper; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml new file mode 100644 index 0000000000..a20b20dae8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml @@ -0,0 +1,8 @@ +
+ Hello world + @string.Format("{0}", "Hello") +
+@{ + var cls = "foo"; +} +

diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs new file mode 100644 index 0000000000..d39b64c26d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs @@ -0,0 +1,71 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + __o = this.ToString(); + +#line default +#line hidden +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" +__o = string.Format("{0}", "Hello"); + +#line default +#line hidden +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + + var cls = "foo"; + +#line default +#line hidden +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + if(cls != null) { + +#line default +#line hidden +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + __o = cls; + +#line default +#line hidden +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + } + +#line default +#line hidden + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt new file mode 100644 index 0000000000..4074239b9f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt @@ -0,0 +1,64 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (0:0,0 [4] Basic.cshtml) + IntermediateToken - (0:0,0 [4] Basic.cshtml) - Html -

+ IntermediateToken - (30:0,30 [23] Basic.cshtml) - Html - \n Hello world\n + CSharpExpression - (54:2,5 [29] Basic.cshtml) + IntermediateToken - (54:2,5 [29] Basic.cshtml) - CSharp - string.Format("{0}", "Hello") + HtmlContent - (83:2,34 [10] Basic.cshtml) + IntermediateToken - (83:2,34 [2] Basic.cshtml) - Html - \n + IntermediateToken - (85:3,0 [6] Basic.cshtml) - Html -
+ IntermediateToken - (91:3,6 [2] Basic.cshtml) - Html - \n + CSharpCode - (95:4,2 [25] Basic.cshtml) + IntermediateToken - (95:4,2 [25] Basic.cshtml) - CSharp - \n var cls = "foo";\n + HtmlContent - (123:7,0 [2] Basic.cshtml) + IntermediateToken - (123:7,0 [2] Basic.cshtml) - Html -

+ IntermediateToken - (162:7,39 [2] Basic.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt new file mode 100644 index 0000000000..372b49cb6f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt @@ -0,0 +1,34 @@ +Source Location: (13:0,13 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|this.ToString()| +Generated Location: (1030:26,13 [15] ) +|this.ToString()| + +Source Location: (54:2,5 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|string.Format("{0}", "Hello")| +Generated Location: (1166:31,6 [29] ) +|string.Format("{0}", "Hello")| + +Source Location: (95:4,2 [25] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +| + var cls = "foo"; +| +Generated Location: (1312:36,2 [25] ) +| + var cls = "foo"; +| + +Source Location: (134:7,11 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|if(cls != null) { | +Generated Location: (1460:42,11 [18] ) +|if(cls != null) { | + +Source Location: (153:7,30 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|cls| +Generated Location: (1622:47,30 [3] ) +|cls| + +Source Location: (156:7,33 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +| }| +Generated Location: (1773:52,33 [2] ) +| }| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs new file mode 100644 index 0000000000..8e6b1a7bd7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs @@ -0,0 +1,95 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "6d079dd6c39f39d17a2faff14404b37ab7e8b8fc" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"6d079dd6c39f39d17a2faff14404b37ab7e8b8fc", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(0, 4, true); + WriteLiteral("

+ IntermediateToken - (30:0,30 [19] Basic.cshtml) - Html - \n Hello world\n + IntermediateToken - (49:2,0 [4] Basic.cshtml) - Html - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(54, 29, false); + CSharpExpression - (54:2,5 [29] Basic.cshtml) + IntermediateToken - (54:2,5 [29] Basic.cshtml) - CSharp - string.Format("{0}", "Hello") + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(83, 10, true); + HtmlContent - (83:2,34 [10] Basic.cshtml) + IntermediateToken - (83:2,34 [2] Basic.cshtml) - Html - \n + IntermediateToken - (85:3,0 [6] Basic.cshtml) - Html -
+ IntermediateToken - (91:3,6 [2] Basic.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - (95:4,2 [25] Basic.cshtml) + IntermediateToken - (95:4,2 [25] Basic.cshtml) - CSharp - \n var cls = "foo";\n + CSharpCode - + IntermediateToken - - CSharp - BeginContext(123, 2, true); + HtmlContent - (123:7,0 [2] Basic.cshtml) + IntermediateToken - (123:7,0 [2] Basic.cshtml) - Html -

+ IntermediateToken - (162:7,39 [2] Basic.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml new file mode 100644 index 0000000000..224242197b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml @@ -0,0 +1,15 @@ +@* These test files validate that end-to-end, incomplete directives don't throw. *@ + +@page +@page +@page " + +@model +@model + +@inject +@inject +@inject MyService + +@namespace +@namespace diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs new file mode 100644 index 0000000000..dd100bee00 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs @@ -0,0 +1,71 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { +#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..1cfef392ae --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt @@ -0,0 +1,12 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ2001: The 'page' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,1): Error RZ2001: The 'page' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,7): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,1): Error RZ2001: The 'model' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,8): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,8): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,9): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,26): Error RZ1015: The 'inject' directive expects an identifier. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,11): Error RZ1014: The 'namespace' directive expects a namespace name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,1): Error RZ2001: The 'namespace' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,12): Error RZ1014: The 'namespace' directive expects a namespace name. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt new file mode 100644 index 0000000000..2aeddc2fa2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt @@ -0,0 +1,84 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (119:6,6 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (128:7,7 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (139:9,7 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (149:10,8 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (159:11,8 [17] IncompleteDirectives.cshtml) - MyService + DirectiveToken - (176:11,25 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (190:13,10 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (203:14,11 [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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) + IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page + MalformedDirective - (102:4,0 [6] IncompleteDirectives.cshtml) - page + HtmlContent - (108:4,6 [5] IncompleteDirectives.cshtml) + IntermediateToken - (108:4,6 [5] IncompleteDirectives.cshtml) - Html - "\n\n + MalformedDirective - (113:6,0 [6] IncompleteDirectives.cshtml) - model + DirectiveToken - (119:6,6 [0] IncompleteDirectives.cshtml) - + HtmlContent - (119:6,6 [2] IncompleteDirectives.cshtml) + IntermediateToken - (119:6,6 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (121:7,0 [7] IncompleteDirectives.cshtml) - model + DirectiveToken - (128:7,7 [0] IncompleteDirectives.cshtml) - + HtmlContent - (128:7,7 [4] IncompleteDirectives.cshtml) + IntermediateToken - (128:7,7 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (132:9,0 [7] IncompleteDirectives.cshtml) - inject + DirectiveToken - (139:9,7 [0] IncompleteDirectives.cshtml) - + HtmlContent - (139:9,7 [2] IncompleteDirectives.cshtml) + IntermediateToken - (139:9,7 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (141:10,0 [8] IncompleteDirectives.cshtml) - inject + DirectiveToken - (149:10,8 [0] IncompleteDirectives.cshtml) - + HtmlContent - (149:10,8 [2] IncompleteDirectives.cshtml) + IntermediateToken - (149:10,8 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (151:11,0 [25] IncompleteDirectives.cshtml) - inject + DirectiveToken - (159:11,8 [17] IncompleteDirectives.cshtml) - MyService + DirectiveToken - (176:11,25 [0] IncompleteDirectives.cshtml) - + HtmlContent - (176:11,25 [4] IncompleteDirectives.cshtml) + IntermediateToken - (176:11,25 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (180:13,0 [10] IncompleteDirectives.cshtml) - namespace + DirectiveToken - (190:13,10 [0] IncompleteDirectives.cshtml) - + HtmlContent - (190:13,10 [2] IncompleteDirectives.cshtml) + IntermediateToken - (190:13,10 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (192:14,0 [11] IncompleteDirectives.cshtml) - namespace + DirectiveToken - (203:14,11 [0] IncompleteDirectives.cshtml) - + HtmlContent - (203:14,11 [2] IncompleteDirectives.cshtml) + IntermediateToken - (203:14,11 [2] IncompleteDirectives.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt new file mode 100644 index 0000000000..4bb61bf781 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt @@ -0,0 +1,40 @@ +Source Location: (119:6,6 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (671:18,0 [0] ) +|| + +Source Location: (128:7,7 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (724:21,0 [0] ) +|| + +Source Location: (139:9,7 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (777:24,0 [0] ) +|| + +Source Location: (149:10,8 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (830:27,0 [0] ) +|| + +Source Location: (159:11,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|MyService| +Generated Location: (980:31,0 [17] ) +|MyService| + +Source Location: (176:11,25 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (1133:38,0 [0] ) +|| + +Source Location: (190:13,10 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (1186:41,0 [0] ) +|| + +Source Location: (203:14,11 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (1239:44,0 [0] ) +|| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs new file mode 100644 index 0000000000..743eed291e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs @@ -0,0 +1,65 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5add9dba0a182cd75498c5b24f64a2547e7f49b0" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"5add9dba0a182cd75498c5b24f64a2547e7f49b0", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(83, 4, true); + WriteLiteral("\r\n\r\n"); + EndContext(); + BeginContext(108, 5, true); + WriteLiteral("\"\r\n\r\n"); + EndContext(); + BeginContext(119, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(128, 4, true); + WriteLiteral("\r\n\r\n"); + EndContext(); + BeginContext(139, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(149, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(176, 4, true); + WriteLiteral("\r\n\r\n"); + EndContext(); + BeginContext(190, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(203, 2, true); + WriteLiteral("\r\n"); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt new file mode 100644 index 0000000000..1cfef392ae --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt @@ -0,0 +1,12 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ2001: The 'page' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,1): Error RZ2001: The 'page' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,7): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,1): Error RZ2001: The 'model' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,8): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,8): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,9): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,26): Error RZ1015: The 'inject' directive expects an identifier. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,11): Error RZ1014: The 'namespace' directive expects a namespace name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,1): Error RZ2001: The 'namespace' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,12): Error RZ1014: The 'namespace' directive expects a namespace name. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt new file mode 100644 index 0000000000..bd3bdd87e2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt @@ -0,0 +1,95 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(83, 4, true); + HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) + IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page + MalformedDirective - (102:4,0 [6] IncompleteDirectives.cshtml) - page + CSharpCode - + IntermediateToken - - CSharp - BeginContext(108, 5, true); + HtmlContent - (108:4,6 [5] IncompleteDirectives.cshtml) + IntermediateToken - (108:4,6 [5] IncompleteDirectives.cshtml) - Html - "\n\n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (113:6,0 [6] IncompleteDirectives.cshtml) - model + DirectiveToken - (119:6,6 [0] IncompleteDirectives.cshtml) - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(119, 2, true); + HtmlContent - (119:6,6 [2] IncompleteDirectives.cshtml) + IntermediateToken - (119:6,6 [2] IncompleteDirectives.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (121:7,0 [7] IncompleteDirectives.cshtml) - model + DirectiveToken - (128:7,7 [0] IncompleteDirectives.cshtml) - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(128, 4, true); + HtmlContent - (128:7,7 [4] IncompleteDirectives.cshtml) + IntermediateToken - (128:7,7 [4] IncompleteDirectives.cshtml) - Html - \n\n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (132:9,0 [7] IncompleteDirectives.cshtml) - inject + DirectiveToken - (139:9,7 [0] IncompleteDirectives.cshtml) - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(139, 2, true); + HtmlContent - (139:9,7 [2] IncompleteDirectives.cshtml) + IntermediateToken - (139:9,7 [2] IncompleteDirectives.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (141:10,0 [8] IncompleteDirectives.cshtml) - inject + DirectiveToken - (149:10,8 [0] IncompleteDirectives.cshtml) - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(149, 2, true); + HtmlContent - (149:10,8 [2] IncompleteDirectives.cshtml) + IntermediateToken - (149:10,8 [2] IncompleteDirectives.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (151:11,0 [25] IncompleteDirectives.cshtml) - inject + DirectiveToken - (159:11,8 [17] IncompleteDirectives.cshtml) - MyService + DirectiveToken - (176:11,25 [0] IncompleteDirectives.cshtml) - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(176, 4, true); + HtmlContent - (176:11,25 [4] IncompleteDirectives.cshtml) + IntermediateToken - (176:11,25 [4] IncompleteDirectives.cshtml) - Html - \n\n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (180:13,0 [10] IncompleteDirectives.cshtml) - namespace + DirectiveToken - (190:13,10 [0] IncompleteDirectives.cshtml) - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(190, 2, true); + HtmlContent - (190:13,10 [2] IncompleteDirectives.cshtml) + IntermediateToken - (190:13,10 [2] IncompleteDirectives.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + MalformedDirective - (192:14,0 [11] IncompleteDirectives.cshtml) - namespace + DirectiveToken - (203:14,11 [0] IncompleteDirectives.cshtml) - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(203, 2, true); + HtmlContent - (203:14,11 [2] IncompleteDirectives.cshtml) + IntermediateToken - (203:14,11 [2] IncompleteDirectives.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml new file mode 100644 index 0000000000..38efd570da --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml @@ -0,0 +1,2 @@ +@inherits MyBasePageForViews +@model MyModel diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs new file mode 100644 index 0000000000..7cdbaf3326 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs @@ -0,0 +1,56 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel : MyBasePageForViews + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" +MyBasePageForViews __typeHelper = default(MyBasePageForViews); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt new file mode 100644 index 0000000000..3310acfa76 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt @@ -0,0 +1,39 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel - MyBasePageForViews - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (10:0,10 [26] InheritsViewModel.cshtml) - MyBasePageForViews + DirectiveToken - (45:1,7 [7] InheritsViewModel.cshtml) - MyModel + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt new file mode 100644 index 0000000000..6a313a909d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (10:0,10 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml) +|MyBasePageForViews| +Generated Location: (740:19,0 [26] ) +|MyBasePageForViews| + +Source Location: (45:1,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml) +|MyModel| +Generated Location: (1004:27,0 [7] ) +|MyModel| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs new file mode 100644 index 0000000000..9680177b77 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs @@ -0,0 +1,36 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "3ff83e2f0d946feb387a8ea03a529c64350014f8" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"3ff83e2f0d946feb387a8ea03a529c64350014f8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel : MyBasePageForViews + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt new file mode 100644 index 0000000000..2468ef4662 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt @@ -0,0 +1,20 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel - MyBasePageForViews - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml new file mode 100644 index 0000000000..295e4cf3ab --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml @@ -0,0 +1,2 @@ +@page +@model MyModel diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs new file mode 100644 index 0000000000..f174a0fc2f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs @@ -0,0 +1,50 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports : MyPageModel + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public MyModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt new file mode 100644 index 0000000000..bcbf42ae26 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt @@ -0,0 +1,43 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyPageModel - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (10:0,10 [19] TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml) - MyPageModel + DirectiveToken - (14:1,7 [7] InheritsWithViewImports.cshtml) - MyModel + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public MyModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt new file mode 100644 index 0000000000..e7daecd874 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (14:1,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml) +|MyModel| +Generated Location: (745:19,0 [7] ) +|MyModel| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs new file mode 100644 index 0000000000..c1ea0b5c3e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs @@ -0,0 +1,39 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d196fc1c66d46d35e35af9b01c737e12bcce6782" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d196fc1c66d46d35e35af9b01c737e12bcce6782", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml")] + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"f311ecbb5c4d63980a59c24af5ffe8baa1c3f99a", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports : MyPageModel + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public MyModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt new file mode 100644 index 0000000000..2704223a57 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt @@ -0,0 +1,25 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyPageModel - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public MyModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml new file mode 100644 index 0000000000..0aa749dd3f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml @@ -0,0 +1 @@ +@inject MyApp MyPropertyName diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml new file mode 100644 index 0000000000..d699f1e754 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml @@ -0,0 +1,3 @@ +@model MyModel +@inject MyApp MyPropertyName +@inject MyService Html diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs new file mode 100644 index 0000000000..2120622373 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs @@ -0,0 +1,82 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +global::System.Object MyPropertyName = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +global::System.Object Html = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt new file mode 100644 index 0000000000..c1d70d5d89 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt @@ -0,0 +1,43 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [7] InjectWithModel.cshtml) - MyModel + DirectiveToken - (24:1,8 [5] InjectWithModel.cshtml) - MyApp + DirectiveToken - (30:1,14 [14] InjectWithModel.cshtml) - MyPropertyName + DirectiveToken - (54:2,8 [17] InjectWithModel.cshtml) - MyService + DirectiveToken - (72:2,26 [4] InjectWithModel.cshtml) - Html + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt new file mode 100644 index 0000000000..c4838ff64d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt @@ -0,0 +1,25 @@ +Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyModel| +Generated Location: (766:19,0 [7] ) +|MyModel| + +Source Location: (24:1,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyApp| +Generated Location: (990:27,0 [5] ) +|MyApp| + +Source Location: (30:1,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyPropertyName| +Generated Location: (1232:35,22 [14] ) +|MyPropertyName| + +Source Location: (54:2,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyService| +Generated Location: (1438:43,0 [17] ) +|MyService| + +Source Location: (72:2,26 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|Html| +Generated Location: (1704:51,22 [4] ) +|Html| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs new file mode 100644 index 0000000000..36974edf08 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs @@ -0,0 +1,38 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2cafb599699b78d76f0355b6f528050b4720789d" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2cafb599699b78d76f0355b6f528050b4720789d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt new file mode 100644 index 0000000000..d018107ae2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt @@ -0,0 +1,21 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml new file mode 100644 index 0000000000..8cd61913e4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml @@ -0,0 +1,5 @@ +@model MyModel +@inject MyApp MyPropertyName; +@inject MyService Html; +@inject MyApp MyPropertyName2 ; +@inject MyService Html2 ; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs new file mode 100644 index 0000000000..ea95a4e7eb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs @@ -0,0 +1,118 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object MyPropertyName = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object Html = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object MyPropertyName2 = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object Html2 = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt new file mode 100644 index 0000000000..5c4540f366 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt @@ -0,0 +1,49 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [7] InjectWithSemicolon.cshtml) - MyModel + DirectiveToken - (24:1,8 [5] InjectWithSemicolon.cshtml) - MyApp + DirectiveToken - (30:1,14 [14] InjectWithSemicolon.cshtml) - MyPropertyName + DirectiveToken - (58:2,8 [17] InjectWithSemicolon.cshtml) - MyService + DirectiveToken - (76:2,26 [4] InjectWithSemicolon.cshtml) - Html + DirectiveToken - (93:3,8 [5] InjectWithSemicolon.cshtml) - MyApp + DirectiveToken - (99:3,14 [15] InjectWithSemicolon.cshtml) - MyPropertyName2 + DirectiveToken - (129:4,8 [17] InjectWithSemicolon.cshtml) - MyService + DirectiveToken - (147:4,26 [5] InjectWithSemicolon.cshtml) - Html2 + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt new file mode 100644 index 0000000000..6a90f75f3e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt @@ -0,0 +1,45 @@ +Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyModel| +Generated Location: (774:19,0 [7] ) +|MyModel| + +Source Location: (24:1,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyApp| +Generated Location: (1002:27,0 [5] ) +|MyApp| + +Source Location: (30:1,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyPropertyName| +Generated Location: (1248:35,22 [14] ) +|MyPropertyName| + +Source Location: (58:2,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyService| +Generated Location: (1458:43,0 [17] ) +|MyService| + +Source Location: (76:2,26 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|Html| +Generated Location: (1728:51,22 [4] ) +|Html| + +Source Location: (93:3,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyApp| +Generated Location: (1928:59,0 [5] ) +|MyApp| + +Source Location: (99:3,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyPropertyName2| +Generated Location: (2174:67,22 [15] ) +|MyPropertyName2| + +Source Location: (129:4,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyService| +Generated Location: (2385:75,0 [17] ) +|MyService| + +Source Location: (147:4,26 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|Html2| +Generated Location: (2655:83,22 [5] ) +|Html2| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs new file mode 100644 index 0000000000..b8eb5c371d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs @@ -0,0 +1,42 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8a53bde02f202036e674a23018e04268a3a844bb" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"8a53bde02f202036e674a23018e04268a3a844bb", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt new file mode 100644 index 0000000000..898557c170 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt @@ -0,0 +1,23 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs new file mode 100644 index 0000000000..7b2f4fedc6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs @@ -0,0 +1,58 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml" +global::System.Object MyPropertyName = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt new file mode 100644 index 0000000000..0b8beeae9b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt @@ -0,0 +1,40 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (8:0,8 [5] Inject.cshtml) - MyApp + DirectiveToken - (14:0,14 [14] Inject.cshtml) - MyPropertyName + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt new file mode 100644 index 0000000000..10ed356ecf --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (8:0,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml) +|MyApp| +Generated Location: (748:19,0 [5] ) +|MyApp| + +Source Location: (14:0,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml) +|MyPropertyName| +Generated Location: (981:27,22 [14] ) +|MyPropertyName| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs new file mode 100644 index 0000000000..e3493199a4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs @@ -0,0 +1,38 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "592a6d8544c71b828d4a3fbf92d398cd3ea72790" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"592a6d8544c71b828d4a3fbf92d398cd3ea72790", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt new file mode 100644 index 0000000000..e05f9d2df9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt @@ -0,0 +1,21 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml new file mode 100644 index 0000000000..6dfb72bc31 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml @@ -0,0 +1 @@ +@namespace Test. \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs new file mode 100644 index 0000000000..d99c176c52 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..90446dc58b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml(1,12): Error RZ1014: The 'namespace' directive expects a namespace name. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt new file mode 100644 index 0000000000..6f9220aab4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt @@ -0,0 +1,40 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (0:0,0 [11] InvalidNamespaceAtEOF.cshtml) - namespace + HtmlContent - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) + IntermediateToken - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) - Html - Test. + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs new file mode 100644 index 0000000000..2accba6951 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs @@ -0,0 +1,39 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "010d175bb6c3f7fa6f2ae04c1fecb4e3bfbf928b" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"010d175bb6c3f7fa6f2ae04c1fecb4e3bfbf928b", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(11, 5, true); + WriteLiteral("Test."); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt new file mode 100644 index 0000000000..90446dc58b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml(1,12): Error RZ1014: The 'namespace' directive expects a namespace name. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt new file mode 100644 index 0000000000..e99ab2d9c2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt @@ -0,0 +1,27 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (0:0,0 [11] InvalidNamespaceAtEOF.cshtml) - namespace + CSharpCode - + IntermediateToken - - CSharp - BeginContext(11, 5, true); + HtmlContent - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) + IntermediateToken - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) - Html - Test. + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml new file mode 100644 index 0000000000..9b4f9d5559 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml @@ -0,0 +1,4 @@ +@page "foo + +

About Us

+

We are awesome.

\ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs new file mode 100644 index 0000000000..15befce0d0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs @@ -0,0 +1,42 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..637d1e902b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml(1,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt new file mode 100644 index 0000000000..c3fbc6082e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt @@ -0,0 +1,51 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (0:0,0 [6] MalformedPageDirective.cshtml) - page + HtmlContent - (6:0,6 [49] MalformedPageDirective.cshtml) + IntermediateToken - (6:0,6 [8] MalformedPageDirective.cshtml) - Html - "foo\n\n + IntermediateToken - (14:2,0 [4] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (18:2,4 [8] MalformedPageDirective.cshtml) - Html - About Us + IntermediateToken - (26:2,12 [5] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (31:2,17 [2] MalformedPageDirective.cshtml) - Html - \n + IntermediateToken - (33:3,0 [3] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (36:3,3 [15] MalformedPageDirective.cshtml) - Html - We are awesome. + IntermediateToken - (51:3,18 [4] MalformedPageDirective.cshtml) - Html -

+ Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.mappings.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.codegen.cs new file mode 100644 index 0000000000..7835a2dae2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.codegen.cs @@ -0,0 +1,41 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "464e008b9a04181fe1e9f2cc6826095698de4739" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"464e008b9a04181fe1e9f2cc6826095698de4739", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(6, 49, true); + WriteLiteral("\"foo\r\n\r\n

About Us

\r\n

We are awesome.

"); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.diagnostics.txt new file mode 100644 index 0000000000..637d1e902b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml(1,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.ir.txt new file mode 100644 index 0000000000..0692442d42 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.ir.txt @@ -0,0 +1,38 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (0:0,0 [6] MalformedPageDirective.cshtml) - page + CSharpCode - + IntermediateToken - - CSharp - BeginContext(6, 49, true); + HtmlContent - (6:0,6 [49] MalformedPageDirective.cshtml) + IntermediateToken - (6:0,6 [8] MalformedPageDirective.cshtml) - Html - "foo\n\n + IntermediateToken - (14:2,0 [4] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (18:2,4 [8] MalformedPageDirective.cshtml) - Html - About Us + IntermediateToken - (26:2,12 [5] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (31:2,17 [2] MalformedPageDirective.cshtml) - Html - \n + IntermediateToken - (33:3,0 [3] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (36:3,3 [15] MalformedPageDirective.cshtml) - Html - We are awesome. + IntermediateToken - (51:3,18 [4] MalformedPageDirective.cshtml) - Html -

+ CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml new file mode 100644 index 0000000000..4b73b2dc53 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml @@ -0,0 +1 @@ +@model System.Collections.IEnumerable diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml new file mode 100644 index 0000000000..c488b1e443 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml @@ -0,0 +1,6 @@ +@model DateTime + +@addTagHelper "InputTestTagHelper, AppCode" + + + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs new file mode 100644 index 0000000000..82441cd663 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs @@ -0,0 +1,69 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +DateTime __typeHelper = default(DateTime); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +global::System.Object __typeHelper = "InputTestTagHelper, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + __InputTestTagHelper = CreateTagHelper(); +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + __InputTestTagHelper = CreateTagHelper(); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => Model); + +#line default +#line hidden + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt new file mode 100644 index 0000000000..37627e94ea --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt @@ -0,0 +1,68 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [8] ModelExpressionTagHelper.cshtml) - DateTime + DirectiveToken - (33:2,14 [29] ModelExpressionTagHelper.cshtml) - "InputTestTagHelper, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (17:1,0 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (17:1,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n + HtmlContent - (62:2,43 [4] ModelExpressionTagHelper.cshtml) + IntermediateToken - (62:2,43 [4] ModelExpressionTagHelper.cshtml) - Html - \n\n + TagHelper - (66:4,0 [25] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (91:4,25 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (91:4,25 [2] ModelExpressionTagHelper.cshtml) - Html - \n + TagHelper - (93:5,0 [27] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - (111:5,18 [5] ModelExpressionTagHelper.cshtml) - CSharp - Model + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (120:5,27 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (120:5,27 [2] ModelExpressionTagHelper.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt new file mode 100644 index 0000000000..63a7d6ccc1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt @@ -0,0 +1,20 @@ +Source Location: (7:0,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|DateTime| +Generated Location: (851:20,0 [8] ) +|DateTime| + +Source Location: (33:2,14 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|"InputTestTagHelper, AppCode"| +Generated Location: (1123:28,37 [29] ) +|"InputTestTagHelper, AppCode"| + +Source Location: (83:4,17 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|Date| +Generated Location: (1802:44,102 [4] ) +|Date| + +Source Location: (111:5,18 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|Model| +Generated Location: (2118:50,94 [5] ) +|Model| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs new file mode 100644 index 0000000000..799bbc1362 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs @@ -0,0 +1,107 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "741fc99adb54ad906c5cdc5391aeffb51a1e767b" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"741fc99adb54ad906c5cdc5391aeffb51a1e767b", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(17, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(64, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(66, 25, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => { + } + ); + __InputTestTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTestTagHelper); +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("for", __InputTestTagHelper.For, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(91, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(93, 27, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => { + } + ); + __InputTestTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTestTagHelper); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => Model); + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("for", __InputTestTagHelper.For, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(120, 2, true); + WriteLiteral("\r\n"); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt new file mode 100644 index 0000000000..1fb7820a75 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt @@ -0,0 +1,73 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(17, 2, true); + HtmlContent - (17:1,0 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (17:1,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(64, 2, true); + HtmlContent - (64:3,0 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (64:3,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(66, 25, false); + TagHelper - (66:4,0 [25] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(91, 2, true); + HtmlContent - (91:4,25 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (91:4,25 [2] ModelExpressionTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(93, 27, false); + TagHelper - (93:5,0 [27] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - (111:5,18 [5] ModelExpressionTagHelper.cshtml) - CSharp - Model + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(120, 2, true); + HtmlContent - (120:5,27 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (120:5,27 [2] ModelExpressionTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs new file mode 100644 index 0000000000..63c2a52c6f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs @@ -0,0 +1,48 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml" +System.Collections.IEnumerable __typeHelper = default(System.Collections.IEnumerable); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt new file mode 100644 index 0000000000..1ebdc00df2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt @@ -0,0 +1,38 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [30] Model.cshtml) - System.Collections.IEnumerable + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt new file mode 100644 index 0000000000..7d84cf754d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (7:0,7 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml) +|System.Collections.IEnumerable| +Generated Location: (769:19,0 [30] ) +|System.Collections.IEnumerable| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs new file mode 100644 index 0000000000..ae8dc1fe65 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs @@ -0,0 +1,36 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2c1e88396568d309c236020e59bf2abacfadd612" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2c1e88396568d309c236020e59bf2abacfadd612", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt new file mode 100644 index 0000000000..2b7dcff085 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt @@ -0,0 +1,20 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml new file mode 100644 index 0000000000..350f93b776 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml @@ -0,0 +1,2 @@ +@model ThisShouldBeGenerated +@model System.Collections.IEnumerable diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs new file mode 100644 index 0000000000..e8f705cef7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs @@ -0,0 +1,56 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MultipleModels : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml" +ThisShouldBeGenerated __typeHelper = default(ThisShouldBeGenerated); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml" +System.Collections.IEnumerable __typeHelper = default(System.Collections.IEnumerable); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..2fe8233c66 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml(2,1): Error RZ2001: The 'model' directive may only occur once per document. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt new file mode 100644 index 0000000000..f63a69601b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt @@ -0,0 +1,41 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MultipleModels - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [21] MultipleModels.cshtml) - ThisShouldBeGenerated + DirectiveToken - (37:1,7 [30] MultipleModels.cshtml) - System.Collections.IEnumerable + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (30:1,0 [39] MultipleModels.cshtml) - model + DirectiveToken - (37:1,7 [30] MultipleModels.cshtml) - System.Collections.IEnumerable + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt new file mode 100644 index 0000000000..79d7e257c7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (7:0,7 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml) +|ThisShouldBeGenerated| +Generated Location: (778:19,0 [21] ) +|ThisShouldBeGenerated| + +Source Location: (37:1,7 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml) +|System.Collections.IEnumerable| +Generated Location: (1029:27,0 [30] ) +|System.Collections.IEnumerable| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml new file mode 100644 index 0000000000..ecee97de58 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml @@ -0,0 +1,3 @@ +@page +@namespace Test.Namespace +

Hi There!

diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs new file mode 100644 index 0000000000..9d7181bfad --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs @@ -0,0 +1,50 @@ +// +#pragma warning disable 1591 +namespace Test.Namespace +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml" +global::System.Object __typeHelper = nameof(Test.Namespace); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt new file mode 100644 index 0000000000..9238a0a419 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt @@ -0,0 +1,47 @@ +Document - + NamespaceDeclaration - - Test.Namespace + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (18:1,11 [14] PageWithNamespace.cshtml) - Test.Namespace + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (34:2,0 [20] PageWithNamespace.cshtml) + IntermediateToken - (34:2,0 [4] PageWithNamespace.cshtml) - Html -

+ IntermediateToken - (38:2,4 [9] PageWithNamespace.cshtml) - Html - Hi There! + IntermediateToken - (47:2,13 [5] PageWithNamespace.cshtml) - Html -

+ IntermediateToken - (52:2,18 [2] PageWithNamespace.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt new file mode 100644 index 0000000000..b41240c9c5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (18:1,11 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml) +|Test.Namespace| +Generated Location: (809:19,44 [14] ) +|Test.Namespace| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.codegen.cs new file mode 100644 index 0000000000..9c1a5b03f5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.codegen.cs @@ -0,0 +1,41 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "1edfb1ba4f5f6c70e2c72f4f23baf4dc0ae14377" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml", typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace), null)] +namespace Test.Namespace +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"1edfb1ba4f5f6c70e2c72f4f23baf4dc0ae14377", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(34, 20, true); + WriteLiteral("

Hi There!

\r\n"); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.ir.txt new file mode 100644 index 0000000000..53b89427ee --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.ir.txt @@ -0,0 +1,33 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml", typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace), null)] + NamespaceDeclaration - - Test.Namespace + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(34, 20, true); + HtmlContent - (34:2,0 [20] PageWithNamespace.cshtml) + IntermediateToken - (34:2,0 [4] PageWithNamespace.cshtml) - Html -

+ IntermediateToken - (38:2,4 [9] PageWithNamespace.cshtml) - Html - Hi There! + IntermediateToken - (47:2,13 [5] PageWithNamespace.cshtml) - Html -

+ IntermediateToken - (52:2,18 [2] PageWithNamespace.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml new file mode 100644 index 0000000000..5172f8f791 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml @@ -0,0 +1,2 @@ +
Some text here.
+@page diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs new file mode 100644 index 0000000000..ec8a4fd5c9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs @@ -0,0 +1,42 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..393b35646e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml(2,1): Error RZ3906: The '@page' directive must precede all other elements defined in a Razor file. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt new file mode 100644 index 0000000000..c21d9fc82c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt @@ -0,0 +1,46 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (0:0,0 [28] RazorPageWithNoLeadingPageDirective.cshtml) + IntermediateToken - (0:0,0 [5] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (5:0,5 [15] RazorPageWithNoLeadingPageDirective.cshtml) - Html - Some text here. + IntermediateToken - (20:0,20 [6] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (26:0,26 [2] RazorPageWithNoLeadingPageDirective.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.mappings.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs new file mode 100644 index 0000000000..107beef619 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs @@ -0,0 +1,41 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "40c0ffad85d8fef63edfb5d91a08bd1b3609ba6f" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"40c0ffad85d8fef63edfb5d91a08bd1b3609ba6f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(0, 28, true); + WriteLiteral("
Some text here.
\r\n"); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt new file mode 100644 index 0000000000..393b35646e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml(2,1): Error RZ3906: The '@page' directive must precede all other elements defined in a Razor file. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt new file mode 100644 index 0000000000..764b704909 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt @@ -0,0 +1,33 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(0, 28, true); + HtmlContent - (0:0,0 [28] RazorPageWithNoLeadingPageDirective.cshtml) + IntermediateToken - (0:0,0 [5] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (5:0,5 [15] RazorPageWithNoLeadingPageDirective.cshtml) - Html - Some text here. + IntermediateToken - (20:0,20 [6] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (26:0,26 [2] RazorPageWithNoLeadingPageDirective.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml new file mode 100644 index 0000000000..2bc617c509 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml @@ -0,0 +1,40 @@ +@page + +@model NewModel +@addTagHelper "*, AppCode" +@using Microsoft.AspNetCore.Mvc.RazorPages + +@functions { + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } +} + +

New Customer

+
+
+
+ +
+ + +
+
+
+
+ +
+
+
diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml new file mode 100644 index 0000000000..63d5955e72 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml @@ -0,0 +1,13 @@ +@page "/About" + +@model NewModel +@using Microsoft.AspNetCore.Mvc.RazorPages + +@functions { + public class NewModel : PageModel + { + public string Name { get; set; } + } +} + +

New Customer @Model.Name

diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.codegen.cs new file mode 100644 index 0000000000..8f5d082e6a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.codegen.cs @@ -0,0 +1,78 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("RouteTemplate", "/About")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" +global::System.Object __typeHelper = "/About"; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" +NewModel __typeHelper = default(NewModel); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" + __o = Model.Name; + +#line default +#line hidden + } + #pragma warning restore 1998 +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" + + public class NewModel : PageModel + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public NewModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.ir.txt new file mode 100644 index 0000000000..c71b835bf9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.ir.txt @@ -0,0 +1,60 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (36:3,1 [41] RazorPagesWithRouteTemplate.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + RazorCompiledItemMetadataAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (6:0,6 [8] RazorPagesWithRouteTemplate.cshtml) - "/About" + DirectiveToken - (25:2,7 [8] RazorPagesWithRouteTemplate.cshtml) - NewModel + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (16:1,0 [2] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (16:1,0 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + HtmlContent - (77:3,42 [4] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (77:3,42 [4] RazorPagesWithRouteTemplate.cshtml) - Html - \n\n + HtmlContent - (191:10,1 [21] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (191:10,1 [4] RazorPagesWithRouteTemplate.cshtml) - Html - \n\n + IntermediateToken - (195:12,0 [4] RazorPagesWithRouteTemplate.cshtml) - Html -

+ IntermediateToken - (199:12,4 [13] RazorPagesWithRouteTemplate.cshtml) - Html - New Customer + CSharpExpression - (213:12,18 [10] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (213:12,18 [10] RazorPagesWithRouteTemplate.cshtml) - CSharp - Model.Name + HtmlContent - (223:12,28 [7] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (223:12,28 [5] RazorPagesWithRouteTemplate.cshtml) - Html -

+ IntermediateToken - (228:12,33 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + CSharpCode - (93:5,12 [97] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (93:5,12 [97] RazorPagesWithRouteTemplate.cshtml) - CSharp - \n public class NewModel : PageModel\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public NewModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.mappings.txt new file mode 100644 index 0000000000..cc5e9cad30 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.mappings.txt @@ -0,0 +1,35 @@ +Source Location: (36:3,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +|using Microsoft.AspNetCore.Mvc.RazorPages| +Generated Location: (492:14,0 [41] ) +|using Microsoft.AspNetCore.Mvc.RazorPages| + +Source Location: (6:0,6 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +|"/About"| +Generated Location: (1108:25,37 [8] ) +|"/About"| + +Source Location: (25:2,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +|NewModel| +Generated Location: (1313:33,0 [8] ) +|NewModel| + +Source Location: (213:12,18 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +|Model.Name| +Generated Location: (1841:48,18 [10] ) +|Model.Name| + +Source Location: (93:5,12 [97] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +| + public class NewModel : PageModel + { + public string Name { get; set; } + } +| +Generated Location: (2049:55,12 [97] ) +| + public class NewModel : PageModel + { + public string Name { get; set; } + } +| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.codegen.cs new file mode 100644 index 0000000000..bff519edb2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.codegen.cs @@ -0,0 +1,72 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "547900310554f446d88da593a245719ee9dbb12f" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate), @"/About")] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("RouteTemplate", "/About")] + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"547900310554f446d88da593a245719ee9dbb12f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(16, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(79, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(193, 19, true); + WriteLiteral("\r\n

New Customer "); + EndContext(); + BeginContext(213, 10, false); +#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" + Write(Model.Name); + +#line default +#line hidden + EndContext(); + BeginContext(223, 7, true); + WriteLiteral("

\r\n"); + EndContext(); + } + #pragma warning restore 1998 +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" + + public class NewModel : PageModel + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public NewModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.ir.txt new file mode 100644 index 0000000000..5d54680b90 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.ir.txt @@ -0,0 +1,61 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate), @"/About")] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (36:3,1 [43] RazorPagesWithRouteTemplate.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + RazorCompiledItemMetadataAttribute - + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(16, 2, true); + HtmlContent - (16:1,0 [2] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (16:1,0 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(79, 2, true); + HtmlContent - (79:4,0 [2] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (79:4,0 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(193, 19, true); + HtmlContent - (193:11,0 [19] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (193:11,0 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + IntermediateToken - (195:12,0 [4] RazorPagesWithRouteTemplate.cshtml) - Html -

+ IntermediateToken - (199:12,4 [13] RazorPagesWithRouteTemplate.cshtml) - Html - New Customer + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(213, 10, false); + CSharpExpression - (213:12,18 [10] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (213:12,18 [10] RazorPagesWithRouteTemplate.cshtml) - CSharp - Model.Name + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(223, 7, true); + HtmlContent - (223:12,28 [7] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (223:12,28 [5] RazorPagesWithRouteTemplate.cshtml) - Html -

+ IntermediateToken - (228:12,33 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - (93:5,12 [97] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (93:5,12 [97] RazorPagesWithRouteTemplate.cshtml) - CSharp - \n public class NewModel : PageModel\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public NewModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml new file mode 100644 index 0000000000..b78cc65ec7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml @@ -0,0 +1,36 @@ +@page + +@addTagHelper "*, AppCode" +@using Microsoft.AspNetCore.Mvc.RazorPages + +@functions { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } +} + +

New Customer

+
+
+
+ +
+ + +
+
+
+
+ +
+
+
diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs new file mode 100644 index 0000000000..aeb2631c46 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs @@ -0,0 +1,83 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + private global::DivTagHelper __DivTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" +global::System.Object __typeHelper = "*, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + __DivTagHelper = CreateTagHelper(); +#line 25 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" + __o = Name; + +#line default +#line hidden + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + } + #pragma warning restore 1998 +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" + + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt new file mode 100644 index 0000000000..913b80d2aa --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt @@ -0,0 +1,143 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (38:3,1 [41] RazorPagesWithoutModel.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (23:2,14 [12] RazorPagesWithoutModel.cshtml) - "*, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (7:1,0 [2] RazorPagesWithoutModel.cshtml) + IntermediateToken - (7:1,0 [2] RazorPagesWithoutModel.cshtml) - Html - \n + HtmlContent - (35:2,26 [2] RazorPagesWithoutModel.cshtml) + IntermediateToken - (35:2,26 [2] RazorPagesWithoutModel.cshtml) - Html - \n + HtmlContent - (79:3,42 [4] RazorPagesWithoutModel.cshtml) + IntermediateToken - (79:3,42 [4] RazorPagesWithoutModel.cshtml) - Html - \n\n + HtmlContent - (379:18,1 [77] RazorPagesWithoutModel.cshtml) + IntermediateToken - (379:18,1 [4] RazorPagesWithoutModel.cshtml) - Html - \n\n + IntermediateToken - (383:20,0 [4] RazorPagesWithoutModel.cshtml) - Html -

+ IntermediateToken - (387:20,4 [12] RazorPagesWithoutModel.cshtml) - Html - New Customer + IntermediateToken - (399:20,16 [5] RazorPagesWithoutModel.cshtml) - Html -

+ IntermediateToken - (404:20,21 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (406:21,0 [5] RazorPagesWithoutModel.cshtml) - Html -
+ IntermediateToken - (450:21,44 [6] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (456:22,4 [31] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (468:22,16 [11] RazorPagesWithoutModel.cshtml) + IntermediateToken - (468:22,16 [11] RazorPagesWithoutModel.cshtml) - Html - text-danger + DefaultTagHelperExecute - + HtmlContent - (487:22,35 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (487:22,35 [6] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (493:23,4 [237] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (517:23,28 [48] RazorPagesWithoutModel.cshtml) + IntermediateToken - (517:23,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (527:24,8 [6] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (578:24,59 [10] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (588:25,8 [130] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (611:25,31 [101] RazorPagesWithoutModel.cshtml) + IntermediateToken - (611:25,31 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (625:26,12 [6] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (655:26,42 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (669:27,12 [5] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (695:27,38 [7] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (702:27,45 [10] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (600:25,20 [9] RazorPagesWithoutModel.cshtml) + IntermediateToken - (600:25,20 [9] RazorPagesWithoutModel.cshtml) - Html - col-md-10 + DefaultTagHelperExecute - + HtmlContent - (718:28,14 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (718:28,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (505:23,16 [10] RazorPagesWithoutModel.cshtml) + IntermediateToken - (505:23,16 [10] RazorPagesWithoutModel.cshtml) - Html - form-group + DefaultTagHelperExecute - + HtmlContent - (730:29,10 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (730:29,10 [6] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (736:30,4 [174] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (760:30,28 [10] RazorPagesWithoutModel.cshtml) + IntermediateToken - (760:30,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (770:31,8 [128] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (809:31,47 [83] RazorPagesWithoutModel.cshtml) + IntermediateToken - (809:31,47 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (823:32,12 [7] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (882:32,71 [10] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (782:31,20 [25] RazorPagesWithoutModel.cshtml) + IntermediateToken - (782:31,20 [25] RazorPagesWithoutModel.cshtml) - Html - col-md-offset-2 col-md-10 + DefaultTagHelperExecute - + HtmlContent - (898:33,14 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (898:33,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (748:30,16 [10] RazorPagesWithoutModel.cshtml) + IntermediateToken - (748:30,16 [10] RazorPagesWithoutModel.cshtml) - Html - form-group + DefaultTagHelperExecute - + HtmlContent - (910:34,10 [11] RazorPagesWithoutModel.cshtml) + IntermediateToken - (910:34,10 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (912:35,0 [7] RazorPagesWithoutModel.cshtml) - Html -
+ IntermediateToken - (919:35,7 [2] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - (95:5,12 [283] RazorPagesWithoutModel.cshtml) + IntermediateToken - (95:5,12 [283] RazorPagesWithoutModel.cshtml) - CSharp - \n public IActionResult OnPost(Customer customer)\n {\n Name = customer.Name;\n return Redirect("~/customers/inlinepagemodels/");\n }\n\n public string Name { get; set; }\n\n public class Customer\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt new file mode 100644 index 0000000000..33f7baa377 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt @@ -0,0 +1,46 @@ +Source Location: (38:3,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) +|using Microsoft.AspNetCore.Mvc.RazorPages| +Generated Location: (487:14,0 [41] ) +|using Microsoft.AspNetCore.Mvc.RazorPages| + +Source Location: (23:2,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) +|"*, AppCode"| +Generated Location: (1035:25,37 [12] ) +|"*, AppCode"| + +Source Location: (566:24,47 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) +|Name| +Generated Location: (1629:41,47 [4] ) +|Name| + +Source Location: (95:5,12 [283] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) +| + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } +| +Generated Location: (2110:52,12 [283] ) +| + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } +| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.codegen.cs new file mode 100644 index 0000000000..f11c563667 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.codegen.cs @@ -0,0 +1,204 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8bf3954ad78688478de155359db8af32627ee2b8" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"8bf3954ad78688478de155359db8af32627ee2b8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + 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("text-danger"), 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("col-md-10"), 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("form-group"), 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("col-md-offset-2 col-md-10"), 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; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(7, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(81, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(381, 75, true); + WriteLiteral("\r\n

New Customer

\r\n
\r\n "); + EndContext(); + BeginContext(456, 31, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(487, 6, true); + WriteLiteral("\r\n "); + EndContext(); + BeginContext(493, 237, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + BeginContext(517, 48, true); + WriteLiteral("\r\n \r\n "); + EndContext(); + BeginContext(588, 130, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + BeginContext(611, 101, true); + WriteLiteral("\r\n \r\n \r\n "); + EndContext(); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(718, 6, true); + WriteLiteral("\r\n "); + EndContext(); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(730, 6, true); + WriteLiteral("\r\n "); + EndContext(); + BeginContext(736, 174, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + BeginContext(760, 10, true); + WriteLiteral("\r\n "); + EndContext(); + BeginContext(770, 128, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + BeginContext(809, 83, true); + WriteLiteral("\r\n \r\n "); + EndContext(); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(898, 6, true); + WriteLiteral("\r\n "); + EndContext(); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(910, 11, true); + WriteLiteral("\r\n\r\n"); + EndContext(); + } + #pragma warning restore 1998 +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" + + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.ir.txt new file mode 100644 index 0000000000..519006aec3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.ir.txt @@ -0,0 +1,193 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (38:3,1 [43] RazorPagesWithoutModel.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - text-danger - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - col-md-10 - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - class - form-group - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - class - col-md-offset-2 col-md-10 - HtmlAttributeValueStyle.DoubleQuotes + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(7, 2, true); + HtmlContent - (7:1,0 [2] RazorPagesWithoutModel.cshtml) + IntermediateToken - (7:1,0 [2] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(81, 2, true); + HtmlContent - (81:4,0 [2] RazorPagesWithoutModel.cshtml) + IntermediateToken - (81:4,0 [2] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(381, 75, true); + HtmlContent - (381:19,0 [75] RazorPagesWithoutModel.cshtml) + IntermediateToken - (381:19,0 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (383:20,0 [4] RazorPagesWithoutModel.cshtml) - Html -

+ IntermediateToken - (387:20,4 [12] RazorPagesWithoutModel.cshtml) - Html - New Customer + IntermediateToken - (399:20,16 [5] RazorPagesWithoutModel.cshtml) - Html -

+ IntermediateToken - (404:20,21 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (406:21,0 [5] RazorPagesWithoutModel.cshtml) - Html -
+ IntermediateToken - (450:21,44 [6] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(456, 31, false); + TagHelper - (456:22,4 [31] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(487, 6, true); + HtmlContent - (487:22,35 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (487:22,35 [6] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(493, 237, false); + TagHelper - (493:23,4 [237] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(517, 48, true); + HtmlContent - (517:23,28 [48] RazorPagesWithoutModel.cshtml) + IntermediateToken - (517:23,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (527:24,8 [6] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (578:24,59 [10] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(588, 130, false); + TagHelper - (588:25,8 [130] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(611, 101, true); + HtmlContent - (611:25,31 [101] RazorPagesWithoutModel.cshtml) + IntermediateToken - (611:25,31 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (625:26,12 [6] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (655:26,42 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (669:27,12 [5] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (695:27,38 [7] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (702:27,45 [10] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(718, 6, true); + HtmlContent - (718:28,14 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (718:28,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(730, 6, true); + HtmlContent - (730:29,10 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (730:29,10 [6] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(736, 174, false); + TagHelper - (736:30,4 [174] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(760, 10, true); + HtmlContent - (760:30,28 [10] RazorPagesWithoutModel.cshtml) + IntermediateToken - (760:30,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(770, 128, false); + TagHelper - (770:31,8 [128] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(809, 83, true); + HtmlContent - (809:31,47 [83] RazorPagesWithoutModel.cshtml) + IntermediateToken - (809:31,47 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (823:32,12 [7] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (882:32,71 [10] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(898, 6, true); + HtmlContent - (898:33,14 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (898:33,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(910, 11, true); + HtmlContent - (910:34,10 [11] RazorPagesWithoutModel.cshtml) + IntermediateToken - (910:34,10 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (912:35,0 [7] RazorPagesWithoutModel.cshtml) - Html -
+ IntermediateToken - (919:35,7 [2] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - (95:5,12 [283] RazorPagesWithoutModel.cshtml) + IntermediateToken - (95:5,12 [283] RazorPagesWithoutModel.cshtml) - CSharp - \n public IActionResult OnPost(Customer customer)\n {\n Name = customer.Name;\n return Redirect("~/customers/inlinepagemodels/");\n }\n\n public string Name { get; set; }\n\n public class Customer\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs new file mode 100644 index 0000000000..d7acbdf7d1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs @@ -0,0 +1,94 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + private global::DivTagHelper __DivTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" +NewModel __typeHelper = default(NewModel); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" +global::System.Object __typeHelper = "*, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + __DivTagHelper = CreateTagHelper(); +#line 29 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" + __o = Model.Name; + +#line default +#line hidden + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + } + #pragma warning restore 1998 +#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" + + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public NewModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt new file mode 100644 index 0000000000..2266b746f6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt @@ -0,0 +1,144 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (55:4,1 [41] RazorPages.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (16:2,7 [8] RazorPages.cshtml) - NewModel + DirectiveToken - (40:3,14 [12] RazorPages.cshtml) - "*, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (7:1,0 [2] RazorPages.cshtml) + IntermediateToken - (7:1,0 [2] RazorPages.cshtml) - Html - \n + HtmlContent - (52:3,26 [2] RazorPages.cshtml) + IntermediateToken - (52:3,26 [2] RazorPages.cshtml) - Html - \n + HtmlContent - (96:4,42 [4] RazorPages.cshtml) + IntermediateToken - (96:4,42 [4] RazorPages.cshtml) - Html - \n\n + HtmlContent - (473:22,1 [78] RazorPages.cshtml) + IntermediateToken - (473:22,1 [4] RazorPages.cshtml) - Html - \n\n + IntermediateToken - (477:24,0 [4] RazorPages.cshtml) - Html -

+ IntermediateToken - (481:24,4 [12] RazorPages.cshtml) - Html - New Customer + IntermediateToken - (493:24,16 [5] RazorPages.cshtml) - Html -

+ IntermediateToken - (498:24,21 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (500:25,0 [5] RazorPages.cshtml) - Html -
+ IntermediateToken - (545:25,45 [6] RazorPages.cshtml) - Html - \n + TagHelper - (551:26,4 [31] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (563:26,16 [11] RazorPages.cshtml) + IntermediateToken - (563:26,16 [11] RazorPages.cshtml) - Html - text-danger + DefaultTagHelperExecute - + HtmlContent - (582:26,35 [6] RazorPages.cshtml) + IntermediateToken - (582:26,35 [6] RazorPages.cshtml) - Html - \n + TagHelper - (588:27,4 [243] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (612:27,28 [48] RazorPages.cshtml) + IntermediateToken - (612:27,28 [10] RazorPages.cshtml) - Html - \n + IntermediateToken - (622:28,8 [6] RazorPages.cshtml) - Html - + IntermediateToken - (679:28,65 [10] RazorPages.cshtml) - Html - \n + TagHelper - (689:29,8 [130] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (712:29,31 [101] RazorPages.cshtml) + IntermediateToken - (712:29,31 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (726:30,12 [6] RazorPages.cshtml) - Html - + IntermediateToken - (756:30,42 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (770:31,12 [5] RazorPages.cshtml) - Html - + IntermediateToken - (796:31,38 [7] RazorPages.cshtml) - Html - + IntermediateToken - (803:31,45 [10] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (701:29,20 [9] RazorPages.cshtml) + IntermediateToken - (701:29,20 [9] RazorPages.cshtml) - Html - col-md-10 + DefaultTagHelperExecute - + HtmlContent - (819:32,14 [6] RazorPages.cshtml) + IntermediateToken - (819:32,14 [6] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (600:27,16 [10] RazorPages.cshtml) + IntermediateToken - (600:27,16 [10] RazorPages.cshtml) - Html - form-group + DefaultTagHelperExecute - + HtmlContent - (831:33,10 [6] RazorPages.cshtml) + IntermediateToken - (831:33,10 [6] RazorPages.cshtml) - Html - \n + TagHelper - (837:34,4 [174] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (861:34,28 [10] RazorPages.cshtml) + IntermediateToken - (861:34,28 [10] RazorPages.cshtml) - Html - \n + TagHelper - (871:35,8 [128] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (910:35,47 [83] RazorPages.cshtml) + IntermediateToken - (910:35,47 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (924:36,12 [7] RazorPages.cshtml) - Html - + IntermediateToken - (983:36,71 [10] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (883:35,20 [25] RazorPages.cshtml) + IntermediateToken - (883:35,20 [25] RazorPages.cshtml) - Html - col-md-offset-2 col-md-10 + DefaultTagHelperExecute - + HtmlContent - (999:37,14 [6] RazorPages.cshtml) + IntermediateToken - (999:37,14 [6] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (849:34,16 [10] RazorPages.cshtml) + IntermediateToken - (849:34,16 [10] RazorPages.cshtml) - Html - form-group + DefaultTagHelperExecute - + HtmlContent - (1011:38,10 [11] RazorPages.cshtml) + IntermediateToken - (1011:38,10 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (1013:39,0 [7] RazorPages.cshtml) - Html -
+ IntermediateToken - (1020:39,7 [2] RazorPages.cshtml) - Html - \n + CSharpCode - (112:6,12 [360] RazorPages.cshtml) + IntermediateToken - (112:6,12 [360] RazorPages.cshtml) - CSharp - \n public class NewModel : PageModel\n {\n public IActionResult OnPost(Customer customer)\n {\n Name = customer.Name;\n return Redirect("~/customers/inlinepagemodels/");\n }\n\n public string Name { get; set; }\n }\n\n public class Customer\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public NewModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt new file mode 100644 index 0000000000..0af8c77dfd --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt @@ -0,0 +1,57 @@ +Source Location: (55:4,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +|using Microsoft.AspNetCore.Mvc.RazorPages| +Generated Location: (475:14,0 [41] ) +|using Microsoft.AspNetCore.Mvc.RazorPages| + +Source Location: (16:2,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +|NewModel| +Generated Location: (962:25,0 [8] ) +|NewModel| + +Source Location: (40:3,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +|"*, AppCode"| +Generated Location: (1220:33,37 [12] ) +|"*, AppCode"| + +Source Location: (661:28,47 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +|Model.Name| +Generated Location: (1802:49,47 [10] ) +|Model.Name| + +Source Location: (112:6,12 [360] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +| + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } +| +Generated Location: (2277:60,12 [360] ) +| + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } +| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.codegen.cs new file mode 100644 index 0000000000..ca08b5e268 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.codegen.cs @@ -0,0 +1,207 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d33caff161b646a61b273d7c544111395b652557" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d33caff161b646a61b273d7c544111395b652557", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + 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("text-danger"), 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("col-md-10"), 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("form-group"), 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("col-md-offset-2 col-md-10"), 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; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(7, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(98, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(475, 76, true); + WriteLiteral("\r\n

New Customer

\r\n
\r\n "); + EndContext(); + BeginContext(551, 31, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(582, 6, true); + WriteLiteral("\r\n "); + EndContext(); + BeginContext(588, 243, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + BeginContext(612, 48, true); + WriteLiteral("\r\n \r\n "); + EndContext(); + BeginContext(689, 130, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + BeginContext(712, 101, true); + WriteLiteral("\r\n \r\n \r\n "); + EndContext(); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(819, 6, true); + WriteLiteral("\r\n "); + EndContext(); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(831, 6, true); + WriteLiteral("\r\n "); + EndContext(); + BeginContext(837, 174, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + BeginContext(861, 10, true); + WriteLiteral("\r\n "); + EndContext(); + BeginContext(871, 128, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + BeginContext(910, 83, true); + WriteLiteral("\r\n \r\n "); + EndContext(); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(999, 6, true); + WriteLiteral("\r\n "); + EndContext(); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(1011, 11, true); + WriteLiteral("\r\n\r\n"); + EndContext(); + } + #pragma warning restore 1998 +#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" + + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public NewModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.ir.txt new file mode 100644 index 0000000000..cc1bc6f718 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.ir.txt @@ -0,0 +1,193 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (55:4,1 [43] RazorPages.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - text-danger - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - col-md-10 - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - class - form-group - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - class - col-md-offset-2 col-md-10 - HtmlAttributeValueStyle.DoubleQuotes + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(7, 2, true); + HtmlContent - (7:1,0 [2] RazorPages.cshtml) + IntermediateToken - (7:1,0 [2] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(98, 2, true); + HtmlContent - (98:5,0 [2] RazorPages.cshtml) + IntermediateToken - (98:5,0 [2] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(475, 76, true); + HtmlContent - (475:23,0 [76] RazorPages.cshtml) + IntermediateToken - (475:23,0 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (477:24,0 [4] RazorPages.cshtml) - Html -

+ IntermediateToken - (481:24,4 [12] RazorPages.cshtml) - Html - New Customer + IntermediateToken - (493:24,16 [5] RazorPages.cshtml) - Html -

+ IntermediateToken - (498:24,21 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (500:25,0 [5] RazorPages.cshtml) - Html -
+ IntermediateToken - (545:25,45 [6] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(551, 31, false); + TagHelper - (551:26,4 [31] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(582, 6, true); + HtmlContent - (582:26,35 [6] RazorPages.cshtml) + IntermediateToken - (582:26,35 [6] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(588, 243, false); + TagHelper - (588:27,4 [243] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(612, 48, true); + HtmlContent - (612:27,28 [48] RazorPages.cshtml) + IntermediateToken - (612:27,28 [10] RazorPages.cshtml) - Html - \n + IntermediateToken - (622:28,8 [6] RazorPages.cshtml) - Html - + IntermediateToken - (679:28,65 [10] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(689, 130, false); + TagHelper - (689:29,8 [130] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(712, 101, true); + HtmlContent - (712:29,31 [101] RazorPages.cshtml) + IntermediateToken - (712:29,31 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (726:30,12 [6] RazorPages.cshtml) - Html - + IntermediateToken - (756:30,42 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (770:31,12 [5] RazorPages.cshtml) - Html - + IntermediateToken - (796:31,38 [7] RazorPages.cshtml) - Html - + IntermediateToken - (803:31,45 [10] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(819, 6, true); + HtmlContent - (819:32,14 [6] RazorPages.cshtml) + IntermediateToken - (819:32,14 [6] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(831, 6, true); + HtmlContent - (831:33,10 [6] RazorPages.cshtml) + IntermediateToken - (831:33,10 [6] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(837, 174, false); + TagHelper - (837:34,4 [174] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(861, 10, true); + HtmlContent - (861:34,28 [10] RazorPages.cshtml) + IntermediateToken - (861:34,28 [10] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(871, 128, false); + TagHelper - (871:35,8 [128] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(910, 83, true); + HtmlContent - (910:35,47 [83] RazorPages.cshtml) + IntermediateToken - (910:35,47 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (924:36,12 [7] RazorPages.cshtml) - Html - + IntermediateToken - (983:36,71 [10] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(999, 6, true); + HtmlContent - (999:37,14 [6] RazorPages.cshtml) + IntermediateToken - (999:37,14 [6] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(1011, 11, true); + HtmlContent - (1011:38,10 [11] RazorPages.cshtml) + IntermediateToken - (1011:38,10 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (1013:39,0 [7] RazorPages.cshtml) - Html -
+ IntermediateToken - (1020:39,7 [2] RazorPages.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - (112:6,12 [360] RazorPages.cshtml) + IntermediateToken - (112:6,12 [360] RazorPages.cshtml) - CSharp - \n public class NewModel : PageModel\n {\n public IActionResult OnPost(Customer customer)\n {\n Name = customer.Name;\n return Redirect("~/customers/inlinepagemodels/");\n }\n\n public string Name { get; set; }\n }\n\n public class Customer\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public NewModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml new file mode 100644 index 0000000000..7438788ff4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml @@ -0,0 +1,14 @@ +@model DateTime + +@addTagHelper "InputTestTagHelper, AppCode" + +@{ + Layout = "_SectionTestLayout.cshtml"; +} + +
Some body
+ +@section Section1 { +
This is in Section 1
+ +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs new file mode 100644 index 0000000000..3ca46af8a7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs @@ -0,0 +1,80 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +DateTime __typeHelper = default(DateTime); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +global::System.Object __typeHelper = "InputTestTagHelper, AppCode"; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +global::System.Object Section1 = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" + + Layout = "_SectionTestLayout.cshtml"; + +#line default +#line hidden + DefineSection("Section1", async(__razor_section_writer) => { + __InputTestTagHelper = CreateTagHelper(); +#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + } + ); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt new file mode 100644 index 0000000000..312d7bb7ae --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt @@ -0,0 +1,73 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [8] Sections.cshtml) - DateTime + DirectiveToken - (33:2,14 [29] Sections.cshtml) - "InputTestTagHelper, AppCode" + DirectiveToken - (152:10,9 [8] Sections.cshtml) - Section1 + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (17:1,0 [2] Sections.cshtml) + IntermediateToken - (17:1,0 [2] Sections.cshtml) - Html - \n + HtmlContent - (62:2,43 [4] Sections.cshtml) + IntermediateToken - (62:2,43 [4] Sections.cshtml) - Html - \n\n + CSharpCode - (68:4,2 [46] Sections.cshtml) + IntermediateToken - (68:4,2 [46] Sections.cshtml) - CSharp - \n Layout = "_SectionTestLayout.cshtml";\n + HtmlContent - (117:7,0 [26] Sections.cshtml) + IntermediateToken - (117:7,0 [2] Sections.cshtml) - Html - \n + IntermediateToken - (119:8,0 [5] Sections.cshtml) - Html -
+ IntermediateToken - (124:8,5 [9] Sections.cshtml) - Html - Some body + IntermediateToken - (133:8,14 [6] Sections.cshtml) - Html -
+ IntermediateToken - (139:8,20 [4] Sections.cshtml) - Html - \n\n + Section - - Section1 + HtmlContent - (162:10,19 [43] Sections.cshtml) + IntermediateToken - (162:10,19 [6] Sections.cshtml) - Html - \n + IntermediateToken - (168:11,4 [5] Sections.cshtml) - Html -
+ IntermediateToken - (173:11,9 [20] Sections.cshtml) - Html - This is in Section 1 + IntermediateToken - (193:11,29 [6] Sections.cshtml) - Html -
+ IntermediateToken - (199:11,35 [6] Sections.cshtml) - Html - \n + TagHelper - (205:12,4 [25] Sections.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (222:12,21 [4] Sections.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (222:12,21 [4] Sections.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (230:12,29 [2] Sections.cshtml) + IntermediateToken - (230:12,29 [2] Sections.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt new file mode 100644 index 0000000000..1cc991810c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt @@ -0,0 +1,29 @@ +Source Location: (7:0,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|DateTime| +Generated Location: (819:20,0 [8] ) +|DateTime| + +Source Location: (33:2,14 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|"InputTestTagHelper, AppCode"| +Generated Location: (1075:28,37 [29] ) +|"InputTestTagHelper, AppCode"| + +Source Location: (152:10,9 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|Section1| +Generated Location: (1305:36,22 [8] ) +|Section1| + +Source Location: (68:4,2 [46] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +| + Layout = "_SectionTestLayout.cshtml"; +| +Generated Location: (1771:51,2 [46] ) +| + Layout = "_SectionTestLayout.cshtml"; +| + +Source Location: (222:12,21 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|Date| +Generated Location: (2196:59,102 [4] ) +|Date| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs new file mode 100644 index 0000000000..5d5ab480d6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs @@ -0,0 +1,99 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "4b7b87da15db4343c99430c0813fd6bc03643453" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"4b7b87da15db4343c99430c0813fd6bc03643453", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(17, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(64, 2, true); + WriteLiteral("\r\n"); + EndContext(); +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" + + Layout = "_SectionTestLayout.cshtml"; + +#line default +#line hidden + BeginContext(117, 26, true); + WriteLiteral("\r\n
Some body
\r\n\r\n"); + EndContext(); + DefineSection("Section1", async() => { + BeginContext(162, 43, true); + WriteLiteral("\r\n
This is in Section 1
\r\n "); + EndContext(); + BeginContext(205, 25, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => { + } + ); + __InputTestTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTestTagHelper); +#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("for", __InputTestTagHelper.For, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(230, 2, true); + WriteLiteral("\r\n"); + EndContext(); + } + ); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt new file mode 100644 index 0000000000..8a5b810749 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt @@ -0,0 +1,77 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(17, 2, true); + HtmlContent - (17:1,0 [2] Sections.cshtml) + IntermediateToken - (17:1,0 [2] Sections.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(64, 2, true); + HtmlContent - (64:3,0 [2] Sections.cshtml) + IntermediateToken - (64:3,0 [2] Sections.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - (68:4,2 [46] Sections.cshtml) + IntermediateToken - (68:4,2 [46] Sections.cshtml) - CSharp - \n Layout = "_SectionTestLayout.cshtml";\n + CSharpCode - + IntermediateToken - - CSharp - BeginContext(117, 26, true); + HtmlContent - (117:7,0 [26] Sections.cshtml) + IntermediateToken - (117:7,0 [2] Sections.cshtml) - Html - \n + IntermediateToken - (119:8,0 [5] Sections.cshtml) - Html -
+ IntermediateToken - (124:8,5 [9] Sections.cshtml) - Html - Some body + IntermediateToken - (133:8,14 [6] Sections.cshtml) - Html -
+ IntermediateToken - (139:8,20 [4] Sections.cshtml) - Html - \n\n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Section - - Section1 + CSharpCode - + IntermediateToken - - CSharp - BeginContext(162, 43, true); + HtmlContent - (162:10,19 [43] Sections.cshtml) + IntermediateToken - (162:10,19 [6] Sections.cshtml) - Html - \n + IntermediateToken - (168:11,4 [5] Sections.cshtml) - Html -
+ IntermediateToken - (173:11,9 [20] Sections.cshtml) - Html - This is in Section 1 + IntermediateToken - (193:11,29 [6] Sections.cshtml) - Html -
+ IntermediateToken - (199:11,35 [6] Sections.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(205, 25, false); + TagHelper - (205:12,4 [25] Sections.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (222:12,21 [4] Sections.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (222:12,21 [4] Sections.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(230, 2, true); + HtmlContent - (230:12,29 [2] Sections.cshtml) + IntermediateToken - (230:12,29 [2] Sections.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml new file mode 100644 index 0000000000..ed2648a986 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml @@ -0,0 +1,4 @@ +@using System.ComponentModel +@using System.Collections +@using System +@using System \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.codegen.cs new file mode 100644 index 0000000000..ad57e4a82b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.codegen.cs @@ -0,0 +1,59 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System.ComponentModel; + +#line default +#line hidden +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System.Collections; + +#line default +#line hidden +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System; + +#line default +#line hidden +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System; + +#line default +#line hidden + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.ir.txt new file mode 100644 index 0000000000..0163b00a81 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.ir.txt @@ -0,0 +1,46 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (1:0,1 [27] UsingDirectives.cshtml) - System.ComponentModel + UsingDirective - (31:1,1 [24] UsingDirectives.cshtml) - System.Collections + UsingDirective - (58:2,1 [12] UsingDirectives.cshtml) - System + UsingDirective - (73:3,1 [12] UsingDirectives.cshtml) - System + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (28:0,28 [2] UsingDirectives.cshtml) + IntermediateToken - (28:0,28 [2] UsingDirectives.cshtml) - Html - \n + HtmlContent - (55:1,25 [2] UsingDirectives.cshtml) + IntermediateToken - (55:1,25 [2] UsingDirectives.cshtml) - Html - \n + HtmlContent - (70:2,13 [2] UsingDirectives.cshtml) + IntermediateToken - (70:2,13 [2] UsingDirectives.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.mappings.txt new file mode 100644 index 0000000000..71a6bf2b2d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.mappings.txt @@ -0,0 +1,20 @@ +Source Location: (1:0,1 [27] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml) +|using System.ComponentModel| +Generated Location: (461:13,0 [27] ) +|using System.ComponentModel| + +Source Location: (31:1,1 [24] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml) +|using System.Collections| +Generated Location: (613:18,0 [24] ) +|using System.Collections| + +Source Location: (58:2,1 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml) +|using System| +Generated Location: (762:23,0 [12] ) +|using System| + +Source Location: (73:3,1 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml) +|using System| +Generated Location: (899:28,0 [12] ) +|using System| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.codegen.cs new file mode 100644 index 0000000000..1310cb0d8c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.codegen.cs @@ -0,0 +1,55 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "452979e8e4dd77a84a4c50425dd3a162e265990d" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives))] +namespace AspNetCore +{ + #line hidden + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System.ComponentModel; + +#line default +#line hidden +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System.Collections; + +#line default +#line hidden +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System; + +#line default +#line hidden +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"452979e8e4dd77a84a4c50425dd3a162e265990d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.ir.txt new file mode 100644 index 0000000000..c3b71e0393 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.ir.txt @@ -0,0 +1,23 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (1:0,1 [29] UsingDirectives.cshtml) - System.ComponentModel + UsingDirective - (31:1,1 [26] UsingDirectives.cshtml) - System.Collections + UsingDirective - (58:2,1 [14] UsingDirectives.cshtml) - System + UsingDirective - (73:3,1 [12] UsingDirectives.cshtml) - System + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml new file mode 100644 index 0000000000..0430ccfc69 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml @@ -0,0 +1,6 @@ +@addTagHelper "*, AppCode" +@{ + var foo = "Hello"; +} + + \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs new file mode 100644 index 0000000000..b6196f6651 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs @@ -0,0 +1,84 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::AllTagHelper __AllTagHelper; + private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper __TestViewComponentTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" +global::System.Object __typeHelper = "*, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + + var foo = "Hello"; + +#line default +#line hidden + __AllTagHelper = CreateTagHelper(); + __TestViewComponentTagHelper = CreateTagHelper(); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + __o = foo; + +#line default +#line hidden + __TestViewComponentTagHelper.firstName = string.Empty; + __AllTagHelper.Bar = " World"; + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("vc:test")] + public class __Generated__TestViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper + { + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TestViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.String firstName { get; set; } + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync("Test", new { firstName }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } + } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt new file mode 100644 index 0000000000..8e7497e7d6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt @@ -0,0 +1,59 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::AllTagHelper - __AllTagHelper + FieldDeclaration - - private - global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper - __TestViewComponentTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (14:0,14 [12] ViewComponentTagHelper.cshtml) - "*, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (26:0,26 [2] ViewComponentTagHelper.cshtml) + IntermediateToken - (26:0,26 [2] ViewComponentTagHelper.cshtml) - Html - \n + CSharpCode - (30:1,2 [26] ViewComponentTagHelper.cshtml) + IntermediateToken - (30:1,2 [26] ViewComponentTagHelper.cshtml) - CSharp - \n var foo = "Hello";\n + HtmlContent - (59:4,0 [2] ViewComponentTagHelper.cshtml) + IntermediateToken - (59:4,0 [2] ViewComponentTagHelper.cshtml) - Html - \n + TagHelper - (61:5,0 [50] ViewComponentTagHelper.cshtml) - vc:test - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - AllTagHelper + DefaultTagHelperCreate - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper + DefaultTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - string TestViewComponentTagHelper.firstName - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - (83:5,22 [3] ViewComponentTagHelper.cshtml) + IntermediateToken - (83:5,22 [3] ViewComponentTagHelper.cshtml) - CSharp - foo + DefaultTagHelperProperty - (93:5,32 [6] ViewComponentTagHelper.cshtml) - bar - string AllTagHelper.Bar - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (93:5,32 [6] ViewComponentTagHelper.cshtml) + IntermediateToken - (93:5,32 [6] ViewComponentTagHelper.cshtml) - Html - World + DefaultTagHelperExecute - + Inject - + Inject - + Inject - + Inject - + Inject - + ViewComponentTagHelper - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt new file mode 100644 index 0000000000..9c5fd32efb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt @@ -0,0 +1,19 @@ +Source Location: (14:0,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) +|"*, AppCode"| +Generated Location: (1057:21,37 [12] ) +|"*, AppCode"| + +Source Location: (30:1,2 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) +| + var foo = "Hello"; +| +Generated Location: (1534:36,2 [26] ) +| + var foo = "Hello"; +| + +Source Location: (83:5,22 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) +|foo| +Generated Location: (1985:44,22 [3] ) +|foo| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs new file mode 100644 index 0000000000..28241f9687 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs @@ -0,0 +1,112 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "bf860c3a5e96240c9d41a0b950e49c1a165ca44d" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"bf860c3a5e96240c9d41a0b950e49c1a165ca44d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper __TestViewComponentTagHelper; + private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("bar", " 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::AllTagHelper __AllTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + + var foo = "Hello"; + +#line default +#line hidden + BeginContext(59, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(61, 50, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("vc:test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + } + ); + __AllTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__AllTagHelper); + __TestViewComponentTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__TestViewComponentTagHelper); + BeginWriteTagHelperAttribute(); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + WriteLiteral(foo); + +#line default +#line hidden + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __TestViewComponentTagHelper.firstName = __tagHelperStringValueBuffer; + __tagHelperExecutionContext.AddTagHelperAttribute("first-name", __TestViewComponentTagHelper.firstName, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); + __AllTagHelper.Bar = (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(); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("vc:test")] + public class __Generated__TestViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper + { + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TestViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.String firstName { get; set; } + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync("Test", new { firstName }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } + } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt new file mode 100644 index 0000000000..4c215a09d3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt @@ -0,0 +1,46 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + FieldDeclaration - - private - global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper - __TestViewComponentTagHelper + PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - bar - World - HtmlAttributeValueStyle.DoubleQuotes + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::AllTagHelper - __AllTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - (30:1,2 [26] ViewComponentTagHelper.cshtml) + IntermediateToken - (30:1,2 [26] ViewComponentTagHelper.cshtml) - CSharp - \n var foo = "Hello";\n + CSharpCode - + IntermediateToken - - CSharp - BeginContext(59, 2, true); + HtmlContent - (59:4,0 [2] ViewComponentTagHelper.cshtml) + IntermediateToken - (59:4,0 [2] ViewComponentTagHelper.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(61, 50, false); + TagHelper - (61:5,0 [50] ViewComponentTagHelper.cshtml) - vc:test - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - AllTagHelper + DefaultTagHelperCreate - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper + DefaultTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - string TestViewComponentTagHelper.firstName - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - (83:5,22 [3] ViewComponentTagHelper.cshtml) + IntermediateToken - (83:5,22 [3] ViewComponentTagHelper.cshtml) - CSharp - foo + PreallocatedTagHelperProperty - (93:5,32 [6] ViewComponentTagHelper.cshtml) - __tagHelperAttribute_0 - bar - Bar + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - + ViewComponentTagHelper - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml new file mode 100644 index 0000000000..eaf33e48ec --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml @@ -0,0 +1,2 @@ +@namespace Test.Namespace +

Hi There!

diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs new file mode 100644 index 0000000000..209d3361f0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs @@ -0,0 +1,48 @@ +// +#pragma warning disable 1591 +namespace Test.Namespace +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml" +global::System.Object __typeHelper = nameof(Test.Namespace); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt new file mode 100644 index 0000000000..42d53bcd1b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt @@ -0,0 +1,43 @@ +Document - + NamespaceDeclaration - - Test.Namespace + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (11:0,11 [14] ViewWithNamespace.cshtml) - Test.Namespace + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (27:1,0 [20] ViewWithNamespace.cshtml) + IntermediateToken - (27:1,0 [4] ViewWithNamespace.cshtml) - Html -

+ IntermediateToken - (31:1,4 [9] ViewWithNamespace.cshtml) - Html - Hi There! + IntermediateToken - (40:1,13 [5] ViewWithNamespace.cshtml) - Html -

+ IntermediateToken - (45:1,18 [2] ViewWithNamespace.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt new file mode 100644 index 0000000000..2b7a295e01 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (11:0,11 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml) +|Test.Namespace| +Generated Location: (818:19,44 [14] ) +|Test.Namespace| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.codegen.cs new file mode 100644 index 0000000000..fb4ec5e55e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.codegen.cs @@ -0,0 +1,39 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "471b74bb73c8ae8e0ed24c654340198b9b4a1ec8" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml", typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace))] +namespace Test.Namespace +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"471b74bb73c8ae8e0ed24c654340198b9b4a1ec8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(27, 20, true); + WriteLiteral("

Hi There!

\r\n"); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.ir.txt new file mode 100644 index 0000000000..471464c580 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.ir.txt @@ -0,0 +1,29 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml", typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace))] + NamespaceDeclaration - - Test.Namespace + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(27, 20, true); + HtmlContent - (27:1,0 [20] ViewWithNamespace.cshtml) + IntermediateToken - (27:1,0 [4] ViewWithNamespace.cshtml) - Html -

+ IntermediateToken - (31:1,4 [9] ViewWithNamespace.cshtml) - Html - Hi There! + IntermediateToken - (40:1,13 [5] ViewWithNamespace.cshtml) - Html -

+ IntermediateToken - (45:1,18 [2] ViewWithNamespace.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml new file mode 100644 index 0000000000..f4e110d289 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml @@ -0,0 +1 @@ +@inject IHtmlHelper Helper \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs new file mode 100644 index 0000000000..1f60d924cc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs @@ -0,0 +1,58 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml" +IHtmlHelper __typeHelper = default(IHtmlHelper); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml" +global::System.Object Helper = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public IHtmlHelper Helper { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt new file mode 100644 index 0000000000..b677049ce1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt @@ -0,0 +1,40 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (8:0,8 [19] _ViewImports.cshtml) - IHtmlHelper + DirectiveToken - (28:0,28 [6] _ViewImports.cshtml) - Helper + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt new file mode 100644 index 0000000000..dc03ca32da --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (8:0,8 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml) +|IHtmlHelper| +Generated Location: (760:19,0 [19] ) +|IHtmlHelper| + +Source Location: (28:0,28 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml) +|Helper| +Generated Location: (1027:27,22 [6] ) +|Helper| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs new file mode 100644 index 0000000000..346428fa0d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs @@ -0,0 +1,38 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "74c90591b68437a0868e91dc714ea9827ab8e03a" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"74c90591b68437a0868e91dc714ea9827ab8e03a", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public IHtmlHelper Helper { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt new file mode 100644 index 0000000000..addc2754ec --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt @@ -0,0 +1,21 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.codegen.cs new file mode 100644 index 0000000000..8c5b2e0f79 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.codegen.cs @@ -0,0 +1,118 @@ +#pragma checksum "TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "78993008d95836bec2b9175d4294bf7bd5f5f109" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Razor.Template), @"default", @"/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml")] +namespace Razor +{ + #line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"78993008d95836bec2b9175d4294bf7bd5f5f109", @"/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml")] + public class Template + { + 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::FormTagHelper __FormTagHelper; + private global::InputTagHelper __InputTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(31, 28, true); + WriteLiteral("Hola\r\n"); + EndContext(); + BeginContext(61, 7, false); +#line 3 "TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml" +Write("Hello"); + +#line default +#line hidden + EndContext(); + BeginContext(69, 2, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(71, 87, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("form", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + BeginContext(91, 6, true); + WriteLiteral("\r\n "); + EndContext(); + BeginContext(97, 52, false); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => { + } + ); + __InputTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTagHelper); + __InputTagHelper.FooProp = (string)__tagHelperAttribute_0.Value; + __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0); +#line 5 "TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml" +__InputTagHelper.BarProp = DateTime.Now; + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("date", __InputTagHelper.BarProp, 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(); + EndContext(); + BeginContext(149, 2, true); + WriteLiteral("\r\n"); + EndContext(); + } + ); + __FormTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__FormTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + EndContext(); + BeginContext(158, 31, true); + WriteLiteral("\r\n\r\nHere is some content "); + EndContext(); + BeginContext(207, 9, true); + WriteLiteral("\r\n"); + EndContext(); + BeginContext(217, 29, false); +#line 9 "TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml" +Write(Foo(item => new Template(async(__razor_template_writer) => { + PushWriter(__razor_template_writer); + BeginContext(222, 24, true); + WriteLiteral("Hello world"); + EndContext(); + PopWriter(); +} +))); + +#line default +#line hidden + EndContext(); + } + #pragma warning restore 1998 + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml new file mode 100644 index 0000000000..8b4fdef616 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml @@ -0,0 +1,9 @@ +@addTagHelper *, TestAssembly +Hola +@("Hello") +
+ +
+ +Here is some content @*with a comment*@ +@Foo(@Hello world) \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt new file mode 100644 index 0000000000..c4ba72abd9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt @@ -0,0 +1,100 @@ +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::FormTagHelper - __FormTagHelper + FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - + IntermediateToken - - CSharp - BeginContext(31, 28, true); + HtmlContent - (31:1,0 [28] BasicTest.cshtml) + IntermediateToken - (31:1,0 [5] BasicTest.cshtml) - Html - + IntermediateToken - (46:1,15 [4] BasicTest.cshtml) - Html - Hola + IntermediateToken - (50:1,19 [7] BasicTest.cshtml) - Html - + IntermediateToken - (57:1,26 [2] BasicTest.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(61, 7, false); + CSharpExpression - (61:2,2 [7] BasicTest.cshtml) + IntermediateToken - (61:2,2 [7] BasicTest.cshtml) - CSharp - "Hello" + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(69, 2, true); + HtmlContent - (69:2,10 [2] BasicTest.cshtml) + IntermediateToken - (69:2,10 [2] BasicTest.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(71, 87, false); + TagHelper - (71:3,0 [87] BasicTest.cshtml) - form - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + CSharpCode - + IntermediateToken - - CSharp - BeginContext(91, 6, true); + HtmlContent - (91:3,20 [6] BasicTest.cshtml) + IntermediateToken - (91:3,20 [6] BasicTest.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(97, 52, false); + TagHelper - (97:4,4 [52] BasicTest.cshtml) - input - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTagHelper + PreallocatedTagHelperProperty - (110:4,17 [5] BasicTest.cshtml) - __tagHelperAttribute_0 - value - FooProp + DefaultTagHelperProperty - (121:4,28 [13] BasicTest.cshtml) - date - System.DateTime InputTagHelper.BarProp - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - (122:4,29 [12] BasicTest.cshtml) + IntermediateToken - (122:4,29 [12] BasicTest.cshtml) - CSharp - DateTime.Now + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(149, 2, true); + HtmlContent - (149:4,56 [2] BasicTest.cshtml) + IntermediateToken - (149:4,56 [2] BasicTest.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + DefaultTagHelperCreate - - FormTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 + DefaultTagHelperExecute - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(158, 31, true); + HtmlContent - (158:5,7 [31] BasicTest.cshtml) + IntermediateToken - (158:5,7 [4] BasicTest.cshtml) - Html - \n\n + IntermediateToken - (162:7,0 [6] BasicTest.cshtml) - Html - + IntermediateToken - (168:7,6 [21] BasicTest.cshtml) - Html - Here is some content + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(207, 9, true); + HtmlContent - (207:7,45 [9] BasicTest.cshtml) + IntermediateToken - (207:7,45 [7] BasicTest.cshtml) - Html - + IntermediateToken - (214:7,52 [2] BasicTest.cshtml) - Html - \n + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + CSharpCode - + IntermediateToken - - CSharp - BeginContext(217, 29, false); + CSharpExpression - (217:8,1 [29] BasicTest.cshtml) + IntermediateToken - (217:8,1 [4] BasicTest.cshtml) - CSharp - Foo( + Template - (222:8,6 [24] BasicTest.cshtml) + CSharpCode - + IntermediateToken - - CSharp - BeginContext(222, 24, true); + HtmlContent - (222:8,6 [24] BasicTest.cshtml) + IntermediateToken - (222:8,6 [6] BasicTest.cshtml) - Html - + IntermediateToken - (228:8,12 [11] BasicTest.cshtml) - Html - Hello world + IntermediateToken - (239:8,23 [7] BasicTest.cshtml) - Html - + CSharpCode - + IntermediateToken - - CSharp - EndContext(); + IntermediateToken - (246:8,30 [1] BasicTest.cshtml) - CSharp - ) + CSharpCode - + IntermediateToken - - CSharp - EndContext(); diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs new file mode 100644 index 0000000000..d27fdb3129 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs @@ -0,0 +1,485 @@ +// 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.Reflection; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class ViewComponentTagHelperDescriptorFactoryTest + { + private static readonly Assembly _assembly = typeof(ViewComponentTagHelperDescriptorFactoryTest).GetTypeInfo().Assembly; + + [Fact] + public void CreateDescriptor_UnderstandsStringParameters() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(StringParameterViewComponent).FullName); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__StringParameterViewComponentTagHelper", + typeof(StringParameterViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__StringParameterViewComponentTagHelper") + .DisplayName("StringParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:string-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("foo")) + .RequireAttributeDescriptor(attribute => attribute.Name("bar"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("foo") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("bar") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "StringParameter") + .Build(); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_UnderstandsVariousParameterTypes() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(VariousParameterViewComponent).FullName); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__VariousParameterViewComponentTagHelper", + typeof(VariousParameterViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__VariousParameterViewComponentTagHelper") + .DisplayName("VariousParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:various-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("test-enum")) + .RequireAttributeDescriptor(attribute => attribute.Name("test-string")) + .RequireAttributeDescriptor(attribute => attribute.Name("baz"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("test-enum") + .PropertyName("testEnum") + .TypeName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum)) + .AsEnum() + .DisplayName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum) + " VariousParameterViewComponentTagHelper.testEnum")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("test-string") + .PropertyName("testString") + .TypeName(typeof(string).FullName) + .DisplayName("string VariousParameterViewComponentTagHelper.testString")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("baz") + .PropertyName("baz") + .TypeName(typeof(int).FullName) + .DisplayName("int VariousParameterViewComponentTagHelper.baz")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "VariousParameter") + .Build(); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_UnderstandsGenericParameters() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(GenericParameterViewComponent).FullName); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__GenericParameterViewComponentTagHelper", + typeof(GenericParameterViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__GenericParameterViewComponentTagHelper") + .DisplayName("GenericParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:generic-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("foo"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("Foo") + .TypeName("System.Collections.Generic.List") + .DisplayName("System.Collections.Generic.List GenericParameterViewComponentTagHelper.Foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("Bar") + .TypeName("System.Collections.Generic.Dictionary") + .AsDictionaryAttribute("bar-", typeof(int).FullName) + .DisplayName("System.Collections.Generic.Dictionary GenericParameterViewComponentTagHelper.Bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "GenericParameter") + .Build(); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_ForSyncViewComponentWithInvokeInBaseType_Works() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__SyncDerivedViewComponentTagHelper", + typeof(SyncDerivedViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__SyncDerivedViewComponentTagHelper") + .DisplayName("SyncDerivedViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:sync-derived") + .RequireAttributeDescriptor(attribute => attribute.Name("foo")) + .RequireAttributeDescriptor(attribute => attribute.Name("bar"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("foo") + .TypeName(typeof(string).FullName) + .DisplayName("string SyncDerivedViewComponentTagHelper.foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("bar") + .TypeName(typeof(string).FullName) + .DisplayName("string SyncDerivedViewComponentTagHelper.bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "SyncDerived") + .Build(); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncDerivedViewComponent).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_ForAsyncViewComponentWithInvokeInBaseType_Works() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__AsyncDerivedViewComponentTagHelper", + typeof(AsyncDerivedViewComponent).Assembly.GetName().Name) + .TypeName("__Generated__AsyncDerivedViewComponentTagHelper") + .DisplayName("AsyncDerivedViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("vc:async-derived")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "AsyncDerived") + .Build(); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncDerivedViewComponent).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_AddsDiagnostic_ForViewComponentWithNoInvokeMethod() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(ViewComponentWithoutInvokeMethod).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_CannotFindMethod.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_AddsDiagnostic_ForViewComponentWithNoInstanceInvokeMethod() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(StaticInvokeAsyncViewComponent).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_CannotFindMethod.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_AddsDiagnostic_ForViewComponentWithNoPublicInvokeMethod() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(NonPublicInvokeAsyncViewComponent).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_CannotFindMethod.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_UnderstandsGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Empty(descriptor.GetAllDiagnostics()); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_UnderstandsNonGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithNonGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Empty(descriptor.GetAllDiagnostics()); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_DoesNotUnderstandVoid() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithString).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_AsyncMethod_ShouldReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_DoesNotUnderstandString() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithString).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_AsyncMethod_ShouldReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvoke_DoesNotUnderstandVoid() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncViewComponentWithVoid).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_SyncMethod_ShouldReturnValue.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvoke_DoesNotUnderstandNonGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncViewComponentWithNonGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_SyncMethod_CannotReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvoke_DoesNotUnderstandGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncViewComponentWithGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_SyncMethod_CannotReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponent_WithAmbiguousMethods() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(DerivedViewComponentWithAmbiguity).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_AmbiguousMethods.Id, diagnostic.Id); + } + } + + public class StringParameterViewComponent + { + public string Invoke(string foo, string bar) => null; + } + + public class VariousParameterViewComponent + { + public string Invoke(TestEnum testEnum, string testString, int baz = 5) => null; + + public enum TestEnum + { + A = 1, + B = 2, + C = 3 + } + } + + public class GenericParameterViewComponent + { + public string Invoke(List Foo, Dictionary Bar) => null; + } + + public class ViewComponentWithoutInvokeMethod + { + } + + public class AsyncViewComponentWithGenericTask + { + public Task InvokeAsync() => null; + } + + public class AsyncViewComponentWithNonGenericTask + { + public Task InvokeAsync() => null; + } + + public class AsyncViewComponentWithVoid + { + public void InvokeAsync() { } + } + + public class AsyncViewComponentWithString + { + public string InvokeAsync() => null; + } + + public class SyncViewComponentWithVoid + { + public void Invoke() { } + } + + public class SyncViewComponentWithNonGenericTask + { + public Task Invoke() => null; + } + + public class SyncViewComponentWithGenericTask + { + public Task Invoke() => null; + } + + public class SyncDerivedViewComponent : StringParameterViewComponent + { + } + + public class AsyncDerivedViewComponent : AsyncViewComponentWithNonGenericTask + { + } + + public class DerivedViewComponentWithAmbiguity : AsyncViewComponentWithNonGenericTask + { + public string Invoke() => null; + } + + public class StaticInvokeAsyncViewComponent + { + public static Task InvokeAsync() => null; + } + + public class NonPublicInvokeAsyncViewComponent + { + protected Task InvokeAsync() => null; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs new file mode 100644 index 0000000000..6c15d62a1f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.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.IO; +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Razor; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + // This is just a basic integration test. There are detailed tests for the VCTH visitor and descriptor factory. + public class ViewComponentTagHelperDescriptorProviderTest + { + [Fact] + public void DescriptorProvider_FindsVCTH() + { + // Arrange + var code = @" + public class StringParameterViewComponent + { + public string Invoke(string foo, string bar) => null; + } +"; + + var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code)); + + var context = TagHelperDescriptorProviderContext.Create(); + context.SetCompilation(compilation); + + var provider = new ViewComponentTagHelperDescriptorProvider() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__StringParameterViewComponentTagHelper", + TestCompilation.AssemblyName) + .TypeName("__Generated__StringParameterViewComponentTagHelper") + .DisplayName("StringParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:string-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("foo")) + .RequireAttributeDescriptor(attribute => attribute.Name("bar"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("foo") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("bar") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "StringParameter") + .Build(); + + // Act + provider.Execute(context); + + // Assert + Assert.Single(context.Results, d => TagHelperDescriptorComparer.CaseSensitive.Equals(d, expectedDescriptor)); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperPassTest.cs new file mode 100644 index 0000000000..00330a4eef --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperPassTest.cs @@ -0,0 +1,275 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class ViewComponentTagHelperPassTest + { + [Fact] + public void ViewComponentTagHelperPass_Execute_IgnoresRegularTagHelper() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .TypeName("TestTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p")) + .Build() + }; + + var projectEngine = CreateProjectEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = projectEngine.Engine, + }; + + var irDocument = CreateIRDocument(projectEngine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.Equal(3, @class.Children.Count); // No class node created for a VCTH + for (var i = 0; i < @class.Children.Count; i++) + { + Assert.IsNotType(@class.Children[i]); + } + } + + [Fact] + public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Int32") + .PropertyName("Foo")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build() + }; + + var projectEngine = CreateProjectEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = projectEngine.Engine, + }; + + var irDocument = CreateIRDocument(projectEngine, codeDocument); + + var vcthFullName = "AspNetCore.test.__Generated__TagCloudViewComponentTagHelper"; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + Assert.Equal(vcthFullName, Assert.IsType(tagHelper.Children[1]).TypeName); + Assert.Equal("Foo", Assert.IsType(tagHelper.Children[2]).PropertyName); + + + var @class = FindClassNode(irDocument); + Assert.Equal(4, @class.Children.Count); + + Assert.IsType(@class.Children.Last()); + } + + [Fact] + public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_WithIndexer() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Collections.Generic.Dictionary") + .PropertyName("Tags") + .AsDictionaryAttribute("foo-", "System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build() + }; + + var projectEngine = CreateProjectEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = projectEngine.Engine, + }; + + var irDocument = CreateIRDocument(projectEngine, codeDocument); + + var vcthFullName = "AspNetCore.test.__Generated__TagCloudViewComponentTagHelper"; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + Assert.Equal(vcthFullName, Assert.IsType(tagHelper.Children[1]).TypeName); + Assert.IsType(tagHelper.Children[2]); + + var @class = FindClassNode(irDocument); + Assert.Equal(4, @class.Children.Count); + + Assert.IsType(@class.Children[3]); + } + + [Fact] + public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_Nested() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper *, TestAssembly +

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("PTestTagHelper", "TestAssembly") + .TypeName("PTestTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .PropertyName("Foo") + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p")) + .Build(), + TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .PropertyName("Foo") + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build() + }; + + var projectEngine = CreateProjectEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = projectEngine.Engine, + }; + + var irDocument = CreateIRDocument(projectEngine, codeDocument); + + var vcthFullName = "AspNetCore.test.__Generated__TagCloudViewComponentTagHelper"; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var outerTagHelper = FindTagHelperNode(irDocument); + Assert.Equal("PTestTagHelper", Assert.IsType(outerTagHelper.Children[1]).TypeName); + Assert.Equal("Foo", Assert.IsType(outerTagHelper.Children[2]).PropertyName); + + var vcth = FindTagHelperNode(outerTagHelper.Children[0]); + Assert.Equal(vcthFullName, Assert.IsType(vcth.Children[1]).TypeName); + Assert.Equal("Foo", Assert.IsType(vcth.Children[2]).PropertyName); + + + var @class = FindClassNode(irDocument); + Assert.Equal(5, @class.Children.Count); + + Assert.IsType(@class.Children.Last()); + } + + private RazorCodeDocument CreateDocument(string content) + { + var source = RazorSourceDocument.Create(content, "test.cshtml"); + return RazorCodeDocument.Create(source); + } + + private RazorProjectEngine CreateProjectEngine(params TagHelperDescriptor[] tagHelpers) + { + return RazorProjectEngine.Create(b => + { + b.Features.Add(new MvcViewDocumentClassifierPass()); + + b.Features.Add(new TestTagHelperFeature(tagHelpers)); + }); + } + + private DocumentIntermediateNode CreateIRDocument(RazorProjectEngine projectEngine, RazorCodeDocument codeDocument) + { + for (var i = 0; i < projectEngine.Phases.Count; i++) + { + var phase = projectEngine.Phases[i]; + phase.Execute(codeDocument); + + if (phase is IRazorDirectiveClassifierPhase) + { + break; + } + } + + // We also expect the default tag helper pass to run first. + var documentNode = codeDocument.GetDocumentIntermediateNode(); + + var defaultTagHelperPass = projectEngine.EngineFeatures.OfType().Single(); + defaultTagHelperPass.Execute(codeDocument, documentNode); + + return codeDocument.GetDocumentIntermediateNode(); + } + + private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node) + { + var visitor = new ClassDeclarationNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private TagHelperIntermediateNode FindTagHelperNode(IntermediateNode node) + { + var visitor = new TagHelperNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private class ClassDeclarationNodeVisitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Node { get; set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Node = node; + } + } + + private class TagHelperNodeVisitor : IntermediateNodeWalker + { + public TagHelperIntermediateNode Node { get; set; } + + public override void VisitTagHelper(TagHelperIntermediateNode node) + { + Node = node; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperTargetExtensionTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperTargetExtensionTest.cs new file mode 100644 index 0000000000..c5c148b6a5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperTargetExtensionTest.cs @@ -0,0 +1,120 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class ViewComponentTagHelperTargetExtensionTest + { + [Fact] + public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper() + { + // Arrange + var tagHelper = TagHelperDescriptorBuilder + .Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Int32") + .PropertyName("Foo")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build(); + + var extension = new ViewComponentTagHelperTargetExtension(); + var context = TestCodeRenderingContext.CreateRuntime(); + var node = new ViewComponentTagHelperIntermediateNode() + { + ClassName = "__Generated__TagCloudViewComponentTagHelper", + TagHelper = tagHelper + }; + + // Act + extension.WriteViewComponentTagHelper(context, node); + + // Assert + var csharp = context.CodeWriter.GenerateCode(); + Assert.Equal( + @"[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute(""tagcloud"")] +public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper +{ + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TagCloudViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.Int32 Foo { get; set; } + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync(""TagCloud"", new { Foo }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } +} +", + csharp, + ignoreLineEndingDifferences: true); + } + + [Fact] + public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper_WithIndexer() + { + // Arrange + var tagHelper = TagHelperDescriptorBuilder + .Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Collections.Generic.Dictionary") + .PropertyName("Tags") + .AsDictionaryAttribute("foo-", "System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build(); + + var extension = new ViewComponentTagHelperTargetExtension(); + var context = TestCodeRenderingContext.CreateRuntime(); + var node = new ViewComponentTagHelperIntermediateNode() + { + ClassName = "__Generated__TagCloudViewComponentTagHelper", + TagHelper = tagHelper + }; + + // Act + extension.WriteViewComponentTagHelper(context, node); + + // Assert + var csharp = context.CodeWriter.GenerateCode(); + Assert.Equal( + @"[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute(""tagcloud"")] +public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper +{ + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TagCloudViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.Collections.Generic.Dictionary Tags { get; set; } + = new System.Collections.Generic.Dictionary(); + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync(""TagCloud"", new { Tags }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } +} +", + csharp, + ignoreLineEndingDifferences: true); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTypeVisitorTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTypeVisitorTest.cs new file mode 100644 index 0000000000..206b74375d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTypeVisitorTest.cs @@ -0,0 +1,202 @@ +// 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; +using Microsoft.CodeAnalysis; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X +{ + public class ViewComponentTypeVisitorTest + { + private static readonly Assembly _assembly = typeof(ViewComponentTypeVisitorTest).GetTypeInfo().Assembly; + + private static Compilation Compilation { get; } = TestCompilation.Create(_assembly); + + // In practice MVC will provide a marker attribute for ViewComponents. To prevent a circular reference between MVC and Razor + // we can use a test class as a marker. + private static INamedTypeSymbol TestViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestViewComponentAttribute).FullName); + private static INamedTypeSymbol TestNonViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestNonViewComponentAttribute).FullName); + + [Fact] + public void IsViewComponent_PlainViewComponent_ReturnsTrue() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_PlainViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.True(isViewComponent); + } + + [Fact] + public void IsViewComponent_DecoratedViewComponent_ReturnsTrue() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_DecoratedVC).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.True(isViewComponent); + } + + [Fact] + public void IsViewComponent_InheritedViewComponent_ReturnsTrue() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_InheritedVC).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.True(isViewComponent); + } + + [Fact] + public void IsViewComponent_AbstractViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_AbstractViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_GenericViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_GenericViewComponent<>).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_InternalViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InternalViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_DecoratedNonViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_DecoratedViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_InheritedNonViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InheritedViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + public abstract class Invalid_AbstractViewComponent + { + } + + public class Invalid_GenericViewComponent + { + } + + internal class Invalid_InternalViewComponent + { + } + + public class Valid_PlainViewComponent + { + } + + [TestViewComponent] + public class Valid_DecoratedVC + { + } + + public class Valid_InheritedVC : Valid_DecoratedVC + { + } + + [TestNonViewComponent] + public class Invalid_DecoratedViewComponent + { + } + + [TestViewComponent] + public class Invalid_InheritedViewComponent : Invalid_DecoratedViewComponent + { + } + + public class TestViewComponentAttribute : Attribute + { + } + + public class TestNonViewComponentAttribute : Attribute + { + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/xunit.runner.json b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/xunit.runner.json new file mode 100644 index 0000000000..fcf172c8fc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "methodDisplay": "method", + "shadowCopy": false +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/AssemblyAttributeInjectionPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/AssemblyAttributeInjectionPass.cs new file mode 100644 index 0000000000..cf5549d0f5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/AssemblyAttributeInjectionPass.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.Diagnostics; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class AssemblyAttributeInjectionPass : IntermediateNodePassBase, IRazorOptimizationPass + { + private const string RazorViewAttribute = "global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute"; + private const string RazorPageAttribute = "global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute"; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.Options.DesignTime) + { + return; + } + + var @namespace = documentNode.FindPrimaryNamespace(); + if (@namespace == null || string.IsNullOrEmpty(@namespace.Content)) + { + // No namespace node or it's incomplete. Skip. + return; + } + + var @class = documentNode.FindPrimaryClass(); + if (@class == null || string.IsNullOrEmpty(@class.ClassName)) + { + // No class node or it's incomplete. Skip. + return; + } + + var generatedTypeName = $"{@namespace.Content}.{@class.ClassName}"; + + // The MVC attributes require a relative path to be specified so that we can make a view engine path. + // We can't use a rooted path because we don't know what the project root is. + // + // If we can't sanitize the path, we'll just set it to null and let is blow up at runtime - we don't + // want to create noise if this code has to run in some unanticipated scenario. + var escapedPath = MakeVerbatimStringLiteral(ConvertToViewEnginePath(codeDocument.Source.RelativePath)); + + string attribute; + if (documentNode.DocumentKind == MvcViewDocumentClassifierPass.MvcViewDocumentKind) + { + attribute = $"[assembly:{RazorViewAttribute}({escapedPath}, typeof({generatedTypeName}))]"; + } + else if (documentNode.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind && + PageDirective.TryGetPageDirective(documentNode, out var pageDirective)) + { + var escapedRoutePrefix = MakeVerbatimStringLiteral(pageDirective.RouteTemplate); + attribute = $"[assembly:{RazorPageAttribute}({escapedPath}, typeof({generatedTypeName}), {escapedRoutePrefix})]"; + } + else + { + return; + } + + var index = documentNode.Children.IndexOf(@namespace); + Debug.Assert(index >= 0); + + var pageAttribute = new CSharpCodeIntermediateNode(); + pageAttribute.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = attribute, + }); + + documentNode.Children.Insert(index, pageAttribute); + } + + private static string MakeVerbatimStringLiteral(string value) + { + if (value == null) + { + return "null"; + } + + value = value.Replace("\"", "\"\""); + return $"@\"{value}\""; + } + + private static string ConvertToViewEnginePath(string relativePath) + { + if (string.IsNullOrEmpty(relativePath)) + { + return null; + } + + // Checking for both / and \ because a \ will become a /. + if (!relativePath.StartsWith("/") && !relativePath.StartsWith("\\")) + { + relativePath = "/" + relativePath; + } + + relativePath = relativePath.Replace('\\', '/'); + return relativePath; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ExtensionInitializer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ExtensionInitializer.cs new file mode 100644 index 0000000000..8c650ebedb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ExtensionInitializer.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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Components; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + internal class ExtensionInitializer : RazorExtensionInitializer + { + public override void Initialize(RazorProjectEngineBuilder builder) + { + RazorExtensions.Register(builder); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/IInjectTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/IInjectTargetExtension.cs new file mode 100644 index 0000000000..89f74d5aaa --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/IInjectTargetExtension.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public interface IInjectTargetExtension : ICodeTargetExtension + { + void WriteInjectProperty(CodeRenderingContext context, InjectIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/IViewComponentTagHelperTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/IViewComponentTagHelperTargetExtension.cs new file mode 100644 index 0000000000..1f303e7422 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/IViewComponentTagHelperTargetExtension.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public interface IViewComponentTagHelperTargetExtension : ICodeTargetExtension + { + void WriteViewComponentTagHelper(CodeRenderingContext context, ViewComponentTagHelperIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectDirective.cs new file mode 100644 index 0000000000..4282ea559f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectDirective.cs @@ -0,0 +1,131 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public static class InjectDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "inject", + DirectiveKind.SingleLine, + builder => + { + builder + .AddTypeToken(Resources.InjectDirective_TypeToken_Name, Resources.InjectDirective_TypeToken_Description) + .AddMemberToken(Resources.InjectDirective_MemberToken_Name, Resources.InjectDirective_MemberToken_Description); + + builder.Usage = DirectiveUsage.FileScopedMultipleOccurring; + builder.Description = Resources.InjectDirective_Description; + }); + + public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + builder.AddTargetExtension(new InjectTargetExtension()); + return builder; + } + + internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + // Runs after the @model and @namespace directives + public override int Order => 10; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind && + documentNode.DocumentKind != MvcViewDocumentClassifierPass.MvcViewDocumentKind) + { + // Not a MVC file. Skip. + return; + } + + var visitor = new Visitor(); + visitor.Visit(documentNode); + var modelType = ModelDirective.GetModelType(documentNode); + + var properties = new HashSet(StringComparer.Ordinal); + + for (var i = visitor.Directives.Count - 1; i >= 0; i--) + { + var directive = visitor.Directives[i]; + var tokens = directive.Tokens.ToArray(); + if (tokens.Length < 2) + { + continue; + } + + var typeName = tokens[0].Content; + var memberName = tokens[1].Content; + + if (!properties.Add(memberName)) + { + continue; + } + + typeName = typeName.Replace("", "<" + modelType + ">"); + + var injectNode = new InjectIntermediateNode() + { + TypeName = typeName, + MemberName = memberName, + }; + + visitor.Class.Children.Add(injectNode); + } + } + } + + private class Visitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Class { get; private set; } + + public IList Directives { get; } = new List(); + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (Class == null) + { + Class = node; + } + + base.VisitClassDeclaration(node); + } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + Directives.Add(node); + } + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static IRazorEngineBuilder Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + builder.AddTargetExtension(new InjectTargetExtension()); + return builder; + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectIntermediateNode.cs new file mode 100644 index 0000000000..572d8bb1dc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectIntermediateNode.cs @@ -0,0 +1,58 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class InjectIntermediateNode : ExtensionIntermediateNode + { + public string TypeName { get; set; } + + public string MemberName { get; set; } + + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteInjectProperty(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(MemberName); + + formatter.WriteProperty(nameof(MemberName), MemberName); + formatter.WriteProperty(nameof(TypeName), TypeName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectTargetExtension.cs new file mode 100644 index 0000000000..9569cca41f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/InjectTargetExtension.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 System; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class InjectTargetExtension : IInjectTargetExtension + { + private const string RazorInjectAttribute = "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]"; + + public void WriteInjectProperty(CodeRenderingContext context, InjectIntermediateNode node) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + var property = $"public {node.TypeName} {node.MemberName} {{ get; private set; }}"; + + if (node.Source.HasValue) + { + using (context.CodeWriter.BuildLinePragma(node.Source.Value)) + { + context.CodeWriter + .WriteLine(RazorInjectAttribute) + .WriteLine(property); + } + } + else + { + context.CodeWriter + .WriteLine(RazorInjectAttribute) + .WriteLine(property); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj new file mode 100644 index 0000000000..afa5ecd679 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj @@ -0,0 +1,20 @@ + + + + ASP.NET Core design time hosting infrastructure for the Razor view engine. + netstandard2.0 + $(PackageTags);aspnetcoremvc + + + + + + + + + + + + + + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ModelDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ModelDirective.cs new file mode 100644 index 0000000000..a8c4bafbd9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ModelDirective.cs @@ -0,0 +1,152 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public static class ModelDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "model", + DirectiveKind.SingleLine, + builder => + { + builder.AddTypeToken(Resources.ModelDirective_TypeToken_Name, Resources.ModelDirective_TypeToken_Description); + builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; + builder.Description = Resources.ModelDirective_Description; + }); + + public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + return builder; + } + + public static string GetModelType(DocumentIntermediateNode document) + { + if (document == null) + { + throw new ArgumentNullException(nameof(document)); + } + + var visitor = new Visitor(); + return GetModelType(document, visitor); + } + + private static string GetModelType(DocumentIntermediateNode document, Visitor visitor) + { + visitor.Visit(document); + + for (var i = visitor.ModelDirectives.Count - 1; i >= 0; i--) + { + var directive = visitor.ModelDirectives[i]; + + var tokens = directive.Tokens.ToArray(); + if (tokens.Length >= 1) + { + return tokens[0].Content; + } + } + + if (document.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind) + { + return visitor.Class.ClassName; + } + else + { + return "dynamic"; + } + } + + internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + // Runs after the @inherits directive + public override int Order => 5; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var visitor = new Visitor(); + var modelType = GetModelType(documentNode, visitor); + + if (documentNode.Options.DesignTime) + { + // Alias the TModel token to a known type. + // This allows design time compilation to succeed for Razor files where the token isn't replaced. + var typeName = $"global::{typeof(object).FullName}"; + var usingNode = new UsingDirectiveIntermediateNode() + { + Content = $"TModel = {typeName}" + }; + + visitor.Namespace?.Children.Insert(0, usingNode); + } + + var baseType = visitor.Class?.BaseType?.Replace("", "<" + modelType + ">"); + visitor.Class.BaseType = baseType; + } + } + + private class Visitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Namespace { get; private set; } + + public ClassDeclarationIntermediateNode Class { get; private set; } + + public IList ModelDirectives { get; } = new List(); + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + if (Namespace == null) + { + Namespace = node; + } + + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (Class == null) + { + Class = node; + } + + base.VisitClassDeclaration(node); + } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + ModelDirectives.Add(node); + } + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static IRazorEngineBuilder Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + return builder; + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ModelExpressionPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ModelExpressionPass.cs new file mode 100644 index 0000000000..7b44002ff9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ModelExpressionPass.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; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class ModelExpressionPass : IntermediateNodePassBase, IRazorOptimizationPass + { + private const string ModelExpressionTypeName = "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression"; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var visitor = new Visitor(); + visitor.Visit(documentNode); + } + + private class Visitor : IntermediateNodeWalker + { + public List TagHelpers { get; } = new List(); + + public override void VisitTagHelperProperty(TagHelperPropertyIntermediateNode node) + { + if (string.Equals(node.BoundAttribute.TypeName, ModelExpressionTypeName, StringComparison.Ordinal) || + (node.IsIndexerNameMatch && + string.Equals(node.BoundAttribute.IndexerTypeName, ModelExpressionTypeName, StringComparison.Ordinal))) + { + var expression = new CSharpExpressionIntermediateNode(); + + expression.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = "ModelExpressionProvider.CreateModelExpression(ViewData, __model => ", + }); + + if (node.Children.Count == 1 && node.Children[0] is IntermediateToken token && token.IsCSharp) + { + // A 'simple' expression will look like __model => __model.Foo + + expression.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = "__model." + }); + + expression.Children.Add(token); + } + else + { + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is CSharpExpressionIntermediateNode nestedExpression) + { + for (var j = 0; j < nestedExpression.Children.Count; j++) + { + if (nestedExpression.Children[j] is IntermediateToken cSharpToken && + cSharpToken.IsCSharp) + { + expression.Children.Add(cSharpToken); + } + } + + continue; + } + } + } + + expression.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = ")", + }); + + node.Children.Clear(); + + node.Children.Add(expression); + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcImportProjectFeature.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcImportProjectFeature.cs new file mode 100644 index 0000000000..5c6ee7361d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcImportProjectFeature.cs @@ -0,0 +1,91 @@ +// 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.IO; +using System.Linq; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + internal class MvcImportProjectFeature : RazorProjectEngineFeatureBase, IImportProjectFeature + { + private const string ImportsFileName = "_ViewImports.cshtml"; + + public IReadOnlyList GetImports(RazorProjectItem projectItem) + { + if (projectItem == null) + { + throw new ArgumentNullException(nameof(projectItem)); + } + + var imports = new List(); + AddDefaultDirectivesImport(imports); + + // We add hierarchical imports second so any default directive imports can be overridden. + AddHierarchicalImports(projectItem, imports); + + return imports; + } + + // Internal for testing + internal static void AddDefaultDirectivesImport(List imports) + { + imports.Add(DefaultDirectivesProjectItem.Instance); + } + + // Internal for testing + internal void AddHierarchicalImports(RazorProjectItem projectItem, List imports) + { + // We want items in descending order. FindHierarchicalItems returns items in ascending order. + var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(projectItem.FilePath, ImportsFileName).Reverse(); + imports.AddRange(importProjectItems); + } + + private class DefaultDirectivesProjectItem : RazorProjectItem + { + private readonly byte[] _defaultImportBytes; + + private DefaultDirectivesProjectItem() + { + var preamble = Encoding.UTF8.GetPreamble(); + var content = @" +@using System +@using System.Collections.Generic +@using System.Linq +@using System.Threading.Tasks +@using Microsoft.AspNetCore.Mvc +@using Microsoft.AspNetCore.Mvc.Rendering +@using Microsoft.AspNetCore.Mvc.ViewFeatures +@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html +@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json +@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component +@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url +@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider +@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor +@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor +@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor +"; + var contentBytes = Encoding.UTF8.GetBytes(content); + + _defaultImportBytes = new byte[preamble.Length + contentBytes.Length]; + preamble.CopyTo(_defaultImportBytes, 0); + contentBytes.CopyTo(_defaultImportBytes, preamble.Length); + } + + public override string BasePath => null; + + public override string FilePath => null; + + public override string PhysicalPath => null; + + public override bool Exists => true; + + public static DefaultDirectivesProjectItem Instance { get; } = new DefaultDirectivesProjectItem(); + + public override Stream Read() => new MemoryStream(_defaultImportBytes); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcRazorTemplateEngine.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcRazorTemplateEngine.cs new file mode 100644 index 0000000000..f278b20a45 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcRazorTemplateEngine.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 System.Text; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + /// + /// A for Mvc Razor views. + /// + public class MvcRazorTemplateEngine : RazorTemplateEngine + { + /// + /// Initializes a new instance of . + /// + /// The . + /// The . + public MvcRazorTemplateEngine( + RazorEngine engine, + RazorProject project) + : base(engine, project) + { + Options.ImportsFileName = "_ViewImports.cshtml"; + Options.DefaultImports = GetDefaultImports(); + } + + public override RazorCodeDocument CreateCodeDocument(RazorProjectItem projectItem) + { + return base.CreateCodeDocument(projectItem); + } + + // Internal for testing. + internal static RazorSourceDocument GetDefaultImports() + { + using (var stream = new MemoryStream()) + using (var writer = new StreamWriter(stream, Encoding.UTF8)) + { + writer.WriteLine("@using System"); + writer.WriteLine("@using System.Collections.Generic"); + writer.WriteLine("@using System.Linq"); + writer.WriteLine("@using System.Threading.Tasks"); + writer.WriteLine("@using Microsoft.AspNetCore.Mvc"); + writer.WriteLine("@using Microsoft.AspNetCore.Mvc.Rendering"); + writer.WriteLine("@using Microsoft.AspNetCore.Mvc.ViewFeatures"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url"); + writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider"); + writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor"); + writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor"); + writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor"); + writer.Flush(); + + stream.Position = 0; + return RazorSourceDocument.ReadFrom(stream, fileName: null, encoding: Encoding.UTF8); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcViewDocumentClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcViewDocumentClassifierPass.cs new file mode 100644 index 0000000000..975cf90666 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/MvcViewDocumentClassifierPass.cs @@ -0,0 +1,70 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class MvcViewDocumentClassifierPass : DocumentClassifierPassBase + { + public static readonly string MvcViewDocumentKind = "mvc.1.0.view"; + + protected override string DocumentKind => MvcViewDocumentKind; + + protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) => true; + + protected override void OnDocumentStructureCreated( + RazorCodeDocument codeDocument, + NamespaceDeclarationIntermediateNode @namespace, + ClassDeclarationIntermediateNode @class, + MethodDeclarationIntermediateNode method) + { + base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method); + + @namespace.Content = "AspNetCore"; + + var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath; + if (string.IsNullOrEmpty(filePath)) + { + // It's possible for a Razor document to not have a file path. + // Eg. When we try to generate code for an in memory document like default imports. + var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum()); + @class.ClassName = $"AspNetCore_{checksum}"; + } + else + { + @class.ClassName = GetClassNameFromPath(filePath); + } + + @class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage"; + @class.Modifiers.Clear(); + @class.Modifiers.Add("public"); + + method.MethodName = "ExecuteAsync"; + method.Modifiers.Clear(); + method.Modifiers.Add("public"); + method.Modifiers.Add("async"); + method.Modifiers.Add("override"); + method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}"; + } + + private static string GetClassNameFromPath(string path) + { + const string cshtmlExtension = ".cshtml"; + + if (string.IsNullOrEmpty(path)) + { + return path; + } + + if (path.EndsWith(cshtmlExtension, StringComparison.OrdinalIgnoreCase)) + { + path = path.Substring(0, path.Length - cshtmlExtension.Length); + } + + return CSharpIdentifier.SanitizeIdentifier(path); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/NamespaceDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/NamespaceDirective.cs new file mode 100644 index 0000000000..1a809c0629 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/NamespaceDirective.cs @@ -0,0 +1,204 @@ +// 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 System.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public static class NamespaceDirective + { + private static readonly char[] Separators = new char[] { '\\', '/' }; + + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "namespace", + DirectiveKind.SingleLine, + builder => + { + builder.AddNamespaceToken( + Resources.NamespaceDirective_NamespaceToken_Name, + Resources.NamespaceDirective_NamespaceToken_Description); + builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; + builder.Description = Resources.NamespaceDirective_Description; + }); + + public static void Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + } + + // internal for testing + internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind && + documentNode.DocumentKind != MvcViewDocumentClassifierPass.MvcViewDocumentKind) + { + // Not a page. Skip. + return; + } + + var visitor = new Visitor(); + visitor.Visit(documentNode); + + var directive = visitor.LastNamespaceDirective; + if (directive == null) + { + // No namespace set. Skip. + return; + } + + var @namespace = visitor.FirstNamespace; + if (@namespace == null) + { + // No namespace node. Skip. + return; + } + + @namespace.Content = GetNamespace(codeDocument.Source.FilePath, directive); + } + } + + // internal for testing. + // + // This code does a best-effort attempt to compute a namespace 'suffix' - the path difference between + // where the @namespace directive appears and where the current document is on disk. + // + // In the event that these two source either don't have FileNames set or don't follow a coherent hierarchy, + // we will just use the namespace verbatim. + internal static string GetNamespace(string source, DirectiveIntermediateNode directive) + { + var directiveSource = NormalizeDirectory(directive.Source?.FilePath); + + var baseNamespace = directive.Tokens.FirstOrDefault()?.Content; + if (string.IsNullOrEmpty(baseNamespace)) + { + // The namespace directive was incomplete. + return string.Empty; + } + + if (string.IsNullOrEmpty(source) || directiveSource == null) + { + // No sources, can't compute a suffix. + return baseNamespace; + } + + // We're specifically using OrdinalIgnoreCase here because Razor treats all paths as case-insensitive. + if (!source.StartsWith(directiveSource, StringComparison.OrdinalIgnoreCase) || + source.Length <= directiveSource.Length) + { + // The imports are not from the directory hierarchy, can't compute a suffix. + return baseNamespace; + } + + // OK so that this point we know that the 'imports' file containing this directive is in the directory + // hierarchy of this soure file. This is the case where we can append a suffix to the baseNamespace. + // + // Everything so far has just been defensiveness on our part. + + var builder = new StringBuilder(baseNamespace); + + var segments = source.Substring(directiveSource.Length).Split(Separators); + + // Skip the last segment because it's the FileName. + for (var i = 0; i < segments.Length - 1; i++) + { + builder.Append('.'); + builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[i])); + } + + return builder.ToString(); + } + + // We want to normalize the path of the file containing the '@namespace' directive to just the containing + // directory with a trailing separator. + // + // Not using Path.GetDirectoryName here because it doesn't meet these requirements, and we want to handle + // both 'view engine' style paths and absolute paths. + // + // We also don't normalize the separators here. We expect that all documents are using a consistent style of path. + // + // If we can't normalize the path, we just return null so it will be ignored. + private static string NormalizeDirectory(string path) + { + if (string.IsNullOrEmpty(path)) + { + return null; + } + + var lastSeparator = path.LastIndexOfAny(Separators); + if (lastSeparator == -1) + { + return null; + } + + // Includes the separator + return path.Substring(0, lastSeparator + 1); + } + + private class Visitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode FirstClass { get; private set; } + + public NamespaceDeclarationIntermediateNode FirstNamespace { get; private set; } + + // We want the last one, so get them all and then . + public DirectiveIntermediateNode LastNamespaceDirective { get; private set; } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + if (FirstNamespace == null) + { + FirstNamespace = node; + } + + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (FirstClass == null) + { + FirstClass = node; + } + + base.VisitClassDeclaration(node); + } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + LastNamespaceDirective = node; + } + + base.VisitDirective(node); + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static void Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(); + } + + builder.AddDirective(Directive); + builder.Features.Add(new Pass()); + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/PageDirective.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/PageDirective.cs new file mode 100644 index 0000000000..322c6564ef --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/PageDirective.cs @@ -0,0 +1,121 @@ +// 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.Diagnostics; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class PageDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + "page", + DirectiveKind.SingleLine, + builder => + { + builder.AddOptionalStringToken(Resources.PageDirective_RouteToken_Name, Resources.PageDirective_RouteToken_Description); + builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; + builder.Description = Resources.PageDirective_Description; + }); + + private PageDirective(string routeTemplate, IntermediateNode directiveNode) + { + RouteTemplate = routeTemplate; + DirectiveNode = directiveNode; + } + + public string RouteTemplate { get; } + + public IntermediateNode DirectiveNode { get; } + + public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + return builder; + } + + public static bool TryGetPageDirective(DocumentIntermediateNode documentNode, out PageDirective pageDirective) + { + var visitor = new Visitor(); + for (var i = 0; i < documentNode.Children.Count; i++) + { + visitor.Visit(documentNode.Children[i]); + } + + if (visitor.DirectiveTokens == null) + { + pageDirective = null; + return false; + } + + var tokens = visitor.DirectiveTokens.ToList(); + string routeTemplate = null; + if (tokens.Count > 0) + { + routeTemplate = TrimQuotes(tokens[0].Content); + } + + pageDirective = new PageDirective(routeTemplate, visitor.DirectiveNode); + return true; + } + + private static string TrimQuotes(string content) + { + // Tokens aren't captured if they're malformed. Therefore, this method will + // always be called with a valid token content. + Debug.Assert(content.Length >= 2); + Debug.Assert(content.StartsWith("\"", StringComparison.Ordinal)); + Debug.Assert(content.EndsWith("\"", StringComparison.Ordinal)); + + return content.Substring(1, content.Length - 2); + } + + private class Visitor : IntermediateNodeWalker + { + public IntermediateNode DirectiveNode { get; private set; } + + public IEnumerable DirectiveTokens { get; private set; } + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (node.Directive == Directive) + { + DirectiveNode = node; + DirectiveTokens = node.Tokens; + } + } + + public override void VisitMalformedDirective(MalformedDirectiveIntermediateNode node) + { + if (DirectiveTokens == null && node.Directive == Directive) + { + DirectiveNode = node; + DirectiveTokens = node.Tokens; + } + } + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static IRazorEngineBuilder Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + return builder; + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/PagesPropertyInjectionPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/PagesPropertyInjectionPass.cs new file mode 100644 index 0000000000..4a47275e13 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/PagesPropertyInjectionPass.cs @@ -0,0 +1,57 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class PagesPropertyInjectionPass : IntermediateNodePassBase, IRazorOptimizationPass + { + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind) + { + return; + } + + var modelType = ModelDirective.GetModelType(documentNode); + var visitor = new Visitor(); + visitor.Visit(documentNode); + + var @class = visitor.Class; + + var viewDataType = $"global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<{modelType}>"; + var vddProperty = new CSharpCodeIntermediateNode(); + vddProperty.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = $"public {viewDataType} ViewData => ({viewDataType})PageContext?.ViewData;", + }); + @class.Children.Add(vddProperty); + + var modelProperty = new CSharpCodeIntermediateNode(); + modelProperty.Children.Add(new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = $"public {modelType} Model => ViewData.Model;", + }); + @class.Children.Add(modelProperty); + } + + private class Visitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Class { get; private set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + if (Class == null) + { + Class = node; + } + + base.VisitClassDeclaration(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..7d8a47bc67 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/AssemblyInfo.cs @@ -0,0 +1,11 @@ +// 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; +using Microsoft.AspNetCore.Mvc.Razor.Extensions; +using Microsoft.AspNetCore.Razor.Language; + +[assembly: ProvideRazorExtensionInitializer("MVC-3.0", typeof(ExtensionInitializer))] + +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] +[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/Resources.Designer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..dfa9a59ca9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/Resources.Designer.cs @@ -0,0 +1,338 @@ +// +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class Resources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNetCore.Mvc.Razor.Extensions.Resources", typeof(Resources).GetTypeInfo().Assembly); + + /// + /// Value cannot be null or empty. + /// + internal static string ArgumentCannotBeNullOrEmpty + { + get => GetString("ArgumentCannotBeNullOrEmpty"); + } + + /// + /// Value cannot be null or empty. + /// + internal static string FormatArgumentCannotBeNullOrEmpty() + => GetString("ArgumentCannotBeNullOrEmpty"); + + /// + /// Inject a service from the application's service container into a property. + /// + internal static string InjectDirective_Description + { + get => GetString("InjectDirective_Description"); + } + + /// + /// Inject a service from the application's service container into a property. + /// + internal static string FormatInjectDirective_Description() + => GetString("InjectDirective_Description"); + + /// + /// The name of the property. + /// + internal static string InjectDirective_MemberToken_Description + { + get => GetString("InjectDirective_MemberToken_Description"); + } + + /// + /// The name of the property. + /// + internal static string FormatInjectDirective_MemberToken_Description() + => GetString("InjectDirective_MemberToken_Description"); + + /// + /// PropertyName + /// + internal static string InjectDirective_MemberToken_Name + { + get => GetString("InjectDirective_MemberToken_Name"); + } + + /// + /// PropertyName + /// + internal static string FormatInjectDirective_MemberToken_Name() + => GetString("InjectDirective_MemberToken_Name"); + + /// + /// The type of the service to inject. + /// + internal static string InjectDirective_TypeToken_Description + { + get => GetString("InjectDirective_TypeToken_Description"); + } + + /// + /// The type of the service to inject. + /// + internal static string FormatInjectDirective_TypeToken_Description() + => GetString("InjectDirective_TypeToken_Description"); + + /// + /// TypeName + /// + internal static string InjectDirective_TypeToken_Name + { + get => GetString("InjectDirective_TypeToken_Name"); + } + + /// + /// TypeName + /// + internal static string FormatInjectDirective_TypeToken_Name() + => GetString("InjectDirective_TypeToken_Name"); + + /// + /// Specify the view or page model for the page. + /// + internal static string ModelDirective_Description + { + get => GetString("ModelDirective_Description"); + } + + /// + /// Specify the view or page model for the page. + /// + internal static string FormatModelDirective_Description() + => GetString("ModelDirective_Description"); + + /// + /// The model type. + /// + internal static string ModelDirective_TypeToken_Description + { + get => GetString("ModelDirective_TypeToken_Description"); + } + + /// + /// The model type. + /// + internal static string FormatModelDirective_TypeToken_Description() + => GetString("ModelDirective_TypeToken_Description"); + + /// + /// TypeName + /// + internal static string ModelDirective_TypeToken_Name + { + get => GetString("ModelDirective_TypeToken_Name"); + } + + /// + /// TypeName + /// + internal static string FormatModelDirective_TypeToken_Name() + => GetString("ModelDirective_TypeToken_Name"); + + /// + /// The 'inherits' keyword is not allowed when a '{0}' keyword is used. + /// + internal static string MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword + { + get => GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword"); + } + + /// + /// The 'inherits' keyword is not allowed when a '{0}' keyword is used. + /// + internal static string FormatMvcRazorCodeParser_CannotHaveModelAndInheritsKeyword(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword"), p0); + + /// + /// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'. + /// + internal static string MvcRazorCodeParser_InjectDirectivePropertyNameRequired + { + get => GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired"); + } + + /// + /// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'. + /// + internal static string FormatMvcRazorCodeParser_InjectDirectivePropertyNameRequired(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired"), p0); + + /// + /// The '{0}' keyword must be followed by a type name on the same line. + /// + internal static string MvcRazorCodeParser_KeywordMustBeFollowedByTypeName + { + get => GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName"); + } + + /// + /// The '{0}' keyword must be followed by a type name on the same line. + /// + internal static string FormatMvcRazorCodeParser_KeywordMustBeFollowedByTypeName(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName"), p0); + + /// + /// Only one '{0}' statement is allowed in a file. + /// + internal static string MvcRazorCodeParser_OnlyOneModelStatementIsAllowed + { + get => GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed"); + } + + /// + /// Only one '{0}' statement is allowed in a file. + /// + internal static string FormatMvcRazorCodeParser_OnlyOneModelStatementIsAllowed(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed"), p0); + + /// + /// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'. + /// + internal static string MvcRazorParser_InvalidPropertyType + { + get => GetString("MvcRazorParser_InvalidPropertyType"); + } + + /// + /// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'. + /// + internal static string FormatMvcRazorParser_InvalidPropertyType(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorParser_InvalidPropertyType"), p0, p1, p2); + + /// + /// Specify the base namespace for the page. + /// + internal static string NamespaceDirective_Description + { + get => GetString("NamespaceDirective_Description"); + } + + /// + /// Specify the base namespace for the page. + /// + internal static string FormatNamespaceDirective_Description() + => GetString("NamespaceDirective_Description"); + + /// + /// The namespace for the page. + /// + internal static string NamespaceDirective_NamespaceToken_Description + { + get => GetString("NamespaceDirective_NamespaceToken_Description"); + } + + /// + /// The namespace for the page. + /// + internal static string FormatNamespaceDirective_NamespaceToken_Description() + => GetString("NamespaceDirective_NamespaceToken_Description"); + + /// + /// Namespace + /// + internal static string NamespaceDirective_NamespaceToken_Name + { + get => GetString("NamespaceDirective_NamespaceToken_Name"); + } + + /// + /// Namespace + /// + internal static string FormatNamespaceDirective_NamespaceToken_Name() + => GetString("NamespaceDirective_NamespaceToken_Name"); + + /// + /// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file. + /// + internal static string PageDirectiveCannotBeImported + { + get => GetString("PageDirectiveCannotBeImported"); + } + + /// + /// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file. + /// + internal static string FormatPageDirectiveCannotBeImported(object p0, object p1) + => string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveCannotBeImported"), p0, p1); + + /// + /// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive. + /// + internal static string PageDirectiveMustExistAtTheTopOfFile + { + get => GetString("PageDirectiveMustExistAtTheTopOfFile"); + } + + /// + /// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive. + /// + internal static string FormatPageDirectiveMustExistAtTheTopOfFile(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveMustExistAtTheTopOfFile"), p0); + + /// + /// Mark the page as a Razor Page. + /// + internal static string PageDirective_Description + { + get => GetString("PageDirective_Description"); + } + + /// + /// Mark the page as a Razor Page. + /// + internal static string FormatPageDirective_Description() + => GetString("PageDirective_Description"); + + /// + /// An optional route template for the page. + /// + internal static string PageDirective_RouteToken_Description + { + get => GetString("PageDirective_RouteToken_Description"); + } + + /// + /// An optional route template for the page. + /// + internal static string FormatPageDirective_RouteToken_Description() + => GetString("PageDirective_RouteToken_Description"); + + /// + /// RouteTemplate + /// + internal static string PageDirective_RouteToken_Name + { + get => GetString("PageDirective_RouteToken_Name"); + } + + /// + /// RouteTemplate + /// + internal static string FormatPageDirective_RouteToken_Name() + => GetString("PageDirective_RouteToken_Name"); + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/ViewComponentResources.Designer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/ViewComponentResources.Designer.cs new file mode 100644 index 0000000000..514af37554 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Properties/ViewComponentResources.Designer.cs @@ -0,0 +1,100 @@ +// +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class ViewComponentResources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentResources", typeof(ViewComponentResources).GetTypeInfo().Assembly); + + /// + /// View component '{0}' must have exactly one public method named '{1}' or '{2}'. + /// + internal static string ViewComponent_AmbiguousMethods + { + get => GetString("ViewComponent_AmbiguousMethods"); + } + + /// + /// View component '{0}' must have exactly one public method named '{1}' or '{2}'. + /// + internal static string FormatViewComponent_AmbiguousMethods(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AmbiguousMethods"), p0, p1, p2); + + /// + /// Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;. + /// + internal static string ViewComponent_AsyncMethod_ShouldReturnTask + { + get => GetString("ViewComponent_AsyncMethod_ShouldReturnTask"); + } + + /// + /// Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;. + /// + internal static string FormatViewComponent_AsyncMethod_ShouldReturnTask(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AsyncMethod_ShouldReturnTask"), p0, p1, p2); + + /// + /// Could not find an '{0}' or '{1}' method for the view component '{2}'. + /// + internal static string ViewComponent_CannotFindMethod + { + get => GetString("ViewComponent_CannotFindMethod"); + } + + /// + /// Could not find an '{0}' or '{1}' method for the view component '{2}'. + /// + internal static string FormatViewComponent_CannotFindMethod(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_CannotFindMethod"), p0, p1, p2); + + /// + /// Method '{0}' of view component '{1}' cannot return a {2}. + /// + internal static string ViewComponent_SyncMethod_CannotReturnTask + { + get => GetString("ViewComponent_SyncMethod_CannotReturnTask"); + } + + /// + /// Method '{0}' of view component '{1}' cannot return a {2}. + /// + internal static string FormatViewComponent_SyncMethod_CannotReturnTask(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_CannotReturnTask"), p0, p1, p2); + + /// + /// Method '{0}' of view component '{1}' should be declared to return a value. + /// + internal static string ViewComponent_SyncMethod_ShouldReturnValue + { + get => GetString("ViewComponent_SyncMethod_ShouldReturnValue"); + } + + /// + /// Method '{0}' of view component '{1}' should be declared to return a value. + /// + internal static string FormatViewComponent_SyncMethod_ShouldReturnValue(object p0, object p1) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_ShouldReturnValue"), p0, p1); + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorExtensions.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorExtensions.cs new file mode 100644 index 0000000000..04febb17d6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorExtensions.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 System; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.CodeAnalysis.Razor; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public static class RazorExtensions + { + public static void Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + InjectDirective.Register(builder); + ModelDirective.Register(builder); + NamespaceDirective.Register(builder); + PageDirective.Register(builder); + + InheritsDirective.Register(builder); + SectionDirective.Register(builder); + + builder.Features.Add(new DefaultTagHelperDescriptorProvider()); + builder.Features.Add(new ViewComponentTagHelperDescriptorProvider()); + + builder.AddTargetExtension(new ViewComponentTagHelperTargetExtension()); + builder.AddTargetExtension(new TemplateTargetExtension() + { + TemplateTypeName = "global::Microsoft.AspNetCore.Mvc.Razor.HelperResult", + }); + + builder.Features.Add(new ModelExpressionPass()); + builder.Features.Add(new PagesPropertyInjectionPass()); + builder.Features.Add(new ViewComponentTagHelperPass()); + builder.Features.Add(new RazorPageDocumentClassifierPass()); + builder.Features.Add(new MvcViewDocumentClassifierPass()); + builder.Features.Add(new AssemblyAttributeInjectionPass()); + + builder.SetImportFeature(new MvcImportProjectFeature()); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorExtensionsDiagnosticFactory.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorExtensionsDiagnosticFactory.cs new file mode 100644 index 0000000000..74adb4fe93 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorExtensionsDiagnosticFactory.cs @@ -0,0 +1,131 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + internal class RazorExtensionsDiagnosticFactory + { + private const string DiagnosticPrefix = "RZ"; + + internal static readonly RazorDiagnosticDescriptor ViewComponent_CannotFindMethod = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3900", + () => ViewComponentResources.ViewComponent_CannotFindMethod, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_CannotFindMethod(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_CannotFindMethod, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.SyncMethodName, + ViewComponentTypes.AsyncMethodName, + tagHelperType); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_AmbiguousMethods = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3901", + () => ViewComponentResources.ViewComponent_AmbiguousMethods, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_AmbiguousMethods(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_AmbiguousMethods, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + tagHelperType, + ViewComponentTypes.SyncMethodName, + ViewComponentTypes.AsyncMethodName); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_AsyncMethod_ShouldReturnTask = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3902", + () => ViewComponentResources.ViewComponent_AsyncMethod_ShouldReturnTask, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_AsyncMethod_ShouldReturnTask(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_AsyncMethod_ShouldReturnTask, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.AsyncMethodName, + tagHelperType, + nameof(Task)); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_ShouldReturnValue = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3903", + () => ViewComponentResources.ViewComponent_SyncMethod_ShouldReturnValue, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_SyncMethod_ShouldReturnValue(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_SyncMethod_ShouldReturnValue, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.SyncMethodName, + tagHelperType); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_CannotReturnTask = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3904", + () => ViewComponentResources.ViewComponent_SyncMethod_CannotReturnTask, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreateViewComponent_SyncMethod_CannotReturnTask(string tagHelperType) + { + var diagnostic = RazorDiagnostic.Create( + ViewComponent_SyncMethod_CannotReturnTask, + new SourceSpan(SourceLocation.Undefined, contentLength: 0), + ViewComponentTypes.SyncMethodName, + tagHelperType, + nameof(Task)); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor PageDirective_CannotBeImported = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3905", + () => Resources.PageDirectiveCannotBeImported, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreatePageDirective_CannotBeImported(SourceSpan source) + { + var fileName = Path.GetFileName(source.FilePath); + var diagnostic = RazorDiagnostic.Create(PageDirective_CannotBeImported, source, PageDirective.Directive.Directive, fileName); + + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor PageDirective_MustExistAtTheTopOfFile = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}3906", + () => Resources.PageDirectiveMustExistAtTheTopOfFile, + RazorDiagnosticSeverity.Error); + + public static RazorDiagnostic CreatePageDirective_MustExistAtTheTopOfFile(SourceSpan source) + { + var fileName = Path.GetFileName(source.FilePath); + var diagnostic = RazorDiagnostic.Create(PageDirective_MustExistAtTheTopOfFile, source, PageDirective.Directive.Directive); + + return diagnostic; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorPageDocumentClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorPageDocumentClassifierPass.cs new file mode 100644 index 0000000000..c6c0df9345 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/RazorPageDocumentClassifierPass.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 System; +using System.Diagnostics; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class RazorPageDocumentClassifierPass : DocumentClassifierPassBase + { + public static readonly string RazorPageDocumentKind = "mvc.1.0.razor-page"; + public static readonly string RouteTemplateKey = "RouteTemplate"; + + private static readonly RazorProjectEngine LeadingDirectiveParsingEngine = RazorProjectEngine.Create( + RazorConfiguration.Default, + RazorProjectFileSystem.Create("/"), + builder => + { + for (var i = builder.Phases.Count - 1; i >= 0; i--) + { + var phase = builder.Phases[i]; + builder.Phases.RemoveAt(i); + if (phase is IRazorDocumentClassifierPhase) + { + break; + } + } + + RazorExtensions.Register(builder); + builder.Features.Add(new LeadingDirectiveParserOptionsFeature()); + }); + + protected override string DocumentKind => RazorPageDocumentKind; + + protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + return PageDirective.TryGetPageDirective(documentNode, out var pageDirective); + } + + protected override void OnDocumentStructureCreated( + RazorCodeDocument codeDocument, + NamespaceDeclarationIntermediateNode @namespace, + ClassDeclarationIntermediateNode @class, + MethodDeclarationIntermediateNode method) + { + base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method); + + @namespace.Content = "AspNetCore"; + + @class.BaseType = "global::Microsoft.AspNetCore.Mvc.RazorPages.Page"; + + var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath; + if (string.IsNullOrEmpty(filePath)) + { + // It's possible for a Razor document to not have a file path. + // Eg. When we try to generate code for an in memory document like default imports. + var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum()); + @class.ClassName = $"AspNetCore_{checksum}"; + } + else + { + @class.ClassName = GetClassNameFromPath(filePath); + } + + @class.Modifiers.Clear(); + @class.Modifiers.Add("public"); + + method.MethodName = "ExecuteAsync"; + method.Modifiers.Clear(); + method.Modifiers.Add("public"); + method.Modifiers.Add("async"); + method.Modifiers.Add("override"); + method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}"; + + var document = codeDocument.GetDocumentIntermediateNode(); + PageDirective.TryGetPageDirective(document, out var pageDirective); + + EnsureValidPageDirective(codeDocument, pageDirective); + + AddRouteTemplateMetadataAttribute(@namespace, @class, pageDirective); + } + + private static void AddRouteTemplateMetadataAttribute(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class, PageDirective pageDirective) + { + if (string.IsNullOrEmpty(pageDirective.RouteTemplate)) + { + return; + } + + var classIndex = @namespace.Children.IndexOf(@class); + if (classIndex == -1) + { + return; + } + + var metadataAttributeNode = new RazorCompiledItemMetadataAttributeIntermediateNode + { + Key = RouteTemplateKey, + Value = pageDirective.RouteTemplate, + }; + // Metadata attributes need to be inserted right before the class declaration. + @namespace.Children.Insert(classIndex, metadataAttributeNode); + } + + private void EnsureValidPageDirective(RazorCodeDocument codeDocument, PageDirective pageDirective) + { + Debug.Assert(pageDirective != null); + + if (pageDirective.DirectiveNode.IsImported()) + { + pageDirective.DirectiveNode.Diagnostics.Add( + RazorExtensionsDiagnosticFactory.CreatePageDirective_CannotBeImported(pageDirective.DirectiveNode.Source.Value)); + } + else + { + // The document contains a page directive and it is not imported. + // We now want to make sure this page directive exists at the top of the file. + // We are going to do that by re-parsing the document until the very first line that is not Razor comment + // or whitespace. We then make sure the page directive still exists in the re-parsed IR tree. + var leadingDirectiveCodeDocument = RazorCodeDocument.Create(codeDocument.Source); + LeadingDirectiveParsingEngine.Engine.Process(leadingDirectiveCodeDocument); + + var leadingDirectiveDocumentNode = leadingDirectiveCodeDocument.GetDocumentIntermediateNode(); + if (!PageDirective.TryGetPageDirective(leadingDirectiveDocumentNode, out var _)) + { + // The page directive is not the leading directive. Add an error. + pageDirective.DirectiveNode.Diagnostics.Add( + RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(pageDirective.DirectiveNode.Source.Value)); + } + } + } + + private class LeadingDirectiveParserOptionsFeature : RazorEngineFeatureBase, IConfigureRazorParserOptionsFeature + { + public int Order { get; } + + public void Configure(RazorParserOptionsBuilder options) + { + options.ParseLeadingDirectives = true; + } + } + + private static string GetClassNameFromPath(string path) + { + const string cshtmlExtension = ".cshtml"; + + if (string.IsNullOrEmpty(path)) + { + return path; + } + + if (path.EndsWith(cshtmlExtension, StringComparison.OrdinalIgnoreCase)) + { + path = path.Substring(0, path.Length - cshtmlExtension.Length); + } + + return CSharpIdentifier.SanitizeIdentifier(path); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Resources.resx b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Resources.resx new file mode 100644 index 0000000000..474537197e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/Resources.resx @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Value cannot be null or empty. + + + Inject a service from the application's service container into a property. + + + The name of the property. + + + PropertyName + + + The type of the service to inject. + + + TypeName + + + Specify the view or page model for the page. + + + The model type. + + + TypeName + + + The 'inherits' keyword is not allowed when a '{0}' keyword is used. + + + A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'. + + + The '{0}' keyword must be followed by a type name on the same line. + + + Only one '{0}' statement is allowed in a file. + + + Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'. + + + Specify the base namespace for the page. + + + The namespace for the page. + + + Namespace + + + The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file. + + + The '@{0}' directive must precede all other elements defined in a Razor file. + + + Mark the page as a Razor Page. + + + An optional route template for the page. + + + RouteTemplate + + \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/TagHelperDescriptorExtensions.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/TagHelperDescriptorExtensions.cs new file mode 100644 index 0000000000..dd32c0b013 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/TagHelperDescriptorExtensions.cs @@ -0,0 +1,37 @@ +// 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; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public static class TagHelperDescriptorExtensions + { + /// + /// Indicates whether a represents a view component. + /// + /// The to check. + /// Whether a represents a view component. + public static bool IsViewComponentKind(this TagHelperDescriptor tagHelper) + { + if (tagHelper == null) + { + throw new ArgumentNullException(nameof(tagHelper)); + } + + return string.Equals(ViewComponentTagHelperConventions.Kind, tagHelper.Kind, StringComparison.Ordinal); + } + + public static string GetViewComponentName(this TagHelperDescriptor tagHelper) + { + if (tagHelper == null) + { + throw new ArgumentNullException(nameof(tagHelper)); + } + + tagHelper.Metadata.TryGetValue(ViewComponentTagHelperMetadata.Name, out var result); + return result; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentResources.resx b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentResources.resx new file mode 100644 index 0000000000..d6aad4ff3f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentResources.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + View component '{0}' must have exactly one public method named '{1}' or '{2}'. + + + Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;. + + + Could not find an '{0}' or '{1}' method for the view component '{2}'. + + + Method '{0}' of view component '{1}' cannot return a {2}. + + + Method '{0}' of view component '{1}' should be declared to return a value. + + \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperConventions.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperConventions.cs new file mode 100644 index 0000000000..fa7563d37b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperConventions.cs @@ -0,0 +1,10 @@ +// 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.Mvc.Razor.Extensions +{ + public static class ViewComponentTagHelperConventions + { + public static readonly string Kind = "MVC.ViewComponent"; + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorFactory.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorFactory.cs new file mode 100644 index 0000000000..a5181fd789 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorFactory.cs @@ -0,0 +1,284 @@ +// 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.Collections.Immutable; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + internal class ViewComponentTagHelperDescriptorFactory + { + private readonly INamedTypeSymbol _viewComponentAttributeSymbol; + private readonly INamedTypeSymbol _genericTaskSymbol; + private readonly INamedTypeSymbol _taskSymbol; + private readonly INamedTypeSymbol _iDictionarySymbol; + + private static readonly SymbolDisplayFormat FullNameTypeDisplayFormat = + SymbolDisplayFormat.FullyQualifiedFormat + .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted) + .WithMiscellaneousOptions(SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions & (~SymbolDisplayMiscellaneousOptions.UseSpecialTypes)); + + private static readonly IReadOnlyDictionary PrimitiveDisplayTypeNameLookups = new Dictionary(StringComparer.Ordinal) + { + [typeof(byte).FullName] = "byte", + [typeof(sbyte).FullName] = "sbyte", + [typeof(int).FullName] = "int", + [typeof(uint).FullName] = "uint", + [typeof(short).FullName] = "short", + [typeof(ushort).FullName] = "ushort", + [typeof(long).FullName] = "long", + [typeof(ulong).FullName] = "ulong", + [typeof(float).FullName] = "float", + [typeof(double).FullName] = "double", + [typeof(char).FullName] = "char", + [typeof(bool).FullName] = "bool", + [typeof(object).FullName] = "object", + [typeof(string).FullName] = "string", + [typeof(decimal).FullName] = "decimal", + }; + + public ViewComponentTagHelperDescriptorFactory(Compilation compilation) + { + _viewComponentAttributeSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute); + _genericTaskSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.GenericTask); + _taskSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.Task); + _iDictionarySymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.IDictionary); + } + + public virtual TagHelperDescriptor CreateDescriptor(INamedTypeSymbol type) + { + var assemblyName = type.ContainingAssembly.Name; + var shortName = GetShortName(type); + var tagName = $"vc:{HtmlConventions.ToHtmlCase(shortName)}"; + var typeName = $"__Generated__{shortName}ViewComponentTagHelper"; + var displayName = shortName + "ViewComponentTagHelper"; + var descriptorBuilder = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, typeName, assemblyName); + descriptorBuilder.SetTypeName(typeName); + descriptorBuilder.DisplayName = displayName; + + if (TryFindInvokeMethod(type, out var method, out var diagnostic)) + { + var methodParameters = method.Parameters; + descriptorBuilder.TagMatchingRule(ruleBuilder => + { + ruleBuilder.TagName = tagName; + AddRequiredAttributes(methodParameters, ruleBuilder); + }); + + AddBoundAttributes(methodParameters, displayName, descriptorBuilder); + } + else + { + descriptorBuilder.Diagnostics.Add(diagnostic); + } + + descriptorBuilder.Metadata[ViewComponentTagHelperMetadata.Name] = shortName; + + var descriptor = descriptorBuilder.Build(); + return descriptor; + } + + private bool TryFindInvokeMethod(INamedTypeSymbol type, out IMethodSymbol method, out RazorDiagnostic diagnostic) + { + var methods = GetInvokeMethods(type); + + if (methods.Count == 0) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_CannotFindMethod(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + else if (methods.Count > 1) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_AmbiguousMethods(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + + var selectedMethod = methods[0]; + var returnType = selectedMethod.ReturnType as INamedTypeSymbol; + if (string.Equals(selectedMethod.Name, ViewComponentTypes.AsyncMethodName, StringComparison.Ordinal)) + { + // Will invoke asynchronously. Method must not return Task or Task. + if (returnType == _taskSymbol) + { + // This is ok. + } + else if (returnType.IsGenericType && returnType.ConstructedFrom == _genericTaskSymbol) + { + // This is ok. + } + else + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_AsyncMethod_ShouldReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + } + else + { + // Will invoke synchronously. Method must not return void, Task or Task. + if (returnType.SpecialType == SpecialType.System_Void) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_ShouldReturnValue(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + else if (returnType == _taskSymbol) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_CannotReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + else if (returnType.IsGenericType && returnType.ConstructedFrom == _genericTaskSymbol) + { + diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_CannotReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat)); + method = null; + return false; + } + } + + method = selectedMethod; + diagnostic = null; + return true; + } + + private static IReadOnlyList GetInvokeMethods(INamedTypeSymbol type) + { + var methods = new List(); + while (type != null) + { + var currentTypeMethods = type.GetMembers() + .OfType() + .Where(m => + m.DeclaredAccessibility == Accessibility.Public && + !m.IsStatic && + (string.Equals(m.Name, ViewComponentTypes.AsyncMethodName, StringComparison.Ordinal) || + string.Equals(m.Name, ViewComponentTypes.SyncMethodName, StringComparison.Ordinal))); + + methods.AddRange(currentTypeMethods); + + type = type.BaseType; + } + + return methods; + } + + private void AddRequiredAttributes(ImmutableArray methodParameters, TagMatchingRuleDescriptorBuilder builder) + { + foreach (var parameter in methodParameters) + { + if (GetIndexerValueTypeName(parameter) == null) + { + // Set required attributes only for non-indexer attributes. Indexer attributes can't be required attributes + // because there are two ways of setting values for the attribute. + builder.Attribute(attributeBuilder => + { + var lowerKebabName = HtmlConventions.ToHtmlCase(parameter.Name); + attributeBuilder.Name = lowerKebabName; + }); + } + } + } + + private void AddBoundAttributes(ImmutableArray methodParameters, string containingDisplayName, TagHelperDescriptorBuilder builder) + { + foreach (var parameter in methodParameters) + { + var lowerKebabName = HtmlConventions.ToHtmlCase(parameter.Name); + var typeName = parameter.Type.ToDisplayString(FullNameTypeDisplayFormat); + + if (!PrimitiveDisplayTypeNameLookups.TryGetValue(typeName, out var simpleName)) + { + simpleName = typeName; + } + + builder.BindAttribute(attributeBuilder => + { + attributeBuilder.Name = lowerKebabName; + attributeBuilder.TypeName = typeName; + attributeBuilder.DisplayName = $"{simpleName} {containingDisplayName}.{parameter.Name}"; + attributeBuilder.SetPropertyName(parameter.Name); + + if (parameter.Type.TypeKind == TypeKind.Enum) + { + attributeBuilder.IsEnum = true; + } + else + { + var dictionaryValueType = GetIndexerValueTypeName(parameter); + if (dictionaryValueType != null) + { + attributeBuilder.AsDictionary(lowerKebabName + "-", dictionaryValueType); + } + } + }); + } + } + + private string GetIndexerValueTypeName(IParameterSymbol parameter) + { + INamedTypeSymbol dictionaryType; + if ((parameter.Type as INamedTypeSymbol)?.ConstructedFrom == _iDictionarySymbol) + { + dictionaryType = (INamedTypeSymbol)parameter.Type; + } + else if (parameter.Type.AllInterfaces.Any(s => s.ConstructedFrom == _iDictionarySymbol)) + { + dictionaryType = parameter.Type.AllInterfaces.First(s => s.ConstructedFrom == _iDictionarySymbol); + } + else + { + dictionaryType = null; + } + + if (dictionaryType == null || dictionaryType.TypeArguments[0].SpecialType != SpecialType.System_String) + { + return null; + } + + var type = dictionaryType.TypeArguments[1]; + var typeName = type.ToDisplayString(FullNameTypeDisplayFormat); + + return typeName; + } + + private string GetShortName(INamedTypeSymbol componentType) + { + var viewComponentAttribute = componentType.GetAttributes().Where(a => a.AttributeClass == _viewComponentAttributeSymbol).FirstOrDefault(); + var name = viewComponentAttribute + ?.NamedArguments + .Where(namedArgument => string.Equals(namedArgument.Key, ViewComponentTypes.ViewComponent.Name, StringComparison.Ordinal)) + .FirstOrDefault() + .Value + .Value as string; + + if (!string.IsNullOrEmpty(name)) + { + var separatorIndex = name.LastIndexOf('.'); + if (separatorIndex >= 0) + { + return name.Substring(separatorIndex + 1); + } + else + { + return name; + } + } + + // Get name by convention + if (componentType.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix, StringComparison.OrdinalIgnoreCase)) + { + return componentType.Name.Substring(0, componentType.Name.Length - ViewComponentTypes.ViewComponentSuffix.Length); + } + else + { + return componentType.Name; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorProvider.cs new file mode 100644 index 0000000000..d0d9805f6b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorProvider.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.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Razor; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public sealed class ViewComponentTagHelperDescriptorProvider : RazorEngineFeatureBase, ITagHelperDescriptorProvider + { + public int Order { get; set; } + + public void Execute(TagHelperDescriptorProviderContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var compilation = context.GetCompilation(); + if (compilation == null) + { + // No compilation, nothing to do. + return; + } + + var vcAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute); + var nonVCAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.NonViewComponentAttribute); + if (vcAttribute == null || vcAttribute.TypeKind == TypeKind.Error) + { + // Could not find attributes we care about in the compilation. Nothing to do. + return; + } + + var types = new List(); + var visitor = new ViewComponentTypeVisitor(vcAttribute, nonVCAttribute, types); + + // We always visit the global namespace. + visitor.Visit(compilation.Assembly.GlobalNamespace); + + foreach (var reference in compilation.References) + { + if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly) + { + if (IsTagHelperAssembly(assembly)) + { + visitor.Visit(assembly.GlobalNamespace); + } + } + } + + var factory = new ViewComponentTagHelperDescriptorFactory(compilation); + for (var i = 0; i < types.Count; i++) + { + var descriptor = factory.CreateDescriptor(types[i]); + + if (descriptor != null) + { + context.Results.Add(descriptor); + } + } + } + + private bool IsTagHelperAssembly(IAssemblySymbol assembly) + { + return assembly.Name != null && !assembly.Name.StartsWith("System.", StringComparison.Ordinal); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperIntermediateNode.cs new file mode 100644 index 0000000000..9283b2c092 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperIntermediateNode.cs @@ -0,0 +1,59 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public sealed class ViewComponentTagHelperIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = IntermediateNodeCollection.ReadOnly; + + public string ClassName { get; set; } + + public TagHelperDescriptor TagHelper { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteViewComponentTagHelper(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(ClassName); + + formatter.WriteProperty(nameof(ClassName), ClassName); + formatter.WriteProperty(nameof(TagHelper), TagHelper?.DisplayName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperMetadata.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperMetadata.cs new file mode 100644 index 0000000000..ca8aae361d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperMetadata.cs @@ -0,0 +1,14 @@ +// 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.Mvc.Razor.Extensions +{ + public static class ViewComponentTagHelperMetadata + { + /// + /// The key in a containing + /// the short name of a view component. + /// + public static readonly string Name = "MVC.ViewComponent.Name"; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperPass.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperPass.cs new file mode 100644 index 0000000000..0c3b14563e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperPass.cs @@ -0,0 +1,203 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class ViewComponentTagHelperPass : IntermediateNodePassBase, IRazorOptimizationPass + { + // Run after the default taghelper pass + public override int Order => IntermediateNodePassBase.DefaultFeatureOrder + 2000; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var @namespace = documentNode.FindPrimaryNamespace(); + var @class = documentNode.FindPrimaryClass(); + if (@namespace == null || @class == null) + { + // Nothing to do, bail. We can't function without the standard structure. + return; + } + + var context = new Context(@namespace, @class); + + // For each VCTH *usage* we need to rewrite the tag helper node to use the tag helper runtime to construct + // and set properties on the the correct field, and using the name of the type we will generate. + var nodes = documentNode.FindDescendantNodes(); + for (var i = 0; i < nodes.Count; i++) + { + var node = nodes[i]; + foreach (var tagHelper in node.TagHelpers) + { + RewriteUsage(context, node, tagHelper); + } + } + + // Then for each VCTH *definition* that we've seen we need to generate the class that implements + // ITagHelper and the field that will hold it. + foreach (var tagHelper in context.TagHelpers) + { + AddField(context, tagHelper); + AddTagHelperClass(context, tagHelper); + } + } + + private void RewriteUsage(Context context, TagHelperIntermediateNode node, TagHelperDescriptor tagHelper) + { + if (!tagHelper.IsViewComponentKind()) + { + return; + } + + context.Add(tagHelper); + + // Now we need to insert a create node using the default tag helper runtime. This is similar to + // code in DefaultTagHelperOptimizationPass. + // + // Find the body node. + var i = 0; + while (i < node.Children.Count && node.Children[i] is TagHelperBodyIntermediateNode) + { + i++; + } + while (i < node.Children.Count && node.Children[i] is DefaultTagHelperBodyIntermediateNode) + { + i++; + } + + // Now find the last create node. + while (i < node.Children.Count && node.Children[i] is DefaultTagHelperCreateIntermediateNode) + { + i++; + } + + // Now i has the right insertion point. + node.Children.Insert(i, new DefaultTagHelperCreateIntermediateNode() + { + FieldName = context.GetFieldName(tagHelper), + TagHelper = tagHelper, + TypeName = context.GetFullyQualifiedName(tagHelper), + }); + + // Now we need to rewrite any set property nodes to use the default runtime. + for (i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode && + propertyNode.TagHelper == tagHelper) + { + // This is a set property for this VCTH - we need to replace it with a node + // that will use our field and property name. + node.Children[i] = new DefaultTagHelperPropertyIntermediateNode(propertyNode) + { + FieldName = context.GetFieldName(tagHelper), + PropertyName = propertyNode.BoundAttribute.GetPropertyName(), + }; + } + } + } + + private void AddField(Context context, TagHelperDescriptor tagHelper) + { + // We need to insert a node for the field that will hold the tag helper. We've already generated a field name + // at this time and use it for all uses of the same tag helper type. + // + // We also want to preserve the ordering of the nodes for testability. So insert at the end of any existing + // field nodes. + var i = 0; + while (i < context.Class.Children.Count && context.Class.Children[i] is DefaultTagHelperRuntimeIntermediateNode) + { + i++; + } + + while (i < context.Class.Children.Count && context.Class.Children[i] is FieldDeclarationIntermediateNode) + { + i++; + } + + context.Class.Children.Insert(i, new FieldDeclarationIntermediateNode() + { + Annotations = + { + { CommonAnnotations.DefaultTagHelperExtension.TagHelperField, bool.TrueString }, + }, + Modifiers = + { + "private", + }, + FieldName = context.GetFieldName(tagHelper), + FieldType = "global::" + context.GetFullyQualifiedName(tagHelper), + }); + } + + private void AddTagHelperClass(Context context, TagHelperDescriptor tagHelper) + { + var node = new ViewComponentTagHelperIntermediateNode() + { + ClassName = context.GetClassName(tagHelper), + TagHelper = tagHelper + }; + + context.Class.Children.Add(node); + } + + private struct Context + { + private Dictionary _tagHelpers; + + public Context(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class) + { + Namespace = @namespace; + Class = @class; + + _tagHelpers = new Dictionary(); + } + + public ClassDeclarationIntermediateNode Class { get; } + + public NamespaceDeclarationIntermediateNode Namespace { get; } + + + public IEnumerable TagHelpers => _tagHelpers.Keys; + + public bool Add(TagHelperDescriptor tagHelper) + { + if (_tagHelpers.ContainsKey(tagHelper)) + { + return false; + } + + var className = $"__Generated__{tagHelper.GetViewComponentName()}ViewComponentTagHelper"; + var fullyQualifiedName = $"{Namespace.Content}.{Class.ClassName}.{className}"; + var fieldName = GenerateFieldName(tagHelper); + + _tagHelpers.Add(tagHelper, (className, fullyQualifiedName, fieldName)); + + return true; + } + + public string GetClassName(TagHelperDescriptor taghelper) + { + return _tagHelpers[taghelper].className; + } + + public string GetFullyQualifiedName(TagHelperDescriptor taghelper) + { + return _tagHelpers[taghelper].fullyQualifiedName; + } + + public string GetFieldName(TagHelperDescriptor taghelper) + { + return _tagHelpers[taghelper].fieldName; + } + + private static string GenerateFieldName(TagHelperDescriptor tagHelper) + { + return $"__{tagHelper.GetViewComponentName()}ViewComponentTagHelper"; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperTargetExtension.cs new file mode 100644 index 0000000000..89aba13222 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperTargetExtension.cs @@ -0,0 +1,183 @@ +// 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.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + internal class ViewComponentTagHelperTargetExtension : IViewComponentTagHelperTargetExtension + { + private static readonly string[] PublicModifiers = new[] { "public" }; + + public string TagHelperTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelper"; + + public string ViewComponentHelperTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.IViewComponentHelper"; + + public string ViewComponentHelperVariableName { get; set; } = "_helper"; + + public string ViewComponentInvokeMethodName { get; set; } = "InvokeAsync"; + + public string HtmlAttributeNotBoundAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute"; + + public string ViewContextAttributeTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute"; + + public string ViewContextTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext"; + + public string ViewContextPropertyName { get; set; } = "ViewContext"; + + public string HtmlTargetElementAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute"; + + public string TagHelperProcessMethodName { get; set; } = "ProcessAsync"; + + public string TagHelperContextTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext"; + + public string TagHelperContextVariableName { get; set; } = "context"; + + public string TagHelperOutputTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput"; + + public string TagHelperOutputVariableName { get; set; } = "output"; + + public string TagHelperOutputTagNamePropertyName { get; set; } = "TagName"; + + public string TagHelperOutputContentPropertyName { get; set; } = "Content"; + + public string TagHelperContentSetMethodName { get; set; } = "SetHtmlContent"; + + public string TagHelperContentVariableName { get; set; } = "content"; + + public string IViewContextAwareTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware"; + + public string IViewContextAwareContextualizeMethodName { get; set; } = "Contextualize"; + + public void WriteViewComponentTagHelper(CodeRenderingContext context, ViewComponentTagHelperIntermediateNode node) + { + // Add target element. + WriteTargetElementString(context.CodeWriter, node.TagHelper); + + // Initialize declaration. + using (context.CodeWriter.BuildClassDeclaration( + PublicModifiers, + node.ClassName, + TagHelperTypeName, + interfaces: null, + typeParameters: null)) + { + // Add view component helper. + context.CodeWriter.WriteVariableDeclaration( + $"private readonly {ViewComponentHelperTypeName}", + ViewComponentHelperVariableName, + value: null); + + // Add constructor. + WriteConstructorString(context.CodeWriter, node.ClassName); + + // Add attributes. + WriteAttributeDeclarations(context.CodeWriter, node.TagHelper); + + // Add process method. + WriteProcessMethodString(context.CodeWriter, node.TagHelper); + } + } + + private void WriteConstructorString(CodeWriter writer, string className) + { + writer.Write("public ") + .Write(className) + .Write("(") + .Write($"{ViewComponentHelperTypeName} helper") + .WriteLine(")"); + using (writer.BuildScope()) + { + writer.WriteStartAssignment(ViewComponentHelperVariableName) + .Write("helper") + .WriteLine(";"); + } + } + + private void WriteAttributeDeclarations(CodeWriter writer, TagHelperDescriptor tagHelper) + { + writer.Write("[") + .Write(HtmlAttributeNotBoundAttributeTypeName) + .WriteParameterSeparator() + .Write(ViewContextAttributeTypeName) + .WriteLine("]"); + + writer.WriteAutoPropertyDeclaration( + PublicModifiers, + ViewContextTypeName, + ViewContextPropertyName); + + foreach (var attribute in tagHelper.BoundAttributes) + { + writer.WriteAutoPropertyDeclaration( + PublicModifiers, + attribute.TypeName, + attribute.GetPropertyName()); + + if (attribute.IndexerTypeName != null) + { + writer.Write(" = ") + .WriteStartNewObject(attribute.TypeName) + .WriteEndMethodInvocation(); + } + } + } + + private void WriteProcessMethodString(CodeWriter writer, TagHelperDescriptor tagHelper) + { + using (writer.BuildMethodDeclaration( + $"public override async", + $"global::{typeof(Task).FullName}", + TagHelperProcessMethodName, + new Dictionary() + { + { TagHelperContextTypeName, TagHelperContextVariableName }, + { TagHelperOutputTypeName, TagHelperOutputVariableName } + })) + { + writer.WriteInstanceMethodInvocation( + $"({ViewComponentHelperVariableName} as {IViewContextAwareTypeName})?", + IViewContextAwareContextualizeMethodName, + new[] { ViewContextPropertyName }); + + var methodParameters = GetMethodParameters(tagHelper); + writer.Write("var ") + .WriteStartAssignment(TagHelperContentVariableName) + .WriteInstanceMethodInvocation($"await {ViewComponentHelperVariableName}", ViewComponentInvokeMethodName, methodParameters); + writer.WriteStartAssignment($"{TagHelperOutputVariableName}.{TagHelperOutputTagNamePropertyName}") + .WriteLine("null;"); + writer.WriteInstanceMethodInvocation( + $"{TagHelperOutputVariableName}.{TagHelperOutputContentPropertyName}", + TagHelperContentSetMethodName, + new[] { TagHelperContentVariableName }); + } + } + + private string[] GetMethodParameters(TagHelperDescriptor tagHelper) + { + var propertyNames = tagHelper.BoundAttributes.Select(attribute => attribute.GetPropertyName()); + var joinedPropertyNames = string.Join(", ", propertyNames); + var parametersString = $"new {{ { joinedPropertyNames } }}"; + var viewComponentName = tagHelper.GetViewComponentName(); + var methodParameters = new[] { $"\"{viewComponentName}\"", parametersString }; + return methodParameters; + } + + private void WriteTargetElementString(CodeWriter writer, TagHelperDescriptor tagHelper) + { + Debug.Assert(tagHelper.TagMatchingRules.Count() == 1); + + var rule = tagHelper.TagMatchingRules.First(); + + writer.Write("[") + .WriteStartMethodInvocation(HtmlTargetElementAttributeTypeName) + .WriteStringLiteral(rule.TagName) + .WriteLine(")]"); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTypeVisitor.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTypeVisitor.cs new file mode 100644 index 0000000000..9e1f936060 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTypeVisitor.cs @@ -0,0 +1,88 @@ +// 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.CodeAnalysis; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + internal class ViewComponentTypeVisitor : SymbolVisitor + { + private readonly INamedTypeSymbol _viewComponentAttribute; + private readonly INamedTypeSymbol _nonViewComponentAttribute; + private readonly List _results; + + public ViewComponentTypeVisitor( + INamedTypeSymbol viewComponentAttribute, + INamedTypeSymbol nonViewComponentAttribute, + List results) + { + _viewComponentAttribute = viewComponentAttribute; + _nonViewComponentAttribute = nonViewComponentAttribute; + _results = results; + } + + public override void VisitNamedType(INamedTypeSymbol symbol) + { + if (IsViewComponent(symbol)) + { + _results.Add(symbol); + } + + if (symbol.DeclaredAccessibility != Accessibility.Public) + { + return; + } + + foreach (var member in symbol.GetTypeMembers()) + { + Visit(member); + } + } + + public override void VisitNamespace(INamespaceSymbol symbol) + { + foreach (var member in symbol.GetMembers()) + { + Visit(member); + } + } + + internal bool IsViewComponent(INamedTypeSymbol symbol) + { + if (_viewComponentAttribute == null) + { + return false; + } + + if (symbol.DeclaredAccessibility != Accessibility.Public || + symbol.IsAbstract || + symbol.IsGenericType || + AttributeIsDefined(symbol, _nonViewComponentAttribute)) + { + return false; + } + + return symbol.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix) || + AttributeIsDefined(symbol, _viewComponentAttribute); + } + + private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol queryAttribute) + { + if (type == null || queryAttribute == null) + { + return false; + } + + var attribute = type.GetAttributes().Where(a => a.AttributeClass == queryAttribute).FirstOrDefault(); + + if (attribute != null) + { + return true; + } + + return AttributeIsDefined(type.BaseType, queryAttribute); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTypes.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTypes.cs new file mode 100644 index 0000000000..5558ba5e06 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTypes.cs @@ -0,0 +1,35 @@ +// 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.Mvc.Razor.Extensions +{ + internal static class ViewComponentTypes + { + public const string Assembly = "Microsoft.AspNetCore.Mvc.ViewFeatures"; + + public static readonly Version AssemblyVersion = new Version(1, 1, 0, 0); + + public const string ViewComponentSuffix = "ViewComponent"; + + public const string ViewComponentAttribute = "Microsoft.AspNetCore.Mvc.ViewComponentAttribute"; + + public const string NonViewComponentAttribute = "Microsoft.AspNetCore.Mvc.NonViewComponentAttribute"; + + public const string GenericTask = "System.Threading.Tasks.Task`1"; + + public const string Task = "System.Threading.Tasks.Task"; + + public const string IDictionary = "System.Collections.Generic.IDictionary`2"; + + public const string AsyncMethodName = "InvokeAsync"; + + public const string SyncMethodName = "Invoke"; + + public static class ViewComponent + { + public const string Name = "Name"; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/baseline.netcore.json b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/baseline.netcore.json new file mode 100644 index 0000000000..488fa33c0e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/baseline.netcore.json @@ -0,0 +1,1235 @@ +{ + "AssemblyIdentity": "Microsoft.AspNetCore.Mvc.Razor.Extensions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "Types": [ + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.AssemblyAttributeInjectionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.IInjectTargetExtension", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.CodeGeneration.ICodeTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteInjectProperty", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectIntermediateNode" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectIntermediateNode", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.Intermediate.ExtensionIntermediateNode", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_TypeName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_TypeName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_MemberName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_MemberName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_Children", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeCollection", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Accept", + "Parameters": [ + { + "Name": "visitor", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeVisitor" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "WriteNode", + "Parameters": [ + { + "Name": "target", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeTarget" + }, + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectTargetExtension", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Mvc.Razor.Extensions.IInjectTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteInjectProperty", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Mvc.Razor.Extensions.IInjectTargetExtension", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InstrumentationPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Virtual": true, + "Override": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.IViewComponentTagHelperTargetExtension", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.CodeGeneration.ICodeTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteViewComponentTagHelper", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperIntermediateNode" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ModelDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetModelType", + "Parameters": [ + { + "Name": "document", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.String", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ModelExpressionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.MvcRazorTemplateEngine", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.RazorTemplateEngine", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "CreateCodeDocument", + "Parameters": [ + { + "Name": "projectItem", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectItem" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "engine", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorEngine" + }, + { + "Name": "project", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProject" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.MvcViewDocumentClassifierPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_DocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "IsMatch", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Boolean", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "OnDocumentStructureCreated", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "namespace", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode" + }, + { + "Name": "class", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode" + }, + { + "Name": "method", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "MvcViewDocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.NamespaceDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.PageDirective", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_RouteTemplate", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_DirectiveNode", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNode", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "TryGetPageDirective", + "Parameters": [ + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + }, + { + "Name": "pageDirective", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.PageDirective", + "Direction": "Out" + } + ], + "ReturnType": "System.Boolean", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.PagesPropertyInjectionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.RazorExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.RazorPageDocumentClassifierPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_DocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "IsMatch", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Boolean", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "OnDocumentStructureCreated", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "namespace", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode" + }, + { + "Name": "class", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode" + }, + { + "Name": "method", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "RazorPageDocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "RouteTemplateKey", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.TagHelperDescriptorExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "IsViewComponentKind", + "Parameters": [ + { + "Name": "tagHelper", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.Boolean", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetViewComponentName", + "Parameters": [ + { + "Name": "tagHelper", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.String", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperConventions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Kind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperDescriptorProvider", + "Visibility": "Public", + "Kind": "Class", + "Sealed": true, + "BaseType": "Microsoft.AspNetCore.Razor.Language.RazorEngineFeatureBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_Order", + "Parameters": [ + { + "Name": "value", + "Type": "System.Int32" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Execute", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptorProviderContext" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperIntermediateNode", + "Visibility": "Public", + "Kind": "Class", + "Sealed": true, + "BaseType": "Microsoft.AspNetCore.Razor.Language.Intermediate.ExtensionIntermediateNode", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_Children", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeCollection", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_ClassName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_ClassName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_TagHelper", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_TagHelper", + "Parameters": [ + { + "Name": "value", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Accept", + "Parameters": [ + { + "Name": "visitor", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeVisitor" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "WriteNode", + "Parameters": [ + { + "Name": "target", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeTarget" + }, + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperMetadata", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Name", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Virtual": true, + "Override": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriterExtensions+CSharpCodeWritingScope", + "Visibility": "Public", + "Kind": "Struct", + "Sealed": true, + "ImplementedInterfaces": [ + "System.IDisposable" + ], + "Members": [ + { + "Kind": "Method", + "Name": "Dispose", + "Parameters": [], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "System.IDisposable", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "writer", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriter" + }, + { + "Name": "tabSize", + "Type": "System.Int32", + "DefaultValue": "4" + }, + { + "Name": "autoSpace", + "Type": "System.Boolean", + "DefaultValue": "True" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTypes+ViewComponent", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Name", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "Visibility": "Public", + "GenericParameter": [], + "Constant": true, + "Literal": "\"Name\"" + } + ], + "GenericParameters": [] + } + ] +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/baseline.netframework.json b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/baseline.netframework.json new file mode 100644 index 0000000000..7d416ca9c3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/baseline.netframework.json @@ -0,0 +1,1023 @@ +{ + "AssemblyIdentity": "Microsoft.AspNetCore.Mvc.Razor.Extensions, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "Types": [ + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.AssemblyAttributeInjectionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.IInjectTargetExtension", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.CodeGeneration.ICodeTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteInjectProperty", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectIntermediateNode" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectIntermediateNode", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.Intermediate.ExtensionIntermediateNode", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_TypeName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_TypeName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_MemberName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_MemberName", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_Children", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeCollection", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Accept", + "Parameters": [ + { + "Name": "visitor", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeVisitor" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "WriteNode", + "Parameters": [ + { + "Name": "target", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeTarget" + }, + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectTargetExtension", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Mvc.Razor.Extensions.IInjectTargetExtension" + ], + "Members": [ + { + "Kind": "Method", + "Name": "WriteInjectProperty", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext" + }, + { + "Name": "node", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InjectIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Mvc.Razor.Extensions.IInjectTargetExtension", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.InstrumentationPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Virtual": true, + "Override": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ModelDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetModelType", + "Parameters": [ + { + "Name": "document", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.String", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ModelExpressionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.MvcRazorTemplateEngine", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.RazorTemplateEngine", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "CreateCodeDocument", + "Parameters": [ + { + "Name": "projectItem", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectItem" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "engine", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorEngine" + }, + { + "Name": "project", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorProject" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.MvcViewDocumentClassifierPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_DocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "IsMatch", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Boolean", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "OnDocumentStructureCreated", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "namespace", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode" + }, + { + "Name": "class", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode" + }, + { + "Name": "method", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "MvcViewDocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.NamespaceDirective", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.PageDirective", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_RouteTemplate", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_DirectiveNode", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNode", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "TryGetPageDirective", + "Parameters": [ + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + }, + { + "Name": "pageDirective", + "Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.PageDirective", + "Direction": "Out" + } + ], + "ReturnType": "System.Boolean", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "Directive", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.PagesPropertyInjectionPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.RazorExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Register", + "Parameters": [ + { + "Name": "builder", + "Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.RazorPageDocumentClassifierPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_DocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "IsMatch", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Boolean", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "OnDocumentStructureCreated", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "namespace", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode" + }, + { + "Name": "class", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode" + }, + { + "Name": "method", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Field", + "Name": "RazorPageDocumentKind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.TagHelperDescriptorExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "IsViewComponentKind", + "Parameters": [ + { + "Name": "tagHelper", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.Boolean", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetViewComponentName", + "Parameters": [ + { + "Name": "tagHelper", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor" + } + ], + "ReturnType": "System.String", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperConventions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Kind", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperDescriptorProvider", + "Visibility": "Public", + "Kind": "Class", + "Sealed": true, + "BaseType": "Microsoft.AspNetCore.Razor.Language.RazorEngineFeatureBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_Order", + "Parameters": [ + { + "Name": "value", + "Type": "System.Int32" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Execute", + "Parameters": [ + { + "Name": "context", + "Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptorProviderContext" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperMetadata", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Name", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "ReadOnly": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTagHelperPass", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Order", + "Parameters": [], + "ReturnType": "System.Int32", + "Virtual": true, + "Override": true, + "ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ExecuteCore", + "Parameters": [ + { + "Name": "codeDocument", + "Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument" + }, + { + "Name": "documentNode", + "Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriterExtensions+CSharpCodeWritingScope", + "Visibility": "Public", + "Kind": "Struct", + "Sealed": true, + "ImplementedInterfaces": [ + "System.IDisposable" + ], + "Members": [ + { + "Kind": "Method", + "Name": "Dispose", + "Parameters": [], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "System.IDisposable", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "writer", + "Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriter" + }, + { + "Name": "tabSize", + "Type": "System.Int32", + "DefaultValue": "4" + }, + { + "Name": "autoSpace", + "Type": "System.Boolean", + "DefaultValue": "True" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.ViewComponentTypes+ViewComponent", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Name", + "Parameters": [], + "ReturnType": "System.String", + "Static": true, + "Visibility": "Public", + "GenericParameter": [], + "Constant": true, + "Literal": "\"Name\"" + } + ], + "GenericParameters": [] + } + ] +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/breakingchanges.netcore.json b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/breakingchanges.netcore.json new file mode 100644 index 0000000000..5f5b6444f6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/breakingchanges.netcore.json @@ -0,0 +1,11 @@ +[ + { + "TypeId": "public static class Microsoft.AspNetCore.Mvc.Razor.Extensions.RazorExtensions", + "MemberId": "public static System.Void Register(Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder builder)", + "Kind": "Removal" + }, + { + "TypeId": "public class Microsoft.AspNetCore.Mvc.Razor.Extensions.InstrumentationPass : Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase, Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Kind": "Removal" + } +] diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/breakingchanges.netframework.json b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/breakingchanges.netframework.json new file mode 100644 index 0000000000..5f5b6444f6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/breakingchanges.netframework.json @@ -0,0 +1,11 @@ +[ + { + "TypeId": "public static class Microsoft.AspNetCore.Mvc.Razor.Extensions.RazorExtensions", + "MemberId": "public static System.Void Register(Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder builder)", + "Kind": "Removal" + }, + { + "TypeId": "public class Microsoft.AspNetCore.Mvc.Razor.Extensions.InstrumentationPass : Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase, Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass", + "Kind": "Removal" + } +] diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/AssemblyAttributeInjectionPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/AssemblyAttributeInjectionPassTest.cs new file mode 100644 index 0000000000..0ccd553a08 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/AssemblyAttributeInjectionPassTest.cs @@ -0,0 +1,444 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class AssemblyAttributeInjectionPassTest + { + [Fact] + public void Execute_NoOps_IfNamespaceNodeIsMissing() + { + // Arrange + var irDocument = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Empty(irDocument.Children); + } + + [Fact] + public void Execute_NoOps_IfNamespaceNodeHasEmptyContent() + { + // Arrange + var irDocument = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = string.Empty }; + @namespace.Annotations[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace; + builder.Push(@namespace); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_NoOps_IfClassNameNodeIsMissing() + { + // Arrange + var irDocument = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "SomeNamespace" }; + builder.Push(@namespace); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Collection( + irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_NoOps_IfClassNameIsEmpty() + { + // Arrange + var irDocument = new DocumentIntermediateNode() + { + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace, + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_NoOps_IfDocumentIsNotViewOrPage() + { + // Arrange + var irDocument = new DocumentIntermediateNode + { + DocumentKind = "Default", + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "SomeNamespace" }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + // Act + pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument); + + // Assert + Assert.Collection( + irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_NoOps_ForDesignTime() + { + // Arrange + var irDocument = new DocumentIntermediateNode + { + DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, + Options = RazorCodeGenerationOptions.CreateDesignTimeDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection( + irDocument.Children, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_AddsRazorViewAttribute_ToViews() + { + // Arrange + var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/Views/Index.cshtml\", typeof(SomeNamespace.SomeName))]"; + var irDocument = new DocumentIntermediateNode + { + DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => + { + var csharpCode = Assert.IsType(node); + var token = Assert.IsType(Assert.Single(csharpCode.Children)); + Assert.Equal(TokenKind.CSharp, token.Kind); + Assert.Equal(expectedAttribute, token.Content); + }, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_EscapesViewPathWhenAddingAttributeToViews() + { + // Arrange + var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/test/\"\"Index.cshtml\", typeof(SomeNamespace.SomeName))]"; + var irDocument = new DocumentIntermediateNode + { + DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "\\test\\\"Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => + { + var csharpCode = Assert.IsType(node); + var token = Assert.IsType(Assert.Single(csharpCode.Children)); + Assert.Equal(TokenKind.CSharp, token.Kind); + Assert.Equal(expectedAttribute, token.Content); + }, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_AddsRazorPagettribute_ToPage() + { + // Arrange + var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@\"/Views/Index.cshtml\", typeof(SomeNamespace.SomeName), null)]"; + var irDocument = new DocumentIntermediateNode + { + DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind, + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var pageDirective = new DirectiveIntermediateNode + { + Directive = PageDirective.Directive, + }; + builder.Add(pageDirective); + + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => Assert.Same(pageDirective, node), + node => + { + var csharpCode = Assert.IsType(node); + var token = Assert.IsType(Assert.Single(csharpCode.Children)); + Assert.Equal(TokenKind.CSharp, token.Kind); + Assert.Equal(expectedAttribute, token.Content); + }, + node => Assert.Same(@namespace, node)); + } + + [Fact] + public void Execute_EscapesViewPathAndRouteWhenAddingAttributeToPage() + { + // Arrange + var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/test/\"\"Index.cshtml\", typeof(SomeNamespace.SomeName))]"; + var irDocument = new DocumentIntermediateNode + { + DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, + Options = RazorCodeGenerationOptions.CreateDefault(), + }; + var builder = IntermediateNodeBuilder.Create(irDocument); + var @namespace = new NamespaceDeclarationIntermediateNode + { + Content = "SomeNamespace", + Annotations = + { + [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace + }, + }; + builder.Push(@namespace); + var @class = new ClassDeclarationIntermediateNode + { + ClassName = "SomeName", + Annotations = + { + [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass, + }, + }; + + builder.Add(@class); + + var pass = new AssemblyAttributeInjectionPass + { + Engine = RazorProjectEngine.Create().Engine, + }; + + var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "test\\\"Index.cshtml")); + var document = RazorCodeDocument.Create(source); + + // Act + pass.Execute(document, irDocument); + + // Assert + Assert.Collection(irDocument.Children, + node => + { + var csharpCode = Assert.IsType(node); + var token = Assert.IsType(Assert.Single(csharpCode.Children)); + Assert.Equal(TokenKind.CSharp, token.Kind); + Assert.Equal(expectedAttribute, token.Content); + }, + node => Assert.Same(@namespace, node)); + } + + 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 IRazorDocumentClassifierPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/InjectDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/InjectDirectiveTest.cs new file mode 100644 index 0000000000..54a2fa4fd1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/InjectDirectiveTest.cs @@ -0,0 +1,212 @@ +// 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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class InjectDirectiveTest + { + [Fact] + public void InjectDirectivePass_Execute_DefinesProperty() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_DedupesPropertiesByName() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +@inject PropertyType2 PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType2", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_ExpandsTModel_WithDynamic() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_ExpandsTModel_WithModelTypeFirst() + { + // Arrange + var codeDocument = CreateDocument(@" +@model ModelType +@inject PropertyType PropertyName +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + [Fact] + public void InjectDirectivePass_Execute_ExpandsTModel_WithModelType() + { + // Arrange + var codeDocument = CreateDocument(@" +@inject PropertyType PropertyName +@model ModelType +"); + + var engine = CreateEngine(); + var pass = new InjectDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal(2, @class.Children.Count); + + var node = Assert.IsType(@class.Children[1]); + Assert.Equal("PropertyType", node.TypeName); + Assert.Equal("PropertyName", node.MemberName); + } + + private RazorCodeDocument CreateDocument(string content) + { + var source = RazorSourceDocument.Create(content, "test.cshtml"); + return RazorCodeDocument.Create(source); + } + + private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node) + { + var visitor = new ClassNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private RazorEngine CreateEngine() + { + return RazorProjectEngine.Create(b => + { + // Notice we're not registering the InjectDirective.Pass here so we can run it on demand. + b.AddDirective(InjectDirective.Directive); + b.AddDirective(ModelDirective.Directive); + }).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 IRazorDocumentClassifierPhase) + { + break; + } + } + + var irDocument = codeDocument.GetDocumentIntermediateNode(); + irDocument.DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind; + return irDocument; + } + + private class ClassNodeVisitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Node { get; set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Node = node; + } + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/InjectTargetExtensionTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/InjectTargetExtensionTest.cs new file mode 100644 index 0000000000..ec36da6564 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/InjectTargetExtensionTest.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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class InjectTargetExtensionTest + { + [Fact] + public void InjectDirectiveTargetExtension_WritesProperty() + { + // Arrange + var context = TestCodeRenderingContext.CreateRuntime(); + var target = new InjectTargetExtension(); + var node = new InjectIntermediateNode() + { + TypeName = "PropertyType", + MemberName = "PropertyName", + }; + + // Act + target.WriteInjectProperty(context, node); + + // Assert + Assert.Equal( + "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine + + "public PropertyType PropertyName { get; private set; }" + Environment.NewLine, + context.CodeWriter.GenerateCode()); + } + + [Fact] + public void InjectDirectiveTargetExtension_WritesPropertyWithLinePragma_WhenSourceIsSet() + { + // Arrange + var context = TestCodeRenderingContext.CreateRuntime(); + var target = new InjectTargetExtension(); + var node = new InjectIntermediateNode() + { + TypeName = "PropertyType", + MemberName = "PropertyName", + Source = new SourceSpan( + filePath: "test-path", + absoluteIndex: 0, + lineIndex: 1, + characterIndex: 1, + length: 10) + }; + + // Act + target.WriteInjectProperty(context, node); + + // Assert + Assert.Equal( + "#line 2 \"test-path\"" + Environment.NewLine + + "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine + + "public PropertyType PropertyName { get; private set; }" + Environment.NewLine + Environment.NewLine + + "#line default" + Environment.NewLine + + "#line hidden" + Environment.NewLine, + context.CodeWriter.GenerateCode()); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/IntegrationTests/CodeGenerationIntegrationTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/IntegrationTests/CodeGenerationIntegrationTest.cs new file mode 100644 index 0000000000..8273810ca3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/IntegrationTests/CodeGenerationIntegrationTest.cs @@ -0,0 +1,961 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.IntegrationTests; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.IntegrationTests +{ + public class CodeGenerationIntegrationTest : IntegrationTestBase + { + private readonly static CSharpCompilation DefaultBaseCompilation = MvcShim.BaseCompilation.WithAssemblyName("AppCode"); + + public CodeGenerationIntegrationTest() + : base(generateBaselines: null) + { + Configuration = RazorConfiguration.Create( + RazorLanguageVersion.Version_3_0, + "MVC-3.0", + new[] { new AssemblyExtension("MVC-3.0", typeof(ExtensionInitializer).Assembly) }); + } + + protected override CSharpCompilation BaseCompilation => DefaultBaseCompilation; + + protected override RazorConfiguration Configuration { get; } + + #region Runtime + + [Fact] + public void UsingDirectives_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false, throwOnFailure: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + var diagnostics = compiled.Compilation.GetDiagnostics().Where(d => d.Severity >= DiagnosticSeverity.Warning); + Assert.Equal("The using directive for 'System' appeared previously in this namespace", Assert.Single(diagnostics).GetMessage()); + } + + [Fact] + public void InvalidNamespaceAtEOF_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ1014", Assert.Single(diagnotics).Id); + } + + [Fact] + public void IncompleteDirectives_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyService +{ + public string Html { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + // We expect this test to generate a bunch of errors. + Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + } + + [Fact] + public void InheritsViewModel_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Razor; + +public class MyBasePageForViews : RazorPage +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} +public class MyModel +{ + +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void InheritsWithViewImports_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.RazorPages; + +public abstract class MyPageModel : Page +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} + +public class MyModel +{ + +}"); + AddProjectItemFromText(@"@inherits MyPageModel"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void MalformedPageDirective_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ1016", Assert.Single(diagnotics).Id); + } + + [Fact] + public void Basic_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void Sections_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void _ViewImports_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void Inject_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyApp +{ + public string MyProperty { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void InjectWithModel_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyService +{ + public string Html { get; set; } +} + +public class MyApp +{ + public string MyProperty { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void InjectWithSemicolon_Runtime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyApp +{ + public string MyProperty { get; set; } +} + +public class MyService +{ + public string Html { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void Model_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void ModelExpressionTagHelper_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void RazorPages_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class DivTagHelper : {typeof(TagHelper).FullName} +{{ + +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void RazorPagesWithRouteTemplate_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void RazorPagesWithoutModel_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class DivTagHelper : {typeof(TagHelper).FullName} +{{ + +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void PageWithNamespace_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void ViewWithNamespace_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void ViewComponentTagHelper_Runtime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class TestViewComponent +{{ + public string Invoke(string firstName) + {{ + return firstName; + }} +}} + +[{typeof(HtmlTargetElementAttribute).FullName}] +public class AllTagHelper : {typeof(TagHelper).FullName} +{{ + public string Bar {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + } + + [Fact] + public void RazorPageWithNoLeadingPageDirective_Runtime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ3906", Assert.Single(diagnotics).Id); + } + #endregion + + #region DesignTime + + [Fact] + public void UsingDirectives_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true, throwOnFailure: false); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnostics = compiled.Compilation.GetDiagnostics().Where(d => d.Severity >= DiagnosticSeverity.Warning); + Assert.Equal("The using directive for 'System' appeared previously in this namespace", Assert.Single(diagnostics).GetMessage()); + } + + [Fact] + public void InvalidNamespaceAtEOF_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ1014", Assert.Single(diagnotics).Id); + } + + [Fact] + public void IncompleteDirectives_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyService +{ + public string Html { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + // We expect this test to generate a bunch of errors. + Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + } + + [Fact] + public void InheritsViewModel_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Razor; + +public class MyBasePageForViews : RazorPage +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} +public class MyModel +{ + +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void InheritsWithViewImports_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.RazorPages; + +public abstract class MyPageModel : Page +{ + public override Task ExecuteAsync() + { + throw new System.NotImplementedException(); + } +} + +public class MyModel +{ + +}"); + + AddProjectItemFromText(@"@inherits MyPageModel"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void MalformedPageDirective_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ1016", Assert.Single(diagnotics).Id); + } + + [Fact] + public void Basic_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Sections_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void _ViewImports_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Inject_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyApp +{ + public string MyProperty { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void InjectWithModel_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyService +{ + public string Html { get; set; } +} + +public class MyApp +{ + public string MyProperty { get; set; } +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void InjectWithSemicolon_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class MyModel +{ + +} + +public class MyApp +{ + public string MyProperty { get; set; } +} + +public class MyService +{ + public string Html { get; set; } +} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void Model_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void MultipleModels_DesignTime() + { + // Arrange + AddCSharpSyntaxTree(@" +public class ThisShouldBeGenerated +{ + +}"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ2001", Assert.Single(diagnotics).Id); + } + + [Fact] + public void ModelExpressionTagHelper_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +public class InputTestTagHelper : {typeof(TagHelper).FullName} +{{ + public ModelExpression For {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void RazorPages_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class DivTagHelper : {typeof(TagHelper).FullName} +{{ + +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void RazorPagesWithRouteTemplate_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void RazorPagesWithoutModel_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class DivTagHelper : {typeof(TagHelper).FullName} +{{ + +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void PageWithNamespace_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void ViewWithNamespace_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void ViewComponentTagHelper_DesignTime() + { + // Arrange + AddCSharpSyntaxTree($@" +public class TestViewComponent +{{ + public string Invoke(string firstName) + {{ + return firstName; + }} +}} + +[{typeof(HtmlTargetElementAttribute).FullName}] +public class AllTagHelper : {typeof(TagHelper).FullName} +{{ + public string Bar {{ get; set; }} +}} +"); + + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToAssembly(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + } + + [Fact] + public void RazorPageWithNoLeadingPageDirective_DesignTime() + { + // Arrange + var projectItem = CreateProjectItemFromFile(); + + // Act + var compiled = CompileToCSharp(projectItem, designTime: true); + + // Assert + AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode()); + AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); + AssertSourceMappingsMatchBaseline(compiled.CodeDocument); + + var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics; + Assert.Equal("RZ3906", Assert.Single(diagnotics).Id); + } + + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj new file mode 100644 index 0000000000..86d975d404 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj @@ -0,0 +1,51 @@ + + + + $(StandardTestTfms) + true + $(DefaultItemExcludes);TestFiles\** + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + Content + PreserveNewest + Build + + + + + + + + + + + + + + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ModelDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ModelDirectiveTest.cs new file mode 100644 index 0000000000..425b1b41c6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ModelDirectiveTest.cs @@ -0,0 +1,343 @@ +// 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 Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class ModelDirectiveTest + { + [Fact] + public void ModelDirective_GetModelType_GetsTypeFromFirstWellFormedDirective() + { + // Arrange + var codeDocument = CreateDocument(@" +@model Type1 +@model Type2 +@model +"); + + var engine = CreateEngine(); + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = ModelDirective.GetModelType(irDocument); + + // Assert + Assert.Equal("Type1", result); + } + + [Fact] + public void ModelDirective_GetModelType_DefaultsToDynamic() + { + // Arrange + var codeDocument = CreateDocument(@" "); + + var engine = CreateEngine(); + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = ModelDirective.GetModelType(irDocument); + + // Assert + Assert.Equal("dynamic", result); + } + + [Fact] + public void ModelDirectivePass_Execute_ReplacesTModelInBaseType() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +@model Type1 +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_Execute_ReplacesTModelInBaseType_DifferentOrdering() + { + // Arrange + var codeDocument = CreateDocument(@" +@model Type1 +@inherits BaseType +@model Type2 +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_Execute_NoOpWithoutTModel() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +@model Type1 +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_Execute_ReplacesTModelInBaseType_DefaultDynamic() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +"); + + var engine = CreateEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + } + + [Fact] + public void ModelDirectivePass_DesignTime_AddsTModelUsingDirective() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +"); + + var engine = CreateDesignTimeEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + + var @namespace = FindNamespaceNode(irDocument); + var usingNode = Assert.IsType(@namespace.Children[0]); + Assert.Equal($"TModel = global::{typeof(object).FullName}", usingNode.Content); + } + + [Fact] + public void ModelDirectivePass_DesignTime_WithModel_AddsTModelUsingDirective() + { + // Arrange + var codeDocument = CreateDocument(@" +@inherits BaseType +@model SomeType +"); + + var engine = CreateDesignTimeEngine(); + var pass = new ModelDirective.Pass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.NotNull(@class); + Assert.Equal("BaseType", @class.BaseType); + + var @namespace = FindNamespaceNode(irDocument); + var usingNode = Assert.IsType(@namespace.Children[0]); + Assert.Equal($"TModel = global::System.Object", usingNode.Content); + } + + private RazorCodeDocument CreateDocument(string content) + { + var source = RazorSourceDocument.Create(content, "test.cshtml"); + return RazorCodeDocument.Create(source); + } + + private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node) + { + var visitor = new ClassNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private NamespaceDeclarationIntermediateNode FindNamespaceNode(IntermediateNode node) + { + var visitor = new NamespaceNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private RazorEngine CreateEngine() + { + return CreateEngineCore(); + } + + private RazorEngine CreateDesignTimeEngine() + { + return CreateEngineCore(designTime: true); + } + + private RazorEngine CreateEngineCore(bool designTime = false) + { + return RazorProjectEngine.Create(b => + { + // Notice we're not registering the ModelDirective.Pass here so we can run it on demand. + b.AddDirective(ModelDirective.Directive); + + // There's some special interaction with the inherits directive + InheritsDirective.Register(b); + + b.Features.Add(new DesignTimeOptionsFeature(designTime)); + }).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 IRazorDocumentClassifierPhase) + { + break; + } + } + + // InheritsDirectivePass needs to run before ModelDirective. + var pass = new InheritsDirectivePass() + { + Engine = engine + }; + pass.Execute(codeDocument, codeDocument.GetDocumentIntermediateNode()); + + return codeDocument.GetDocumentIntermediateNode(); + } + + private string GetCSharpContent(IntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + var child = node.Children[i] as IntermediateToken; + if (child.Kind == TokenKind.CSharp) + { + builder.Append(child.Content); + } + } + + return builder.ToString(); + } + + private class ClassNodeVisitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Node { get; set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Node = node; + } + } + + private class NamespaceNodeVisitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Node { get; set; } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + Node = node; + } + } + + 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); + } + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ModelExpressionPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ModelExpressionPassTest.cs new file mode 100644 index 0000000000..92f6ef816e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ModelExpressionPassTest.cs @@ -0,0 +1,208 @@ +// 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 System.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class ModelExpressionPassTest + { + [Fact] + public void ModelExpressionPass_NonModelExpressionProperty_Ignored() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BoundAttributeDescriptor(attribute => + attribute + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => + rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ModelExpressionPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + var setProperty = tagHelper.Children.OfType().Single(); + + var token = Assert.IsType(Assert.Single(setProperty.Children)); + Assert.True(token.IsCSharp); + Assert.Equal("17", token.Content); + } + + [Fact] + public void ModelExpressionPass_ModelExpressionProperty_SimpleExpression() + { + // Arrange + + // Using \r\n here because we verify line mappings + var codeDocument = CreateDocument( + "@addTagHelper TestTagHelper, TestAssembly\r\n

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BoundAttributeDescriptor(attribute => + attribute + .Name("Foo") + .TypeName("Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression")) + .TagMatchingRuleDescriptor(rule => + rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ModelExpressionPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + var setProperty = tagHelper.Children.OfType().Single(); + + var expression = Assert.IsType(Assert.Single(setProperty.Children)); + Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Bar)", GetCSharpContent(expression)); + + var originalNode = Assert.IsType(expression.Children[2]); + Assert.Equal(TokenKind.CSharp, originalNode.Kind); + Assert.Equal("Bar", originalNode.Content); + Assert.Equal(new SourceSpan("test.cshtml", 51, 1, 8, 3), originalNode.Source.Value); + } + + [Fact] + public void ModelExpressionPass_ModelExpressionProperty_ComplexExpression() + { + // Arrange + + // Using \r\n here because we verify line mappings + var codeDocument = CreateDocument( + "@addTagHelper TestTagHelper, TestAssembly\r\n

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BoundAttributeDescriptor(attribute => + attribute + .Name("Foo") + .TypeName("Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression")) + .TagMatchingRuleDescriptor(rule => + rule.RequireTagName("p")) + .Build() + }; + + var engine = CreateEngine(tagHelpers); + var pass = new ModelExpressionPass() + { + Engine = engine, + }; + + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + var setProperty = tagHelper.Children.OfType().Single(); + + var expression = Assert.IsType(Assert.Single(setProperty.Children)); + Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => Bar)", GetCSharpContent(expression)); + + var originalNode = Assert.IsType(expression.Children[1]); + Assert.Equal(TokenKind.CSharp, originalNode.Kind); + Assert.Equal("Bar", originalNode.Content); + Assert.Equal(new SourceSpan("test.cshtml", 52, 1, 9, 3), originalNode.Source.Value); + } + + 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 string GetCSharpContent(IntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + var child = node.Children[i] as IntermediateToken; + if (child.Kind == TokenKind.CSharp) + { + builder.Append(child.Content); + } + } + + return builder.ToString(); + } + + private class TagHelperNodeVisitor : IntermediateNodeWalker + { + public TagHelperIntermediateNode Node { get; set; } + + public override void VisitTagHelper(TagHelperIntermediateNode node) + { + Node = node; + } + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcImportProjectFeatureTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcImportProjectFeatureTest.cs new file mode 100644 index 0000000000..7e811ee261 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcImportProjectFeatureTest.cs @@ -0,0 +1,76 @@ +// 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; +using Moq; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class MvcImportProjectFeatureTest + { + [Fact] + public void AddDefaultDirectivesImport_AddsSingleDynamicImport() + { + // Arrange + var imports = new List(); + + // Act + MvcImportProjectFeature.AddDefaultDirectivesImport(imports); + + // Assert + var import = Assert.Single(imports); + Assert.Null(import.FilePath); + } + + [Fact] + public void AddHierarchicalImports_AddsViewImportSourceDocumentsOnDisk() + { + // Arrange + var imports = new List(); + var projectItem = new TestRazorProjectItem("/Contact/Index.cshtml"); + var testFileSystem = new TestRazorProjectFileSystem(new[] + { + new TestRazorProjectItem("/Index.cshtml"), + new TestRazorProjectItem("/_ViewImports.cshtml"), + new TestRazorProjectItem("/Contact/_ViewImports.cshtml"), + projectItem, + }); + var mvcImportFeature = new MvcImportProjectFeature() + { + ProjectEngine = Mock.Of(projectEngine => projectEngine.FileSystem == testFileSystem) + }; + + // Act + mvcImportFeature.AddHierarchicalImports(projectItem, imports); + + // Assert + Assert.Collection(imports, + import => Assert.Equal("/_ViewImports.cshtml", import.FilePath), + import => Assert.Equal("/Contact/_ViewImports.cshtml", import.FilePath)); + } + + [Fact] + public void AddHierarchicalImports_AddsViewImportSourceDocumentsNotOnDisk() + { + // Arrange + var imports = new List(); + var projectItem = new TestRazorProjectItem("/Pages/Contact/Index.cshtml"); + var testFileSystem = new TestRazorProjectFileSystem(new[] { projectItem }); + var mvcImportFeature = new MvcImportProjectFeature() + { + ProjectEngine = Mock.Of(projectEngine => projectEngine.FileSystem == testFileSystem) + }; + + // Act + mvcImportFeature.AddHierarchicalImports(projectItem, imports); + + // Assert + Assert.Collection(imports, + import => Assert.Equal("/_ViewImports.cshtml", import.FilePath), + import => Assert.Equal("/Pages/_ViewImports.cshtml", import.FilePath), + import => Assert.Equal("/Pages/Contact/_ViewImports.cshtml", import.FilePath)); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcRazorTemplateEngineTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcRazorTemplateEngineTest.cs new file mode 100644 index 0000000000..f6c61c42a6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcRazorTemplateEngineTest.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 System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class MvcRazorTemplateEngineTest + { + [Fact] + public void GetDefaultImports_IncludesDefaultImports() + { + // Arrange + var expectedImports = new[] + { + "@using System", + "@using System.Collections.Generic", + "@using System.Linq", + "@using System.Threading.Tasks", + "@using Microsoft.AspNetCore.Mvc", + "@using Microsoft.AspNetCore.Mvc.Rendering", + "@using Microsoft.AspNetCore.Mvc.ViewFeatures", + }; + var mvcRazorTemplateEngine = new MvcRazorTemplateEngine( + RazorProjectEngine.Create().Engine, + new TestRazorProjectFileSystem()); + + // Act + var imports = mvcRazorTemplateEngine.Options.DefaultImports; + + // Assert + var importContent = GetContent(imports) + .Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .Where(line => line.StartsWith("@using")); + Assert.Equal(expectedImports, importContent); + } + + [Fact] + public void GetDefaultImports_IncludesDefaulInjects() + { + // Arrange + var expectedImports = new[] + { + "@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html", + "@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json", + "@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component", + "@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url", + "@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider", + }; + var mvcRazorTemplateEngine = new MvcRazorTemplateEngine( + RazorProjectEngine.Create().Engine, + new TestRazorProjectFileSystem()); + + // Act + var imports = mvcRazorTemplateEngine.Options.DefaultImports; + + // Assert + var importContent = GetContent(imports) + .Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .Where(line => line.StartsWith("@inject")); + Assert.Equal(expectedImports, importContent); + } + + [Fact] + public void GetDefaultImports_IncludesDefaultTagHelpers() + { + // Arrange + var mvcRazorTemplateEngine = new MvcRazorTemplateEngine( + RazorProjectEngine.Create().Engine, + new TestRazorProjectFileSystem()); + + // Act + var imports = mvcRazorTemplateEngine.Options.DefaultImports; + + // Assert + var importContent = GetContent(imports) + .Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .Where(line => line.StartsWith("@addTagHelper")); + Assert.Contains("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor", importContent); + Assert.Contains("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor", importContent); + Assert.Contains("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor", importContent); + } + + private string GetContent(RazorSourceDocument imports) + { + var contentChars = new char[imports.Length]; + imports.CopyTo(0, contentChars, 0, imports.Length); + return new string(contentChars); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcShim.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcShim.cs new file mode 100644 index 0000000000..0ee1e1a66d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcShim.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 System.IO; +using System.Reflection; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + internal static class MvcShim + { + public static readonly string AssemblyName = "Microsoft.AspNetCore.Razor.Test.MvcShim"; + + private static Assembly _assembly; + private static CSharpCompilation _baseCompilation; + + public static Assembly Assembly + { + get + { + if (_assembly == null) + { + var filePath = Path.Combine(Directory.GetCurrentDirectory(), AssemblyName + ".dll"); + _assembly = Assembly.LoadFrom(filePath); + } + + return _assembly; + } + } + + public static CSharpCompilation BaseCompilation + { + get + { + if (_baseCompilation == null) + { + _baseCompilation = TestCompilation.Create(Assembly); + } + + return _baseCompilation; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcViewDocumentClassifierPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcViewDocumentClassifierPassTest.cs new file mode 100644 index 0000000000..d7c0ae6854 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/MvcViewDocumentClassifierPassTest.cs @@ -0,0 +1,264 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class MvcViewDocumentClassifierPassTest + { + [Fact] + public void MvcViewDocumentClassifierPass_SetsDocumentKind() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("mvc.1.0.view", irDocument.DocumentKind); + } + + [Fact] + public void MvcViewDocumentClassifierPass_NoOpsIfDocumentKindIsAlreadySet() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + irDocument.DocumentKind = "some-value"; + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("some-value", irDocument.DocumentKind); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SetsNamespace() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("AspNetCore", visitor.Namespace.Content); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("Test", visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_NullFilePath_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("AspNetCore_d9f877a857a7e9928eac04d09a59f25967624155", visitor.Class.ClassName); + } + + [Theory] + [InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")] + [InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")] + public void MvcViewDocumentClassifierPass_UsesRelativePathToGenerateTypeName(string relativePath, string expected) + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: relativePath); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal(expected, visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_UsesAbsolutePath_IfRelativePathIsNotSet() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x::\application\Views\Home\Index.cshtml", relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("x___application_Views_Home_Index", visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SanitizesClassName() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x:\Test.cshtml", relativePath: "path.with+invalid-chars"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("path_with_invalid_chars", visitor.Class.ClassName); + } + + [Fact] + public void MvcViewDocumentClassifierPass_SetsUpExecuteAsyncMethod() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml")); + + var projectEngine = CreateProjectEngine(); + var irDocument = CreateIRDocument(projectEngine, codeDocument); + var pass = new MvcViewDocumentClassifierPass + { + Engine = projectEngine.Engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("ExecuteAsync", visitor.Method.MethodName); + Assert.Equal("global::System.Threading.Tasks.Task", visitor.Method.ReturnType); + Assert.Equal(new[] { "public", "async", "override" }, visitor.Method.Modifiers); + } + + private static RazorProjectEngine CreateProjectEngine() => RazorProjectEngine.Create(); + + private static DocumentIntermediateNode CreateIRDocument(RazorProjectEngine projectEngine, RazorCodeDocument codeDocument) + { + for (var i = 0; i < projectEngine.Phases.Count; i++) + { + var phase = projectEngine.Phases[i]; + phase.Execute(codeDocument); + + if (phase is IRazorIntermediateNodeLoweringPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + + private class Visitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Namespace { get; private set; } + + public ClassDeclarationIntermediateNode Class { get; private set; } + + public MethodDeclarationIntermediateNode Method { get; private set; } + + public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node) + { + Method = node; + } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + Namespace = node; + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Class = node; + base.VisitClassDeclaration(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/NamespaceDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/NamespaceDirectiveTest.cs new file mode 100644 index 0000000000..d744eec9fb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/NamespaceDirectiveTest.cs @@ -0,0 +1,352 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Moq; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class NamespaceDirectiveTest + { + [Fact] + public void GetNamespace_IncompleteDirective_UsesEmptyNamespace() + { + // Arrange + var source = "c:\\foo\\bar\\bleh.cshtml"; + var imports = "c:\\foo\\baz\\bleh.cshtml"; + var node = new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + + // Act + var @namespace = NamespaceDirective.GetNamespace(source, node); + + // Assert + Assert.Equal(string.Empty, @namespace); + } + + [Fact] + public void GetNamespace_EmptyDirective_UsesEmptyNamespace() + { + // Arrange + var source = "c:\\foo\\bar\\bleh.cshtml"; + var imports = "c:\\foo\\baz\\bleh.cshtml"; + var node = new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + node.Children.Add(new DirectiveTokenIntermediateNode() { Content = string.Empty }); + + // Act + var @namespace = NamespaceDirective.GetNamespace(source, node); + + // Assert + Assert.Equal(string.Empty, @namespace); + } + + // When we don't have a relationship between the source file and the imports file + // we will just use the namespace on the node directly. + [Theory] + [InlineData((string)null, (string)null)] + [InlineData("", "")] + [InlineData(null, "/foo/bar")] + [InlineData("/foo/baz", "/foo/bar/bleh")] + [InlineData("/foo.cshtml", "/foo/bar.cshtml")] + [InlineData("c:\\foo.cshtml", "d:\\foo\\bar.cshtml")] + [InlineData("c:\\foo\\bar\\bleh.cshtml", "c:\\foo\\baz\\bleh.cshtml")] + public void GetNamespace_ForNonRelatedFiles_UsesNamespaceVerbatim(string source, string imports) + { + // Arrange + var node = new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + + node.Children.Add(new DirectiveTokenIntermediateNode() { Content = "Base" }); + + // Act + var @namespace = NamespaceDirective.GetNamespace(source, node); + + // Assert + Assert.Equal("Base", @namespace); + } + + [Theory] + [InlineData("/foo.cshtml", "/_ViewImports.cshtml", "Base")] + [InlineData("/foo/bar.cshtml", "/_ViewImports.cshtml", "Base.foo")] + [InlineData("/foo/bar/baz.cshtml", "/_ViewImports.cshtml", "Base.foo.bar")] + [InlineData("/foo/bar/baz.cshtml", "/foo/_ViewImports.cshtml", "Base.bar")] + [InlineData("/Foo/bar/baz.cshtml", "/foo/_ViewImports.cshtml", "Base.bar")] + [InlineData("c:\\foo.cshtml", "c:\\_ViewImports.cshtml", "Base")] + [InlineData("c:\\foo\\bar.cshtml", "c:\\_ViewImports.cshtml", "Base.foo")] + [InlineData("c:\\foo\\bar\\baz.cshtml", "c:\\_ViewImports.cshtml", "Base.foo.bar")] + [InlineData("c:\\foo\\bar\\baz.cshtml", "c:\\foo\\_ViewImports.cshtml", "Base.bar")] + [InlineData("c:\\Foo\\bar\\baz.cshtml", "c:\\foo\\_ViewImports.cshtml", "Base.bar")] + public void GetNamespace_ForRelatedFiles_ComputesNamespaceWithSuffix(string source, string imports, string expected) + { + // Arrange + var node = new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + + node.Children.Add(new DirectiveTokenIntermediateNode() { Content = "Base" }); + + // Act + var @namespace = NamespaceDirective.GetNamespace(source, node); + + // Assert + Assert.Equal(expected, @namespace); + } + + // This is the case where a _ViewImports sets the namespace. + [Fact] + public void Pass_SetsNamespace_ComputedFromImports() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account.Manage", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + // This is the case where the source file sets the namespace. + [Fact] + public void Pass_SetsNamespace_ComputedFromSource() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + // This will be ignored. + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "ignored" }); + builder.Pop(); + + // This will be used. + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/Manage/AddUser.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account.Manage" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account.Manage", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + // Handles cases where invalid characters appears in FileNames. Note that we don't sanitize the part of + // the namespace that you put in an import, just the file-based-suffix. Garbage in, garbage out. + [Fact] + public void Pass_SetsNamespace_SanitizesClassAndNamespace() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage-Info/Add+User.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account.Manage_Info", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + // This is the case where the source file sets the namespace. + [Fact] + public void Pass_SetsNamespace_ComputedFromSource_ForView() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + // This will be ignored. + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "ignored" }); + builder.Pop(); + + // This will be used. + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan("/Account/Manage/AddUser.cshtml", 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account.Manage" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account.Manage", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + // This handles an error case where we can't determine the relationship between the + // imports and the source. + [Fact] + public void Pass_SetsNamespace_VerbatimFromImports() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(null, 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("WebApplication.Account", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + + [Fact] + public void Pass_DoesNothing_ForUnknownDocumentKind() + { + // Arrange + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + builder.Push(new DirectiveIntermediateNode() + { + Directive = NamespaceDirective.Directive, + Source = new SourceSpan(null, 0, 0, 0, 0), + }); + builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" }); + builder.Pop(); + + var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" }; + builder.Push(@namespace); + + var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" }; + builder.Add(@class); + + document.DocumentKind = null; + + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml")); + + var pass = new NamespaceDirective.Pass(); + pass.Engine = Mock.Of(); + + // Act + pass.Execute(codeDocument, document); + + // Assert + Assert.Equal("default", @namespace.Content); + Assert.Equal("default", @class.ClassName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/PageDirectiveTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/PageDirectiveTest.cs new file mode 100644 index 0000000000..6cf2796358 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/PageDirectiveTest.cs @@ -0,0 +1,148 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class PageDirectiveTest + { + [Fact] + public void TryGetPageDirective_ReturnsTrue_IfPageIsMalformed() + { + // Arrange + var content = "@page \"some-route-template\" Invalid"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Equal("some-route-template", pageDirective.RouteTemplate); + Assert.NotNull(pageDirective.DirectiveNode); + } + + [Fact] + public void TryGetPageDirective_ReturnsTrue_IfPageIsImported() + { + // Arrange + var content = "Hello world"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var importDocument = RazorSourceDocument.Create("@page", "imports.cshtml"); + var codeDocument = RazorCodeDocument.Create(sourceDocument, new[] { importDocument }); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Null(pageDirective.RouteTemplate); + } + + [Fact] + public void TryGetPageDirective_ReturnsFalse_IfPageDoesNotHaveDirective() + { + // Arrange + var content = "Hello world"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.False(result); + Assert.Null(pageDirective); + } + + [Fact] + public void TryGetPageDirective_ReturnsTrue_IfPageDoesStartWithDirective() + { + // Arrange + var content = "Hello @page"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Null(pageDirective.RouteTemplate); + Assert.NotNull(pageDirective.DirectiveNode); + } + + [Fact] + public void TryGetPageDirective_ReturnsTrue_IfContentHasDirective() + { + // Arrange + var content = "@page"; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Null(pageDirective.RouteTemplate); + } + + [Fact] + public void TryGetPageDirective_ParsesRouteTemplate() + { + // Arrange + var content = "@page \"some-route-template\""; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Equal("some-route-template", pageDirective.RouteTemplate); + } + + private RazorEngine CreateEngine() + { + return RazorProjectEngine.Create(b => + { + PageDirective.Register(b); + }).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 IRazorDocumentClassifierPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..3337ebeac2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/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/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/RazorPageDocumentClassifierPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/RazorPageDocumentClassifierPassTest.cs new file mode 100644 index 0000000000..a0cdbd7f80 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/RazorPageDocumentClassifierPassTest.cs @@ -0,0 +1,417 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class RazorPageDocumentClassifierPassTest + { + [Fact] + public void RazorPageDocumentClassifierPass_LogsErrorForImportedPageDirectives() + { + // Arrange + var sourceSpan = new SourceSpan("import.cshtml", 0, 0, 0, 5); + var expectedDiagnostic = RazorExtensionsDiagnosticFactory.CreatePageDirective_CannotBeImported(sourceSpan); + var importDocument = RazorSourceDocument.Create("@page", "import.cshtml"); + var sourceDocument = RazorSourceDocument.Create("

Hello World

", "main.cshtml"); + var codeDocument = RazorCodeDocument.Create(sourceDocument, new[] { importDocument }); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive); + var directive = Assert.Single(pageDirectives); + var diagnostic = Assert.Single(directive.Node.Diagnostics); + Assert.Equal(expectedDiagnostic, diagnostic); + } + + [Fact] + public void RazorPageDocumentClassifierPass_LogsErrorIfDirectiveNotAtTopOfFile() + { + // Arrange + var sourceSpan = new SourceSpan( + "Test.cshtml", + absoluteIndex: 14 + Environment.NewLine.Length * 2, + lineIndex: 2, + characterIndex: 0, + length: 5 + Environment.NewLine.Length); + + var expectedDiagnostic = RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(sourceSpan); + var content = @" +@somethingelse +@page +"; + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive); + var directive = Assert.Single(pageDirectives); + var diagnostic = Assert.Single(directive.Node.Diagnostics); + Assert.Equal(expectedDiagnostic, diagnostic); + } + + [Fact] + public void RazorPageDocumentClassifierPass_DoesNotLogErrorIfCommentAndWhitespaceBeforeDirective() + { + // Arrange + var content = @" +@* some comment *@ + +@page +"; + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive); + var directive = Assert.Single(pageDirectives); + Assert.Empty(directive.Node.Diagnostics); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SetsDocumentKind() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("mvc.1.0.razor-page", irDocument.DocumentKind); + } + + [Fact] + public void RazorPageDocumentClassifierPass_NoOpsIfDocumentKindIsAlreadySet() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + irDocument.DocumentKind = "some-value"; + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("some-value", irDocument.DocumentKind); + } + + [Fact] + public void RazorPageDocumentClassifierPass_NoOpsIfPageDirectiveIsMalformed() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page+1", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + irDocument.DocumentKind = "some-value"; + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + Assert.Equal("some-value", irDocument.DocumentKind); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SetsNamespace() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("AspNetCore", visitor.Namespace.Content); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.RazorPages.Page", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("Test", visitor.Class.ClassName); + } + + [Fact] + public void RazorPageDocumentClassifierPass_NullFilePath_SetsClass() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("global::Microsoft.AspNetCore.Mvc.RazorPages.Page", visitor.Class.BaseType); + Assert.Equal(new[] { "public" }, visitor.Class.Modifiers); + Assert.Equal("AspNetCore_74fbaab062bb228ed1ab09c5ff8d6ed2417320e2", visitor.Class.ClassName); + } + + [Theory] + [InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")] + [InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")] + public void RazorPageDocumentClassifierPass_UsesRelativePathToGenerateTypeName(string relativePath, string expected) + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: relativePath); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal(expected, visitor.Class.ClassName); + } + + [Fact] + public void RazorPageDocumentClassifierPass_UsesAbsolutePath_IfRelativePathIsNotSet() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x::\application\Views\Home\Index.cshtml", relativePath: null); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("x___application_Views_Home_Index", visitor.Class.ClassName); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SanitizesClassName() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: @"x:\Test.cshtml", relativePath: "path.with+invalid-chars"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("path_with_invalid_chars", visitor.Class.ClassName); + } + + [Fact] + public void RazorPageDocumentClassifierPass_SetsUpExecuteAsyncMethod() + { + // Arrange + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml")); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + Assert.Equal("ExecuteAsync", visitor.Method.MethodName); + Assert.Equal("global::System.Threading.Tasks.Task", visitor.Method.ReturnType); + Assert.Equal(new[] { "public", "async", "override" }, visitor.Method.Modifiers); + } + + [Fact] + public void RazorPageDocumentClassifierPass_AddsRouteTemplateMetadata() + { + // Arrange + var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml"); + var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page \"some-route\"", properties)); + + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + var pass = new RazorPageDocumentClassifierPass + { + Engine = engine + }; + + // Act + pass.Execute(codeDocument, irDocument); + var visitor = new Visitor(); + visitor.Visit(irDocument); + + // Assert + var attributeNode = Assert.IsType(visitor.ExtensionNode); + Assert.Equal("RouteTemplate", attributeNode.Key); + Assert.Equal("some-route", attributeNode.Value); + } + + private static RazorEngine CreateEngine() + { + return RazorProjectEngine.Create(b => + { + PageDirective.Register(b); + }).Engine; + } + + private static 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 IRazorIntermediateNodeLoweringPhase) + { + break; + } + } + + return codeDocument.GetDocumentIntermediateNode(); + } + + private class Visitor : IntermediateNodeWalker + { + public NamespaceDeclarationIntermediateNode Namespace { get; private set; } + + public ClassDeclarationIntermediateNode Class { get; private set; } + + public MethodDeclarationIntermediateNode Method { get; private set; } + + public ExtensionIntermediateNode ExtensionNode { get; private set; } + + public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node) + { + Method = node; + } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + Namespace = node; + base.VisitNamespaceDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Class = node; + base.VisitClassDeclaration(node); + } + + public override void VisitExtension(ExtensionIntermediateNode node) + { + ExtensionNode = node; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/SourceMappingsSerializer.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/SourceMappingsSerializer.cs new file mode 100644 index 0000000000..c2dd799b05 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/SourceMappingsSerializer.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 System; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public static class SourceMappingsSerializer + { + public static string Serialize(RazorCSharpDocument csharpDocument, RazorSourceDocument sourceDocument) + { + var builder = new StringBuilder(); + var sourceFilePath = sourceDocument.FilePath; + var charBuffer = new char[sourceDocument.Length]; + sourceDocument.CopyTo(0, charBuffer, 0, sourceDocument.Length); + var sourceContent = new string(charBuffer); + + for (var i = 0; i < csharpDocument.SourceMappings.Count; i++) + { + var sourceMapping = csharpDocument.SourceMappings[i]; + if (!string.Equals(sourceMapping.OriginalSpan.FilePath, sourceFilePath, StringComparison.Ordinal)) + { + continue; + } + + builder.Append("Source Location: "); + AppendMappingLocation(builder, sourceMapping.OriginalSpan, sourceContent); + + builder.Append("Generated Location: "); + AppendMappingLocation(builder, sourceMapping.GeneratedSpan, csharpDocument.GeneratedCode); + + builder.AppendLine(); + } + + return builder.ToString(); + } + + private static void AppendMappingLocation(StringBuilder builder, SourceSpan location, string content) + { + builder + .AppendLine(location.ToString()) + .Append("|"); + + for (var i = 0; i < location.Length; i++) + { + builder.Append(content[location.AbsoluteIndex + i]); + } + + builder.AppendLine("|"); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TagHelperDescriptorExtensionsTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TagHelperDescriptorExtensionsTest.cs new file mode 100644 index 0000000000..e9e423853c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TagHelperDescriptorExtensionsTest.cs @@ -0,0 +1,82 @@ +// 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; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class TagHelperDescriptorExtensionsTest + { + [Fact] + public void IsViewComponentKind_ReturnsFalse_ForNonVCTHDescriptor() + { + // Arrange + var tagHelper = CreateTagHelperDescriptor(); + + // Act + var result = tagHelper.IsViewComponentKind(); + + // Assert + Assert.False(result); + } + + [Fact] + public void IsViewComponentKind_ReturnsTrue_ForVCTHDescriptor() + { + // Arrange + var tagHelper = CreateViewComponentTagHelperDescriptor(); + + // Act + var result = tagHelper.IsViewComponentKind(); + + // Assert + Assert.True(result); + } + + [Fact] + public void GetViewComponentName_ReturnsNull_ForNonVCTHDescriptor() + { + //Arrange + var tagHelper = CreateTagHelperDescriptor(); + + // Act + var result = tagHelper.GetViewComponentName(); + + // Assert + Assert.Null(result); + } + + [Fact] + public void GetViewComponentName_ReturnsName_ForVCTHDescriptor() + { + // Arrange + var tagHelper = CreateViewComponentTagHelperDescriptor("ViewComponentName"); + + // Act + var result = tagHelper.GetViewComponentName(); + + // Assert + Assert.Equal("ViewComponentName", result); + } + + private static TagHelperDescriptor CreateTagHelperDescriptor() + { + var tagHelper = TagHelperDescriptorBuilder.Create("TypeName", "AssemblyName") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name")) + .Build(); + + return tagHelper; + } + + private static TagHelperDescriptor CreateViewComponentTagHelperDescriptor(string name = "ViewComponentName") + { + var tagHelper = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TypeName", "AssemblyName") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, name) + .Build(); + + return tagHelper; + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml new file mode 100644 index 0000000000..a20b20dae8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml @@ -0,0 +1,8 @@ +
+ Hello world + @string.Format("{0}", "Hello") +
+@{ + var cls = "foo"; +} +

diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs new file mode 100644 index 0000000000..d39b64c26d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs @@ -0,0 +1,71 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + __o = this.ToString(); + +#line default +#line hidden +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" +__o = string.Format("{0}", "Hello"); + +#line default +#line hidden +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + + var cls = "foo"; + +#line default +#line hidden +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + if(cls != null) { + +#line default +#line hidden +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + __o = cls; + +#line default +#line hidden +#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" + } + +#line default +#line hidden + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt new file mode 100644 index 0000000000..4074239b9f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt @@ -0,0 +1,64 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (0:0,0 [4] Basic.cshtml) + IntermediateToken - (0:0,0 [4] Basic.cshtml) - Html -

+ IntermediateToken - (30:0,30 [23] Basic.cshtml) - Html - \n Hello world\n + CSharpExpression - (54:2,5 [29] Basic.cshtml) + IntermediateToken - (54:2,5 [29] Basic.cshtml) - CSharp - string.Format("{0}", "Hello") + HtmlContent - (83:2,34 [10] Basic.cshtml) + IntermediateToken - (83:2,34 [2] Basic.cshtml) - Html - \n + IntermediateToken - (85:3,0 [6] Basic.cshtml) - Html -
+ IntermediateToken - (91:3,6 [2] Basic.cshtml) - Html - \n + CSharpCode - (95:4,2 [25] Basic.cshtml) + IntermediateToken - (95:4,2 [25] Basic.cshtml) - CSharp - \n var cls = "foo";\n + HtmlContent - (123:7,0 [2] Basic.cshtml) + IntermediateToken - (123:7,0 [2] Basic.cshtml) - Html -

+ IntermediateToken - (162:7,39 [2] Basic.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt new file mode 100644 index 0000000000..372b49cb6f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt @@ -0,0 +1,34 @@ +Source Location: (13:0,13 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|this.ToString()| +Generated Location: (1030:26,13 [15] ) +|this.ToString()| + +Source Location: (54:2,5 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|string.Format("{0}", "Hello")| +Generated Location: (1166:31,6 [29] ) +|string.Format("{0}", "Hello")| + +Source Location: (95:4,2 [25] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +| + var cls = "foo"; +| +Generated Location: (1312:36,2 [25] ) +| + var cls = "foo"; +| + +Source Location: (134:7,11 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|if(cls != null) { | +Generated Location: (1460:42,11 [18] ) +|if(cls != null) { | + +Source Location: (153:7,30 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +|cls| +Generated Location: (1622:47,30 [3] ) +|cls| + +Source Location: (156:7,33 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) +| }| +Generated Location: (1773:52,33 [2] ) +| }| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs new file mode 100644 index 0000000000..ec84263550 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_Runtime.codegen.cs @@ -0,0 +1,81 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "6d079dd6c39f39d17a2faff14404b37ab7e8b8fc" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"6d079dd6c39f39d17a2faff14404b37ab7e8b8fc", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("

+ IntermediateToken - (30:0,30 [19] Basic.cshtml) - Html - \n Hello world\n + IntermediateToken - (49:2,0 [4] Basic.cshtml) - Html - + CSharpExpression - (54:2,5 [29] Basic.cshtml) + IntermediateToken - (54:2,5 [29] Basic.cshtml) - CSharp - string.Format("{0}", "Hello") + HtmlContent - (83:2,34 [10] Basic.cshtml) + IntermediateToken - (83:2,34 [2] Basic.cshtml) - Html - \n + IntermediateToken - (85:3,0 [6] Basic.cshtml) - Html -
+ IntermediateToken - (91:3,6 [2] Basic.cshtml) - Html - \n + CSharpCode - (95:4,2 [25] Basic.cshtml) + IntermediateToken - (95:4,2 [25] Basic.cshtml) - CSharp - \n var cls = "foo";\n + HtmlContent - (123:7,0 [2] Basic.cshtml) + IntermediateToken - (123:7,0 [2] Basic.cshtml) - Html -

+ IntermediateToken - (162:7,39 [2] Basic.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml new file mode 100644 index 0000000000..224242197b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml @@ -0,0 +1,15 @@ +@* These test files validate that end-to-end, incomplete directives don't throw. *@ + +@page +@page +@page " + +@model +@model + +@inject +@inject +@inject MyService + +@namespace +@namespace diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs new file mode 100644 index 0000000000..dd100bee00 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs @@ -0,0 +1,71 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { + } + ))(); + ((System.Action)(() => { +#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..1cfef392ae --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt @@ -0,0 +1,12 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ2001: The 'page' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,1): Error RZ2001: The 'page' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,7): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,1): Error RZ2001: The 'model' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,8): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,8): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,9): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,26): Error RZ1015: The 'inject' directive expects an identifier. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,11): Error RZ1014: The 'namespace' directive expects a namespace name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,1): Error RZ2001: The 'namespace' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,12): Error RZ1014: The 'namespace' directive expects a namespace name. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt new file mode 100644 index 0000000000..2aeddc2fa2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt @@ -0,0 +1,84 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (119:6,6 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (128:7,7 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (139:9,7 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (149:10,8 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (159:11,8 [17] IncompleteDirectives.cshtml) - MyService + DirectiveToken - (176:11,25 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (190:13,10 [0] IncompleteDirectives.cshtml) - + DirectiveToken - (203:14,11 [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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) + IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page + MalformedDirective - (102:4,0 [6] IncompleteDirectives.cshtml) - page + HtmlContent - (108:4,6 [5] IncompleteDirectives.cshtml) + IntermediateToken - (108:4,6 [5] IncompleteDirectives.cshtml) - Html - "\n\n + MalformedDirective - (113:6,0 [6] IncompleteDirectives.cshtml) - model + DirectiveToken - (119:6,6 [0] IncompleteDirectives.cshtml) - + HtmlContent - (119:6,6 [2] IncompleteDirectives.cshtml) + IntermediateToken - (119:6,6 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (121:7,0 [7] IncompleteDirectives.cshtml) - model + DirectiveToken - (128:7,7 [0] IncompleteDirectives.cshtml) - + HtmlContent - (128:7,7 [4] IncompleteDirectives.cshtml) + IntermediateToken - (128:7,7 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (132:9,0 [7] IncompleteDirectives.cshtml) - inject + DirectiveToken - (139:9,7 [0] IncompleteDirectives.cshtml) - + HtmlContent - (139:9,7 [2] IncompleteDirectives.cshtml) + IntermediateToken - (139:9,7 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (141:10,0 [8] IncompleteDirectives.cshtml) - inject + DirectiveToken - (149:10,8 [0] IncompleteDirectives.cshtml) - + HtmlContent - (149:10,8 [2] IncompleteDirectives.cshtml) + IntermediateToken - (149:10,8 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (151:11,0 [25] IncompleteDirectives.cshtml) - inject + DirectiveToken - (159:11,8 [17] IncompleteDirectives.cshtml) - MyService + DirectiveToken - (176:11,25 [0] IncompleteDirectives.cshtml) - + HtmlContent - (176:11,25 [4] IncompleteDirectives.cshtml) + IntermediateToken - (176:11,25 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (180:13,0 [10] IncompleteDirectives.cshtml) - namespace + DirectiveToken - (190:13,10 [0] IncompleteDirectives.cshtml) - + HtmlContent - (190:13,10 [2] IncompleteDirectives.cshtml) + IntermediateToken - (190:13,10 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (192:14,0 [11] IncompleteDirectives.cshtml) - namespace + DirectiveToken - (203:14,11 [0] IncompleteDirectives.cshtml) - + HtmlContent - (203:14,11 [2] IncompleteDirectives.cshtml) + IntermediateToken - (203:14,11 [2] IncompleteDirectives.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt new file mode 100644 index 0000000000..4bb61bf781 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt @@ -0,0 +1,40 @@ +Source Location: (119:6,6 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (671:18,0 [0] ) +|| + +Source Location: (128:7,7 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (724:21,0 [0] ) +|| + +Source Location: (139:9,7 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (777:24,0 [0] ) +|| + +Source Location: (149:10,8 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (830:27,0 [0] ) +|| + +Source Location: (159:11,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|MyService| +Generated Location: (980:31,0 [17] ) +|MyService| + +Source Location: (176:11,25 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (1133:38,0 [0] ) +|| + +Source Location: (190:13,10 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (1186:41,0 [0] ) +|| + +Source Location: (203:14,11 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) +|| +Generated Location: (1239:44,0 [0] ) +|| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs new file mode 100644 index 0000000000..31179505bf --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs @@ -0,0 +1,47 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5add9dba0a182cd75498c5b24f64a2547e7f49b0" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"5add9dba0a182cd75498c5b24f64a2547e7f49b0", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n\r\n"); + WriteLiteral("\"\r\n\r\n"); + WriteLiteral("\r\n"); + WriteLiteral("\r\n\r\n"); + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + WriteLiteral("\r\n\r\n"); + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt new file mode 100644 index 0000000000..1cfef392ae --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt @@ -0,0 +1,12 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ2001: The 'page' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,1): Error RZ2001: The 'page' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,7): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,1): Error RZ2001: The 'model' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,8): Error RZ1013: The 'model' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,8): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,9): Error RZ1013: The 'inject' directive expects a type name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,26): Error RZ1015: The 'inject' directive expects an identifier. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,11): Error RZ1014: The 'namespace' directive expects a namespace name. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,1): Error RZ2001: The 'namespace' directive may only occur once per document. +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,12): Error RZ1014: The 'namespace' directive expects a namespace name. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt new file mode 100644 index 0000000000..0478bc1e74 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt @@ -0,0 +1,59 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) + IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page + MalformedDirective - (102:4,0 [6] IncompleteDirectives.cshtml) - page + HtmlContent - (108:4,6 [5] IncompleteDirectives.cshtml) + IntermediateToken - (108:4,6 [5] IncompleteDirectives.cshtml) - Html - "\n\n + MalformedDirective - (113:6,0 [6] IncompleteDirectives.cshtml) - model + DirectiveToken - (119:6,6 [0] IncompleteDirectives.cshtml) - + HtmlContent - (119:6,6 [2] IncompleteDirectives.cshtml) + IntermediateToken - (119:6,6 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (121:7,0 [7] IncompleteDirectives.cshtml) - model + DirectiveToken - (128:7,7 [0] IncompleteDirectives.cshtml) - + HtmlContent - (128:7,7 [4] IncompleteDirectives.cshtml) + IntermediateToken - (128:7,7 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (132:9,0 [7] IncompleteDirectives.cshtml) - inject + DirectiveToken - (139:9,7 [0] IncompleteDirectives.cshtml) - + HtmlContent - (139:9,7 [2] IncompleteDirectives.cshtml) + IntermediateToken - (139:9,7 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (141:10,0 [8] IncompleteDirectives.cshtml) - inject + DirectiveToken - (149:10,8 [0] IncompleteDirectives.cshtml) - + HtmlContent - (149:10,8 [2] IncompleteDirectives.cshtml) + IntermediateToken - (149:10,8 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (151:11,0 [25] IncompleteDirectives.cshtml) - inject + DirectiveToken - (159:11,8 [17] IncompleteDirectives.cshtml) - MyService + DirectiveToken - (176:11,25 [0] IncompleteDirectives.cshtml) - + HtmlContent - (176:11,25 [4] IncompleteDirectives.cshtml) + IntermediateToken - (176:11,25 [4] IncompleteDirectives.cshtml) - Html - \n\n + MalformedDirective - (180:13,0 [10] IncompleteDirectives.cshtml) - namespace + DirectiveToken - (190:13,10 [0] IncompleteDirectives.cshtml) - + HtmlContent - (190:13,10 [2] IncompleteDirectives.cshtml) + IntermediateToken - (190:13,10 [2] IncompleteDirectives.cshtml) - Html - \n + MalformedDirective - (192:14,0 [11] IncompleteDirectives.cshtml) - namespace + DirectiveToken - (203:14,11 [0] IncompleteDirectives.cshtml) - + HtmlContent - (203:14,11 [2] IncompleteDirectives.cshtml) + IntermediateToken - (203:14,11 [2] IncompleteDirectives.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml new file mode 100644 index 0000000000..38efd570da --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml @@ -0,0 +1,2 @@ +@inherits MyBasePageForViews +@model MyModel diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs new file mode 100644 index 0000000000..7cdbaf3326 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs @@ -0,0 +1,56 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel : MyBasePageForViews + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" +MyBasePageForViews __typeHelper = default(MyBasePageForViews); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt new file mode 100644 index 0000000000..3310acfa76 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt @@ -0,0 +1,39 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel - MyBasePageForViews - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (10:0,10 [26] InheritsViewModel.cshtml) - MyBasePageForViews + DirectiveToken - (45:1,7 [7] InheritsViewModel.cshtml) - MyModel + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt new file mode 100644 index 0000000000..6a313a909d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (10:0,10 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml) +|MyBasePageForViews| +Generated Location: (740:19,0 [26] ) +|MyBasePageForViews| + +Source Location: (45:1,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml) +|MyModel| +Generated Location: (1004:27,0 [7] ) +|MyModel| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs new file mode 100644 index 0000000000..9680177b77 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.codegen.cs @@ -0,0 +1,36 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "3ff83e2f0d946feb387a8ea03a529c64350014f8" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"3ff83e2f0d946feb387a8ea03a529c64350014f8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel : MyBasePageForViews + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt new file mode 100644 index 0000000000..2468ef4662 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_Runtime.ir.txt @@ -0,0 +1,20 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel - MyBasePageForViews - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml new file mode 100644 index 0000000000..295e4cf3ab --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml @@ -0,0 +1,2 @@ +@page +@model MyModel diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs new file mode 100644 index 0000000000..f174a0fc2f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs @@ -0,0 +1,50 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports : MyPageModel + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public MyModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt new file mode 100644 index 0000000000..bcbf42ae26 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt @@ -0,0 +1,43 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyPageModel - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (10:0,10 [19] TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml) - MyPageModel + DirectiveToken - (14:1,7 [7] InheritsWithViewImports.cshtml) - MyModel + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public MyModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt new file mode 100644 index 0000000000..e7daecd874 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (14:1,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml) +|MyModel| +Generated Location: (745:19,0 [7] ) +|MyModel| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs new file mode 100644 index 0000000000..c1ea0b5c3e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.codegen.cs @@ -0,0 +1,39 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d196fc1c66d46d35e35af9b01c737e12bcce6782" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d196fc1c66d46d35e35af9b01c737e12bcce6782", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml")] + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"f311ecbb5c4d63980a59c24af5ffe8baa1c3f99a", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports : MyPageModel + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public MyModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt new file mode 100644 index 0000000000..2704223a57 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Runtime.ir.txt @@ -0,0 +1,25 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyPageModel - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public MyModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml new file mode 100644 index 0000000000..0aa749dd3f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml @@ -0,0 +1 @@ +@inject MyApp MyPropertyName diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml new file mode 100644 index 0000000000..d699f1e754 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml @@ -0,0 +1,3 @@ +@model MyModel +@inject MyApp MyPropertyName +@inject MyService Html diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs new file mode 100644 index 0000000000..2120622373 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs @@ -0,0 +1,82 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +global::System.Object MyPropertyName = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" +global::System.Object Html = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt new file mode 100644 index 0000000000..c1d70d5d89 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt @@ -0,0 +1,43 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [7] InjectWithModel.cshtml) - MyModel + DirectiveToken - (24:1,8 [5] InjectWithModel.cshtml) - MyApp + DirectiveToken - (30:1,14 [14] InjectWithModel.cshtml) - MyPropertyName + DirectiveToken - (54:2,8 [17] InjectWithModel.cshtml) - MyService + DirectiveToken - (72:2,26 [4] InjectWithModel.cshtml) - Html + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt new file mode 100644 index 0000000000..c4838ff64d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt @@ -0,0 +1,25 @@ +Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyModel| +Generated Location: (766:19,0 [7] ) +|MyModel| + +Source Location: (24:1,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyApp| +Generated Location: (990:27,0 [5] ) +|MyApp| + +Source Location: (30:1,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyPropertyName| +Generated Location: (1232:35,22 [14] ) +|MyPropertyName| + +Source Location: (54:2,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|MyService| +Generated Location: (1438:43,0 [17] ) +|MyService| + +Source Location: (72:2,26 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) +|Html| +Generated Location: (1704:51,22 [4] ) +|Html| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs new file mode 100644 index 0000000000..36974edf08 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.codegen.cs @@ -0,0 +1,38 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2cafb599699b78d76f0355b6f528050b4720789d" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2cafb599699b78d76f0355b6f528050b4720789d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt new file mode 100644 index 0000000000..d018107ae2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_Runtime.ir.txt @@ -0,0 +1,21 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml new file mode 100644 index 0000000000..8cd61913e4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml @@ -0,0 +1,5 @@ +@model MyModel +@inject MyApp MyPropertyName; +@inject MyService Html; +@inject MyApp MyPropertyName2 ; +@inject MyService Html2 ; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs new file mode 100644 index 0000000000..ea95a4e7eb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs @@ -0,0 +1,118 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyModel __typeHelper = default(MyModel); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object MyPropertyName = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object Html = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object MyPropertyName2 = null; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +MyService __typeHelper = default(MyService); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" +global::System.Object Html2 = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt new file mode 100644 index 0000000000..5c4540f366 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt @@ -0,0 +1,49 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [7] InjectWithSemicolon.cshtml) - MyModel + DirectiveToken - (24:1,8 [5] InjectWithSemicolon.cshtml) - MyApp + DirectiveToken - (30:1,14 [14] InjectWithSemicolon.cshtml) - MyPropertyName + DirectiveToken - (58:2,8 [17] InjectWithSemicolon.cshtml) - MyService + DirectiveToken - (76:2,26 [4] InjectWithSemicolon.cshtml) - Html + DirectiveToken - (93:3,8 [5] InjectWithSemicolon.cshtml) - MyApp + DirectiveToken - (99:3,14 [15] InjectWithSemicolon.cshtml) - MyPropertyName2 + DirectiveToken - (129:4,8 [17] InjectWithSemicolon.cshtml) - MyService + DirectiveToken - (147:4,26 [5] InjectWithSemicolon.cshtml) - Html2 + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt new file mode 100644 index 0000000000..6a90f75f3e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt @@ -0,0 +1,45 @@ +Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyModel| +Generated Location: (774:19,0 [7] ) +|MyModel| + +Source Location: (24:1,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyApp| +Generated Location: (1002:27,0 [5] ) +|MyApp| + +Source Location: (30:1,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyPropertyName| +Generated Location: (1248:35,22 [14] ) +|MyPropertyName| + +Source Location: (58:2,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyService| +Generated Location: (1458:43,0 [17] ) +|MyService| + +Source Location: (76:2,26 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|Html| +Generated Location: (1728:51,22 [4] ) +|Html| + +Source Location: (93:3,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyApp| +Generated Location: (1928:59,0 [5] ) +|MyApp| + +Source Location: (99:3,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyPropertyName2| +Generated Location: (2174:67,22 [15] ) +|MyPropertyName2| + +Source Location: (129:4,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|MyService| +Generated Location: (2385:75,0 [17] ) +|MyService| + +Source Location: (147:4,26 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) +|Html2| +Generated Location: (2655:83,22 [5] ) +|Html2| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs new file mode 100644 index 0000000000..b8eb5c371d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.codegen.cs @@ -0,0 +1,42 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8a53bde02f202036e674a23018e04268a3a844bb" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"8a53bde02f202036e674a23018e04268a3a844bb", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName2 { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyService Html { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt new file mode 100644 index 0000000000..898557c170 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_Runtime.ir.txt @@ -0,0 +1,23 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs new file mode 100644 index 0000000000..7b2f4fedc6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs @@ -0,0 +1,58 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml" +MyApp __typeHelper = default(MyApp); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml" +global::System.Object MyPropertyName = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt new file mode 100644 index 0000000000..0b8beeae9b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt @@ -0,0 +1,40 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (8:0,8 [5] Inject.cshtml) - MyApp + DirectiveToken - (14:0,14 [14] Inject.cshtml) - MyPropertyName + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt new file mode 100644 index 0000000000..10ed356ecf --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (8:0,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml) +|MyApp| +Generated Location: (748:19,0 [5] ) +|MyApp| + +Source Location: (14:0,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml) +|MyPropertyName| +Generated Location: (981:27,22 [14] ) +|MyPropertyName| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs new file mode 100644 index 0000000000..e3493199a4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.codegen.cs @@ -0,0 +1,38 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "592a6d8544c71b828d4a3fbf92d398cd3ea72790" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"592a6d8544c71b828d4a3fbf92d398cd3ea72790", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public MyApp MyPropertyName { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt new file mode 100644 index 0000000000..e05f9d2df9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_Runtime.ir.txt @@ -0,0 +1,21 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml new file mode 100644 index 0000000000..6dfb72bc31 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml @@ -0,0 +1 @@ +@namespace Test. \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs new file mode 100644 index 0000000000..d99c176c52 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..90446dc58b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml(1,12): Error RZ1014: The 'namespace' directive expects a namespace name. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt new file mode 100644 index 0000000000..6f9220aab4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt @@ -0,0 +1,40 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (0:0,0 [11] InvalidNamespaceAtEOF.cshtml) - namespace + HtmlContent - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) + IntermediateToken - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) - Html - Test. + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs new file mode 100644 index 0000000000..2b269092bb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs @@ -0,0 +1,37 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "010d175bb6c3f7fa6f2ae04c1fecb4e3bfbf928b" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"010d175bb6c3f7fa6f2ae04c1fecb4e3bfbf928b", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("Test."); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt new file mode 100644 index 0000000000..90446dc58b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml(1,12): Error RZ1014: The 'namespace' directive expects a namespace name. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt new file mode 100644 index 0000000000..7a0583e5a0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt @@ -0,0 +1,23 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (0:0,0 [11] InvalidNamespaceAtEOF.cshtml) - namespace + HtmlContent - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) + IntermediateToken - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) - Html - Test. + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml new file mode 100644 index 0000000000..9b4f9d5559 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml @@ -0,0 +1,4 @@ +@page "foo + +

About Us

+

We are awesome.

\ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs new file mode 100644 index 0000000000..15befce0d0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs @@ -0,0 +1,42 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..637d1e902b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml(1,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt new file mode 100644 index 0000000000..c3fbc6082e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt @@ -0,0 +1,51 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (0:0,0 [6] MalformedPageDirective.cshtml) - page + HtmlContent - (6:0,6 [49] MalformedPageDirective.cshtml) + IntermediateToken - (6:0,6 [8] MalformedPageDirective.cshtml) - Html - "foo\n\n + IntermediateToken - (14:2,0 [4] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (18:2,4 [8] MalformedPageDirective.cshtml) - Html - About Us + IntermediateToken - (26:2,12 [5] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (31:2,17 [2] MalformedPageDirective.cshtml) - Html - \n + IntermediateToken - (33:3,0 [3] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (36:3,3 [15] MalformedPageDirective.cshtml) - Html - We are awesome. + IntermediateToken - (51:3,18 [4] MalformedPageDirective.cshtml) - Html -

+ Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.mappings.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.codegen.cs new file mode 100644 index 0000000000..63b6c0a23e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.codegen.cs @@ -0,0 +1,39 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "464e008b9a04181fe1e9f2cc6826095698de4739" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"464e008b9a04181fe1e9f2cc6826095698de4739", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\"foo\r\n\r\n

About Us

\r\n

We are awesome.

"); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.diagnostics.txt new file mode 100644 index 0000000000..637d1e902b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml(1,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.ir.txt new file mode 100644 index 0000000000..7a04b0051a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_Runtime.ir.txt @@ -0,0 +1,34 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (0:0,0 [6] MalformedPageDirective.cshtml) - page + HtmlContent - (6:0,6 [49] MalformedPageDirective.cshtml) + IntermediateToken - (6:0,6 [8] MalformedPageDirective.cshtml) - Html - "foo\n\n + IntermediateToken - (14:2,0 [4] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (18:2,4 [8] MalformedPageDirective.cshtml) - Html - About Us + IntermediateToken - (26:2,12 [5] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (31:2,17 [2] MalformedPageDirective.cshtml) - Html - \n + IntermediateToken - (33:3,0 [3] MalformedPageDirective.cshtml) - Html -

+ IntermediateToken - (36:3,3 [15] MalformedPageDirective.cshtml) - Html - We are awesome. + IntermediateToken - (51:3,18 [4] MalformedPageDirective.cshtml) - Html -

+ Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml new file mode 100644 index 0000000000..4b73b2dc53 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml @@ -0,0 +1 @@ +@model System.Collections.IEnumerable diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml new file mode 100644 index 0000000000..c488b1e443 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml @@ -0,0 +1,6 @@ +@model DateTime + +@addTagHelper "InputTestTagHelper, AppCode" + + + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs new file mode 100644 index 0000000000..82441cd663 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs @@ -0,0 +1,69 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +DateTime __typeHelper = default(DateTime); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +global::System.Object __typeHelper = "InputTestTagHelper, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + __InputTestTagHelper = CreateTagHelper(); +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + __InputTestTagHelper = CreateTagHelper(); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => Model); + +#line default +#line hidden + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt new file mode 100644 index 0000000000..37627e94ea --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt @@ -0,0 +1,68 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [8] ModelExpressionTagHelper.cshtml) - DateTime + DirectiveToken - (33:2,14 [29] ModelExpressionTagHelper.cshtml) - "InputTestTagHelper, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (17:1,0 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (17:1,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n + HtmlContent - (62:2,43 [4] ModelExpressionTagHelper.cshtml) + IntermediateToken - (62:2,43 [4] ModelExpressionTagHelper.cshtml) - Html - \n\n + TagHelper - (66:4,0 [25] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (91:4,25 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (91:4,25 [2] ModelExpressionTagHelper.cshtml) - Html - \n + TagHelper - (93:5,0 [27] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - (111:5,18 [5] ModelExpressionTagHelper.cshtml) - CSharp - Model + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (120:5,27 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (120:5,27 [2] ModelExpressionTagHelper.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt new file mode 100644 index 0000000000..63a7d6ccc1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt @@ -0,0 +1,20 @@ +Source Location: (7:0,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|DateTime| +Generated Location: (851:20,0 [8] ) +|DateTime| + +Source Location: (33:2,14 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|"InputTestTagHelper, AppCode"| +Generated Location: (1123:28,37 [29] ) +|"InputTestTagHelper, AppCode"| + +Source Location: (83:4,17 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|Date| +Generated Location: (1802:44,102 [4] ) +|Date| + +Source Location: (111:5,18 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) +|Model| +Generated Location: (2118:50,94 [5] ) +|Model| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs new file mode 100644 index 0000000000..d5ec95d2aa --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.codegen.cs @@ -0,0 +1,95 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "741fc99adb54ad906c5cdc5391aeffb51a1e767b" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"741fc99adb54ad906c5cdc5391aeffb51a1e767b", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => { + } + ); + __InputTestTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTestTagHelper); +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("for", __InputTestTagHelper.For, 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-test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => { + } + ); + __InputTestTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTestTagHelper); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => Model); + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("for", __InputTestTagHelper.For, 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 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt new file mode 100644 index 0000000000..0d8f3b8ec2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_Runtime.ir.txt @@ -0,0 +1,49 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (17:1,0 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (17:1,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n + HtmlContent - (64:3,0 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (64:3,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n + TagHelper - (66:4,0 [25] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (91:4,25 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (91:4,25 [2] ModelExpressionTagHelper.cshtml) - Html - \n + TagHelper - (93:5,0 [27] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - (111:5,18 [5] ModelExpressionTagHelper.cshtml) - CSharp - Model + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (120:5,27 [2] ModelExpressionTagHelper.cshtml) + IntermediateToken - (120:5,27 [2] ModelExpressionTagHelper.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs new file mode 100644 index 0000000000..63c2a52c6f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs @@ -0,0 +1,48 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml" +System.Collections.IEnumerable __typeHelper = default(System.Collections.IEnumerable); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt new file mode 100644 index 0000000000..1ebdc00df2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt @@ -0,0 +1,38 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [30] Model.cshtml) - System.Collections.IEnumerable + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt new file mode 100644 index 0000000000..7d84cf754d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (7:0,7 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml) +|System.Collections.IEnumerable| +Generated Location: (769:19,0 [30] ) +|System.Collections.IEnumerable| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs new file mode 100644 index 0000000000..ae8dc1fe65 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.codegen.cs @@ -0,0 +1,36 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2c1e88396568d309c236020e59bf2abacfadd612" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2c1e88396568d309c236020e59bf2abacfadd612", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt new file mode 100644 index 0000000000..2b7dcff085 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_Runtime.ir.txt @@ -0,0 +1,20 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml new file mode 100644 index 0000000000..350f93b776 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml @@ -0,0 +1,2 @@ +@model ThisShouldBeGenerated +@model System.Collections.IEnumerable diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs new file mode 100644 index 0000000000..e8f705cef7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs @@ -0,0 +1,56 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MultipleModels : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml" +ThisShouldBeGenerated __typeHelper = default(ThisShouldBeGenerated); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml" +System.Collections.IEnumerable __typeHelper = default(System.Collections.IEnumerable); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..2fe8233c66 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml(2,1): Error RZ2001: The 'model' directive may only occur once per document. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt new file mode 100644 index 0000000000..f63a69601b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt @@ -0,0 +1,41 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MultipleModels - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [21] MultipleModels.cshtml) - ThisShouldBeGenerated + DirectiveToken - (37:1,7 [30] MultipleModels.cshtml) - System.Collections.IEnumerable + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + MalformedDirective - (30:1,0 [39] MultipleModels.cshtml) - model + DirectiveToken - (37:1,7 [30] MultipleModels.cshtml) - System.Collections.IEnumerable + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt new file mode 100644 index 0000000000..79d7e257c7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (7:0,7 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml) +|ThisShouldBeGenerated| +Generated Location: (778:19,0 [21] ) +|ThisShouldBeGenerated| + +Source Location: (37:1,7 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml) +|System.Collections.IEnumerable| +Generated Location: (1029:27,0 [30] ) +|System.Collections.IEnumerable| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml new file mode 100644 index 0000000000..ecee97de58 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml @@ -0,0 +1,3 @@ +@page +@namespace Test.Namespace +

Hi There!

diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs new file mode 100644 index 0000000000..9d7181bfad --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs @@ -0,0 +1,50 @@ +// +#pragma warning disable 1591 +namespace Test.Namespace +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml" +global::System.Object __typeHelper = nameof(Test.Namespace); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt new file mode 100644 index 0000000000..9238a0a419 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt @@ -0,0 +1,47 @@ +Document - + NamespaceDeclaration - - Test.Namespace + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (18:1,11 [14] PageWithNamespace.cshtml) - Test.Namespace + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (34:2,0 [20] PageWithNamespace.cshtml) + IntermediateToken - (34:2,0 [4] PageWithNamespace.cshtml) - Html -

+ IntermediateToken - (38:2,4 [9] PageWithNamespace.cshtml) - Html - Hi There! + IntermediateToken - (47:2,13 [5] PageWithNamespace.cshtml) - Html -

+ IntermediateToken - (52:2,18 [2] PageWithNamespace.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt new file mode 100644 index 0000000000..b41240c9c5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (18:1,11 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml) +|Test.Namespace| +Generated Location: (809:19,44 [14] ) +|Test.Namespace| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.codegen.cs new file mode 100644 index 0000000000..729698a9cc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.codegen.cs @@ -0,0 +1,39 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "1edfb1ba4f5f6c70e2c72f4f23baf4dc0ae14377" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml", typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace), null)] +namespace Test.Namespace +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"1edfb1ba4f5f6c70e2c72f4f23baf4dc0ae14377", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("

Hi There!

\r\n"); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.ir.txt new file mode 100644 index 0000000000..5be907ee1d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_Runtime.ir.txt @@ -0,0 +1,29 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml", typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace), null)] + NamespaceDeclaration - - Test.Namespace + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (34:2,0 [20] PageWithNamespace.cshtml) + IntermediateToken - (34:2,0 [4] PageWithNamespace.cshtml) - Html -

+ IntermediateToken - (38:2,4 [9] PageWithNamespace.cshtml) - Html - Hi There! + IntermediateToken - (47:2,13 [5] PageWithNamespace.cshtml) - Html -

+ IntermediateToken - (52:2,18 [2] PageWithNamespace.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PageWithNamespace Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml new file mode 100644 index 0000000000..5172f8f791 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml @@ -0,0 +1,2 @@ +
Some text here.
+@page diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs new file mode 100644 index 0000000000..ec8a4fd5c9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs @@ -0,0 +1,42 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt new file mode 100644 index 0000000000..393b35646e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml(2,1): Error RZ3906: The '@page' directive must precede all other elements defined in a Razor file. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt new file mode 100644 index 0000000000..c21d9fc82c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt @@ -0,0 +1,46 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (0:0,0 [28] RazorPageWithNoLeadingPageDirective.cshtml) + IntermediateToken - (0:0,0 [5] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (5:0,5 [15] RazorPageWithNoLeadingPageDirective.cshtml) - Html - Some text here. + IntermediateToken - (20:0,20 [6] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (26:0,26 [2] RazorPageWithNoLeadingPageDirective.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.mappings.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs new file mode 100644 index 0000000000..f69dce12eb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs @@ -0,0 +1,39 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "40c0ffad85d8fef63edfb5d91a08bd1b3609ba6f" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"40c0ffad85d8fef63edfb5d91a08bd1b3609ba6f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("
Some text here.
\r\n"); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt new file mode 100644 index 0000000000..393b35646e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt @@ -0,0 +1 @@ +TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml(2,1): Error RZ3906: The '@page' directive must precede all other elements defined in a Razor file. diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt new file mode 100644 index 0000000000..42eb920742 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt @@ -0,0 +1,29 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (0:0,0 [28] RazorPageWithNoLeadingPageDirective.cshtml) + IntermediateToken - (0:0,0 [5] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (5:0,5 [15] RazorPageWithNoLeadingPageDirective.cshtml) - Html - Some text here. + IntermediateToken - (20:0,20 [6] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (26:0,26 [2] RazorPageWithNoLeadingPageDirective.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml new file mode 100644 index 0000000000..2bc617c509 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml @@ -0,0 +1,40 @@ +@page + +@model NewModel +@addTagHelper "*, AppCode" +@using Microsoft.AspNetCore.Mvc.RazorPages + +@functions { + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } +} + +

New Customer

+
+
+
+ +
+ + +
+
+
+
+ +
+
+
diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml new file mode 100644 index 0000000000..63d5955e72 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml @@ -0,0 +1,13 @@ +@page "/About" + +@model NewModel +@using Microsoft.AspNetCore.Mvc.RazorPages + +@functions { + public class NewModel : PageModel + { + public string Name { get; set; } + } +} + +

New Customer @Model.Name

diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.codegen.cs new file mode 100644 index 0000000000..8f5d082e6a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.codegen.cs @@ -0,0 +1,78 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("RouteTemplate", "/About")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" +global::System.Object __typeHelper = "/About"; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" +NewModel __typeHelper = default(NewModel); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" + __o = Model.Name; + +#line default +#line hidden + } + #pragma warning restore 1998 +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" + + public class NewModel : PageModel + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public NewModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.ir.txt new file mode 100644 index 0000000000..c71b835bf9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.ir.txt @@ -0,0 +1,60 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (36:3,1 [41] RazorPagesWithRouteTemplate.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + RazorCompiledItemMetadataAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (6:0,6 [8] RazorPagesWithRouteTemplate.cshtml) - "/About" + DirectiveToken - (25:2,7 [8] RazorPagesWithRouteTemplate.cshtml) - NewModel + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (16:1,0 [2] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (16:1,0 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + HtmlContent - (77:3,42 [4] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (77:3,42 [4] RazorPagesWithRouteTemplate.cshtml) - Html - \n\n + HtmlContent - (191:10,1 [21] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (191:10,1 [4] RazorPagesWithRouteTemplate.cshtml) - Html - \n\n + IntermediateToken - (195:12,0 [4] RazorPagesWithRouteTemplate.cshtml) - Html -

+ IntermediateToken - (199:12,4 [13] RazorPagesWithRouteTemplate.cshtml) - Html - New Customer + CSharpExpression - (213:12,18 [10] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (213:12,18 [10] RazorPagesWithRouteTemplate.cshtml) - CSharp - Model.Name + HtmlContent - (223:12,28 [7] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (223:12,28 [5] RazorPagesWithRouteTemplate.cshtml) - Html -

+ IntermediateToken - (228:12,33 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + CSharpCode - (93:5,12 [97] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (93:5,12 [97] RazorPagesWithRouteTemplate.cshtml) - CSharp - \n public class NewModel : PageModel\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public NewModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.mappings.txt new file mode 100644 index 0000000000..cc5e9cad30 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_DesignTime.mappings.txt @@ -0,0 +1,35 @@ +Source Location: (36:3,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +|using Microsoft.AspNetCore.Mvc.RazorPages| +Generated Location: (492:14,0 [41] ) +|using Microsoft.AspNetCore.Mvc.RazorPages| + +Source Location: (6:0,6 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +|"/About"| +Generated Location: (1108:25,37 [8] ) +|"/About"| + +Source Location: (25:2,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +|NewModel| +Generated Location: (1313:33,0 [8] ) +|NewModel| + +Source Location: (213:12,18 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +|Model.Name| +Generated Location: (1841:48,18 [10] ) +|Model.Name| + +Source Location: (93:5,12 [97] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml) +| + public class NewModel : PageModel + { + public string Name { get; set; } + } +| +Generated Location: (2049:55,12 [97] ) +| + public class NewModel : PageModel + { + public string Name { get; set; } + } +| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.codegen.cs new file mode 100644 index 0000000000..83f08818fc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.codegen.cs @@ -0,0 +1,62 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "547900310554f446d88da593a245719ee9dbb12f" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate), @"/About")] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("RouteTemplate", "/About")] + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"547900310554f446d88da593a245719ee9dbb12f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + WriteLiteral("\r\n

New Customer "); +#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" + Write(Model.Name); + +#line default +#line hidden + WriteLiteral("

\r\n"); + } + #pragma warning restore 1998 +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml" + + public class NewModel : PageModel + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public NewModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.ir.txt new file mode 100644 index 0000000000..c8fbdea2cc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate_Runtime.ir.txt @@ -0,0 +1,41 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate), @"/About")] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (36:3,1 [43] RazorPagesWithRouteTemplate.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + RazorCompiledItemMetadataAttribute - + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithRouteTemplate - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (16:1,0 [2] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (16:1,0 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + HtmlContent - (79:4,0 [2] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (79:4,0 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + HtmlContent - (193:11,0 [19] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (193:11,0 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + IntermediateToken - (195:12,0 [4] RazorPagesWithRouteTemplate.cshtml) - Html -

+ IntermediateToken - (199:12,4 [13] RazorPagesWithRouteTemplate.cshtml) - Html - New Customer + CSharpExpression - (213:12,18 [10] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (213:12,18 [10] RazorPagesWithRouteTemplate.cshtml) - CSharp - Model.Name + HtmlContent - (223:12,28 [7] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (223:12,28 [5] RazorPagesWithRouteTemplate.cshtml) - Html -

+ IntermediateToken - (228:12,33 [2] RazorPagesWithRouteTemplate.cshtml) - Html - \n + CSharpCode - (93:5,12 [97] RazorPagesWithRouteTemplate.cshtml) + IntermediateToken - (93:5,12 [97] RazorPagesWithRouteTemplate.cshtml) - CSharp - \n public class NewModel : PageModel\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public NewModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml new file mode 100644 index 0000000000..b78cc65ec7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml @@ -0,0 +1,36 @@ +@page + +@addTagHelper "*, AppCode" +@using Microsoft.AspNetCore.Mvc.RazorPages + +@functions { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } +} + +

New Customer

+
+
+
+ +
+ + +
+
+
+
+ +
+
+
diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs new file mode 100644 index 0000000000..aeb2631c46 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs @@ -0,0 +1,83 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + private global::DivTagHelper __DivTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" +global::System.Object __typeHelper = "*, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + __DivTagHelper = CreateTagHelper(); +#line 25 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" + __o = Name; + +#line default +#line hidden + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + } + #pragma warning restore 1998 +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" + + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt new file mode 100644 index 0000000000..913b80d2aa --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt @@ -0,0 +1,143 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (38:3,1 [41] RazorPagesWithoutModel.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (23:2,14 [12] RazorPagesWithoutModel.cshtml) - "*, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (7:1,0 [2] RazorPagesWithoutModel.cshtml) + IntermediateToken - (7:1,0 [2] RazorPagesWithoutModel.cshtml) - Html - \n + HtmlContent - (35:2,26 [2] RazorPagesWithoutModel.cshtml) + IntermediateToken - (35:2,26 [2] RazorPagesWithoutModel.cshtml) - Html - \n + HtmlContent - (79:3,42 [4] RazorPagesWithoutModel.cshtml) + IntermediateToken - (79:3,42 [4] RazorPagesWithoutModel.cshtml) - Html - \n\n + HtmlContent - (379:18,1 [77] RazorPagesWithoutModel.cshtml) + IntermediateToken - (379:18,1 [4] RazorPagesWithoutModel.cshtml) - Html - \n\n + IntermediateToken - (383:20,0 [4] RazorPagesWithoutModel.cshtml) - Html -

+ IntermediateToken - (387:20,4 [12] RazorPagesWithoutModel.cshtml) - Html - New Customer + IntermediateToken - (399:20,16 [5] RazorPagesWithoutModel.cshtml) - Html -

+ IntermediateToken - (404:20,21 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (406:21,0 [5] RazorPagesWithoutModel.cshtml) - Html -
+ IntermediateToken - (450:21,44 [6] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (456:22,4 [31] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (468:22,16 [11] RazorPagesWithoutModel.cshtml) + IntermediateToken - (468:22,16 [11] RazorPagesWithoutModel.cshtml) - Html - text-danger + DefaultTagHelperExecute - + HtmlContent - (487:22,35 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (487:22,35 [6] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (493:23,4 [237] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (517:23,28 [48] RazorPagesWithoutModel.cshtml) + IntermediateToken - (517:23,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (527:24,8 [6] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (578:24,59 [10] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (588:25,8 [130] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (611:25,31 [101] RazorPagesWithoutModel.cshtml) + IntermediateToken - (611:25,31 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (625:26,12 [6] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (655:26,42 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (669:27,12 [5] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (695:27,38 [7] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (702:27,45 [10] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (600:25,20 [9] RazorPagesWithoutModel.cshtml) + IntermediateToken - (600:25,20 [9] RazorPagesWithoutModel.cshtml) - Html - col-md-10 + DefaultTagHelperExecute - + HtmlContent - (718:28,14 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (718:28,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (505:23,16 [10] RazorPagesWithoutModel.cshtml) + IntermediateToken - (505:23,16 [10] RazorPagesWithoutModel.cshtml) - Html - form-group + DefaultTagHelperExecute - + HtmlContent - (730:29,10 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (730:29,10 [6] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (736:30,4 [174] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (760:30,28 [10] RazorPagesWithoutModel.cshtml) + IntermediateToken - (760:30,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (770:31,8 [128] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (809:31,47 [83] RazorPagesWithoutModel.cshtml) + IntermediateToken - (809:31,47 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (823:32,12 [7] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (882:32,71 [10] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (782:31,20 [25] RazorPagesWithoutModel.cshtml) + IntermediateToken - (782:31,20 [25] RazorPagesWithoutModel.cshtml) - Html - col-md-offset-2 col-md-10 + DefaultTagHelperExecute - + HtmlContent - (898:33,14 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (898:33,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (748:30,16 [10] RazorPagesWithoutModel.cshtml) + IntermediateToken - (748:30,16 [10] RazorPagesWithoutModel.cshtml) - Html - form-group + DefaultTagHelperExecute - + HtmlContent - (910:34,10 [11] RazorPagesWithoutModel.cshtml) + IntermediateToken - (910:34,10 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (912:35,0 [7] RazorPagesWithoutModel.cshtml) - Html -
+ IntermediateToken - (919:35,7 [2] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - (95:5,12 [283] RazorPagesWithoutModel.cshtml) + IntermediateToken - (95:5,12 [283] RazorPagesWithoutModel.cshtml) - CSharp - \n public IActionResult OnPost(Customer customer)\n {\n Name = customer.Name;\n return Redirect("~/customers/inlinepagemodels/");\n }\n\n public string Name { get; set; }\n\n public class Customer\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt new file mode 100644 index 0000000000..33f7baa377 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt @@ -0,0 +1,46 @@ +Source Location: (38:3,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) +|using Microsoft.AspNetCore.Mvc.RazorPages| +Generated Location: (487:14,0 [41] ) +|using Microsoft.AspNetCore.Mvc.RazorPages| + +Source Location: (23:2,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) +|"*, AppCode"| +Generated Location: (1035:25,37 [12] ) +|"*, AppCode"| + +Source Location: (566:24,47 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) +|Name| +Generated Location: (1629:41,47 [4] ) +|Name| + +Source Location: (95:5,12 [283] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) +| + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } +| +Generated Location: (2110:52,12 [283] ) +| + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } +| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.codegen.cs new file mode 100644 index 0000000000..2a42ce12f2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.codegen.cs @@ -0,0 +1,166 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8bf3954ad78688478de155359db8af32627ee2b8" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"8bf3954ad78688478de155359db8af32627ee2b8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + 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("text-danger"), 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("col-md-10"), 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("form-group"), 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("col-md-offset-2 col-md-10"), 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; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + WriteLiteral("\r\n

New Customer

\r\n
\r\n "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __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("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + WriteLiteral("\r\n \r\n "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + WriteLiteral("\r\n \r\n \r\n "); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __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(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __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("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + WriteLiteral("\r\n "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + WriteLiteral("\r\n \r\n "); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n "); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __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"); + } + #pragma warning restore 1998 +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml" + + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + + public class Customer + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.ir.txt new file mode 100644 index 0000000000..ea80083dd2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_Runtime.ir.txt @@ -0,0 +1,117 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (38:3,1 [43] RazorPagesWithoutModel.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - text-danger - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - col-md-10 - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - class - form-group - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - class - col-md-offset-2 col-md-10 - HtmlAttributeValueStyle.DoubleQuotes + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (7:1,0 [2] RazorPagesWithoutModel.cshtml) + IntermediateToken - (7:1,0 [2] RazorPagesWithoutModel.cshtml) - Html - \n + HtmlContent - (81:4,0 [2] RazorPagesWithoutModel.cshtml) + IntermediateToken - (81:4,0 [2] RazorPagesWithoutModel.cshtml) - Html - \n + HtmlContent - (381:19,0 [75] RazorPagesWithoutModel.cshtml) + IntermediateToken - (381:19,0 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (383:20,0 [4] RazorPagesWithoutModel.cshtml) - Html -

+ IntermediateToken - (387:20,4 [12] RazorPagesWithoutModel.cshtml) - Html - New Customer + IntermediateToken - (399:20,16 [5] RazorPagesWithoutModel.cshtml) - Html -

+ IntermediateToken - (404:20,21 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (406:21,0 [5] RazorPagesWithoutModel.cshtml) - Html -
+ IntermediateToken - (450:21,44 [6] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (456:22,4 [31] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 + DefaultTagHelperExecute - + HtmlContent - (487:22,35 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (487:22,35 [6] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (493:23,4 [237] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (517:23,28 [48] RazorPagesWithoutModel.cshtml) + IntermediateToken - (517:23,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (527:24,8 [6] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (578:24,59 [10] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (588:25,8 [130] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (611:25,31 [101] RazorPagesWithoutModel.cshtml) + IntermediateToken - (611:25,31 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (625:26,12 [6] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (655:26,42 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (669:27,12 [5] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (695:27,38 [7] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (702:27,45 [10] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 + DefaultTagHelperExecute - + HtmlContent - (718:28,14 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (718:28,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 + DefaultTagHelperExecute - + HtmlContent - (730:29,10 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (730:29,10 [6] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (736:30,4 [174] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (760:30,28 [10] RazorPagesWithoutModel.cshtml) + IntermediateToken - (760:30,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n + TagHelper - (770:31,8 [128] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (809:31,47 [83] RazorPagesWithoutModel.cshtml) + IntermediateToken - (809:31,47 [14] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (823:32,12 [7] RazorPagesWithoutModel.cshtml) - Html - + IntermediateToken - (882:32,71 [10] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3 + DefaultTagHelperExecute - + HtmlContent - (898:33,14 [6] RazorPagesWithoutModel.cshtml) + IntermediateToken - (898:33,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 + DefaultTagHelperExecute - + HtmlContent - (910:34,10 [11] RazorPagesWithoutModel.cshtml) + IntermediateToken - (910:34,10 [2] RazorPagesWithoutModel.cshtml) - Html - \n + IntermediateToken - (912:35,0 [7] RazorPagesWithoutModel.cshtml) - Html -
+ IntermediateToken - (919:35,7 [2] RazorPagesWithoutModel.cshtml) - Html - \n + CSharpCode - (95:5,12 [283] RazorPagesWithoutModel.cshtml) + IntermediateToken - (95:5,12 [283] RazorPagesWithoutModel.cshtml) - CSharp - \n public IActionResult OnPost(Customer customer)\n {\n Name = customer.Name;\n return Redirect("~/customers/inlinepagemodels/");\n }\n\n public string Name { get; set; }\n\n public class Customer\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs new file mode 100644 index 0000000000..d7acbdf7d1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs @@ -0,0 +1,94 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + private global::DivTagHelper __DivTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" +NewModel __typeHelper = default(NewModel); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" +global::System.Object __typeHelper = "*, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + __DivTagHelper = CreateTagHelper(); +#line 29 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" + __o = Model.Name; + +#line default +#line hidden + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + __DivTagHelper = CreateTagHelper(); + } + #pragma warning restore 1998 +#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" + + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public NewModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt new file mode 100644 index 0000000000..2266b746f6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt @@ -0,0 +1,144 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (55:4,1 [41] RazorPages.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (16:2,7 [8] RazorPages.cshtml) - NewModel + DirectiveToken - (40:3,14 [12] RazorPages.cshtml) - "*, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (7:1,0 [2] RazorPages.cshtml) + IntermediateToken - (7:1,0 [2] RazorPages.cshtml) - Html - \n + HtmlContent - (52:3,26 [2] RazorPages.cshtml) + IntermediateToken - (52:3,26 [2] RazorPages.cshtml) - Html - \n + HtmlContent - (96:4,42 [4] RazorPages.cshtml) + IntermediateToken - (96:4,42 [4] RazorPages.cshtml) - Html - \n\n + HtmlContent - (473:22,1 [78] RazorPages.cshtml) + IntermediateToken - (473:22,1 [4] RazorPages.cshtml) - Html - \n\n + IntermediateToken - (477:24,0 [4] RazorPages.cshtml) - Html -

+ IntermediateToken - (481:24,4 [12] RazorPages.cshtml) - Html - New Customer + IntermediateToken - (493:24,16 [5] RazorPages.cshtml) - Html -

+ IntermediateToken - (498:24,21 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (500:25,0 [5] RazorPages.cshtml) - Html -
+ IntermediateToken - (545:25,45 [6] RazorPages.cshtml) - Html - \n + TagHelper - (551:26,4 [31] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (563:26,16 [11] RazorPages.cshtml) + IntermediateToken - (563:26,16 [11] RazorPages.cshtml) - Html - text-danger + DefaultTagHelperExecute - + HtmlContent - (582:26,35 [6] RazorPages.cshtml) + IntermediateToken - (582:26,35 [6] RazorPages.cshtml) - Html - \n + TagHelper - (588:27,4 [243] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (612:27,28 [48] RazorPages.cshtml) + IntermediateToken - (612:27,28 [10] RazorPages.cshtml) - Html - \n + IntermediateToken - (622:28,8 [6] RazorPages.cshtml) - Html - + IntermediateToken - (679:28,65 [10] RazorPages.cshtml) - Html - \n + TagHelper - (689:29,8 [130] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (712:29,31 [101] RazorPages.cshtml) + IntermediateToken - (712:29,31 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (726:30,12 [6] RazorPages.cshtml) - Html - + IntermediateToken - (756:30,42 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (770:31,12 [5] RazorPages.cshtml) - Html - + IntermediateToken - (796:31,38 [7] RazorPages.cshtml) - Html - + IntermediateToken - (803:31,45 [10] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (701:29,20 [9] RazorPages.cshtml) + IntermediateToken - (701:29,20 [9] RazorPages.cshtml) - Html - col-md-10 + DefaultTagHelperExecute - + HtmlContent - (819:32,14 [6] RazorPages.cshtml) + IntermediateToken - (819:32,14 [6] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (600:27,16 [10] RazorPages.cshtml) + IntermediateToken - (600:27,16 [10] RazorPages.cshtml) - Html - form-group + DefaultTagHelperExecute - + HtmlContent - (831:33,10 [6] RazorPages.cshtml) + IntermediateToken - (831:33,10 [6] RazorPages.cshtml) - Html - \n + TagHelper - (837:34,4 [174] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (861:34,28 [10] RazorPages.cshtml) + IntermediateToken - (861:34,28 [10] RazorPages.cshtml) - Html - \n + TagHelper - (871:35,8 [128] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (910:35,47 [83] RazorPages.cshtml) + IntermediateToken - (910:35,47 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (924:36,12 [7] RazorPages.cshtml) - Html - + IntermediateToken - (983:36,71 [10] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (883:35,20 [25] RazorPages.cshtml) + IntermediateToken - (883:35,20 [25] RazorPages.cshtml) - Html - col-md-offset-2 col-md-10 + DefaultTagHelperExecute - + HtmlContent - (999:37,14 [6] RazorPages.cshtml) + IntermediateToken - (999:37,14 [6] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (849:34,16 [10] RazorPages.cshtml) + IntermediateToken - (849:34,16 [10] RazorPages.cshtml) - Html - form-group + DefaultTagHelperExecute - + HtmlContent - (1011:38,10 [11] RazorPages.cshtml) + IntermediateToken - (1011:38,10 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (1013:39,0 [7] RazorPages.cshtml) - Html -
+ IntermediateToken - (1020:39,7 [2] RazorPages.cshtml) - Html - \n + CSharpCode - (112:6,12 [360] RazorPages.cshtml) + IntermediateToken - (112:6,12 [360] RazorPages.cshtml) - CSharp - \n public class NewModel : PageModel\n {\n public IActionResult OnPost(Customer customer)\n {\n Name = customer.Name;\n return Redirect("~/customers/inlinepagemodels/");\n }\n\n public string Name { get; set; }\n }\n\n public class Customer\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public NewModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt new file mode 100644 index 0000000000..0af8c77dfd --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt @@ -0,0 +1,57 @@ +Source Location: (55:4,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +|using Microsoft.AspNetCore.Mvc.RazorPages| +Generated Location: (475:14,0 [41] ) +|using Microsoft.AspNetCore.Mvc.RazorPages| + +Source Location: (16:2,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +|NewModel| +Generated Location: (962:25,0 [8] ) +|NewModel| + +Source Location: (40:3,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +|"*, AppCode"| +Generated Location: (1220:33,37 [12] ) +|"*, AppCode"| + +Source Location: (661:28,47 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +|Model.Name| +Generated Location: (1802:49,47 [10] ) +|Model.Name| + +Source Location: (112:6,12 [360] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) +| + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } +| +Generated Location: (2277:60,12 [360] ) +| + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } +| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.codegen.cs new file mode 100644 index 0000000000..8f9b84f114 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.codegen.cs @@ -0,0 +1,169 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d33caff161b646a61b273d7c544111395b652557" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages), null)] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" +using Microsoft.AspNetCore.Mvc.RazorPages; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d33caff161b646a61b273d7c544111395b652557", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + 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("text-danger"), 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("col-md-10"), 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("form-group"), 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("col-md-offset-2 col-md-10"), 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; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + WriteLiteral("\r\n

New Customer

\r\n
\r\n "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __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("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + WriteLiteral("\r\n \r\n "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + WriteLiteral("\r\n \r\n \r\n "); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __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(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __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("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + WriteLiteral("\r\n "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + WriteLiteral("\r\n \r\n "); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n "); + } + ); + __DivTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__DivTagHelper); + __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"); + } + #pragma warning restore 1998 +#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml" + + public class NewModel : PageModel + { + public IActionResult OnPost(Customer customer) + { + Name = customer.Name; + return Redirect("~/customers/inlinepagemodels/"); + } + + public string Name { get; set; } + } + + public class Customer + { + public string Name { get; set; } + } + +#line default +#line hidden + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + public NewModel Model => ViewData.Model; + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.ir.txt new file mode 100644 index 0000000000..8c352308a0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_Runtime.ir.txt @@ -0,0 +1,117 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages), null)] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (55:4,1 [43] RazorPages.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - text-danger - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - col-md-10 - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - class - form-group - HtmlAttributeValueStyle.DoubleQuotes + PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - class - col-md-offset-2 col-md-10 - HtmlAttributeValueStyle.DoubleQuotes + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (7:1,0 [2] RazorPages.cshtml) + IntermediateToken - (7:1,0 [2] RazorPages.cshtml) - Html - \n + HtmlContent - (98:5,0 [2] RazorPages.cshtml) + IntermediateToken - (98:5,0 [2] RazorPages.cshtml) - Html - \n + HtmlContent - (475:23,0 [76] RazorPages.cshtml) + IntermediateToken - (475:23,0 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (477:24,0 [4] RazorPages.cshtml) - Html -

+ IntermediateToken - (481:24,4 [12] RazorPages.cshtml) - Html - New Customer + IntermediateToken - (493:24,16 [5] RazorPages.cshtml) - Html -

+ IntermediateToken - (498:24,21 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (500:25,0 [5] RazorPages.cshtml) - Html -
+ IntermediateToken - (545:25,45 [6] RazorPages.cshtml) - Html - \n + TagHelper - (551:26,4 [31] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 + DefaultTagHelperExecute - + HtmlContent - (582:26,35 [6] RazorPages.cshtml) + IntermediateToken - (582:26,35 [6] RazorPages.cshtml) - Html - \n + TagHelper - (588:27,4 [243] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (612:27,28 [48] RazorPages.cshtml) + IntermediateToken - (612:27,28 [10] RazorPages.cshtml) - Html - \n + IntermediateToken - (622:28,8 [6] RazorPages.cshtml) - Html - + IntermediateToken - (679:28,65 [10] RazorPages.cshtml) - Html - \n + TagHelper - (689:29,8 [130] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (712:29,31 [101] RazorPages.cshtml) + IntermediateToken - (712:29,31 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (726:30,12 [6] RazorPages.cshtml) - Html - + IntermediateToken - (756:30,42 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (770:31,12 [5] RazorPages.cshtml) - Html - + IntermediateToken - (796:31,38 [7] RazorPages.cshtml) - Html - + IntermediateToken - (803:31,45 [10] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 + DefaultTagHelperExecute - + HtmlContent - (819:32,14 [6] RazorPages.cshtml) + IntermediateToken - (819:32,14 [6] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 + DefaultTagHelperExecute - + HtmlContent - (831:33,10 [6] RazorPages.cshtml) + IntermediateToken - (831:33,10 [6] RazorPages.cshtml) - Html - \n + TagHelper - (837:34,4 [174] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (861:34,28 [10] RazorPages.cshtml) + IntermediateToken - (861:34,28 [10] RazorPages.cshtml) - Html - \n + TagHelper - (871:35,8 [128] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + HtmlContent - (910:35,47 [83] RazorPages.cshtml) + IntermediateToken - (910:35,47 [14] RazorPages.cshtml) - Html - \n + IntermediateToken - (924:36,12 [7] RazorPages.cshtml) - Html - + IntermediateToken - (983:36,71 [10] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3 + DefaultTagHelperExecute - + HtmlContent - (999:37,14 [6] RazorPages.cshtml) + IntermediateToken - (999:37,14 [6] RazorPages.cshtml) - Html - \n + DefaultTagHelperCreate - - DivTagHelper + PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 + DefaultTagHelperExecute - + HtmlContent - (1011:38,10 [11] RazorPages.cshtml) + IntermediateToken - (1011:38,10 [2] RazorPages.cshtml) - Html - \n + IntermediateToken - (1013:39,0 [7] RazorPages.cshtml) - Html -
+ IntermediateToken - (1020:39,7 [2] RazorPages.cshtml) - Html - \n + CSharpCode - (112:6,12 [360] RazorPages.cshtml) + IntermediateToken - (112:6,12 [360] RazorPages.cshtml) - CSharp - \n public class NewModel : PageModel\n {\n public IActionResult OnPost(Customer customer)\n {\n Name = customer.Name;\n return Redirect("~/customers/inlinepagemodels/");\n }\n\n public string Name { get; set; }\n }\n\n public class Customer\n {\n public string Name { get; set; }\n }\n + Inject - + Inject - + Inject - + Inject - + Inject - + CSharpCode - + IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + CSharpCode - + IntermediateToken - - CSharp - public NewModel Model => ViewData.Model; diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml new file mode 100644 index 0000000000..7438788ff4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml @@ -0,0 +1,14 @@ +@model DateTime + +@addTagHelper "InputTestTagHelper, AppCode" + +@{ + Layout = "_SectionTestLayout.cshtml"; +} + +
Some body
+ +@section Section1 { +
This is in Section 1
+ +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs new file mode 100644 index 0000000000..3ca46af8a7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs @@ -0,0 +1,80 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +DateTime __typeHelper = default(DateTime); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +global::System.Object __typeHelper = "InputTestTagHelper, AppCode"; + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +global::System.Object Section1 = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" + + Layout = "_SectionTestLayout.cshtml"; + +#line default +#line hidden + DefineSection("Section1", async(__razor_section_writer) => { + __InputTestTagHelper = CreateTagHelper(); +#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + } + ); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt new file mode 100644 index 0000000000..312d7bb7ae --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt @@ -0,0 +1,73 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (7:0,7 [8] Sections.cshtml) - DateTime + DirectiveToken - (33:2,14 [29] Sections.cshtml) - "InputTestTagHelper, AppCode" + DirectiveToken - (152:10,9 [8] Sections.cshtml) - Section1 + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (17:1,0 [2] Sections.cshtml) + IntermediateToken - (17:1,0 [2] Sections.cshtml) - Html - \n + HtmlContent - (62:2,43 [4] Sections.cshtml) + IntermediateToken - (62:2,43 [4] Sections.cshtml) - Html - \n\n + CSharpCode - (68:4,2 [46] Sections.cshtml) + IntermediateToken - (68:4,2 [46] Sections.cshtml) - CSharp - \n Layout = "_SectionTestLayout.cshtml";\n + HtmlContent - (117:7,0 [26] Sections.cshtml) + IntermediateToken - (117:7,0 [2] Sections.cshtml) - Html - \n + IntermediateToken - (119:8,0 [5] Sections.cshtml) - Html -
+ IntermediateToken - (124:8,5 [9] Sections.cshtml) - Html - Some body + IntermediateToken - (133:8,14 [6] Sections.cshtml) - Html -
+ IntermediateToken - (139:8,20 [4] Sections.cshtml) - Html - \n\n + Section - - Section1 + HtmlContent - (162:10,19 [43] Sections.cshtml) + IntermediateToken - (162:10,19 [6] Sections.cshtml) - Html - \n + IntermediateToken - (168:11,4 [5] Sections.cshtml) - Html -
+ IntermediateToken - (173:11,9 [20] Sections.cshtml) - Html - This is in Section 1 + IntermediateToken - (193:11,29 [6] Sections.cshtml) - Html -
+ IntermediateToken - (199:11,35 [6] Sections.cshtml) - Html - \n + TagHelper - (205:12,4 [25] Sections.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (222:12,21 [4] Sections.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (222:12,21 [4] Sections.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (230:12,29 [2] Sections.cshtml) + IntermediateToken - (230:12,29 [2] Sections.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt new file mode 100644 index 0000000000..1cc991810c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt @@ -0,0 +1,29 @@ +Source Location: (7:0,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|DateTime| +Generated Location: (819:20,0 [8] ) +|DateTime| + +Source Location: (33:2,14 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|"InputTestTagHelper, AppCode"| +Generated Location: (1075:28,37 [29] ) +|"InputTestTagHelper, AppCode"| + +Source Location: (152:10,9 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|Section1| +Generated Location: (1305:36,22 [8] ) +|Section1| + +Source Location: (68:4,2 [46] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +| + Layout = "_SectionTestLayout.cshtml"; +| +Generated Location: (1771:51,2 [46] ) +| + Layout = "_SectionTestLayout.cshtml"; +| + +Source Location: (222:12,21 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml) +|Date| +Generated Location: (2196:59,102 [4] ) +|Date| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs new file mode 100644 index 0000000000..9e809e0db5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs @@ -0,0 +1,87 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "4b7b87da15db4343c99430c0813fd6bc03643453" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"4b7b87da15db4343c99430c0813fd6bc03643453", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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::InputTestTagHelper __InputTestTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); +#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" + + Layout = "_SectionTestLayout.cshtml"; + +#line default +#line hidden + WriteLiteral("\r\n
Some body
\r\n\r\n"); + DefineSection("Section1", async() => { + WriteLiteral("\r\n
This is in Section 1
\r\n "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => { + } + ); + __InputTestTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTestTagHelper); +#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" +__InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Date); + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("for", __InputTestTagHelper.For, 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 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt new file mode 100644 index 0000000000..1309bc9423 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt @@ -0,0 +1,53 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (17:1,0 [2] Sections.cshtml) + IntermediateToken - (17:1,0 [2] Sections.cshtml) - Html - \n + HtmlContent - (64:3,0 [2] Sections.cshtml) + IntermediateToken - (64:3,0 [2] Sections.cshtml) - Html - \n + CSharpCode - (68:4,2 [46] Sections.cshtml) + IntermediateToken - (68:4,2 [46] Sections.cshtml) - CSharp - \n Layout = "_SectionTestLayout.cshtml";\n + HtmlContent - (117:7,0 [26] Sections.cshtml) + IntermediateToken - (117:7,0 [2] Sections.cshtml) - Html - \n + IntermediateToken - (119:8,0 [5] Sections.cshtml) - Html -
+ IntermediateToken - (124:8,5 [9] Sections.cshtml) - Html - Some body + IntermediateToken - (133:8,14 [6] Sections.cshtml) - Html -
+ IntermediateToken - (139:8,20 [4] Sections.cshtml) - Html - \n\n + Section - - Section1 + HtmlContent - (162:10,19 [43] Sections.cshtml) + IntermediateToken - (162:10,19 [6] Sections.cshtml) - Html - \n + IntermediateToken - (168:11,4 [5] Sections.cshtml) - Html -
+ IntermediateToken - (173:11,9 [20] Sections.cshtml) - Html - This is in Section 1 + IntermediateToken - (193:11,29 [6] Sections.cshtml) - Html -
+ IntermediateToken - (199:11,35 [6] Sections.cshtml) - Html - \n + TagHelper - (205:12,4 [25] Sections.cshtml) - input-test - TagMode.SelfClosing + DefaultTagHelperBody - + DefaultTagHelperCreate - - InputTestTagHelper + DefaultTagHelperProperty - (222:12,21 [4] Sections.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - + IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model => + IntermediateToken - - CSharp - __model. + IntermediateToken - (222:12,21 [4] Sections.cshtml) - CSharp - Date + IntermediateToken - - CSharp - ) + DefaultTagHelperExecute - + HtmlContent - (230:12,29 [2] Sections.cshtml) + IntermediateToken - (230:12,29 [2] Sections.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml new file mode 100644 index 0000000000..ed2648a986 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml @@ -0,0 +1,4 @@ +@using System.ComponentModel +@using System.Collections +@using System +@using System \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.codegen.cs new file mode 100644 index 0000000000..ad57e4a82b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.codegen.cs @@ -0,0 +1,59 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System.ComponentModel; + +#line default +#line hidden +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System.Collections; + +#line default +#line hidden +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System; + +#line default +#line hidden +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System; + +#line default +#line hidden + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #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 override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.ir.txt new file mode 100644 index 0000000000..0163b00a81 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.ir.txt @@ -0,0 +1,46 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (1:0,1 [27] UsingDirectives.cshtml) - System.ComponentModel + UsingDirective - (31:1,1 [24] UsingDirectives.cshtml) - System.Collections + UsingDirective - (58:2,1 [12] UsingDirectives.cshtml) - System + UsingDirective - (73:3,1 [12] UsingDirectives.cshtml) - System + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (28:0,28 [2] UsingDirectives.cshtml) + IntermediateToken - (28:0,28 [2] UsingDirectives.cshtml) - Html - \n + HtmlContent - (55:1,25 [2] UsingDirectives.cshtml) + IntermediateToken - (55:1,25 [2] UsingDirectives.cshtml) - Html - \n + HtmlContent - (70:2,13 [2] UsingDirectives.cshtml) + IntermediateToken - (70:2,13 [2] UsingDirectives.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.mappings.txt new file mode 100644 index 0000000000..71a6bf2b2d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_DesignTime.mappings.txt @@ -0,0 +1,20 @@ +Source Location: (1:0,1 [27] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml) +|using System.ComponentModel| +Generated Location: (461:13,0 [27] ) +|using System.ComponentModel| + +Source Location: (31:1,1 [24] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml) +|using System.Collections| +Generated Location: (613:18,0 [24] ) +|using System.Collections| + +Source Location: (58:2,1 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml) +|using System| +Generated Location: (762:23,0 [12] ) +|using System| + +Source Location: (73:3,1 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml) +|using System| +Generated Location: (899:28,0 [12] ) +|using System| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.codegen.cs new file mode 100644 index 0000000000..1310cb0d8c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.codegen.cs @@ -0,0 +1,55 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "452979e8e4dd77a84a4c50425dd3a162e265990d" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives))] +namespace AspNetCore +{ + #line hidden + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System.ComponentModel; + +#line default +#line hidden +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System.Collections; + +#line default +#line hidden +#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System; + +#line default +#line hidden +#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml" +using System; + +#line default +#line hidden + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"452979e8e4dd77a84a4c50425dd3a162e265990d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.ir.txt new file mode 100644 index 0000000000..c3b71e0393 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives_Runtime.ir.txt @@ -0,0 +1,23 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + UsingDirective - (1:0,1 [29] UsingDirectives.cshtml) - System.ComponentModel + UsingDirective - (31:1,1 [26] UsingDirectives.cshtml) - System.Collections + UsingDirective - (58:2,1 [14] UsingDirectives.cshtml) - System + UsingDirective - (73:3,1 [12] UsingDirectives.cshtml) - System + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml new file mode 100644 index 0000000000..0430ccfc69 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml @@ -0,0 +1,6 @@ +@addTagHelper "*, AppCode" +@{ + var foo = "Hello"; +} + + \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs new file mode 100644 index 0000000000..b6196f6651 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs @@ -0,0 +1,84 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::AllTagHelper __AllTagHelper; + private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper __TestViewComponentTagHelper; + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" +global::System.Object __typeHelper = "*, AppCode"; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + + var foo = "Hello"; + +#line default +#line hidden + __AllTagHelper = CreateTagHelper(); + __TestViewComponentTagHelper = CreateTagHelper(); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + __o = foo; + +#line default +#line hidden + __TestViewComponentTagHelper.firstName = string.Empty; + __AllTagHelper.Bar = " World"; + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("vc:test")] + public class __Generated__TestViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper + { + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TestViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.String firstName { get; set; } + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync("Test", new { firstName }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } + } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt new file mode 100644 index 0000000000..8e7497e7d6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt @@ -0,0 +1,59 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::AllTagHelper - __AllTagHelper + FieldDeclaration - - private - global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper - __TestViewComponentTagHelper + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (14:0,14 [12] ViewComponentTagHelper.cshtml) - "*, AppCode" + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (26:0,26 [2] ViewComponentTagHelper.cshtml) + IntermediateToken - (26:0,26 [2] ViewComponentTagHelper.cshtml) - Html - \n + CSharpCode - (30:1,2 [26] ViewComponentTagHelper.cshtml) + IntermediateToken - (30:1,2 [26] ViewComponentTagHelper.cshtml) - CSharp - \n var foo = "Hello";\n + HtmlContent - (59:4,0 [2] ViewComponentTagHelper.cshtml) + IntermediateToken - (59:4,0 [2] ViewComponentTagHelper.cshtml) - Html - \n + TagHelper - (61:5,0 [50] ViewComponentTagHelper.cshtml) - vc:test - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - AllTagHelper + DefaultTagHelperCreate - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper + DefaultTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - string TestViewComponentTagHelper.firstName - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - (83:5,22 [3] ViewComponentTagHelper.cshtml) + IntermediateToken - (83:5,22 [3] ViewComponentTagHelper.cshtml) - CSharp - foo + DefaultTagHelperProperty - (93:5,32 [6] ViewComponentTagHelper.cshtml) - bar - string AllTagHelper.Bar - HtmlAttributeValueStyle.DoubleQuotes + HtmlContent - (93:5,32 [6] ViewComponentTagHelper.cshtml) + IntermediateToken - (93:5,32 [6] ViewComponentTagHelper.cshtml) - Html - World + DefaultTagHelperExecute - + Inject - + Inject - + Inject - + Inject - + Inject - + ViewComponentTagHelper - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt new file mode 100644 index 0000000000..9c5fd32efb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt @@ -0,0 +1,19 @@ +Source Location: (14:0,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) +|"*, AppCode"| +Generated Location: (1057:21,37 [12] ) +|"*, AppCode"| + +Source Location: (30:1,2 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) +| + var foo = "Hello"; +| +Generated Location: (1534:36,2 [26] ) +| + var foo = "Hello"; +| + +Source Location: (83:5,22 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) +|foo| +Generated Location: (1985:44,22 [3] ) +|foo| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs new file mode 100644 index 0000000000..f654e3766e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.codegen.cs @@ -0,0 +1,108 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "bf860c3a5e96240c9d41a0b950e49c1a165ca44d" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"bf860c3a5e96240c9d41a0b950e49c1a165ca44d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper __TestViewComponentTagHelper; + private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("bar", " 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::AllTagHelper __AllTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + + var foo = "Hello"; + +#line default +#line hidden + WriteLiteral("\r\n"); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("vc:test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => { + } + ); + __AllTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__AllTagHelper); + __TestViewComponentTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__TestViewComponentTagHelper); + BeginWriteTagHelperAttribute(); +#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml" + WriteLiteral(foo); + +#line default +#line hidden + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __TestViewComponentTagHelper.firstName = __tagHelperStringValueBuffer; + __tagHelperExecutionContext.AddTagHelperAttribute("first-name", __TestViewComponentTagHelper.firstName, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); + __AllTagHelper.Bar = (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(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("vc:test")] + public class __Generated__TestViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper + { + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TestViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.String firstName { get; set; } + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync("Test", new { firstName }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } + } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt new file mode 100644 index 0000000000..c69014763c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_Runtime.ir.txt @@ -0,0 +1,38 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + FieldDeclaration - - private - global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper - __TestViewComponentTagHelper + PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - bar - World - HtmlAttributeValueStyle.DoubleQuotes + DefaultTagHelperRuntime - + FieldDeclaration - - private - global::AllTagHelper - __AllTagHelper + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpCode - (30:1,2 [26] ViewComponentTagHelper.cshtml) + IntermediateToken - (30:1,2 [26] ViewComponentTagHelper.cshtml) - CSharp - \n var foo = "Hello";\n + HtmlContent - (59:4,0 [2] ViewComponentTagHelper.cshtml) + IntermediateToken - (59:4,0 [2] ViewComponentTagHelper.cshtml) - Html - \n + TagHelper - (61:5,0 [50] ViewComponentTagHelper.cshtml) - vc:test - TagMode.StartTagAndEndTag + DefaultTagHelperBody - + DefaultTagHelperCreate - - AllTagHelper + DefaultTagHelperCreate - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper.__Generated__TestViewComponentTagHelper + DefaultTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - string TestViewComponentTagHelper.firstName - HtmlAttributeValueStyle.DoubleQuotes + CSharpExpression - (83:5,22 [3] ViewComponentTagHelper.cshtml) + IntermediateToken - (83:5,22 [3] ViewComponentTagHelper.cshtml) - CSharp - foo + PreallocatedTagHelperProperty - (93:5,32 [6] ViewComponentTagHelper.cshtml) - __tagHelperAttribute_0 - bar - Bar + DefaultTagHelperExecute - + Inject - + Inject - + Inject - + Inject - + Inject - + ViewComponentTagHelper - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml new file mode 100644 index 0000000000..eaf33e48ec --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml @@ -0,0 +1,2 @@ +@namespace Test.Namespace +

Hi There!

diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs new file mode 100644 index 0000000000..209d3361f0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs @@ -0,0 +1,48 @@ +// +#pragma warning disable 1591 +namespace Test.Namespace +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml" +global::System.Object __typeHelper = nameof(Test.Namespace); + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt new file mode 100644 index 0000000000..42d53bcd1b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt @@ -0,0 +1,43 @@ +Document - + NamespaceDeclaration - - Test.Namespace + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (11:0,11 [14] ViewWithNamespace.cshtml) - Test.Namespace + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (27:1,0 [20] ViewWithNamespace.cshtml) + IntermediateToken - (27:1,0 [4] ViewWithNamespace.cshtml) - Html -

+ IntermediateToken - (31:1,4 [9] ViewWithNamespace.cshtml) - Html - Hi There! + IntermediateToken - (40:1,13 [5] ViewWithNamespace.cshtml) - Html -

+ IntermediateToken - (45:1,18 [2] ViewWithNamespace.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt new file mode 100644 index 0000000000..2b7a295e01 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (11:0,11 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml) +|Test.Namespace| +Generated Location: (818:19,44 [14] ) +|Test.Namespace| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.codegen.cs new file mode 100644 index 0000000000..ef6c311053 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.codegen.cs @@ -0,0 +1,37 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "471b74bb73c8ae8e0ed24c654340198b9b4a1ec8" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml", typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace))] +namespace Test.Namespace +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"471b74bb73c8ae8e0ed24c654340198b9b4a1ec8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("

Hi There!

\r\n"); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.ir.txt new file mode 100644 index 0000000000..17f6801a03 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_Runtime.ir.txt @@ -0,0 +1,25 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml", typeof(Test.Namespace.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace))] + NamespaceDeclaration - - Test.Namespace + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewWithNamespace - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (27:1,0 [20] ViewWithNamespace.cshtml) + IntermediateToken - (27:1,0 [4] ViewWithNamespace.cshtml) - Html -

+ IntermediateToken - (31:1,4 [9] ViewWithNamespace.cshtml) - Html - Hi There! + IntermediateToken - (40:1,13 [5] ViewWithNamespace.cshtml) - Html -

+ IntermediateToken - (45:1,18 [2] ViewWithNamespace.cshtml) - Html - \n + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml new file mode 100644 index 0000000000..f4e110d289 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml @@ -0,0 +1 @@ +@inject IHtmlHelper Helper \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs new file mode 100644 index 0000000000..1f60d924cc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs @@ -0,0 +1,58 @@ +// +#pragma warning disable 1591 +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml" +IHtmlHelper __typeHelper = default(IHtmlHelper); + +#line default +#line hidden + } + ))(); + ((System.Action)(() => { +#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml" +global::System.Object Helper = null; + +#line default +#line hidden + } + ))(); + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public IHtmlHelper Helper { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt new file mode 100644 index 0000000000..b677049ce1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt @@ -0,0 +1,40 @@ +Document - + NamespaceDeclaration - - AspNetCore + UsingDirective - - TModel = global::System.Object + UsingDirective - (1:0,1 [12] ) - System + UsingDirective - (16:1,1 [32] ) - System.Collections.Generic + UsingDirective - (51:2,1 [17] ) - System.Linq + UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (8:0,8 [19] _ViewImports.cshtml) - IHtmlHelper + DirectiveToken - (28:0,28 [6] _ViewImports.cshtml) - Helper + 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 override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt new file mode 100644 index 0000000000..dc03ca32da --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt @@ -0,0 +1,10 @@ +Source Location: (8:0,8 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml) +|IHtmlHelper| +Generated Location: (760:19,0 [19] ) +|IHtmlHelper| + +Source Location: (28:0,28 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml) +|Helper| +Generated Location: (1027:27,22 [6] ) +|Helper| + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs new file mode 100644 index 0000000000..346428fa0d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.codegen.cs @@ -0,0 +1,38 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "74c90591b68437a0868e91dc714ea9827ab8e03a" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml")] +[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports))] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"74c90591b68437a0868e91dc714ea9827ab8e03a", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml")] + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public IHtmlHelper Helper { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt new file mode 100644 index 0000000000..addc2754ec --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_Runtime.ir.txt @@ -0,0 +1,21 @@ +Document - + RazorCompiledItemAttribute - + CSharpCode - + IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports))] + NamespaceDeclaration - - AspNetCore + UsingDirective - (1:0,1 [14] ) - System + UsingDirective - (16:1,1 [34] ) - System.Collections.Generic + UsingDirective - (51:2,1 [19] ) - System.Linq + UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks + UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + RazorSourceChecksumAttribute - + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync + Inject - + Inject - + Inject - + Inject - + Inject - + Inject - diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorFactoryTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorFactoryTest.cs new file mode 100644 index 0000000000..d44f0169a1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorFactoryTest.cs @@ -0,0 +1,485 @@ +// 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.Reflection; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class ViewComponentTagHelperDescriptorFactoryTest + { + private static readonly Assembly _assembly = typeof(ViewComponentTagHelperDescriptorFactoryTest).GetTypeInfo().Assembly; + + [Fact] + public void CreateDescriptor_UnderstandsStringParameters() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(StringParameterViewComponent).FullName); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__StringParameterViewComponentTagHelper", + typeof(StringParameterViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__StringParameterViewComponentTagHelper") + .DisplayName("StringParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:string-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("foo")) + .RequireAttributeDescriptor(attribute => attribute.Name("bar"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("foo") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("bar") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "StringParameter") + .Build(); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_UnderstandsVariousParameterTypes() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(VariousParameterViewComponent).FullName); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__VariousParameterViewComponentTagHelper", + typeof(VariousParameterViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__VariousParameterViewComponentTagHelper") + .DisplayName("VariousParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:various-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("test-enum")) + .RequireAttributeDescriptor(attribute => attribute.Name("test-string")) + .RequireAttributeDescriptor(attribute => attribute.Name("baz"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("test-enum") + .PropertyName("testEnum") + .TypeName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum)) + .AsEnum() + .DisplayName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum) + " VariousParameterViewComponentTagHelper.testEnum")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("test-string") + .PropertyName("testString") + .TypeName(typeof(string).FullName) + .DisplayName("string VariousParameterViewComponentTagHelper.testString")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("baz") + .PropertyName("baz") + .TypeName(typeof(int).FullName) + .DisplayName("int VariousParameterViewComponentTagHelper.baz")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "VariousParameter") + .Build(); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_UnderstandsGenericParameters() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(GenericParameterViewComponent).FullName); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__GenericParameterViewComponentTagHelper", + typeof(GenericParameterViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__GenericParameterViewComponentTagHelper") + .DisplayName("GenericParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:generic-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("foo"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("Foo") + .TypeName("System.Collections.Generic.List") + .DisplayName("System.Collections.Generic.List GenericParameterViewComponentTagHelper.Foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("Bar") + .TypeName("System.Collections.Generic.Dictionary") + .AsDictionaryAttribute("bar-", typeof(int).FullName) + .DisplayName("System.Collections.Generic.Dictionary GenericParameterViewComponentTagHelper.Bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "GenericParameter") + .Build(); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_ForSyncViewComponentWithInvokeInBaseType_Works() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__SyncDerivedViewComponentTagHelper", + typeof(SyncDerivedViewComponent).GetTypeInfo().Assembly.GetName().Name) + .TypeName("__Generated__SyncDerivedViewComponentTagHelper") + .DisplayName("SyncDerivedViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:sync-derived") + .RequireAttributeDescriptor(attribute => attribute.Name("foo")) + .RequireAttributeDescriptor(attribute => attribute.Name("bar"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("foo") + .TypeName(typeof(string).FullName) + .DisplayName("string SyncDerivedViewComponentTagHelper.foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("bar") + .TypeName(typeof(string).FullName) + .DisplayName("string SyncDerivedViewComponentTagHelper.bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "SyncDerived") + .Build(); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncDerivedViewComponent).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_ForAsyncViewComponentWithInvokeInBaseType_Works() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__AsyncDerivedViewComponentTagHelper", + typeof(AsyncDerivedViewComponent).Assembly.GetName().Name) + .TypeName("__Generated__AsyncDerivedViewComponentTagHelper") + .DisplayName("AsyncDerivedViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("vc:async-derived")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "AsyncDerived") + .Build(); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncDerivedViewComponent).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.CaseSensitive); + } + + [Fact] + public void CreateDescriptor_AddsDiagnostic_ForViewComponentWithNoInvokeMethod() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(ViewComponentWithoutInvokeMethod).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_CannotFindMethod.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_AddsDiagnostic_ForViewComponentWithNoInstanceInvokeMethod() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(StaticInvokeAsyncViewComponent).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_CannotFindMethod.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_AddsDiagnostic_ForViewComponentWithNoPublicInvokeMethod() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(NonPublicInvokeAsyncViewComponent).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_CannotFindMethod.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_UnderstandsGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Empty(descriptor.GetAllDiagnostics()); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_UnderstandsNonGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithNonGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + Assert.Empty(descriptor.GetAllDiagnostics()); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_DoesNotUnderstandVoid() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithString).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_AsyncMethod_ShouldReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvokeAsync_DoesNotUnderstandString() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(AsyncViewComponentWithString).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_AsyncMethod_ShouldReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvoke_DoesNotUnderstandVoid() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncViewComponentWithVoid).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_SyncMethod_ShouldReturnValue.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvoke_DoesNotUnderstandNonGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncViewComponentWithNonGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_SyncMethod_CannotReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponentWithInvoke_DoesNotUnderstandGenericTask() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(SyncViewComponentWithGenericTask).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_SyncMethod_CannotReturnTask.Id, diagnostic.Id); + } + + [Fact] + public void CreateDescriptor_ForViewComponent_WithAmbiguousMethods() + { + // Arrange + var testCompilation = TestCompilation.Create(_assembly); + var factory = new ViewComponentTagHelperDescriptorFactory(testCompilation); + + var viewComponent = testCompilation.GetTypeByMetadataName(typeof(DerivedViewComponentWithAmbiguity).FullName); + + // Act + var descriptor = factory.CreateDescriptor(viewComponent); + + // Assert + var diagnostic = Assert.Single(descriptor.GetAllDiagnostics()); + Assert.Equal(RazorExtensionsDiagnosticFactory.ViewComponent_AmbiguousMethods.Id, diagnostic.Id); + } + } + + public class StringParameterViewComponent + { + public string Invoke(string foo, string bar) => null; + } + + public class VariousParameterViewComponent + { + public string Invoke(TestEnum testEnum, string testString, int baz = 5) => null; + + public enum TestEnum + { + A = 1, + B = 2, + C = 3 + } + } + + public class GenericParameterViewComponent + { + public string Invoke(List Foo, Dictionary Bar) => null; + } + + public class ViewComponentWithoutInvokeMethod + { + } + + public class AsyncViewComponentWithGenericTask + { + public Task InvokeAsync() => null; + } + + public class AsyncViewComponentWithNonGenericTask + { + public Task InvokeAsync() => null; + } + + public class AsyncViewComponentWithVoid + { + public void InvokeAsync() { } + } + + public class AsyncViewComponentWithString + { + public string InvokeAsync() => null; + } + + public class SyncViewComponentWithVoid + { + public void Invoke() { } + } + + public class SyncViewComponentWithNonGenericTask + { + public Task Invoke() => null; + } + + public class SyncViewComponentWithGenericTask + { + public Task Invoke() => null; + } + + public class SyncDerivedViewComponent : StringParameterViewComponent + { + } + + public class AsyncDerivedViewComponent : AsyncViewComponentWithNonGenericTask + { + } + + public class DerivedViewComponentWithAmbiguity : AsyncViewComponentWithNonGenericTask + { + public string Invoke() => null; + } + + public class StaticInvokeAsyncViewComponent + { + public static Task InvokeAsync() => null; + } + + public class NonPublicInvokeAsyncViewComponent + { + protected Task InvokeAsync() => null; + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs new file mode 100644 index 0000000000..16fb3096dc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.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.IO; +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Razor; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + // This is just a basic integration test. There are detailed tests for the VCTH visitor and descriptor factory. + public class ViewComponentTagHelperDescriptorProviderTest + { + [Fact] + public void DescriptorProvider_FindsVCTH() + { + // Arrange + var code = @" + public class StringParameterViewComponent + { + public string Invoke(string foo, string bar) => null; + } +"; + + var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code)); + + var context = TagHelperDescriptorProviderContext.Create(); + context.SetCompilation(compilation); + + var provider = new ViewComponentTagHelperDescriptorProvider() + { + Engine = RazorProjectEngine.CreateEmpty().Engine, + }; + + var expectedDescriptor = TagHelperDescriptorBuilder.Create( + ViewComponentTagHelperConventions.Kind, + "__Generated__StringParameterViewComponentTagHelper", + TestCompilation.AssemblyName) + .TypeName("__Generated__StringParameterViewComponentTagHelper") + .DisplayName("StringParameterViewComponentTagHelper") + .TagMatchingRuleDescriptor(rule => + rule + .RequireTagName("vc:string-parameter") + .RequireAttributeDescriptor(attribute => attribute.Name("foo")) + .RequireAttributeDescriptor(attribute => attribute.Name("bar"))) + .BoundAttributeDescriptor(attribute => + attribute + .Name("foo") + .PropertyName("foo") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.foo")) + .BoundAttributeDescriptor(attribute => + attribute + .Name("bar") + .PropertyName("bar") + .TypeName(typeof(string).FullName) + .DisplayName("string StringParameterViewComponentTagHelper.bar")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "StringParameter") + .Build(); + + // Act + provider.Execute(context); + + // Assert + Assert.Single(context.Results, d => TagHelperDescriptorComparer.CaseSensitive.Equals(d, expectedDescriptor)); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperPassTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperPassTest.cs new file mode 100644 index 0000000000..02039ced8a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperPassTest.cs @@ -0,0 +1,275 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class ViewComponentTagHelperPassTest + { + [Fact] + public void ViewComponentTagHelperPass_Execute_IgnoresRegularTagHelper() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .TypeName("TestTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p")) + .Build() + }; + + var projectEngine = CreateProjectEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = projectEngine.Engine, + }; + + var irDocument = CreateIRDocument(projectEngine, codeDocument); + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var @class = FindClassNode(irDocument); + Assert.Equal(3, @class.Children.Count); // No class node created for a VCTH + for (var i = 0; i < @class.Children.Count; i++) + { + Assert.IsNotType(@class.Children[i]); + } + } + + [Fact] + public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Int32") + .PropertyName("Foo")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build() + }; + + var projectEngine = CreateProjectEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = projectEngine.Engine, + }; + + var irDocument = CreateIRDocument(projectEngine, codeDocument); + + var vcthFullName = "AspNetCore.test.__Generated__TagCloudViewComponentTagHelper"; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + Assert.Equal(vcthFullName, Assert.IsType(tagHelper.Children[1]).TypeName); + Assert.Equal("Foo", Assert.IsType(tagHelper.Children[2]).PropertyName); + + + var @class = FindClassNode(irDocument); + Assert.Equal(4, @class.Children.Count); + + Assert.IsType(@class.Children.Last()); + } + + [Fact] + public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_WithIndexer() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper TestTagHelper, TestAssembly +"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Collections.Generic.Dictionary") + .PropertyName("Tags") + .AsDictionaryAttribute("foo-", "System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build() + }; + + var projectEngine = CreateProjectEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = projectEngine.Engine, + }; + + var irDocument = CreateIRDocument(projectEngine, codeDocument); + + var vcthFullName = "AspNetCore.test.__Generated__TagCloudViewComponentTagHelper"; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var tagHelper = FindTagHelperNode(irDocument); + Assert.Equal(vcthFullName, Assert.IsType(tagHelper.Children[1]).TypeName); + Assert.IsType(tagHelper.Children[2]); + + var @class = FindClassNode(irDocument); + Assert.Equal(4, @class.Children.Count); + + Assert.IsType(@class.Children[3]); + } + + [Fact] + public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_Nested() + { + // Arrange + var codeDocument = CreateDocument(@" +@addTagHelper *, TestAssembly +

"); + + var tagHelpers = new[] + { + TagHelperDescriptorBuilder.Create("PTestTagHelper", "TestAssembly") + .TypeName("PTestTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .PropertyName("Foo") + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p")) + .Build(), + TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .PropertyName("Foo") + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build() + }; + + var projectEngine = CreateProjectEngine(tagHelpers); + var pass = new ViewComponentTagHelperPass() + { + Engine = projectEngine.Engine, + }; + + var irDocument = CreateIRDocument(projectEngine, codeDocument); + + var vcthFullName = "AspNetCore.test.__Generated__TagCloudViewComponentTagHelper"; + + // Act + pass.Execute(codeDocument, irDocument); + + // Assert + var outerTagHelper = FindTagHelperNode(irDocument); + Assert.Equal("PTestTagHelper", Assert.IsType(outerTagHelper.Children[1]).TypeName); + Assert.Equal("Foo", Assert.IsType(outerTagHelper.Children[2]).PropertyName); + + var vcth = FindTagHelperNode(outerTagHelper.Children[0]); + Assert.Equal(vcthFullName, Assert.IsType(vcth.Children[1]).TypeName); + Assert.Equal("Foo", Assert.IsType(vcth.Children[2]).PropertyName); + + + var @class = FindClassNode(irDocument); + Assert.Equal(5, @class.Children.Count); + + Assert.IsType(@class.Children.Last()); + } + + private RazorCodeDocument CreateDocument(string content) + { + var source = RazorSourceDocument.Create(content, "test.cshtml"); + return RazorCodeDocument.Create(source); + } + + private RazorProjectEngine CreateProjectEngine(params TagHelperDescriptor[] tagHelpers) + { + return RazorProjectEngine.Create(b => + { + b.Features.Add(new MvcViewDocumentClassifierPass()); + + b.Features.Add(new TestTagHelperFeature(tagHelpers)); + }); + } + + private DocumentIntermediateNode CreateIRDocument(RazorProjectEngine projectEngine, RazorCodeDocument codeDocument) + { + for (var i = 0; i < projectEngine.Phases.Count; i++) + { + var phase = projectEngine.Phases[i]; + phase.Execute(codeDocument); + + if (phase is IRazorDirectiveClassifierPhase) + { + break; + } + } + + // We also expect the default tag helper pass to run first. + var documentNode = codeDocument.GetDocumentIntermediateNode(); + + var defaultTagHelperPass = projectEngine.EngineFeatures.OfType().Single(); + defaultTagHelperPass.Execute(codeDocument, documentNode); + + return codeDocument.GetDocumentIntermediateNode(); + } + + private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node) + { + var visitor = new ClassDeclarationNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private TagHelperIntermediateNode FindTagHelperNode(IntermediateNode node) + { + var visitor = new TagHelperNodeVisitor(); + visitor.Visit(node); + return visitor.Node; + } + + private class ClassDeclarationNodeVisitor : IntermediateNodeWalker + { + public ClassDeclarationIntermediateNode Node { get; set; } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + Node = node; + } + } + + private class TagHelperNodeVisitor : IntermediateNodeWalker + { + public TagHelperIntermediateNode Node { get; set; } + + public override void VisitTagHelper(TagHelperIntermediateNode node) + { + Node = node; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperTargetExtensionTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperTargetExtensionTest.cs new file mode 100644 index 0000000000..b841a93583 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperTargetExtensionTest.cs @@ -0,0 +1,120 @@ +// 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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class ViewComponentTagHelperTargetExtensionTest + { + [Fact] + public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper() + { + // Arrange + var tagHelper = TagHelperDescriptorBuilder + .Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Int32") + .PropertyName("Foo")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build(); + + var extension = new ViewComponentTagHelperTargetExtension(); + var context = TestCodeRenderingContext.CreateRuntime(); + var node = new ViewComponentTagHelperIntermediateNode() + { + ClassName = "__Generated__TagCloudViewComponentTagHelper", + TagHelper = tagHelper + }; + + // Act + extension.WriteViewComponentTagHelper(context, node); + + // Assert + var csharp = context.CodeWriter.GenerateCode(); + Assert.Equal( + @"[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute(""tagcloud"")] +public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper +{ + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TagCloudViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.Int32 Foo { get; set; } + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync(""TagCloud"", new { Foo }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } +} +", + csharp, + ignoreLineEndingDifferences: true); + } + + [Fact] + public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper_WithIndexer() + { + // Arrange + var tagHelper = TagHelperDescriptorBuilder + .Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly") + .TypeName("__Generated__TagCloudViewComponentTagHelper") + .BoundAttributeDescriptor(attribute => attribute + .Name("Foo") + .TypeName("System.Collections.Generic.Dictionary") + .PropertyName("Tags") + .AsDictionaryAttribute("foo-", "System.Int32")) + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud") + .Build(); + + var extension = new ViewComponentTagHelperTargetExtension(); + var context = TestCodeRenderingContext.CreateRuntime(); + var node = new ViewComponentTagHelperIntermediateNode() + { + ClassName = "__Generated__TagCloudViewComponentTagHelper", + TagHelper = tagHelper + }; + + // Act + extension.WriteViewComponentTagHelper(context, node); + + // Assert + var csharp = context.CodeWriter.GenerateCode(); + Assert.Equal( + @"[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute(""tagcloud"")] +public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper +{ + private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper _helper = null; + public __Generated__TagCloudViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper) + { + _helper = helper; + } + [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } + public System.Collections.Generic.Dictionary Tags { get; set; } + = new System.Collections.Generic.Dictionary(); + public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) + { + (_helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext); + var content = await _helper.InvokeAsync(""TagCloud"", new { Tags }); + output.TagName = null; + output.Content.SetHtmlContent(content); + } +} +", + csharp, + ignoreLineEndingDifferences: true); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTypeVisitorTest.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTypeVisitorTest.cs new file mode 100644 index 0000000000..48e8cfeec8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTypeVisitorTest.cs @@ -0,0 +1,202 @@ +// 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; +using Microsoft.CodeAnalysis; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Razor.Extensions +{ + public class ViewComponentTypeVisitorTest + { + private static readonly Assembly _assembly = typeof(ViewComponentTypeVisitorTest).GetTypeInfo().Assembly; + + private static Compilation Compilation { get; } = TestCompilation.Create(_assembly); + + // In practice MVC will provide a marker attribute for ViewComponents. To prevent a circular reference between MVC and Razor + // we can use a test class as a marker. + private static INamedTypeSymbol TestViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestViewComponentAttribute).FullName); + private static INamedTypeSymbol TestNonViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestNonViewComponentAttribute).FullName); + + [Fact] + public void IsViewComponent_PlainViewComponent_ReturnsTrue() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_PlainViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.True(isViewComponent); + } + + [Fact] + public void IsViewComponent_DecoratedViewComponent_ReturnsTrue() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_DecoratedVC).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.True(isViewComponent); + } + + [Fact] + public void IsViewComponent_InheritedViewComponent_ReturnsTrue() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_InheritedVC).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.True(isViewComponent); + } + + [Fact] + public void IsViewComponent_AbstractViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_AbstractViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_GenericViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_GenericViewComponent<>).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_InternalViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InternalViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_DecoratedNonViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_DecoratedViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + [Fact] + public void IsViewComponent_InheritedNonViewComponent_ReturnsFalse() + { + // Arrange + var testVisitor = new ViewComponentTypeVisitor( + TestViewComponentAttributeSymbol, + TestNonViewComponentAttributeSymbol, + new List()); + var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InheritedViewComponent).FullName); + + // Act + var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol); + + // Assert + Assert.False(isViewComponent); + } + + public abstract class Invalid_AbstractViewComponent + { + } + + public class Invalid_GenericViewComponent + { + } + + internal class Invalid_InternalViewComponent + { + } + + public class Valid_PlainViewComponent + { + } + + [TestViewComponent] + public class Valid_DecoratedVC + { + } + + public class Valid_InheritedVC : Valid_DecoratedVC + { + } + + [TestNonViewComponent] + public class Invalid_DecoratedViewComponent + { + } + + [TestViewComponent] + public class Invalid_InheritedViewComponent : Invalid_DecoratedViewComponent + { + } + + public class TestViewComponentAttribute : Attribute + { + } + + public class TestNonViewComponentAttribute : Attribute + { + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/xunit.runner.json b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/xunit.runner.json new file mode 100644 index 0000000000..fcf172c8fc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "methodDisplay": "method", + "shadowCopy": false +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptor.cs new file mode 100644 index 0000000000..84a83b3e8c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptor.cs @@ -0,0 +1,48 @@ +// 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 abstract class AllowedChildTagDescriptor : IEquatable + { + public string Name { get; protected set; } + + public string DisplayName { get; protected set; } + + public IReadOnlyList Diagnostics { get; protected set; } + + public bool HasErrors + { + get + { + var errors = Diagnostics.Any(diagnostic => diagnostic.Severity == RazorDiagnosticSeverity.Error); + + return errors; + } + } + + public override string ToString() + { + return DisplayName ?? base.ToString(); + } + + public bool Equals(AllowedChildTagDescriptor other) + { + return AllowedChildTagDescriptorComparer.Default.Equals(this, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as AllowedChildTagDescriptor); + } + + public override int GetHashCode() + { + return AllowedChildTagDescriptorComparer.Default.GetHashCode(this); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptorBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptorBuilder.cs new file mode 100644 index 0000000000..46fc3cc6aa --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptorBuilder.cs @@ -0,0 +1,17 @@ +// 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 +{ + public abstract class AllowedChildTagDescriptorBuilder + { + public abstract string Name { get; set; } + + public abstract string DisplayName { get; set; } + + public abstract RazorDiagnosticCollection Diagnostics { get; } + + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptorComparer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptorComparer.cs new file mode 100644 index 0000000000..37f0a55417 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AllowedChildTagDescriptorComparer.cs @@ -0,0 +1,71 @@ +// 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.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class AllowedChildTagDescriptorComparer : IEqualityComparer + { + /// + /// A default instance of the . + /// + public static readonly AllowedChildTagDescriptorComparer Default = + new AllowedChildTagDescriptorComparer(); + + /// + /// A default instance of the that does case-sensitive comparison. + /// + internal static readonly AllowedChildTagDescriptorComparer CaseSensitive = + new AllowedChildTagDescriptorComparer(caseSensitive: true); + + private readonly StringComparer _stringComparer; + private readonly StringComparison _stringComparison; + + private AllowedChildTagDescriptorComparer(bool caseSensitive = false) + { + if (caseSensitive) + { + _stringComparer = StringComparer.Ordinal; + _stringComparison = StringComparison.Ordinal; + } + else + { + _stringComparer = StringComparer.OrdinalIgnoreCase; + _stringComparison = StringComparison.OrdinalIgnoreCase; + } + } + + /// + public virtual bool Equals( + AllowedChildTagDescriptor descriptorX, + AllowedChildTagDescriptor descriptorY) + { + if (object.ReferenceEquals(descriptorX, descriptorY)) + { + return true; + } + + if (descriptorX == null ^ descriptorY == null) + { + return false; + } + + return + string.Equals(descriptorX.Name, descriptorY.Name, _stringComparison) && + string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal); + } + + /// + public virtual int GetHashCode(AllowedChildTagDescriptor descriptor) + { + var hash = HashCodeCombiner.Start(); + hash.Add(descriptor.Name, _stringComparer); + + return hash.CombinedHash; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AssemblyExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AssemblyExtension.cs new file mode 100644 index 0000000000..97f1c31c15 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AssemblyExtension.cs @@ -0,0 +1,55 @@ +// 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.Reflection; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public class AssemblyExtension : RazorExtension + { + public AssemblyExtension(string extensionName, Assembly assembly) + { + if (extensionName == null) + { + throw new ArgumentNullException(nameof(extensionName)); + } + + if (assembly == null) + { + throw new ArgumentNullException(nameof(assembly)); + } + + ExtensionName = extensionName; + Assembly = assembly; + } + + public override string ExtensionName { get; } + + public Assembly Assembly { get; } + + internal RazorExtensionInitializer CreateInitializer() + { + // It's not an error to have an assembly with no initializers. This is useful to specify a dependency + // that doesn't really provide any Razor configuration. + var attributes = Assembly.GetCustomAttributes(); + foreach (var attribute in attributes) + { + // Using extension names and requiring them to line up allows a single assembly to ship multiple + // extensions/initializers for different configurations. + if (!string.Equals(attribute.ExtensionName, ExtensionName, StringComparison.Ordinal)) + { + continue; + } + + // There's no real protection/exception handling here because this set isn't really user-extensible + // right now. This would be a great place to add some additional diagnostics and hardening in the + // future. + var initializer = (RazorExtensionInitializer)Activator.CreateInstance(attribute.InitializerType); + return initializer; + } + + return null; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AttributeStructure.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AttributeStructure.cs new file mode 100644 index 0000000000..9a191578c4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/AttributeStructure.cs @@ -0,0 +1,15 @@ +// 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 +{ + // This is the design time equivalent of Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle. + // They should be kept in sync. + public enum AttributeStructure + { + DoubleQuotes, + SingleQuotes, + NoQuotes, + Minimized, + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs new file mode 100644 index 0000000000..b416fddd61 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.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 System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + /// + /// A metadata class describing a tag helper attribute. + /// + public abstract class BoundAttributeDescriptor : IEquatable + { + protected BoundAttributeDescriptor(string kind) + { + Kind = kind; + } + + public string Kind { get; } + + public bool IsIndexerStringProperty { get; protected set; } + + public bool IsIndexerBooleanProperty { get; protected set; } + + public bool IsEnum { get; protected set; } + + public bool IsStringProperty { get; protected set; } + + public bool IsBooleanProperty { get; protected set; } + + public string Name { get; protected set; } + + public string IndexerNamePrefix { get; protected set; } + + public string TypeName { get; protected set; } + + public string IndexerTypeName { get; protected set; } + + public bool HasIndexer { get; protected set; } + + public string Documentation { get; protected set; } + + public string DisplayName { get; protected set; } + + public IReadOnlyList Diagnostics { get; protected set; } + + public IReadOnlyDictionary Metadata { get; protected set; } + + public bool HasErrors + { + get + { + var errors = Diagnostics.Any(diagnostic => diagnostic.Severity == RazorDiagnosticSeverity.Error); + + return errors; + } + } + + public override string ToString() + { + return DisplayName ?? base.ToString(); + } + + public bool Equals(BoundAttributeDescriptor other) + { + return BoundAttributeDescriptorComparer.Default.Equals(this, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as BoundAttributeDescriptor); + } + + public override int GetHashCode() + { + return BoundAttributeDescriptorComparer.Default.GetHashCode(this); + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilder.cs new file mode 100644 index 0000000000..b2cbfba675 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilder.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. + +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public abstract class BoundAttributeDescriptorBuilder + { + public abstract string Name { get; set; } + + public abstract string TypeName { get; set; } + + public abstract bool IsEnum { get; set; } + + public abstract bool IsDictionary { get; set; } + + public abstract string IndexerAttributeNamePrefix { get; set; } + + public abstract string IndexerValueTypeName { get; set; } + + public abstract string Documentation { get; set; } + + public abstract string DisplayName { get; set; } + + public abstract IDictionary Metadata { get; } + + public abstract RazorDiagnosticCollection Diagnostics { get; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilderExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilderExtensions.cs new file mode 100644 index 0000000000..8d1ab038ab --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilderExtensions.cs @@ -0,0 +1,55 @@ +// 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 +{ + public static class BoundAttributeDescriptorBuilderExtensions + { + public static void SetPropertyName(this BoundAttributeDescriptorBuilder builder, string propertyName) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + if (propertyName == null) + { + throw new ArgumentNullException(nameof(propertyName)); + } + + builder.Metadata[TagHelperMetadata.Common.PropertyName] = propertyName; + } + + public static string GetPropertyName(this BoundAttributeDescriptorBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + if (builder.Metadata.ContainsKey(TagHelperMetadata.Common.PropertyName)) + { + return builder.Metadata[TagHelperMetadata.Common.PropertyName]; + } + + return null; + } + + public static void AsDictionary( + this BoundAttributeDescriptorBuilder builder, + string attributeNamePrefix, + string valueTypeName) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.IsDictionary = true; + builder.IndexerAttributeNamePrefix = attributeNamePrefix; + builder.IndexerValueTypeName = valueTypeName; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs new file mode 100644 index 0000000000..fbf68929eb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs @@ -0,0 +1,83 @@ +// 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.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class BoundAttributeDescriptorComparer : IEqualityComparer + { + /// + /// A default instance of the . + /// + public static readonly BoundAttributeDescriptorComparer Default = new BoundAttributeDescriptorComparer(); + + /// + /// A default instance of the that does case-sensitive comparison. + /// + internal static readonly BoundAttributeDescriptorComparer CaseSensitive = + new BoundAttributeDescriptorComparer(caseSensitive: true); + + private readonly StringComparer _stringComparer; + private readonly StringComparison _stringComparison; + + private BoundAttributeDescriptorComparer(bool caseSensitive = false) + { + if (caseSensitive) + { + _stringComparer = StringComparer.Ordinal; + _stringComparison = StringComparison.Ordinal; + } + else + { + _stringComparer = StringComparer.OrdinalIgnoreCase; + _stringComparison = StringComparison.OrdinalIgnoreCase; + } + } + + public virtual bool Equals(BoundAttributeDescriptor descriptorX, BoundAttributeDescriptor descriptorY) + { + if (object.ReferenceEquals(descriptorX, descriptorY)) + { + return true; + } + + if (descriptorX == null ^ descriptorY == null) + { + return false; + } + + return + string.Equals(descriptorX.Kind, descriptorY.Kind, StringComparison.Ordinal) && + descriptorX.IsIndexerStringProperty == descriptorY.IsIndexerStringProperty && + descriptorX.IsEnum == descriptorY.IsEnum && + descriptorX.HasIndexer == descriptorY.HasIndexer && + string.Equals(descriptorX.Name, descriptorY.Name, _stringComparison) && + string.Equals(descriptorX.IndexerNamePrefix, descriptorY.IndexerNamePrefix, _stringComparison) && + string.Equals(descriptorX.TypeName, descriptorY.TypeName, StringComparison.Ordinal) && + string.Equals(descriptorX.IndexerTypeName, descriptorY.IndexerTypeName, StringComparison.Ordinal) && + string.Equals(descriptorX.Documentation, descriptorY.Documentation, StringComparison.Ordinal) && + string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) && + Enumerable.SequenceEqual( + descriptorX.Metadata.OrderBy(propertyX => propertyX.Key, StringComparer.Ordinal), + descriptorY.Metadata.OrderBy(propertyY => propertyY.Key, StringComparer.Ordinal)); + } + + public virtual int GetHashCode(BoundAttributeDescriptor descriptor) + { + if (descriptor == null) + { + throw new ArgumentNullException(nameof(descriptor)); + } + + var hash = HashCodeCombiner.Start(); + hash.Add(descriptor.Kind); + hash.Add(descriptor.Name, _stringComparer); + + return hash.CombinedHash; + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorExtensions.cs new file mode 100644 index 0000000000..62b713a8fe --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorExtensions.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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public static class BoundAttributeDescriptorExtensions + { + public static string GetPropertyName(this BoundAttributeDescriptor attribute) + { + if (attribute == null) + { + throw new ArgumentNullException(nameof(attribute)); + } + + attribute.Metadata.TryGetValue(TagHelperMetadata.Common.PropertyName, out var propertyName); + return propertyName; + } + + public static bool IsDefaultKind(this BoundAttributeDescriptor attribute) + { + if (attribute == null) + { + throw new ArgumentNullException(nameof(attribute)); + } + + return string.Equals(attribute.Kind, TagHelperConventions.DefaultKind, StringComparison.Ordinal); + } + + internal static bool ExpectsStringValue(this BoundAttributeDescriptor attribute, string name) + { + if (attribute.IsStringProperty) + { + return true; + } + + var isIndexerNameMatch = TagHelperMatchingConventions.SatisfiesBoundAttributeIndexer(name, attribute); + return isIndexerNameMatch && attribute.IsIndexerStringProperty; + } + + internal static bool ExpectsBooleanValue(this BoundAttributeDescriptor attribute, string name) + { + if (attribute.IsBooleanProperty) + { + return true; + } + + var isIndexerNameMatch = TagHelperMatchingConventions.SatisfiesBoundAttributeIndexer(name, attribute); + return isIndexerNameMatch && attribute.IsIndexerBooleanProperty; + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CSharpIdentifier.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CSharpIdentifier.cs new file mode 100644 index 0000000000..1ec6188aed --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CSharpIdentifier.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.Globalization; +using System.Text; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal static class CSharpIdentifier + { + // CSharp Spec §2.4.2 + private static bool IsIdentifierStart(char character) + { + return char.IsLetter(character) || + character == '_' || + CharUnicodeInfo.GetUnicodeCategory(character) == UnicodeCategory.LetterNumber; + } + + public static bool IsIdentifierPart(char character) + { + return char.IsDigit(character) || + IsIdentifierStart(character) || + IsIdentifierPartByUnicodeCategory(character); + } + + private static bool IsIdentifierPartByUnicodeCategory(char character) + { + var category = CharUnicodeInfo.GetUnicodeCategory(character); + + return category == UnicodeCategory.NonSpacingMark || // Mn + category == UnicodeCategory.SpacingCombiningMark || // Mc + category == UnicodeCategory.ConnectorPunctuation || // Pc + category == UnicodeCategory.Format; // Cf + } + + public static string SanitizeIdentifier(string inputName) + { + if (!IsIdentifierStart(inputName[0]) && IsIdentifierPart(inputName[0])) + { + inputName = "_" + inputName; + } + + var builder = new StringBuilder(inputName.Length); + for (var i = 0; i < inputName.Length; i++) + { + var ch = inputName[i]; + builder.Append(IsIdentifierPart(ch) ? ch : '_'); + } + + return builder.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Checksum.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Checksum.cs new file mode 100644 index 0000000000..57834739e6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Checksum.cs @@ -0,0 +1,28 @@ +// 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.Text; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal static class Checksum + { + public static string BytesToString(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException(nameof(bytes)); + } + + var result = new StringBuilder(bytes.Length); + for (var i = 0; i < bytes.Length; i++) + { + // The x2 format means lowercase hex, where each byte is a 2-character string. + result.Append(bytes[i].ToString("x2")); + } + + return result.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs new file mode 100644 index 0000000000..ec0e7977d0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs @@ -0,0 +1,312 @@ +// 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.Syntax; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class ClassifiedSpanVisitor : SyntaxWalker + { + private RazorSourceDocument _source; + private List _spans; + private BlockKindInternal _currentBlockKind; + private SyntaxNode _currentBlock; + + public ClassifiedSpanVisitor(RazorSourceDocument source) + { + _source = source; + _spans = new List(); + _currentBlockKind = BlockKindInternal.Markup; + } + + public IReadOnlyList ClassifiedSpans => _spans; + + public override void VisitRazorCommentBlock(RazorCommentBlockSyntax node) + { + WriteBlock(node, BlockKindInternal.Comment, razorCommentSyntax => + { + WriteSpan(razorCommentSyntax.StartCommentTransition, SpanKindInternal.Transition, AcceptedCharactersInternal.None); + WriteSpan(razorCommentSyntax.StartCommentStar, SpanKindInternal.MetaCode, AcceptedCharactersInternal.None); + + var comment = razorCommentSyntax.Comment; + if (comment.IsMissing) + { + // We need to generate a classified span at this position. So insert a marker in its place. + comment = (SyntaxToken)SyntaxFactory.Token(SyntaxKind.Marker, string.Empty).Green.CreateRed(razorCommentSyntax, razorCommentSyntax.StartCommentStar.EndPosition); + } + WriteSpan(comment, SpanKindInternal.Comment, AcceptedCharactersInternal.Any); + + WriteSpan(razorCommentSyntax.EndCommentStar, SpanKindInternal.MetaCode, AcceptedCharactersInternal.None); + WriteSpan(razorCommentSyntax.EndCommentTransition, SpanKindInternal.Transition, AcceptedCharactersInternal.None); + }); + } + + public override void VisitCSharpCodeBlock(CSharpCodeBlockSyntax node) + { + if (node.Parent is CSharpStatementBodySyntax || + node.Parent is CSharpExplicitExpressionBodySyntax || + node.Parent is CSharpImplicitExpressionBodySyntax || + node.Parent is RazorDirectiveBodySyntax || + (_currentBlockKind == BlockKindInternal.Directive && + node.Children.Count == 1 && + node.Children[0] is CSharpStatementLiteralSyntax)) + { + base.VisitCSharpCodeBlock(node); + return; + } + + WriteBlock(node, BlockKindInternal.Statement, base.VisitCSharpCodeBlock); + } + + public override void VisitCSharpStatement(CSharpStatementSyntax node) + { + WriteBlock(node, BlockKindInternal.Statement, base.VisitCSharpStatement); + } + + public override void VisitCSharpExplicitExpression(CSharpExplicitExpressionSyntax node) + { + WriteBlock(node, BlockKindInternal.Expression, base.VisitCSharpExplicitExpression); + } + + public override void VisitCSharpImplicitExpression(CSharpImplicitExpressionSyntax node) + { + WriteBlock(node, BlockKindInternal.Expression, base.VisitCSharpImplicitExpression); + } + + public override void VisitRazorDirective(RazorDirectiveSyntax node) + { + WriteBlock(node, BlockKindInternal.Directive, base.VisitRazorDirective); + } + + public override void VisitCSharpTemplateBlock(CSharpTemplateBlockSyntax node) + { + WriteBlock(node, BlockKindInternal.Template, base.VisitCSharpTemplateBlock); + } + + public override void VisitMarkupBlock(MarkupBlockSyntax node) + { + WriteBlock(node, BlockKindInternal.Markup, base.VisitMarkupBlock); + } + + public override void VisitMarkupTagHelperAttributeValue(MarkupTagHelperAttributeValueSyntax node) + { + // We don't generate a classified span when the attribute value is a simple literal value. + // This is done so we maintain the classified spans generated in 2.x which + // used ConditionalAttributeCollapser (combines markup literal attribute values into one span with no block parent). + if (node.Children.Count > 1 || + (node.Children.Count == 1 && node.Children[0] is MarkupDynamicAttributeValueSyntax)) + { + WriteBlock(node, BlockKindInternal.Markup, base.VisitMarkupTagHelperAttributeValue); + return; + } + + base.VisitMarkupTagHelperAttributeValue(node); + } + + public override void VisitMarkupTagBlock(MarkupTagBlockSyntax node) + { + WriteBlock(node, BlockKindInternal.Tag, base.VisitMarkupTagBlock); + } + + public override void VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node) + { + WriteBlock(node, BlockKindInternal.Tag, base.VisitMarkupTagHelperElement); + } + + public override void VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node) + { + foreach (var child in node.Children) + { + if (child is MarkupTagHelperAttributeSyntax attribute) + { + Visit(attribute); + } + } + } + + public override void VisitMarkupTagHelperEndTag(MarkupTagHelperEndTagSyntax node) + { + // We don't want to generate a classified span for a tag helper end tag. Do nothing. + } + + public override void VisitMarkupAttributeBlock(MarkupAttributeBlockSyntax node) + { + WriteBlock(node, BlockKindInternal.Markup, n => + { + var equalsSyntax = SyntaxFactory.MarkupTextLiteral(new SyntaxList(node.EqualsToken)); + var mergedAttributePrefix = MergeTextLiteralSpans(node.NamePrefix, node.Name, node.NameSuffix, equalsSyntax, node.ValuePrefix); + Visit(mergedAttributePrefix); + Visit(node.Value); + Visit(node.ValueSuffix); + }); + } + + public override void VisitMarkupTagHelperAttribute(MarkupTagHelperAttributeSyntax node) + { + Visit(node.Value); + } + + public override void VisitMarkupMinimizedAttributeBlock(MarkupMinimizedAttributeBlockSyntax node) + { + WriteBlock(node, BlockKindInternal.Markup, n => + { + var mergedAttributePrefix = MergeTextLiteralSpans(node.NamePrefix, node.Name); + Visit(mergedAttributePrefix); + }); + } + + public override void VisitMarkupCommentBlock(MarkupCommentBlockSyntax node) + { + WriteBlock(node, BlockKindInternal.HtmlComment, base.VisitMarkupCommentBlock); + } + + public override void VisitMarkupDynamicAttributeValue(MarkupDynamicAttributeValueSyntax node) + { + WriteBlock(node, BlockKindInternal.Markup, base.VisitMarkupDynamicAttributeValue); + } + + public override void VisitRazorMetaCode(RazorMetaCodeSyntax node) + { + WriteSpan(node, SpanKindInternal.MetaCode); + base.VisitRazorMetaCode(node); + } + + public override void VisitCSharpTransition(CSharpTransitionSyntax node) + { + WriteSpan(node, SpanKindInternal.Transition); + base.VisitCSharpTransition(node); + } + + public override void VisitMarkupTransition(MarkupTransitionSyntax node) + { + WriteSpan(node, SpanKindInternal.Transition); + base.VisitMarkupTransition(node); + } + + public override void VisitCSharpStatementLiteral(CSharpStatementLiteralSyntax node) + { + WriteSpan(node, SpanKindInternal.Code); + base.VisitCSharpStatementLiteral(node); + } + + public override void VisitCSharpExpressionLiteral(CSharpExpressionLiteralSyntax node) + { + WriteSpan(node, SpanKindInternal.Code); + base.VisitCSharpExpressionLiteral(node); + } + + public override void VisitCSharpEphemeralTextLiteral(CSharpEphemeralTextLiteralSyntax node) + { + WriteSpan(node, SpanKindInternal.Code); + base.VisitCSharpEphemeralTextLiteral(node); + } + + public override void VisitUnclassifiedTextLiteral(UnclassifiedTextLiteralSyntax node) + { + WriteSpan(node, SpanKindInternal.None); + base.VisitUnclassifiedTextLiteral(node); + } + + public override void VisitMarkupLiteralAttributeValue(MarkupLiteralAttributeValueSyntax node) + { + WriteSpan(node, SpanKindInternal.Markup); + base.VisitMarkupLiteralAttributeValue(node); + } + + public override void VisitMarkupTextLiteral(MarkupTextLiteralSyntax node) + { + if (node.Parent is MarkupLiteralAttributeValueSyntax) + { + base.VisitMarkupTextLiteral(node); + return; + } + + WriteSpan(node, SpanKindInternal.Markup); + base.VisitMarkupTextLiteral(node); + } + + public override void VisitMarkupEphemeralTextLiteral(MarkupEphemeralTextLiteralSyntax node) + { + WriteSpan(node, SpanKindInternal.Markup); + base.VisitMarkupEphemeralTextLiteral(node); + } + + private void WriteBlock(TNode node, BlockKindInternal kind, Action handler) where TNode : SyntaxNode + { + var previousBlock = _currentBlock; + var previousKind = _currentBlockKind; + + _currentBlock = node; + _currentBlockKind = kind; + + handler(node); + + _currentBlock = previousBlock; + _currentBlockKind = previousKind; + } + + private void WriteSpan(SyntaxNode node, SpanKindInternal kind, AcceptedCharactersInternal? acceptedCharacters = null) + { + if (node.IsMissing) + { + return; + } + + var spanSource = node.GetSourceSpan(_source); + var blockSource = _currentBlock.GetSourceSpan(_source); + if (!acceptedCharacters.HasValue) + { + acceptedCharacters = AcceptedCharactersInternal.Any; + var context = node.GetSpanContext(); + if (context != null) + { + acceptedCharacters = context.EditHandler.AcceptedCharacters; + } + } + + var span = new ClassifiedSpanInternal(spanSource, blockSource, kind, _currentBlockKind, acceptedCharacters.Value); + _spans.Add(span); + } + + private MarkupTextLiteralSyntax MergeTextLiteralSpans(params MarkupTextLiteralSyntax[] literalSyntaxes) + { + if (literalSyntaxes == null || literalSyntaxes.Length == 0) + { + return null; + } + + SyntaxNode parent = null; + var position = 0; + var seenFirstLiteral = false; + var builder = Syntax.InternalSyntax.SyntaxListBuilder.Create(); + + foreach (var syntax in literalSyntaxes) + { + if (syntax == null) + { + continue; + } + else if (!seenFirstLiteral) + { + // Set the parent and position of the merged literal to the value of the first non-null literal. + parent = syntax.Parent; + position = syntax.Position; + seenFirstLiteral = true; + } + + foreach (var token in syntax.LiteralTokens) + { + builder.Add(token.Green); + } + } + + var mergedLiteralSyntax = Syntax.InternalSyntax.SyntaxFactory.MarkupTextLiteral( + builder.ToList()); + + return (MarkupTextLiteralSyntax)mergedLiteralSyntax.CreateRed(parent, position); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeRenderingContext.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeRenderingContext.cs new file mode 100644 index 0000000000..f726e2ad4b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeRenderingContext.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 System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + public abstract class CodeRenderingContext + { + internal static readonly object NewLineString = "NewLineString"; + + internal static readonly object SuppressUniqueIds = "SuppressUniqueIds"; + + public abstract IEnumerable Ancestors { get; } + + public abstract CodeWriter CodeWriter { get; } + + public abstract RazorDiagnosticCollection Diagnostics { get; } + + public abstract string DocumentKind { get; } + + public abstract ItemCollection Items { get; } + + public abstract IntermediateNodeWriter NodeWriter { get; } + + public abstract RazorCodeGenerationOptions Options { get; } + + public abstract IntermediateNode Parent { get; } + + public abstract RazorSourceDocument SourceDocument { get; } + + public abstract void AddSourceMappingFor(IntermediateNode node); + + public abstract void RenderNode(IntermediateNode node); + + public abstract void RenderNode(IntermediateNode node, IntermediateNodeWriter writer); + + public abstract void RenderChildren(IntermediateNode node); + + public abstract void RenderChildren(IntermediateNode node, IntermediateNodeWriter writer); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeTarget.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeTarget.cs new file mode 100644 index 0000000000..ba8ba8b48c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeTarget.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; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + public abstract class CodeTarget + { + public static CodeTarget CreateDefault(RazorCodeDocument codeDocument, RazorCodeGenerationOptions options) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + return CreateDefault(codeDocument, options, configure: null); + } + + public static CodeTarget CreateDefault( + RazorCodeDocument codeDocument, + RazorCodeGenerationOptions options, + Action configure) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + var builder = new DefaultCodeTargetBuilder(codeDocument, options); + + if (builder.Options.DesignTime) + { + AddDesignTimeDefaults(builder); + } + else + { + AddRuntimeDefaults(builder); + } + + if (configure != null) + { + configure.Invoke(builder); + } + + return builder.Build(); + } + + public static CodeTarget CreateEmpty( + RazorCodeDocument codeDocument, + RazorCodeGenerationOptions options, + Action configure) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + var builder = new DefaultCodeTargetBuilder(codeDocument, options); + configure?.Invoke(builder); + return builder.Build(); + } + + internal static void AddDesignTimeDefaults(CodeTargetBuilder builder) + { + + } + + internal static void AddRuntimeDefaults(CodeTargetBuilder builder) + { + + } + + public abstract IntermediateNodeWriter CreateNodeWriter(); + + public abstract TExtension GetExtension() where TExtension : class, ICodeTargetExtension; + + public abstract bool HasExtension() where TExtension : class, ICodeTargetExtension; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeTargetBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeTargetBuilder.cs new file mode 100644 index 0000000000..de9daf2ea6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeTargetBuilder.cs @@ -0,0 +1,18 @@ +// 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.CodeGeneration +{ + public abstract class CodeTargetBuilder + { + public abstract RazorCodeDocument CodeDocument { get; } + + public abstract RazorCodeGenerationOptions Options { get; } + + public abstract ICollection TargetExtensions { get; } + + public abstract CodeTarget Build(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeWriter.cs new file mode 100644 index 0000000000..5b44fbc7fc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeWriter.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; +using System.Text; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + public sealed class CodeWriter + { + private static readonly char[] NewLineCharacters = { '\r', '\n' }; + + private readonly StringBuilder _builder; + + private string _newLine; + + private int _absoluteIndex; + private int _currentLineIndex; + private int _currentLineCharacterIndex; + + public CodeWriter() + { + NewLine = Environment.NewLine; + _builder = new StringBuilder(); + } + + public int CurrentIndent { get; set; } + + public int Length => _builder.Length; + + public string NewLine + { + get => _newLine; + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + if (value != "\r\n" && value != "\n") + { + throw new ArgumentException(Resources.FormatCodeWriter_InvalidNewLine(value), nameof(value)); + } + + _newLine = value; + } + } + + public SourceLocation Location => new SourceLocation(_absoluteIndex, _currentLineIndex, _currentLineCharacterIndex); + + public char this[int index] + { + get + { + if (index < 0 || index >= _builder.Length) + { + throw new IndexOutOfRangeException(nameof(index)); + } + + return _builder[index]; + } + } + + // Internal for testing. + internal CodeWriter Indent(int size) + { + if (Length == 0 || this[Length - 1] == '\n') + { + _builder.Append(' ', size); + + _currentLineCharacterIndex += size; + _absoluteIndex += size; + } + + return this; + } + + public CodeWriter Write(string value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + return Write(value, 0, value.Length); + } + + public CodeWriter Write(string value, int startIndex, int count) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + if (startIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (startIndex > value.Length - count) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count == 0) + { + return this; + } + + Indent(CurrentIndent); + + _builder.Append(value, startIndex, count); + + _absoluteIndex += count; + + // The data string might contain a partial newline where the previously + // written string has part of the newline. + var i = startIndex; + int? trailingPartStart = null; + + if ( + // Check the last character of the previous write operation. + _builder.Length - count - 1 >= 0 && + _builder[_builder.Length - count - 1] == '\r' && + + // Check the first character of the current write operation. + _builder[_builder.Length - count] == '\n') + { + // This is newline that's spread across two writes. Skip the first character of the + // current write operation. + // + // We don't need to increment our newline counter because we already did that when we + // saw the \r. + i += 1; + trailingPartStart = 1; + } + + // Iterate the string, stopping at each occurrence of a newline character. This lets us count the + // newline occurrences and keep the index of the last one. + while ((i = value.IndexOfAny(NewLineCharacters, i)) >= 0) + { + // Newline found. + _currentLineIndex++; + _currentLineCharacterIndex = 0; + + i++; + + // We might have stopped at a \r, so check if it's followed by \n and then advance the index to + // start the next search after it. + if (count > i && + value[i - 1] == '\r' && + value[i] == '\n') + { + i++; + } + + // The 'suffix' of the current line starts after this newline token. + trailingPartStart = i; + } + + if (trailingPartStart == null) + { + // No newlines, just add the length of the data buffer + _currentLineCharacterIndex += count; + } + else + { + // Newlines found, add the trailing part of 'data' + _currentLineCharacterIndex += (count - trailingPartStart.Value); + } + + return this; + } + + public CodeWriter WriteLine() + { + _builder.Append(NewLine); + + _currentLineIndex++; + _currentLineCharacterIndex = 0; + _absoluteIndex += NewLine.Length; + + return this; + } + + public CodeWriter WriteLine(string value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + return Write(value).WriteLine(); + } + + public string GenerateCode() + { + return _builder.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeWriterExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeWriterExtensions.cs new file mode 100644 index 0000000000..f15acdeaf6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/CodeWriterExtensions.cs @@ -0,0 +1,650 @@ +// 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.Diagnostics; +using System.Globalization; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + internal static class CodeWriterExtensions + { + private const string InstanceMethodFormat = "{0}.{1}"; + + private static readonly char[] CStyleStringLiteralEscapeChars = + { + '\r', + '\t', + '\"', + '\'', + '\\', + '\0', + '\n', + '\u2028', + '\u2029', + }; + + public static bool IsAtBeginningOfLine(this CodeWriter writer) + { + return writer.Length == 0 || writer[writer.Length - 1] == '\n'; + } + + public static CodeWriter WritePadding(this CodeWriter writer, int offset, SourceSpan? span, CodeRenderingContext context) + { + if (span == null) + { + return writer; + } + + var basePadding = CalculatePadding(); + var resolvedPadding = Math.Max(basePadding - offset, 0); + + if (context.Options.IndentWithTabs) + { + // Avoid writing directly to the StringBuilder here, that will throw off the manual indexing + // done by the base class. + var tabs = resolvedPadding / context.Options.IndentSize; + for (var i = 0; i < tabs; i++) + { + writer.Write("\t"); + } + + var spaces = resolvedPadding % context.Options.IndentSize; + for (var i = 0; i < spaces; i++) + { + writer.Write(" "); + } + } + else + { + for (var i = 0; i < resolvedPadding; i++) + { + writer.Write(" "); + } + } + + return writer; + + int CalculatePadding() + { + var spaceCount = 0; + for (var i = span.Value.AbsoluteIndex - 1; i >= 0; i--) + { + var @char = context.SourceDocument[i]; + if (@char == '\n' || @char == '\r') + { + break; + } + else if (@char == '\t') + { + spaceCount += context.Options.IndentSize; + } + else + { + spaceCount++; + } + } + + return spaceCount; + } + } + + public static CodeWriter WriteVariableDeclaration(this CodeWriter writer, string type, string name, string value) + { + writer.Write(type).Write(" ").Write(name); + if (!string.IsNullOrEmpty(value)) + { + writer.Write(" = ").Write(value); + } + else + { + writer.Write(" = null"); + } + + writer.WriteLine(";"); + + return writer; + } + + public static CodeWriter WriteBooleanLiteral(this CodeWriter writer, bool value) + { + return writer.Write(value.ToString().ToLowerInvariant()); + } + + public static CodeWriter WriteStartAssignment(this CodeWriter writer, string name) + { + return writer.Write(name).Write(" = "); + } + + public static CodeWriter WriteParameterSeparator(this CodeWriter writer) + { + return writer.Write(", "); + } + + public static CodeWriter WriteStartNewObject(this CodeWriter writer, string typeName) + { + return writer.Write("new ").Write(typeName).Write("("); + } + + public static CodeWriter WriteStringLiteral(this CodeWriter writer, string literal) + { + if (literal.Length >= 256 && literal.Length <= 1500 && literal.IndexOf('\0') == -1) + { + WriteVerbatimStringLiteral(writer, literal); + } + else + { + WriteCStyleStringLiteral(writer, literal); + } + + return writer; + } + + public static CodeWriter WriteUsing(this CodeWriter writer, string name) + { + return WriteUsing(writer, name, endLine: true); + } + + public static CodeWriter WriteUsing(this CodeWriter writer, string name, bool endLine) + { + writer.Write("using "); + writer.Write(name); + + if (endLine) + { + writer.WriteLine(";"); + } + + return writer; + } + + public static CodeWriter WriteLineNumberDirective(this CodeWriter writer, SourceSpan span) + { + if (writer.Length >= writer.NewLine.Length && !IsAtBeginningOfLine(writer)) + { + writer.WriteLine(); + } + + var lineNumberAsString = (span.LineIndex + 1).ToString(CultureInfo.InvariantCulture); + return writer.Write("#line ").Write(lineNumberAsString).Write(" \"").Write(span.FilePath).WriteLine("\""); + } + + public static CodeWriter WriteStartMethodInvocation(this CodeWriter writer, string methodName) + { + writer.Write(methodName); + + return writer.Write("("); + } + + public static CodeWriter WriteEndMethodInvocation(this CodeWriter writer) + { + return WriteEndMethodInvocation(writer, endLine: true); + } + + public static CodeWriter WriteEndMethodInvocation(this CodeWriter writer, bool endLine) + { + writer.Write(")"); + if (endLine) + { + writer.WriteLine(";"); + } + + return writer; + } + + // Writes a method invocation for the given instance name. + public static CodeWriter WriteInstanceMethodInvocation( + this CodeWriter writer, + string instanceName, + string methodName, + params string[] parameters) + { + if (instanceName == null) + { + throw new ArgumentNullException(nameof(instanceName)); + } + + if (methodName == null) + { + throw new ArgumentNullException(nameof(methodName)); + } + + return WriteInstanceMethodInvocation(writer, instanceName, methodName, endLine: true, parameters: parameters); + } + + // Writes a method invocation for the given instance name. + public static CodeWriter WriteInstanceMethodInvocation( + this CodeWriter writer, + string instanceName, + string methodName, + bool endLine, + params string[] parameters) + { + if (instanceName == null) + { + throw new ArgumentNullException(nameof(instanceName)); + } + + if (methodName == null) + { + throw new ArgumentNullException(nameof(methodName)); + } + + return WriteMethodInvocation( + writer, + string.Format(CultureInfo.InvariantCulture, InstanceMethodFormat, instanceName, methodName), + endLine, + parameters); + } + + public static CodeWriter WriteStartInstanceMethodInvocation(this CodeWriter writer, string instanceName, string methodName) + { + if (instanceName == null) + { + throw new ArgumentNullException(nameof(instanceName)); + } + + if (methodName == null) + { + throw new ArgumentNullException(nameof(methodName)); + } + + return WriteStartMethodInvocation( + writer, + string.Format(CultureInfo.InvariantCulture, InstanceMethodFormat, instanceName, methodName)); + } + + public static CodeWriter WriteField(this CodeWriter writer, IList modifiers, string typeName, string fieldName) + { + if (modifiers == null) + { + throw new ArgumentNullException(nameof(modifiers)); + } + + if (typeName == null) + { + throw new ArgumentNullException(nameof(typeName)); + } + + if (fieldName == null) + { + throw new ArgumentNullException(nameof(fieldName)); + } + + for (var i = 0; i < modifiers.Count; i++) + { + writer.Write(modifiers[i]); + writer.Write(" "); + } + + writer.Write(typeName); + writer.Write(" "); + writer.Write(fieldName); + writer.Write(";"); + writer.WriteLine(); + + return writer; + } + + public static CodeWriter WriteMethodInvocation(this CodeWriter writer, string methodName, params string[] parameters) + { + return WriteMethodInvocation(writer, methodName, endLine: true, parameters: parameters); + } + + public static CodeWriter WriteMethodInvocation(this CodeWriter writer, string methodName, bool endLine, params string[] parameters) + { + return + WriteStartMethodInvocation(writer, methodName) + .Write(string.Join(", ", parameters)) + .WriteEndMethodInvocation(endLine); + } + + public static CodeWriter WriteAutoPropertyDeclaration(this CodeWriter writer, IList modifiers, string typeName, string propertyName) + { + if (modifiers == null) + { + throw new ArgumentNullException(nameof(modifiers)); + } + + if (typeName == null) + { + throw new ArgumentNullException(nameof(typeName)); + } + + if (propertyName == null) + { + throw new ArgumentNullException(nameof(propertyName)); + } + + for (var i = 0; i < modifiers.Count; i++) + { + writer.Write(modifiers[i]); + writer.Write(" "); + } + + writer.Write(typeName); + writer.Write(" "); + writer.Write(propertyName); + writer.Write(" { get; set; }"); + writer.WriteLine(); + + return writer; + } + + public static CSharpCodeWritingScope BuildScope(this CodeWriter writer) + { + return new CSharpCodeWritingScope(writer); + } + + public static CSharpCodeWritingScope BuildLambda(this CodeWriter writer, params string[] parameterNames) + { + return BuildLambda(writer, async: false, parameterNames: parameterNames); + } + + public static CSharpCodeWritingScope BuildAsyncLambda(this CodeWriter writer, params string[] parameterNames) + { + return BuildLambda(writer, async: true, parameterNames: parameterNames); + } + + private static CSharpCodeWritingScope BuildLambda(CodeWriter writer, bool async, string[] parameterNames) + { + if (async) + { + writer.Write("async"); + } + + writer.Write("(").Write(string.Join(", ", parameterNames)).Write(") => "); + + var scope = new CSharpCodeWritingScope(writer); + + return scope; + } + + public static CSharpCodeWritingScope BuildNamespace(this CodeWriter writer, string name) + { + writer.Write("namespace ").WriteLine(name); + + return new CSharpCodeWritingScope(writer); + } + + public static CSharpCodeWritingScope BuildClassDeclaration( + this CodeWriter writer, + IList modifiers, + string name, + string baseType, + IList interfaces, + IList typeParameters) + { + for (var i = 0; i < modifiers.Count; i++) + { + writer.Write(modifiers[i]); + writer.Write(" "); + } + + writer.Write("class "); + writer.Write(name); + + if (typeParameters != null && typeParameters.Count > 0) + { + writer.Write("<"); + writer.Write(string.Join(", ", typeParameters)); + writer.Write(">"); + } + + var hasBaseType = !string.IsNullOrEmpty(baseType); + var hasInterfaces = interfaces != null && interfaces.Count > 0; + + if (hasBaseType || hasInterfaces) + { + writer.Write(" : "); + + if (hasBaseType) + { + writer.Write(baseType); + + if (hasInterfaces) + { + WriteParameterSeparator(writer); + } + } + + if (hasInterfaces) + { + writer.Write(string.Join(", ", interfaces)); + } + } + + writer.WriteLine(); + + return new CSharpCodeWritingScope(writer); + } + + public static CSharpCodeWritingScope BuildMethodDeclaration( + this CodeWriter writer, + string accessibility, + string returnType, + string name, + IEnumerable> parameters) + { + writer.Write(accessibility) + .Write(" ") + .Write(returnType) + .Write(" ") + .Write(name) + .Write("(") + .Write(string.Join(", ", parameters.Select(p => p.Key + " " + p.Value))) + .WriteLine(")"); + + return new CSharpCodeWritingScope(writer); + } + + public static IDisposable BuildLinePragma(this CodeWriter writer, SourceSpan? span) + { + if (string.IsNullOrEmpty(span?.FilePath)) + { + // Can't build a valid line pragma without a file path. + return NullDisposable.Default; + } + + return new LinePragmaWriter(writer, span.Value); + } + + private static void WriteVerbatimStringLiteral(CodeWriter writer, string literal) + { + writer.Write("@\""); + + // We need to suppress indenting during the writing of the string's content. A + // verbatim string literal could contain newlines that don't get escaped. + var indent = writer.CurrentIndent; + writer.CurrentIndent = 0; + + // We need to find the index of each '"' (double-quote) to escape it. + var start = 0; + int end; + while ((end = literal.IndexOf('\"', start)) > -1) + { + writer.Write(literal, start, end - start); + + writer.Write("\"\""); + + start = end + 1; + } + + Debug.Assert(end == -1); // We've hit all of the double-quotes. + + // Write the remainder after the last double-quote. + writer.Write(literal, start, literal.Length - start); + + writer.Write("\""); + + writer.CurrentIndent = indent; + } + + private static void WriteCStyleStringLiteral(CodeWriter writer, string literal) + { + // From CSharpCodeGenerator.QuoteSnippetStringCStyle in CodeDOM + writer.Write("\""); + + // We need to find the index of each escapable character to escape it. + var start = 0; + int end; + while ((end = literal.IndexOfAny(CStyleStringLiteralEscapeChars, start)) > -1) + { + writer.Write(literal, start, end - start); + + switch (literal[end]) + { + case '\r': + writer.Write("\\r"); + break; + case '\t': + writer.Write("\\t"); + break; + case '\"': + writer.Write("\\\""); + break; + case '\'': + writer.Write("\\\'"); + break; + case '\\': + writer.Write("\\\\"); + break; + case '\0': + writer.Write("\\\0"); + break; + case '\n': + writer.Write("\\n"); + break; + case '\u2028': + case '\u2029': + writer.Write("\\u"); + writer.Write(((int)literal[end]).ToString("X4", CultureInfo.InvariantCulture)); + break; + default: + Debug.Assert(false, "Unknown escape character."); + break; + } + + start = end + 1; + } + + Debug.Assert(end == -1); // We've hit all of chars that need escaping. + + // Write the remainder after the last escaped char. + writer.Write(literal, start, literal.Length - start); + + writer.Write("\""); + } + + public struct CSharpCodeWritingScope : IDisposable + { + private CodeWriter _writer; + private bool _autoSpace; + private int _tabSize; + private int _startIndent; + + public CSharpCodeWritingScope(CodeWriter writer, int tabSize = 4, bool autoSpace = true) + { + _writer = writer; + _autoSpace = autoSpace; + _tabSize = tabSize; + _startIndent = -1; // Set in WriteStartScope + + WriteStartScope(); + } + + public void Dispose() + { + WriteEndScope(); + } + + private void WriteStartScope() + { + TryAutoSpace(" "); + + _writer.WriteLine("{"); + _writer.CurrentIndent += _tabSize; + _startIndent = _writer.CurrentIndent; + } + + private void WriteEndScope() + { + TryAutoSpace(_writer.NewLine); + + // Ensure the scope hasn't been modified + if (_writer.CurrentIndent == _startIndent) + { + _writer.CurrentIndent -= _tabSize; + } + + _writer.WriteLine("}"); + } + + private void TryAutoSpace(string spaceCharacter) + { + if (_autoSpace && + _writer.Length > 0 && + !char.IsWhiteSpace(_writer[_writer.Length - 1])) + { + _writer.Write(spaceCharacter); + } + } + } + + private class LinePragmaWriter : IDisposable + { + private readonly CodeWriter _writer; + private readonly int _startIndent; + + public LinePragmaWriter(CodeWriter writer, SourceSpan span) + { + if (writer == null) + { + throw new ArgumentNullException(nameof(writer)); + } + + _writer = writer; + _startIndent = _writer.CurrentIndent; + _writer.CurrentIndent = 0; + WriteLineNumberDirective(writer, span); + } + + public void Dispose() + { + // Need to add an additional line at the end IF there wasn't one already written. + // This is needed to work with the C# editor's handling of #line ... + var endsWithNewline = _writer.Length > 0 && _writer[_writer.Length - 1] == '\n'; + + // Always write at least 1 empty line to potentially separate code from pragmas. + _writer.WriteLine(); + + // Check if the previous empty line wasn't enough to separate code from pragmas. + if (!endsWithNewline) + { + _writer.WriteLine(); + } + + _writer + .WriteLine("#line default") + .WriteLine("#line hidden"); + + _writer.CurrentIndent = _startIndent; + } + } + + private class NullDisposable : IDisposable + { + public static readonly NullDisposable Default = new NullDisposable(); + + private NullDisposable() + { + } + + public void Dispose() + { + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeRenderingContext.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeRenderingContext.cs new file mode 100644 index 0000000000..848d344c3e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeRenderingContext.cs @@ -0,0 +1,213 @@ + +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + internal class DefaultCodeRenderingContext : CodeRenderingContext + { + private readonly Stack _ancestors; + private readonly RazorCodeDocument _codeDocument; + private readonly DocumentIntermediateNode _documentNode; + private readonly List _scopes; + + public DefaultCodeRenderingContext( + CodeWriter codeWriter, + IntermediateNodeWriter nodeWriter, + RazorCodeDocument codeDocument, + DocumentIntermediateNode documentNode, + RazorCodeGenerationOptions options) + { + if (codeWriter == null) + { + throw new ArgumentNullException(nameof(codeWriter)); + } + + if (nodeWriter == null) + { + throw new ArgumentNullException(nameof(nodeWriter)); + } + + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (documentNode == null) + { + throw new ArgumentNullException(nameof(documentNode)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + CodeWriter = codeWriter; + _codeDocument = codeDocument; + _documentNode = documentNode; + Options = options; + + _ancestors = new Stack(); + Diagnostics = new RazorDiagnosticCollection(); + Items = new ItemCollection(); + SourceMappings = new List(); + + var diagnostics = _documentNode.GetAllDiagnostics(); + for (var i = 0; i < diagnostics.Count; i++) + { + Diagnostics.Add(diagnostics[i]); + } + + var newLineString = codeDocument.Items[NewLineString]; + if (newLineString != null) + { + // Set new line character to a specific string regardless of platform, for testing purposes. + codeWriter.NewLine = (string)newLineString; + } + + Items[NewLineString] = codeDocument.Items[NewLineString]; + Items[SuppressUniqueIds] = codeDocument.Items[SuppressUniqueIds]; + + _scopes = new List(); + _scopes.Add(new ScopeInternal(nodeWriter)); + } + + // This will be initialized by the document writer when the context is 'live'. + public IntermediateNodeVisitor Visitor { get; set; } + + public override IEnumerable Ancestors => _ancestors; + + internal Stack AncestorsInternal => _ancestors; + + public override CodeWriter CodeWriter { get; } + + public override RazorDiagnosticCollection Diagnostics { get; } + + public override string DocumentKind { get; } + + public override ItemCollection Items { get; } + + public List SourceMappings { get; } + + public override IntermediateNodeWriter NodeWriter => Current.Writer; + + public override RazorCodeGenerationOptions Options { get; } + + public override IntermediateNode Parent => _ancestors.Count == 0 ? null : _ancestors.Peek(); + + public override RazorSourceDocument SourceDocument => _codeDocument.Source; + + private ScopeInternal Current => _scopes[_scopes.Count - 1]; + + public override void AddSourceMappingFor(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (node.Source == null) + { + return; + } + + if (SourceDocument.FilePath != null && + !string.Equals(SourceDocument.FilePath, node.Source.Value.FilePath, StringComparison.OrdinalIgnoreCase)) + { + // We don't want to generate line mappings for imports. + return; + } + + var source = node.Source.Value; + var generatedLocation = new SourceSpan(CodeWriter.Location, source.Length); + var sourceMapping = new SourceMapping(source, generatedLocation); + + SourceMappings.Add(sourceMapping); + } + + public override void RenderChildren(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + _ancestors.Push(node); + + for (var i = 0; i < node.Children.Count; i++) + { + Visitor.Visit(node.Children[i]); + } + + _ancestors.Pop(); + } + + public override void RenderChildren(IntermediateNode node, IntermediateNodeWriter writer) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (writer == null) + { + throw new ArgumentNullException(nameof(writer)); + } + + _scopes.Add(new ScopeInternal(writer)); + _ancestors.Push(node); + + for (var i = 0; i < node.Children.Count; i++) + { + Visitor.Visit(node.Children[i]); + } + + _ancestors.Pop(); + _scopes.RemoveAt(_scopes.Count - 1); + } + + public override void RenderNode(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + Visitor.Visit(node); + } + + public override void RenderNode(IntermediateNode node, IntermediateNodeWriter writer) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (writer == null) + { + throw new ArgumentNullException(nameof(writer)); + } + + _scopes.Add(new ScopeInternal(writer)); + + Visitor.Visit(node); + + _scopes.RemoveAt(_scopes.Count - 1); + } + + private struct ScopeInternal + { + public ScopeInternal(IntermediateNodeWriter writer) + { + Writer = writer; + } + + public IntermediateNodeWriter Writer { get; } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeTarget.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeTarget.cs new file mode 100644 index 0000000000..e9ef7d1ee7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeTarget.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 System.Collections.Generic; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + internal class DefaultCodeTarget : CodeTarget + { + private readonly RazorCodeGenerationOptions _options; + + public DefaultCodeTarget(RazorCodeGenerationOptions options, IEnumerable extensions) + { + _options = options; + Extensions = extensions.ToArray(); + } + + public ICodeTargetExtension[] Extensions { get; } + + public override IntermediateNodeWriter CreateNodeWriter() + { + return _options.DesignTime ? (IntermediateNodeWriter)new DesignTimeNodeWriter() : new RuntimeNodeWriter(); + } + + public override TExtension GetExtension() + { + for (var i = 0; i < Extensions.Length; i++) + { + var match = Extensions[i] as TExtension; + if (match != null) + { + return match; + } + } + + return null; + } + + public override bool HasExtension() + { + for (var i = 0; i < Extensions.Length; i++) + { + var match = Extensions[i] as TExtension; + if (match != null) + { + return true; + } + } + + return false; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeTargetBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeTargetBuilder.cs new file mode 100644 index 0000000000..8ae23bddf4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultCodeTargetBuilder.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. + +using System; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + internal class DefaultCodeTargetBuilder : CodeTargetBuilder + { + public DefaultCodeTargetBuilder(RazorCodeDocument codeDocument, RazorCodeGenerationOptions options) + { + CodeDocument = codeDocument; + Options = options; + + TargetExtensions = new List(); + } + + public override RazorCodeDocument CodeDocument { get; } + + public override RazorCodeGenerationOptions Options { get; } + + public override ICollection TargetExtensions { get; } + + public override CodeTarget Build() + { + return new DefaultCodeTarget(Options, TargetExtensions); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultDocumentWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultDocumentWriter.cs new file mode 100644 index 0000000000..a47295143d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultDocumentWriter.cs @@ -0,0 +1,266 @@ +// 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 System.Security.Cryptography; +using System.Text; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + internal class DefaultDocumentWriter : DocumentWriter + { + private readonly CodeTarget _codeTarget; + private readonly RazorCodeGenerationOptions _options; + + public DefaultDocumentWriter(CodeTarget codeTarget, RazorCodeGenerationOptions options) + { + _codeTarget = codeTarget; + _options = options; + } + + public override RazorCSharpDocument WriteDocument(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (documentNode == null) + { + throw new ArgumentNullException(nameof(documentNode)); + } + + var context = new DefaultCodeRenderingContext( + new CodeWriter(), + _codeTarget.CreateNodeWriter(), + codeDocument, + documentNode, + _options); + context.Visitor = new Visitor(_codeTarget, context); + + context.Visitor.VisitDocument(documentNode); + + var cSharp = context.CodeWriter.GenerateCode(); + return new DefaultRazorCSharpDocument( + cSharp, + _options, + context.Diagnostics.ToArray(), + context.SourceMappings.ToArray()); + } + + private class Visitor : IntermediateNodeVisitor + { + private readonly DefaultCodeRenderingContext _context; + private readonly CodeTarget _target; + + public Visitor(CodeTarget target, DefaultCodeRenderingContext context) + { + _target = target; + _context = context; + } + + private DefaultCodeRenderingContext Context => _context; + + public override void VisitDocument(DocumentIntermediateNode node) + { + if (!Context.Options.SuppressChecksum) + { + // See http://msdn.microsoft.com/en-us/library/system.codedom.codechecksumpragma.checksumalgorithmid.aspx + // And https://github.com/dotnet/roslyn/blob/614299ff83da9959fa07131c6d0ffbc58873b6ae/src/Compilers/Core/Portable/PEWriter/DebugSourceDocument.cs#L67 + // + // We only support algorithms that the debugger understands, which is currently SHA1 and SHA256. + + string algorithmId; + var algorithm = Context.SourceDocument.GetChecksumAlgorithm(); + if (string.Equals(algorithm, HashAlgorithmName.SHA256.Name, StringComparison.Ordinal)) + { + algorithmId = "{8829d00f-11b8-4213-878b-770e8597ac16}"; + } + else if (string.Equals(algorithm, HashAlgorithmName.SHA1.Name, StringComparison.Ordinal) || + + // In 2.0, we didn't actually expose the name of the algorithm, so it's possible we could get null here. + // If that's the case, we just assume SHA1 since that's the only thing we supported in 2.0. + algorithm == null) + { + algorithmId = "{ff1816ec-aa5e-4d10-87f7-6f4963833460}"; + } + else + { + var supportedAlgorithms = string.Join(" ", new string[] + { + HashAlgorithmName.SHA1.Name, + HashAlgorithmName.SHA256.Name + }); + + var message = Resources.FormatUnsupportedChecksumAlgorithm( + algorithm, + supportedAlgorithms, + nameof(RazorCodeGenerationOptions) + "." + nameof(RazorCodeGenerationOptions.SuppressChecksum), + bool.TrueString); + throw new InvalidOperationException(message); + } + + var sourceDocument = Context.SourceDocument; + + var checksum = Checksum.BytesToString(sourceDocument.GetChecksum()); + if (!string.IsNullOrEmpty(checksum)) + { + Context.CodeWriter + .Write("#pragma checksum \"") + .Write(sourceDocument.FilePath) + .Write("\" \"") + .Write(algorithmId) + .Write("\" \"") + .Write(checksum) + .WriteLine("\""); + } + } + + Context.CodeWriter + .WriteLine("// ") + .WriteLine("#pragma warning disable 1591"); + + VisitDefault(node); + + Context.CodeWriter.WriteLine("#pragma warning restore 1591"); + } + + public override void VisitUsingDirective(UsingDirectiveIntermediateNode node) + { + Context.NodeWriter.WriteUsingDirective(Context, node); + } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + using (Context.CodeWriter.BuildNamespace(node.Content)) + { + Context.CodeWriter.WriteLine("#line hidden"); + VisitDefault(node); + } + } + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + using (Context.CodeWriter.BuildClassDeclaration( + node.Modifiers, + node.ClassName, + node.BaseType, + node.Interfaces, + node.TypeParameters.Select(p => p.ParameterName).ToArray())) + { + VisitDefault(node); + } + } + + public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node) + { + Context.CodeWriter.WriteLine("#pragma warning disable 1998"); + + for (var i = 0; i < node.Modifiers.Count; i++) + { + Context.CodeWriter.Write(node.Modifiers[i]); + Context.CodeWriter.Write(" "); + } + + Context.CodeWriter.Write(node.ReturnType); + Context.CodeWriter.Write(" "); + + Context.CodeWriter.Write(node.MethodName); + Context.CodeWriter.Write("("); + + for (var i = 0; i < node.Parameters.Count; i++) + { + var parameter = node.Parameters[i]; + + for (var j = 0; j < parameter.Modifiers.Count; j++) + { + Context.CodeWriter.Write(parameter.Modifiers[j]); + Context.CodeWriter.Write(" "); + } + + Context.CodeWriter.Write(parameter.TypeName); + Context.CodeWriter.Write(" "); + + Context.CodeWriter.Write(parameter.ParameterName); + + if (i < node.Parameters.Count - 1) + { + Context.CodeWriter.Write(", "); + } + } + + Context.CodeWriter.Write(")"); + Context.CodeWriter.WriteLine(); + + using (Context.CodeWriter.BuildScope()) + { + VisitDefault(node); + } + + Context.CodeWriter.WriteLine("#pragma warning restore 1998"); + } + + public override void VisitFieldDeclaration(FieldDeclarationIntermediateNode node) + { + Context.CodeWriter.WriteField(node.Modifiers, node.FieldType, node.FieldName); + } + + public override void VisitPropertyDeclaration(PropertyDeclarationIntermediateNode node) + { + Context.CodeWriter.WriteAutoPropertyDeclaration(node.Modifiers, node.PropertyType, node.PropertyName); + } + + public override void VisitExtension(ExtensionIntermediateNode node) + { + node.WriteNode(_target, Context); + } + + public override void VisitCSharpExpression(CSharpExpressionIntermediateNode node) + { + Context.NodeWriter.WriteCSharpExpression(Context, node); + } + + public override void VisitCSharpCode(CSharpCodeIntermediateNode node) + { + Context.NodeWriter.WriteCSharpCode(Context, node); + } + + public override void VisitHtmlAttribute(HtmlAttributeIntermediateNode node) + { + Context.NodeWriter.WriteHtmlAttribute(Context, node); + } + + public override void VisitHtmlAttributeValue(HtmlAttributeValueIntermediateNode node) + { + Context.NodeWriter.WriteHtmlAttributeValue(Context, node); + } + + public override void VisitCSharpExpressionAttributeValue(CSharpExpressionAttributeValueIntermediateNode node) + { + Context.NodeWriter.WriteCSharpExpressionAttributeValue(Context, node); + } + + public override void VisitCSharpCodeAttributeValue(CSharpCodeAttributeValueIntermediateNode node) + { + Context.NodeWriter.WriteCSharpCodeAttributeValue(Context, node); + } + + public override void VisitHtml(HtmlContentIntermediateNode node) + { + Context.NodeWriter.WriteHtmlContent(Context, node); + } + + public override void VisitTagHelper(TagHelperIntermediateNode node) + { + VisitDefault(node); + } + + public override void VisitDefault(IntermediateNode node) + { + Context.RenderChildren(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DesignTimeNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DesignTimeNodeWriter.cs new file mode 100644 index 0000000000..d937c6f626 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DesignTimeNodeWriter.cs @@ -0,0 +1,259 @@ +// 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 Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + public class DesignTimeNodeWriter : IntermediateNodeWriter + { + public override void WriteUsingDirective(CodeRenderingContext context, UsingDirectiveIntermediateNode node) + { + if (node.Source.HasValue) + { + using (context.CodeWriter.BuildLinePragma(node.Source.Value)) + { + context.AddSourceMappingFor(node); + context.CodeWriter.WriteUsing(node.Content); + } + } + else + { + context.CodeWriter.WriteUsing(node.Content); + } + } + + public override void WriteCSharpExpression(CodeRenderingContext context, CSharpExpressionIntermediateNode node) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (node.Children.Count == 0) + { + return; + } + + if (node.Source != null) + { + using (context.CodeWriter.BuildLinePragma(node.Source.Value)) + { + var offset = DesignTimeDirectivePass.DesignTimeVariable.Length + " = ".Length; + context.CodeWriter.WritePadding(offset, node.Source, context); + context.CodeWriter.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable); + + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + context.AddSourceMappingFor(token); + context.CodeWriter.Write(token.Content); + } + else + { + // There may be something else inside the expression like a Template or another extension node. + context.RenderNode(node.Children[i]); + } + } + + context.CodeWriter.WriteLine(";"); + } + } + else + { + context.CodeWriter.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable); + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + context.CodeWriter.Write(token.Content); + } + else + { + // There may be something else inside the expression like a Template or another extension node. + context.RenderNode(node.Children[i]); + } + } + context.CodeWriter.WriteLine(";"); + } + } + + public override void WriteCSharpCode(CodeRenderingContext context, CSharpCodeIntermediateNode node) + { + IDisposable linePragmaScope = null; + if (node.Source != null) + { + linePragmaScope = context.CodeWriter.BuildLinePragma(node.Source.Value); + + context.CodeWriter.WritePadding(0, node.Source.Value, context); + } + + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + context.AddSourceMappingFor(token); + context.CodeWriter.Write(token.Content); + } + else + { + // There may be something else inside the statement like an extension node. + context.RenderNode(node.Children[i]); + } + } + + if (linePragmaScope != null) + { + linePragmaScope.Dispose(); + } + else + { + context.CodeWriter.WriteLine(); + } + } + + public override void WriteHtmlAttribute(CodeRenderingContext context, HtmlAttributeIntermediateNode node) + { + context.RenderChildren(node); + } + + public override void WriteHtmlAttributeValue(CodeRenderingContext context, HtmlAttributeValueIntermediateNode node) + { + context.RenderChildren(node); + } + + public override void WriteCSharpExpressionAttributeValue(CodeRenderingContext context, CSharpExpressionAttributeValueIntermediateNode node) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (node.Children.Count == 0) + { + return; + } + + var firstChild = node.Children[0]; + if (firstChild.Source != null) + { + using (context.CodeWriter.BuildLinePragma(firstChild.Source.Value)) + { + var offset = DesignTimeDirectivePass.DesignTimeVariable.Length + " = ".Length; + context.CodeWriter.WritePadding(offset, firstChild.Source, context); + context.CodeWriter.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable); + + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + context.AddSourceMappingFor(token); + context.CodeWriter.Write(token.Content); + } + else + { + // There may be something else inside the expression like a Template or another extension node. + context.RenderNode(node.Children[i]); + } + } + + context.CodeWriter.WriteLine(";"); + } + } + else + { + context.CodeWriter.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable); + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + if (token.Source != null) + { + context.AddSourceMappingFor(token); + } + + context.CodeWriter.Write(token.Content); + } + else + { + // There may be something else inside the expression like a Template or another extension node. + context.RenderNode(node.Children[i]); + } + } + context.CodeWriter.WriteLine(";"); + } + } + + public override void WriteCSharpCodeAttributeValue(CodeRenderingContext context, CSharpCodeAttributeValueIntermediateNode node) + { + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + IDisposable linePragmaScope = null; + var isWhitespaceStatement = string.IsNullOrWhiteSpace(token.Content); + + if (token.Source != null) + { + if (!isWhitespaceStatement) + { + linePragmaScope = context.CodeWriter.BuildLinePragma(token.Source.Value); + } + + context.CodeWriter.WritePadding(0, token.Source.Value, context); + } + else if (isWhitespaceStatement) + { + // Don't write whitespace if there is no line mapping for it. + continue; + } + + context.AddSourceMappingFor(token); + context.CodeWriter.Write(token.Content); + + if (linePragmaScope != null) + { + linePragmaScope.Dispose(); + } + else + { + context.CodeWriter.WriteLine(); + } + } + else + { + // There may be something else inside the statement like an extension node. + context.RenderNode(node.Children[i]); + } + } + } + + public override void WriteHtmlContent(CodeRenderingContext context, HtmlContentIntermediateNode node) + { + // Do nothing + } + + public override void BeginWriterScope(CodeRenderingContext context, string writer) + { + // Do nothing + } + + public override void EndWriterScope(CodeRenderingContext context) + { + // Do nothing + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DocumentWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DocumentWriter.cs new file mode 100644 index 0000000000..68f7ddffc0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DocumentWriter.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; +using System.ComponentModel; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + public abstract class DocumentWriter + { + public static DocumentWriter CreateDefault(CodeTarget codeTarget, RazorCodeGenerationOptions options) + { + if (codeTarget == null) + { + throw new ArgumentNullException(nameof(codeTarget)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + return new DefaultDocumentWriter(codeTarget, options); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This method was intended to be static, use CreateDefault instead.")] + public DocumentWriter Create(CodeTarget codeTarget, RazorCodeGenerationOptions options) + { + if (codeTarget == null) + { + throw new ArgumentNullException(nameof(codeTarget)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + return new DefaultDocumentWriter(codeTarget, options); + } + + public abstract RazorCSharpDocument WriteDocument(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/ICodeTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/ICodeTargetExtension.cs new file mode 100644 index 0000000000..c8414f1335 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/ICodeTargetExtension.cs @@ -0,0 +1,9 @@ +// 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.CodeGeneration +{ + public interface ICodeTargetExtension + { + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/IntermediateNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/IntermediateNodeWriter.cs new file mode 100644 index 0000000000..d8c636f064 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/IntermediateNodeWriter.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. + +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + public abstract class IntermediateNodeWriter + { + public abstract void WriteUsingDirective(CodeRenderingContext context, UsingDirectiveIntermediateNode node); + + public abstract void WriteCSharpExpression(CodeRenderingContext context, CSharpExpressionIntermediateNode node); + + public abstract void WriteCSharpCode(CodeRenderingContext context, CSharpCodeIntermediateNode node); + + public abstract void WriteHtmlContent(CodeRenderingContext context, HtmlContentIntermediateNode node); + + public abstract void WriteHtmlAttribute(CodeRenderingContext context, HtmlAttributeIntermediateNode node); + + public abstract void WriteHtmlAttributeValue(CodeRenderingContext context, HtmlAttributeValueIntermediateNode node); + + public abstract void WriteCSharpExpressionAttributeValue(CodeRenderingContext context, CSharpExpressionAttributeValueIntermediateNode node); + + public abstract void WriteCSharpCodeAttributeValue(CodeRenderingContext context, CSharpCodeAttributeValueIntermediateNode node); + + public abstract void BeginWriterScope(CodeRenderingContext context, string writer); + + public abstract void EndWriterScope(CodeRenderingContext context); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/LiteralRuntimeNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/LiteralRuntimeNodeWriter.cs new file mode 100644 index 0000000000..21d542f663 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/LiteralRuntimeNodeWriter.cs @@ -0,0 +1,10 @@ +// 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.CodeGeneration +{ + internal class LiteralRuntimeNodeWriter : RuntimeNodeWriter + { + public override string WriteCSharpExpressionMethod { get; set; } = "WriteLiteral"; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/RuntimeNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/RuntimeNodeWriter.cs new file mode 100644 index 0000000000..f913a53fc4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/RuntimeNodeWriter.cs @@ -0,0 +1,391 @@ +// 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.Globalization; +using System.Linq; +using System.Text; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + public class RuntimeNodeWriter : IntermediateNodeWriter + { + public virtual string WriteCSharpExpressionMethod { get; set; } = "Write"; + + public virtual string WriteHtmlContentMethod { get; set; } = "WriteLiteral"; + + public virtual string BeginWriteAttributeMethod { get; set; } = "BeginWriteAttribute"; + + public virtual string EndWriteAttributeMethod { get; set; } = "EndWriteAttribute"; + + public virtual string WriteAttributeValueMethod { get; set; } = "WriteAttributeValue"; + + public virtual string PushWriterMethod { get; set; } = "PushWriter"; + + public virtual string PopWriterMethod { get; set; } = "PopWriter"; + + public string TemplateTypeName { get; set; } = "Microsoft.AspNetCore.Mvc.Razor.HelperResult"; + + public override void WriteUsingDirective(CodeRenderingContext context, UsingDirectiveIntermediateNode node) + { + if (node.Source.HasValue) + { + using (context.CodeWriter.BuildLinePragma(node.Source.Value)) + { + context.CodeWriter.WriteUsing(node.Content); + } + } + else + { + context.CodeWriter.WriteUsing(node.Content); + } + } + + public override void WriteCSharpExpression(CodeRenderingContext context, CSharpExpressionIntermediateNode node) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + IDisposable linePragmaScope = null; + if (node.Source != null) + { + linePragmaScope = context.CodeWriter.BuildLinePragma(node.Source.Value); + context.CodeWriter.WritePadding(WriteCSharpExpressionMethod.Length + 1, node.Source, context); + } + + context.CodeWriter.WriteStartMethodInvocation(WriteCSharpExpressionMethod); + + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + context.CodeWriter.Write(token.Content); + } + else + { + // There may be something else inside the expression like a Template or another extension node. + context.RenderNode(node.Children[i]); + } + } + + context.CodeWriter.WriteEndMethodInvocation(); + + linePragmaScope?.Dispose(); + } + + public override void WriteCSharpCode(CodeRenderingContext context, CSharpCodeIntermediateNode node) + { + var isWhitespaceStatement = true; + for (var i = 0; i < node.Children.Count; i++) + { + var token = node.Children[i] as IntermediateToken; + if (token == null || !string.IsNullOrWhiteSpace(token.Content)) + { + isWhitespaceStatement = false; + break; + } + } + + if (isWhitespaceStatement) + { + return; + } + + IDisposable linePragmaScope = null; + if (node.Source != null) + { + linePragmaScope = context.CodeWriter.BuildLinePragma(node.Source.Value); + context.CodeWriter.WritePadding(0, node.Source.Value, context); + } + + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + context.CodeWriter.Write(token.Content); + } + else + { + // There may be something else inside the statement like an extension node. + context.RenderNode(node.Children[i]); + } + } + + if (linePragmaScope == null) + { + context.CodeWriter.WriteLine(); + } + + linePragmaScope?.Dispose(); + } + + public override void WriteHtmlAttribute(CodeRenderingContext context, HtmlAttributeIntermediateNode node) + { + var valuePieceCount = node + .Children + .Count(child => + child is HtmlAttributeValueIntermediateNode || + child is CSharpExpressionAttributeValueIntermediateNode || + child is CSharpCodeAttributeValueIntermediateNode || + child is ExtensionIntermediateNode); + + var prefixLocation = node.Source.Value.AbsoluteIndex; + var suffixLocation = node.Source.Value.AbsoluteIndex + node.Source.Value.Length - node.Suffix.Length; + context.CodeWriter + .WriteStartMethodInvocation(BeginWriteAttributeMethod) + .WriteStringLiteral(node.AttributeName) + .WriteParameterSeparator() + .WriteStringLiteral(node.Prefix) + .WriteParameterSeparator() + .Write(prefixLocation.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator() + .WriteStringLiteral(node.Suffix) + .WriteParameterSeparator() + .Write(suffixLocation.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator() + .Write(valuePieceCount.ToString(CultureInfo.InvariantCulture)) + .WriteEndMethodInvocation(); + + context.RenderChildren(node); + + context.CodeWriter + .WriteStartMethodInvocation(EndWriteAttributeMethod) + .WriteEndMethodInvocation(); + } + + public override void WriteHtmlAttributeValue(CodeRenderingContext context, HtmlAttributeValueIntermediateNode node) + { + var prefixLocation = node.Source.Value.AbsoluteIndex; + var valueLocation = node.Source.Value.AbsoluteIndex + node.Prefix.Length; + var valueLength = node.Source.Value.Length; + context.CodeWriter + .WriteStartMethodInvocation(WriteAttributeValueMethod) + .WriteStringLiteral(node.Prefix) + .WriteParameterSeparator() + .Write(prefixLocation.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator(); + + // Write content + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsHtml) + { + context.CodeWriter.WriteStringLiteral(token.Content); + } + else + { + // There may be something else inside the attribute value like an extension node. + context.RenderNode(node.Children[i]); + } + } + + context.CodeWriter + .WriteParameterSeparator() + .Write(valueLocation.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator() + .Write(valueLength.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator() + .WriteBooleanLiteral(true) + .WriteEndMethodInvocation(); + } + + public override void WriteCSharpExpressionAttributeValue(CodeRenderingContext context, CSharpExpressionAttributeValueIntermediateNode node) + { + using (context.CodeWriter.BuildLinePragma(node.Source.Value)) + { + var prefixLocation = node.Source.Value.AbsoluteIndex; + context.CodeWriter + .WriteStartMethodInvocation(WriteAttributeValueMethod) + .WriteStringLiteral(node.Prefix) + .WriteParameterSeparator() + .Write(prefixLocation.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator(); + + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + context.CodeWriter.Write(token.Content); + } + else + { + // There may be something else inside the expression like an extension node. + context.RenderNode(node.Children[i]); + } + } + + var valueLocation = node.Source.Value.AbsoluteIndex + node.Prefix.Length; + var valueLength = node.Source.Value.Length - node.Prefix.Length; + context.CodeWriter + .WriteParameterSeparator() + .Write(valueLocation.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator() + .Write(valueLength.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator() + .WriteBooleanLiteral(false) + .WriteEndMethodInvocation(); + } + } + + public override void WriteCSharpCodeAttributeValue(CodeRenderingContext context, CSharpCodeAttributeValueIntermediateNode node) + { + const string ValueWriterName = "__razor_attribute_value_writer"; + + var prefixLocation = node.Source.Value.AbsoluteIndex; + var valueLocation = node.Source.Value.AbsoluteIndex + node.Prefix.Length; + var valueLength = node.Source.Value.Length - node.Prefix.Length; + context.CodeWriter + .WriteStartMethodInvocation(WriteAttributeValueMethod) + .WriteStringLiteral(node.Prefix) + .WriteParameterSeparator() + .Write(prefixLocation.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator(); + + context.CodeWriter.WriteStartNewObject(TemplateTypeName); + + using (context.CodeWriter.BuildAsyncLambda(ValueWriterName)) + { + BeginWriterScope(context, ValueWriterName); + + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsCSharp) + { + var isWhitespaceStatement = string.IsNullOrWhiteSpace(token.Content); + IDisposable linePragmaScope = null; + if (token.Source != null) + { + if (!isWhitespaceStatement) + { + linePragmaScope = context.CodeWriter.BuildLinePragma(token.Source.Value); + } + + context.CodeWriter.WritePadding(0, token.Source.Value, context); + } + else if (isWhitespaceStatement) + { + // Don't write whitespace if there is no line mapping for it. + continue; + } + + context.CodeWriter.Write(token.Content); + + if (linePragmaScope != null) + { + linePragmaScope.Dispose(); + } + else + { + context.CodeWriter.WriteLine(); + } + } + else + { + // There may be something else inside the statement like an extension node. + context.RenderNode(node.Children[i]); + } + } + + EndWriterScope(context); + } + + context.CodeWriter.WriteEndMethodInvocation(false); + + context.CodeWriter + .WriteParameterSeparator() + .Write(valueLocation.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator() + .Write(valueLength.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator() + .WriteBooleanLiteral(false) + .WriteEndMethodInvocation(); + } + + public override void WriteHtmlContent(CodeRenderingContext context, HtmlContentIntermediateNode node) + { + const int MaxStringLiteralLength = 1024; + + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsHtml) + { + builder.Append(token.Content); + } + } + + var content = builder.ToString(); + + WriteHtmlLiteral(context, MaxStringLiteralLength, content); + } + + // Internal for testing + internal void WriteHtmlLiteral(CodeRenderingContext context, int maxStringLiteralLength, string literal) + { + if (literal.Length <= maxStringLiteralLength) + { + WriteLiteral(literal); + return; + } + + // String is too large, render the string in pieces to avoid Roslyn OOM exceptions at compile time: https://github.com/aspnet/External/issues/54 + var charactersConsumed = 0; + do + { + var charactersRemaining = literal.Length - charactersConsumed; + var charactersToSubstring = Math.Min(maxStringLiteralLength, charactersRemaining); + var lastCharBeforeSplitIndex = charactersConsumed + charactersToSubstring - 1; + var lastCharBeforeSplit = literal[lastCharBeforeSplitIndex]; + + if (char.IsHighSurrogate(lastCharBeforeSplit)) + { + if (charactersRemaining > 1) + { + // Take one less character this iteration. We're attempting to split inbetween a surrogate pair. + // This can happen when something like an emoji sits on the barrier between splits; if we were to + // split the emoji we'd end up with invalid bytes in our output. + charactersToSubstring--; + } + else + { + // The user has an invalid file with a partial surrogate a the splitting point. + // We'll let the invalid character flow but we'll explode later on. + } + } + + var textToRender = literal.Substring(charactersConsumed, charactersToSubstring); + + WriteLiteral(textToRender); + + charactersConsumed += textToRender.Length; + } while (charactersConsumed < literal.Length); + + void WriteLiteral(string content) + { + context.CodeWriter + .WriteStartMethodInvocation(WriteHtmlContentMethod) + .WriteStringLiteral(content) + .WriteEndMethodInvocation(); + } + } + + public override void BeginWriterScope(CodeRenderingContext context, string writer) + { + context.CodeWriter.WriteMethodInvocation(PushWriterMethod, writer); + } + + public override void EndWriterScope(CodeRenderingContext context) + { + context.CodeWriter.WriteMethodInvocation(PopWriterMethod); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/TagHelperHtmlAttributeRuntimeNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/TagHelperHtmlAttributeRuntimeNodeWriter.cs new file mode 100644 index 0000000000..eec5a76575 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/TagHelperHtmlAttributeRuntimeNodeWriter.cs @@ -0,0 +1,10 @@ +// 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.CodeGeneration +{ + internal class TagHelperHtmlAttributeRuntimeNodeWriter : RuntimeNodeWriter + { + public override string WriteAttributeValueMethod { get; set; } = "AddHtmlAttributeValue"; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/TagHelperRenderingContext.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/TagHelperRenderingContext.cs new file mode 100644 index 0000000000..a8cbe5c96c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/TagHelperRenderingContext.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 System; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration +{ + internal class TagHelperRenderingContext + { + private Dictionary _renderedBoundAttributes; + private HashSet _verifiedPropertyDictionaries; + + public Dictionary RenderedBoundAttributes + { + get + { + if (_renderedBoundAttributes == null) + { + _renderedBoundAttributes = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + + return _renderedBoundAttributes; + } + } + + public HashSet VerifiedPropertyDictionaries + { + get + { + if (_verifiedPropertyDictionaries == null) + { + _verifiedPropertyDictionaries = new HashSet(StringComparer.Ordinal); + } + + return _verifiedPropertyDictionaries; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/CodeGenerationConstants.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/CodeGenerationConstants.cs new file mode 100644 index 0000000000..35c176a678 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/CodeGenerationConstants.cs @@ -0,0 +1,27 @@ +// 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.Components +{ + // Constants for method names used in code-generation + // Keep these in sync with the actual definitions + internal static class CodeGenerationConstants + { + public static class RazorComponent + { + public const string FullTypeName = "Microsoft.AspNetCore.Components.Component"; + public const string BuildRenderTree = "BuildRenderTree"; + public const string BuildRenderTreeParameter = "builder"; + } + + public static class RenderTreeBuilder + { + public const string FullTypeName = "Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder"; + } + + public static class InjectDirective + { + public const string FullTypeName = "Microsoft.AspNetCore.Razor.Components.InjectAttribute"; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDocumentClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDocumentClassifierPass.cs new file mode 100644 index 0000000000..29afa982af --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDocumentClassifierPass.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 System.IO; +using System.Text; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Components +{ + internal class ComponentDocumentClassifierPass : DocumentClassifierPassBase + { + public static readonly string ComponentDocumentKind = "component.1.0"; + private static readonly object BuildRenderTreeBaseCallAnnotation = new object(); + private static readonly char[] PathSeparators = new char[] { '/', '\\' }; + private static readonly char[] NamespaceSeparators = new char[] { '.' }; + + protected override string DocumentKind => ComponentDocumentKind; + + // Ensure this runs before the MVC classifiers which have Order = 0 + public override int Order => -100; + + protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + return codeDocument.GetInputDocumentKind() == InputDocumentKind.Component; + } + + protected override void OnDocumentStructureCreated(RazorCodeDocument codeDocument, NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class, MethodDeclarationIntermediateNode method) + { + base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method); + + if (!TryComputeNamespaceAndClass( + codeDocument.Source.FilePath, + codeDocument.Source.RelativePath, + out var computedNamespace, + out var computedClass)) + { + // If we can't compute a nice namespace (no relative path) then just generate something + // mangled. + computedNamespace = "AspNetCore"; + var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum()); + computedClass = $"AspNetCore_{checksum}"; + } + + @namespace.Content = computedNamespace; + + @class.ClassName = computedClass; + @class.BaseType = $"global::{CodeGenerationConstants.RazorComponent.FullTypeName}"; + var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath; + if (string.IsNullOrEmpty(filePath)) + { + // It's possible for a Razor document to not have a file path. + // Eg. When we try to generate code for an in memory document like default imports. + var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum()); + @class.ClassName = $"AspNetCore_{checksum}"; + } + else + { + @class.ClassName = CSharpIdentifier.SanitizeIdentifier(Path.GetFileNameWithoutExtension(filePath)); + } + + @class.Modifiers.Clear(); + @class.Modifiers.Add("public"); + @class.Modifiers.Add("sealed"); + + method.MethodName = CodeGenerationConstants.RazorComponent.BuildRenderTree; + method.ReturnType = "void"; + method.Modifiers.Clear(); + method.Modifiers.Add("public"); + method.Modifiers.Add("override"); + + method.Parameters.Clear(); + method.Parameters.Add(new MethodParameter() + { + TypeName = CodeGenerationConstants.RenderTreeBuilder.FullTypeName, + ParameterName = CodeGenerationConstants.RazorComponent.BuildRenderTreeParameter, + }); + + // We need to call the 'base' method as the first statement. + var callBase = new CSharpCodeIntermediateNode(); + callBase.Annotations.Add(BuildRenderTreeBaseCallAnnotation, true); + callBase.Children.Add(new IntermediateToken + { + Kind = TokenKind.CSharp, + Content = $"base.{CodeGenerationConstants.RazorComponent.BuildRenderTree}({CodeGenerationConstants.RazorComponent.BuildRenderTreeParameter});" + }); + method.Children.Insert(0, callBase); + } + + private bool TryComputeNamespaceAndClass(string filePath, string relativePath, out string @namespace, out string @class) + { + if (filePath == null || relativePath == null || filePath.Length <= relativePath.Length) + { + @namespace = null; + @class = null; + return false; + } + + // Try and infer a namespace from the project directory. We don't yet have the ability to pass + // the namespace through from the project. + var trimLength = relativePath.Length + (relativePath.StartsWith("/") ? 0 : 1); + var baseDirectory = filePath.Substring(0, filePath.Length - trimLength); + + var lastSlash = baseDirectory.LastIndexOfAny(PathSeparators); + var baseNamespace = lastSlash == -1 ? baseDirectory : baseDirectory.Substring(lastSlash + 1); + if (string.IsNullOrEmpty(baseNamespace)) + { + @namespace = null; + @class = null; + return false; + } + + var builder = new StringBuilder(); + + // Sanitize the base namespace, but leave the dots. + var segments = baseNamespace.Split(NamespaceSeparators, StringSplitOptions.RemoveEmptyEntries); + builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[0])); + for (var i = 1; i < segments.Length; i++) + { + builder.Append('.'); + builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[i])); + } + + segments = relativePath.Split(PathSeparators, StringSplitOptions.RemoveEmptyEntries); + + // Skip the last segment because it's the FileName. + for (var i = 0; i < segments.Length - 1; i++) + { + builder.Append('.'); + builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[i])); + } + + @namespace = builder.ToString(); + @class = CSharpIdentifier.SanitizeIdentifier(Path.GetFileNameWithoutExtension(relativePath)); + + return true; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentExtensions.cs new file mode 100644 index 0000000000..6f7a2affa4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentExtensions.cs @@ -0,0 +1,22 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Components +{ + public static class ComponentExtensions + { + public static void Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + FunctionsDirective.Register(builder); + builder.Features.Add(new ComponentDocumentClassifierPass()); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultAllowedChildTagDescriptor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultAllowedChildTagDescriptor.cs new file mode 100644 index 0000000000..28fa3f0b68 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultAllowedChildTagDescriptor.cs @@ -0,0 +1,15 @@ +// 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 +{ + internal class DefaultAllowedChildTagDescriptor : AllowedChildTagDescriptor + { + public DefaultAllowedChildTagDescriptor(string name, string displayName, RazorDiagnostic[] diagnostics) + { + Name = name; + DisplayName = displayName; + Diagnostics = diagnostics; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultAllowedChildTagDescriptorBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultAllowedChildTagDescriptorBuilder.cs new file mode 100644 index 0000000000..b420992e80 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultAllowedChildTagDescriptorBuilder.cs @@ -0,0 +1,77 @@ +// 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 +{ + internal class DefaultAllowedChildTagDescriptorBuilder : AllowedChildTagDescriptorBuilder + { + private readonly DefaultTagHelperDescriptorBuilder _parent; + private RazorDiagnosticCollection _diagnostics; + + public DefaultAllowedChildTagDescriptorBuilder(DefaultTagHelperDescriptorBuilder parent) + { + _parent = parent; + } + + public override string Name { get; set; } + + public override string DisplayName { get; set; } + + public override RazorDiagnosticCollection Diagnostics + { + get + { + if (_diagnostics == null) + { + _diagnostics = new RazorDiagnosticCollection(); + } + + return _diagnostics; + } + } + + public AllowedChildTagDescriptor Build() + { + var validationDiagnostics = Validate(); + var diagnostics = new HashSet(validationDiagnostics); + if (_diagnostics != null) + { + diagnostics.UnionWith(_diagnostics); + } + + var displayName = DisplayName ?? Name; + var descriptor = new DefaultAllowedChildTagDescriptor( + Name, + displayName, + diagnostics?.ToArray() ?? Array.Empty()); + + return descriptor; + } + + private IEnumerable Validate() + { + if (string.IsNullOrWhiteSpace(Name)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChildNullOrWhitespace(_parent.GetDisplayName()); + + yield return diagnostic; + } + else if (Name != TagHelperMatchingConventions.ElementCatchAllName) + { + foreach (var character in Name) + { + if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChild(_parent.GetDisplayName(), Name, character); + + yield return diagnostic; + } + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs new file mode 100644 index 0000000000..597d721a96 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.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.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultBoundAttributeDescriptor : BoundAttributeDescriptor + { + public DefaultBoundAttributeDescriptor( + string kind, + string name, + string typeName, + bool isEnum, + bool hasIndexer, + string indexerNamePrefix, + string indexerTypeName, + string documentation, + string displayName, + Dictionary metadata, + RazorDiagnostic[] diagnostics) + : base(kind) + { + Name = name; + TypeName = typeName; + IsEnum = isEnum; + HasIndexer = hasIndexer; + IndexerNamePrefix = indexerNamePrefix; + IndexerTypeName = indexerTypeName; + Documentation = documentation; + DisplayName = displayName; + + Metadata = metadata; + Diagnostics = diagnostics; + + IsIndexerStringProperty = indexerTypeName == typeof(string).FullName || indexerTypeName == "string"; + IsStringProperty = typeName == typeof(string).FullName || typeName == "string"; + + IsIndexerBooleanProperty = indexerTypeName == typeof(bool).FullName || indexerTypeName == "bool"; + IsBooleanProperty = typeName == typeof(bool).FullName || typeName == "bool"; + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs new file mode 100644 index 0000000000..0652686dd2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs @@ -0,0 +1,209 @@ +// 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 +{ + internal class DefaultBoundAttributeDescriptorBuilder : BoundAttributeDescriptorBuilder + { + private static readonly IReadOnlyDictionary PrimitiveDisplayTypeNameLookups = new Dictionary(StringComparer.Ordinal) + { + [typeof(byte).FullName] = "byte", + [typeof(sbyte).FullName] = "sbyte", + [typeof(int).FullName] = "int", + [typeof(uint).FullName] = "uint", + [typeof(short).FullName] = "short", + [typeof(ushort).FullName] = "ushort", + [typeof(long).FullName] = "long", + [typeof(ulong).FullName] = "ulong", + [typeof(float).FullName] = "float", + [typeof(double).FullName] = "double", + [typeof(char).FullName] = "char", + [typeof(bool).FullName] = "bool", + [typeof(object).FullName] = "object", + [typeof(string).FullName] = "string", + [typeof(decimal).FullName] = "decimal", + }; + + private readonly DefaultTagHelperDescriptorBuilder _parent; + private readonly string _kind; + private readonly Dictionary _metadata; + + private RazorDiagnosticCollection _diagnostics; + + public DefaultBoundAttributeDescriptorBuilder(DefaultTagHelperDescriptorBuilder parent, string kind) + { + _parent = parent; + _kind = kind; + + _metadata = new Dictionary(); + } + + public override string Name { get; set; } + + public override string TypeName { get; set; } + + public override bool IsEnum { get; set; } + + public override bool IsDictionary { get; set; } + + public override string IndexerAttributeNamePrefix { get; set; } + + public override string IndexerValueTypeName { get; set; } + + public override string Documentation { get; set; } + + public override string DisplayName { get; set; } + + public override IDictionary Metadata => _metadata; + + public override RazorDiagnosticCollection Diagnostics + { + get + { + if (_diagnostics == null) + { + _diagnostics = new RazorDiagnosticCollection(); + } + + return _diagnostics; + } + } + + public BoundAttributeDescriptor Build() + { + var validationDiagnostics = Validate(); + var diagnostics = new HashSet(validationDiagnostics); + if (_diagnostics != null) + { + diagnostics.UnionWith(_diagnostics); + } + + var descriptor = new DefaultBoundAttributeDescriptor( + _kind, + Name, + TypeName, + IsEnum, + IsDictionary, + IndexerAttributeNamePrefix, + IndexerValueTypeName, + Documentation, + GetDisplayName(), + new Dictionary(Metadata), + diagnostics.ToArray()); + + return descriptor; + } + + private string GetDisplayName() + { + if (DisplayName != null) + { + return DisplayName; + } + + var parentTypeName = _parent.GetTypeName(); + var propertyName = this.GetPropertyName(); + + if (TypeName != null && + propertyName != null && + parentTypeName != null) + { + // This looks like a normal c# property, so lets compute a display name based on that. + if (!PrimitiveDisplayTypeNameLookups.TryGetValue(TypeName, out var simpleTypeName)) + { + simpleTypeName = TypeName; + } + + return $"{simpleTypeName} {parentTypeName}.{propertyName}"; + } + + return Name; + } + + private IEnumerable Validate() + { + // data-* attributes are explicitly not implemented by user agents and are not intended for use on + // the server; therefore it's invalid for TagHelpers to bind to them. + const string DataDashPrefix = "data-"; + + if (string.IsNullOrWhiteSpace(Name)) + { + if (IndexerAttributeNamePrefix == null) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeNullOrWhitespace( + _parent.GetDisplayName(), + GetDisplayName()); + + yield return diagnostic; + } + } + else + { + if (Name.StartsWith(DataDashPrefix, StringComparison.OrdinalIgnoreCase)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeNameStartsWith( + _parent.GetDisplayName(), + GetDisplayName(), + Name); + + yield return diagnostic; + } + + foreach (var character in Name) + { + if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeName( + _parent.GetDisplayName(), + GetDisplayName(), + Name, + character); + + yield return diagnostic; + } + } + } + + if (IndexerAttributeNamePrefix != null) + { + if (IndexerAttributeNamePrefix.StartsWith(DataDashPrefix, StringComparison.OrdinalIgnoreCase)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributePrefixStartsWith( + _parent.GetDisplayName(), + GetDisplayName(), + IndexerAttributeNamePrefix); + + yield return diagnostic; + } + else if (IndexerAttributeNamePrefix.Length > 0 && string.IsNullOrWhiteSpace(IndexerAttributeNamePrefix)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeNullOrWhitespace( + _parent.GetDisplayName(), + GetDisplayName()); + + yield return diagnostic; + } + else + { + foreach (var character in IndexerAttributeNamePrefix) + { + if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributePrefix( + _parent.GetDisplayName(), + GetDisplayName(), + IndexerAttributeNamePrefix, + character); + + yield return diagnostic; + } + } + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDirectiveSyntaxTreePass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDirectiveSyntaxTreePass.cs new file mode 100644 index 0000000000..65e578b5ce --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDirectiveSyntaxTreePass.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.Linq; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Microsoft.AspNetCore.Razor.Language.Syntax; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultDirectiveSyntaxTreePass : RazorEngineFeatureBase, IRazorSyntaxTreePass + { + public int Order => 75; + + public RazorSyntaxTree Execute(RazorCodeDocument codeDocument, RazorSyntaxTree syntaxTree) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (syntaxTree == null) + { + throw new ArgumentNullException(nameof(syntaxTree)); + } + + var sectionVerifier = new NestedSectionVerifier(syntaxTree); + return sectionVerifier.Verify(); + } + + private class NestedSectionVerifier : SyntaxRewriter + { + private int _nestedLevel; + private RazorSyntaxTree _syntaxTree; + + public NestedSectionVerifier(RazorSyntaxTree syntaxTree) + { + _syntaxTree = syntaxTree; + } + + public RazorSyntaxTree Verify() + { + var root = Visit(_syntaxTree.Root); + var rewrittenTree = new DefaultRazorSyntaxTree(root, _syntaxTree.Source, _syntaxTree.Diagnostics, _syntaxTree.Options); + return rewrittenTree; + } + + public override SyntaxNode VisitRazorDirective(RazorDirectiveSyntax node) + { + if (_nestedLevel > 0) + { + var directiveStart = node.Transition.GetSourceLocation(_syntaxTree.Source); + var errorLength = /* @ */ 1 + SectionDirective.Directive.Directive.Length; + var error = RazorDiagnosticFactory.CreateParsing_SectionsCannotBeNested(new SourceSpan(directiveStart, errorLength)); + node = node.AppendDiagnostic(error); + } + _nestedLevel++; + var result = base.VisitRazorDirective(node); + _nestedLevel--; + + return result; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDocumentClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDocumentClassifierPass.cs new file mode 100644 index 0000000000..860e42a583 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDocumentClassifierPass.cs @@ -0,0 +1,49 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultDocumentClassifierPass : DocumentClassifierPassBase + { + public override int Order => DefaultFeatureOrder; + + protected override string DocumentKind => "default"; + + protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + return true; + } + + protected override void OnDocumentStructureCreated( + RazorCodeDocument codeDocument, + NamespaceDeclarationIntermediateNode @namespace, + ClassDeclarationIntermediateNode @class, + MethodDeclarationIntermediateNode method) + { + var configuration = Engine.Features.OfType().FirstOrDefault(); + if (configuration != null) + { + for (var i = 0; i < configuration.ConfigureClass.Count; i++) + { + var configureClass = configuration.ConfigureClass[i]; + configureClass(codeDocument, @class); + } + + for (var i = 0; i < configuration.ConfigureNamespace.Count; i++) + { + var configureNamespace = configuration.ConfigureNamespace[i]; + configureNamespace(codeDocument, @namespace); + } + + for (var i = 0; i < configuration.ConfigureMethod.Count; i++) + { + var configureMethod = configuration.ConfigureMethod[i]; + configureMethod(codeDocument, @method); + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDocumentClassifierPassFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDocumentClassifierPassFeature.cs new file mode 100644 index 0000000000..278e825de7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultDocumentClassifierPassFeature.cs @@ -0,0 +1,21 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultDocumentClassifierPassFeature : RazorEngineFeatureBase + { + public IList> ConfigureClass { get; } = + new List>(); + + public IList> ConfigureNamespace { get; } = + new List>(); + + public IList> ConfigureMethod { get; } = + new List>(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultImportProjectFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultImportProjectFeature.cs new file mode 100644 index 0000000000..92778322d7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultImportProjectFeature.cs @@ -0,0 +1,13 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultImportProjectFeature : RazorProjectEngineFeatureBase, IImportProjectFeature + { + public IReadOnlyList GetImports(RazorProjectItem projectItem) => Array.Empty(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCSharpDocument.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCSharpDocument.cs new file mode 100644 index 0000000000..cae8cfb69d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCSharpDocument.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 System; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorCSharpDocument : RazorCSharpDocument + { + private readonly string _generatedCode; + private readonly RazorDiagnostic[] _diagnostics; + private readonly SourceMapping[] _sourceMappings; + private readonly RazorCodeGenerationOptions _options; + + public DefaultRazorCSharpDocument( + string generatedCode, + RazorCodeGenerationOptions options, + RazorDiagnostic[] diagnostics, + SourceMapping[] sourceMappings) + { + if (generatedCode == null) + { + throw new ArgumentNullException(nameof(generatedCode)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + _generatedCode = generatedCode; + _options = options; + + _diagnostics = diagnostics ?? Array.Empty(); + _sourceMappings = sourceMappings ?? Array.Empty(); + } + + public override IReadOnlyList Diagnostics => _diagnostics; + + public override string GeneratedCode => _generatedCode; + + public override IReadOnlyList SourceMappings => _sourceMappings; + + public override RazorCodeGenerationOptions Options => _options; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCSharpLoweringPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCSharpLoweringPhase.cs new file mode 100644 index 0000000000..f09c68069a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCSharpLoweringPhase.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 System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorCSharpLoweringPhase : RazorEnginePhaseBase, IRazorCSharpLoweringPhase + { + protected override void ExecuteCore(RazorCodeDocument codeDocument) + { + var documentNode = codeDocument.GetDocumentIntermediateNode(); + ThrowForMissingDocumentDependency(documentNode); + + var target = documentNode.Target; + if (target == null) + { + var message = Resources.FormatDocumentMissingTarget( + documentNode.DocumentKind, + nameof(CodeTarget), + nameof(DocumentIntermediateNode.Target)); + throw new InvalidOperationException(message); + } + + var writer = DocumentWriter.CreateDefault(documentNode.Target, documentNode.Options); + var cSharpDocument = writer.WriteDocument(codeDocument, documentNode); + codeDocument.SetCSharpDocument(cSharpDocument); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeDocument.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeDocument.cs new file mode 100644 index 0000000000..bceb14cbda --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeDocument.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 System.Collections.Generic; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorCodeDocument : RazorCodeDocument + { + public DefaultRazorCodeDocument( + RazorSourceDocument source, + IEnumerable imports) + { + if (source == null) + { + throw new ArgumentNullException(nameof(source)); + } + + Source = source; + Imports = imports?.ToArray() ?? RazorSourceDocument.EmptyArray; + + Items = new ItemCollection(); + } + + public override IReadOnlyList Imports { get; } + + public override ItemCollection Items { get; } + + public override RazorSourceDocument Source { get; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptions.cs new file mode 100644 index 0000000000..6b694d9382 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptions.cs @@ -0,0 +1,32 @@ +// 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 +{ + internal class DefaultRazorCodeGenerationOptions : RazorCodeGenerationOptions + { + public DefaultRazorCodeGenerationOptions( + bool indentWithTabs, + int indentSize, + bool designTime, + bool suppressChecksum, + bool supressMetadataAttributes, + bool suppressPrimaryMethodBody) + { + IndentWithTabs = indentWithTabs; + IndentSize = indentSize; + DesignTime = designTime; + SuppressChecksum = suppressChecksum; + SuppressMetadataAttributes = supressMetadataAttributes; + SuppressPrimaryMethodBody = suppressPrimaryMethodBody; + } + + public override bool DesignTime { get; } + + public override bool IndentWithTabs { get; } + + public override int IndentSize { get; } + + public override bool SuppressChecksum { get; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs new file mode 100644 index 0000000000..7507ac0fee --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.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 System; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorCodeGenerationOptionsBuilder : RazorCodeGenerationOptionsBuilder + { + private bool _designTime; + + public DefaultRazorCodeGenerationOptionsBuilder(RazorConfiguration configuration) + { + if (configuration == null) + { + throw new ArgumentNullException(nameof(configuration)); + } + } + + public DefaultRazorCodeGenerationOptionsBuilder(bool designTime) + { + _designTime = designTime; + } + + public override RazorConfiguration Configuration { get; } + + public override bool DesignTime => _designTime; + + public override int IndentSize { get; set; } = 4; + + public override bool IndentWithTabs { get; set; } + + public override bool SuppressChecksum { get; set; } + + public override RazorCodeGenerationOptions Build() + { + return new DefaultRazorCodeGenerationOptions( + IndentWithTabs, + IndentSize, + DesignTime, + SuppressChecksum, + SuppressMetadataAttributes, + SuppressPrimaryMethodBody); + } + + public override void SetDesignTime(bool designTime) + { + _designTime = designTime; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsFactoryProjectFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsFactoryProjectFeature.cs new file mode 100644 index 0000000000..db2a25b81f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsFactoryProjectFeature.cs @@ -0,0 +1,32 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorCodeGenerationOptionsFactoryProjectFeature : RazorProjectEngineFeatureBase, IRazorCodeGenerationOptionsFactoryProjectFeature + { + private IConfigureRazorCodeGenerationOptionsFeature[] _configureOptions; + + protected override void OnInitialized() + { + _configureOptions = ProjectEngine.EngineFeatures.OfType().ToArray(); + } + + public RazorCodeGenerationOptions Create(Action configure) + { + var builder = new DefaultRazorCodeGenerationOptionsBuilder(ProjectEngine.Configuration); + configure?.Invoke(builder); + + for (var i = 0; i < _configureOptions.Length; i++) + { + _configureOptions[i].Configure(builder); + } + + var options = builder.Build(); + return options; + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsFeature.cs new file mode 100644 index 0000000000..1c915364d7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsFeature.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 System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ +#pragma warning disable CS0618 // Type or member is obsolete + internal class DefaultRazorCodeGenerationOptionsFeature : RazorEngineFeatureBase, IRazorCodeGenerationOptionsFeature +#pragma warning restore CS0618 // Type or member is obsolete + { + private readonly bool _designTime; + private IConfigureRazorCodeGenerationOptionsFeature[] _configureOptions; + + public DefaultRazorCodeGenerationOptionsFeature(bool designTime) + { + _designTime = designTime; + } + + protected override void OnInitialized() + { + _configureOptions = Engine.Features.OfType().ToArray(); + } + + public RazorCodeGenerationOptions GetOptions() + { + return _designTime ? RazorCodeGenerationOptions.CreateDesignTime(ConfigureOptions) : RazorCodeGenerationOptions.Create(ConfigureOptions); + } + + private void ConfigureOptions(RazorCodeGenerationOptionsBuilder builder) + { + for (var i = 0; i < _configureOptions.Length; i++) + { + _configureOptions[i].Configure(builder); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDiagnostic.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDiagnostic.cs new file mode 100644 index 0000000000..40f558df26 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDiagnostic.cs @@ -0,0 +1,84 @@ +// 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.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorDiagnostic : RazorDiagnostic + { + internal DefaultRazorDiagnostic(RazorDiagnosticDescriptor descriptor, SourceSpan span, object[] args) + { + Descriptor = descriptor; + Span = span; + Args = args; + } + + public override string Id => Descriptor.Id; + + public override RazorDiagnosticSeverity Severity => Descriptor.Severity; + + public override SourceSpan Span { get; } + + // Internal for testing + internal RazorDiagnosticDescriptor Descriptor { get; } + + // Internal for testing + internal object[] Args { get; } + + public override string GetMessage(IFormatProvider formatProvider) + { + var format = Descriptor.GetMessageFormat(); + return string.Format(formatProvider, format, Args); + } + + public override bool Equals(RazorDiagnostic obj) + { + var other = obj as DefaultRazorDiagnostic; + if (other == null) + { + return false; + } + + if (!Descriptor.Equals(other.Descriptor)) + { + return false; + } + + if (!Span.Equals(other.Span)) + { + return false; + } + + if (Args.Length != other.Args.Length) + { + return false; + } + + for (var i = 0; i < Args.Length; i++) + { + if (!Args[i].Equals(other.Args[i])) + { + return false; + } + } + + return true; + } + + public override int GetHashCode() + { + var hash = new HashCodeCombiner(); + hash.Add(Descriptor.GetHashCode()); + hash.Add(Span.GetHashCode()); + + for (var i = 0; i < Args.Length; i++) + { + hash.Add(Args[i]); + } + + return hash; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDirectiveClassifierPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDirectiveClassifierPhase.cs new file mode 100644 index 0000000000..155bf88455 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDirectiveClassifierPhase.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. + +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorDirectiveClassifierPhase : RazorEnginePhaseBase, IRazorDirectiveClassifierPhase + { + public IRazorDirectiveClassifierPass[] Passes { get; private set; } + + protected override void OnIntialized() + { + Passes = Engine.Features.OfType().OrderBy(p => p.Order).ToArray(); + } + + protected override void ExecuteCore(RazorCodeDocument codeDocument) + { + var irDocument = codeDocument.GetDocumentIntermediateNode(); + ThrowForMissingDocumentDependency(irDocument); + + foreach (var pass in Passes) + { + pass.Execute(codeDocument, irDocument); + } + + codeDocument.SetDocumentIntermediateNode(irDocument); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDirectiveFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDirectiveFeature.cs new file mode 100644 index 0000000000..9738743079 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDirectiveFeature.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. + +using System; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorDirectiveFeature : RazorEngineFeatureBase, IRazorDirectiveFeature, IConfigureRazorParserOptionsFeature + { + public ICollection Directives { get; } = new List(); + + public int Order => 100; + + void IConfigureRazorParserOptionsFeature.Configure(RazorParserOptionsBuilder options) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + options.Directives.Clear(); + + foreach (var directive in Directives) + { + options.Directives.Add(directive); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDocumentClassifierPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDocumentClassifierPhase.cs new file mode 100644 index 0000000000..8a41520dec --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDocumentClassifierPhase.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. + +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorDocumentClassifierPhase : RazorEnginePhaseBase, IRazorDocumentClassifierPhase + { + public IRazorDocumentClassifierPass[] Passes { get; private set; } + + protected override void OnIntialized() + { + Passes = Engine.Features.OfType().OrderBy(p => p.Order).ToArray(); + } + + protected override void ExecuteCore(RazorCodeDocument codeDocument) + { + var irDocument = codeDocument.GetDocumentIntermediateNode(); + ThrowForMissingDocumentDependency(irDocument); + + foreach (var pass in Passes) + { + pass.Execute(codeDocument, irDocument); + } + + codeDocument.SetDocumentIntermediateNode(irDocument); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorEngine.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorEngine.cs new file mode 100644 index 0000000000..27f22e01e3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorEngine.cs @@ -0,0 +1,55 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorEngine : RazorEngine + { + public DefaultRazorEngine(IRazorEngineFeature[] features, IRazorEnginePhase[] phases) + { + if (features == null) + { + throw new ArgumentNullException(nameof(features)); + } + + if (phases == null) + { + throw new ArgumentNullException(nameof(phases)); + } + + Features = features; + Phases = phases; + + for (var i = 0; i < features.Length; i++) + { + features[i].Engine = this; + } + + for (var i = 0; i < phases.Length; i++) + { + phases[i].Engine = this; + } + } + + public override IReadOnlyList Features { get; } + + public override IReadOnlyList Phases { get; } + + public override void Process(RazorCodeDocument document) + { + if (document == null) + { + throw new ArgumentNullException(nameof(document)); + } + + for (var i = 0; i < Phases.Count; i++) + { + var phase = Phases[i]; + phase.Execute(document); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorEngineBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorEngineBuilder.cs new file mode 100644 index 0000000000..50b3f1a6d2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorEngineBuilder.cs @@ -0,0 +1,37 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ +#pragma warning disable CS0618 // Type or member is obsolete + internal class DefaultRazorEngineBuilder : IRazorEngineBuilder +#pragma warning restore CS0618 // Type or member is obsolete + { + public DefaultRazorEngineBuilder(bool designTime) + { + DesignTime = designTime; + Features = new List(); + Phases = new List(); + } + + public ICollection Features { get; } + + public IList Phases { get; } + + public bool DesignTime { get; } + + public RazorEngine Build() + { + var features = new IRazorEngineFeature[Features.Count]; + Features.CopyTo(features, arrayIndex: 0); + + var phases = new IRazorEnginePhase[Phases.Count]; + Phases.CopyTo(phases, arrayIndex: 0); + + return new DefaultRazorEngine(features, phases); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs new file mode 100644 index 0000000000..07e1ad44c8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs @@ -0,0 +1,1118 @@ +// 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.Diagnostics; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Microsoft.AspNetCore.Razor.Language.Syntax; + +namespace Microsoft.AspNetCore.Razor.Language +{ +#pragma warning disable CS0618 // Type or member is obsolete + internal class DefaultRazorIntermediateNodeLoweringPhase : RazorEnginePhaseBase, IRazorIntermediateNodeLoweringPhase + { + private IRazorCodeGenerationOptionsFeature _optionsFeature; + + protected override void OnIntialized() + { + _optionsFeature = GetRequiredFeature(); + } + + protected override void ExecuteCore(RazorCodeDocument codeDocument) + { + var syntaxTree = codeDocument.GetSyntaxTree(); + ThrowForMissingDocumentDependency(syntaxTree); + + // This might not have been set if there are no tag helpers. + var tagHelperContext = codeDocument.GetTagHelperContext(); + + var document = new DocumentIntermediateNode(); + var builder = IntermediateNodeBuilder.Create(document); + + document.Options = codeDocument.GetCodeGenerationOptions() ?? _optionsFeature.GetOptions(); + + IReadOnlyList importedUsings = Array.Empty(); + + // The import documents should be inserted logically before the main document. + var imports = codeDocument.GetImportSyntaxTrees(); + if (imports != null) + { + var importsVisitor = new ImportsVisitor(document, builder, syntaxTree.Options.FeatureFlags); + + for (var j = 0; j < imports.Count; j++) + { + var import = imports[j]; + + importsVisitor.SourceDocument = import.Source; + importsVisitor.Visit(import.Root); + } + + importedUsings = importsVisitor.Usings; + } + + var tagHelperPrefix = tagHelperContext?.Prefix; + var visitor = new MainSourceVisitor(document, builder, tagHelperPrefix, syntaxTree.Options.FeatureFlags) + { + SourceDocument = syntaxTree.Source, + }; + + visitor.Visit(syntaxTree.Root); + + // 1. Prioritize non-imported usings over imported ones. + // 2. Don't import usings that already exist in primary document. + // 3. Allow duplicate usings in primary document (C# warning). + var usingReferences = new List(visitor.Usings); + for (var j = importedUsings.Count - 1; j >= 0; j--) + { + if (!usingReferences.Contains(importedUsings[j])) + { + usingReferences.Insert(0, importedUsings[j]); + } + } + + // In each lowering piece above, namespaces were tracked. We render them here to ensure every + // lowering action has a chance to add a source location to a namespace. Ultimately, closest wins. + + var i = 0; + foreach (var reference in usingReferences) + { + var @using = new UsingDirectiveIntermediateNode() + { + Content = reference.Namespace, + Source = reference.Source, + }; + + builder.Insert(i++, @using); + } + + ImportDirectives(document); + + // The document should contain all errors that currently exist in the system. This involves + // adding the errors from the primary and imported syntax trees. + for (i = 0; i < syntaxTree.Diagnostics.Count; i++) + { + document.Diagnostics.Add(syntaxTree.Diagnostics[i]); + } + + if (imports != null) + { + for (i = 0; i < imports.Count; i++) + { + var import = imports[i]; + for (var j = 0; j < import.Diagnostics.Count; j++) + { + document.Diagnostics.Add(import.Diagnostics[j]); + } + } + } + + codeDocument.SetDocumentIntermediateNode(document); + } + + private void ImportDirectives(DocumentIntermediateNode document) + { + var visitor = new DirectiveVisitor(); + visitor.VisitDocument(document); + + var seenDirectives = new HashSet(); + for (var i = visitor.Directives.Count - 1; i >= 0; i--) + { + var reference = visitor.Directives[i]; + var directive = (DirectiveIntermediateNode)reference.Node; + var descriptor = directive.Directive; + var seenDirective = !seenDirectives.Add(descriptor); + + if (!directive.IsImported()) + { + continue; + } + + switch (descriptor.Kind) + { + case DirectiveKind.SingleLine: + if (seenDirective && descriptor.Usage == DirectiveUsage.FileScopedSinglyOccurring) + { + // This directive has been overridden, it should be removed from the document. + + break; + } + + continue; + case DirectiveKind.RazorBlock: + case DirectiveKind.CodeBlock: + if (descriptor.Usage == DirectiveUsage.FileScopedSinglyOccurring) + { + // A block directive cannot be imported. + + document.Diagnostics.Add( + RazorDiagnosticFactory.CreateDirective_BlockDirectiveCannotBeImported(descriptor.Directive)); + } + break; + default: + throw new InvalidOperationException(Resources.FormatUnexpectedDirectiveKind(typeof(DirectiveKind).FullName)); + } + + // Overridden and invalid imported directives make it to here. They should be removed from the document. + + reference.Remove(); + } + } + + private struct UsingReference : IEquatable + { + public UsingReference(string @namespace, SourceSpan? source) + { + Namespace = @namespace; + Source = source; + } + public string Namespace { get; } + + public SourceSpan? Source { get; } + + public override bool Equals(object other) + { + if (other is UsingReference reference) + { + return Equals(reference); + } + + return false; + } + public bool Equals(UsingReference other) + { + return string.Equals(Namespace, other.Namespace, StringComparison.Ordinal); + } + + public override int GetHashCode() => Namespace.GetHashCode(); + } + + private class LoweringVisitor : SyntaxWalker + { + protected readonly IntermediateNodeBuilder _builder; + protected readonly DocumentIntermediateNode _document; + protected readonly List _usings; + protected readonly RazorParserFeatureFlags _featureFlags; + + public LoweringVisitor(DocumentIntermediateNode document, IntermediateNodeBuilder builder, RazorParserFeatureFlags featureFlags) + { + _document = document; + _builder = builder; + _usings = new List(); + _featureFlags = featureFlags; + } + + public IReadOnlyList Usings => _usings; + + public RazorSourceDocument SourceDocument { get; set; } + + public override void VisitRazorDirective(RazorDirectiveSyntax node) + { + IntermediateNode directiveNode; + var descriptor = node.DirectiveDescriptor; + + if (descriptor != null) + { + var diagnostics = node.GetDiagnostics(); + + // This is an extensible directive. + if (IsMalformed(diagnostics)) + { + directiveNode = new MalformedDirectiveIntermediateNode() + { + DirectiveName = descriptor.Directive, + Directive = descriptor, + Source = BuildSourceSpanFromNode(node), + }; + } + else + { + directiveNode = new DirectiveIntermediateNode() + { + DirectiveName = descriptor.Directive, + Directive = descriptor, + Source = BuildSourceSpanFromNode(node), + }; + } + + for (var i = 0; i < diagnostics.Length; i++) + { + directiveNode.Diagnostics.Add(diagnostics[i]); + } + + _builder.Push(directiveNode); + } + + Visit(node.Body); + + if (descriptor != null) + { + _builder.Pop(); + } + } + + public override void VisitCSharpStatementLiteral(CSharpStatementLiteralSyntax node) + { + var context = node.GetSpanContext(); + if (context == null) + { + base.VisitCSharpStatementLiteral(node); + return; + } + else if (context.ChunkGenerator is DirectiveTokenChunkGenerator tokenChunkGenerator) + { + _builder.Add(new DirectiveTokenIntermediateNode() + { + Content = node.GetContent(), + DirectiveToken = tokenChunkGenerator.Descriptor, + Source = BuildSourceSpanFromNode(node), + }); + } + else if (context.ChunkGenerator is AddImportChunkGenerator importChunkGenerator) + { + var namespaceImport = importChunkGenerator.Namespace.Trim(); + var namespaceSpan = BuildSourceSpanFromNode(node); + _usings.Add(new UsingReference(namespaceImport, namespaceSpan)); + } + else if (context.ChunkGenerator is AddTagHelperChunkGenerator addTagHelperChunkGenerator) + { + IntermediateNode directiveNode; + if (IsMalformed(addTagHelperChunkGenerator.Diagnostics)) + { + directiveNode = new MalformedDirectiveIntermediateNode() + { + DirectiveName = CSharpCodeParser.AddTagHelperDirectiveDescriptor.Directive, + Directive = CSharpCodeParser.AddTagHelperDirectiveDescriptor, + Source = BuildSourceSpanFromNode(node), + }; + } + else + { + directiveNode = new DirectiveIntermediateNode() + { + DirectiveName = CSharpCodeParser.AddTagHelperDirectiveDescriptor.Directive, + Directive = CSharpCodeParser.AddTagHelperDirectiveDescriptor, + Source = BuildSourceSpanFromNode(node), + }; + } + + for (var i = 0; i < addTagHelperChunkGenerator.Diagnostics.Count; i++) + { + directiveNode.Diagnostics.Add(addTagHelperChunkGenerator.Diagnostics[i]); + } + + _builder.Push(directiveNode); + + _builder.Add(new DirectiveTokenIntermediateNode() + { + Content = addTagHelperChunkGenerator.LookupText, + DirectiveToken = CSharpCodeParser.AddTagHelperDirectiveDescriptor.Tokens.First(), + Source = BuildSourceSpanFromNode(node), + }); + + _builder.Pop(); + } + else if (context.ChunkGenerator is RemoveTagHelperChunkGenerator removeTagHelperChunkGenerator) + { + IntermediateNode directiveNode; + if (IsMalformed(removeTagHelperChunkGenerator.Diagnostics)) + { + directiveNode = new MalformedDirectiveIntermediateNode() + { + DirectiveName = CSharpCodeParser.RemoveTagHelperDirectiveDescriptor.Directive, + Directive = CSharpCodeParser.RemoveTagHelperDirectiveDescriptor, + Source = BuildSourceSpanFromNode(node), + }; + } + else + { + directiveNode = new DirectiveIntermediateNode() + { + DirectiveName = CSharpCodeParser.RemoveTagHelperDirectiveDescriptor.Directive, + Directive = CSharpCodeParser.RemoveTagHelperDirectiveDescriptor, + Source = BuildSourceSpanFromNode(node), + }; + } + + for (var i = 0; i < removeTagHelperChunkGenerator.Diagnostics.Count; i++) + { + directiveNode.Diagnostics.Add(removeTagHelperChunkGenerator.Diagnostics[i]); + } + + _builder.Push(directiveNode); + + _builder.Add(new DirectiveTokenIntermediateNode() + { + Content = removeTagHelperChunkGenerator.LookupText, + DirectiveToken = CSharpCodeParser.RemoveTagHelperDirectiveDescriptor.Tokens.First(), + Source = BuildSourceSpanFromNode(node), + }); + + _builder.Pop(); + } + else if (context.ChunkGenerator is TagHelperPrefixDirectiveChunkGenerator tagHelperPrefixChunkGenerator) + { + IntermediateNode directiveNode; + if (IsMalformed(tagHelperPrefixChunkGenerator.Diagnostics)) + { + directiveNode = new MalformedDirectiveIntermediateNode() + { + DirectiveName = CSharpCodeParser.TagHelperPrefixDirectiveDescriptor.Directive, + Directive = CSharpCodeParser.TagHelperPrefixDirectiveDescriptor, + Source = BuildSourceSpanFromNode(node), + }; + } + else + { + directiveNode = new DirectiveIntermediateNode() + { + DirectiveName = CSharpCodeParser.TagHelperPrefixDirectiveDescriptor.Directive, + Directive = CSharpCodeParser.TagHelperPrefixDirectiveDescriptor, + Source = BuildSourceSpanFromNode(node), + }; + } + + for (var i = 0; i < tagHelperPrefixChunkGenerator.Diagnostics.Count; i++) + { + directiveNode.Diagnostics.Add(tagHelperPrefixChunkGenerator.Diagnostics[i]); + } + + _builder.Push(directiveNode); + + _builder.Add(new DirectiveTokenIntermediateNode() + { + Content = tagHelperPrefixChunkGenerator.Prefix, + DirectiveToken = CSharpCodeParser.TagHelperPrefixDirectiveDescriptor.Tokens.First(), + Source = BuildSourceSpanFromNode(node), + }); + + _builder.Pop(); + } + + base.VisitCSharpStatementLiteral(node); + } + + protected SourceSpan? BuildSourceSpanFromNode(SyntaxNode node) + { + if (node == null) + { + return null; + } + + return node.GetSourceSpan(SourceDocument); + } + } + + private class MainSourceVisitor : LoweringVisitor + { + private readonly HashSet _renderedBoundAttributeNames = new HashSet(StringComparer.OrdinalIgnoreCase); + private readonly string _tagHelperPrefix; + + public MainSourceVisitor(DocumentIntermediateNode document, IntermediateNodeBuilder builder, string tagHelperPrefix, RazorParserFeatureFlags featureFlags) + : base(document, builder, featureFlags) + { + _tagHelperPrefix = tagHelperPrefix; + } + + // Example + // + // Name=checked + // Prefix= checked=" + // Suffix=" + public override void VisitMarkupAttributeBlock(MarkupAttributeBlockSyntax node) + { + var prefixTokens = MergeLiterals( + node.NamePrefix?.LiteralTokens, + node.Name.LiteralTokens, + node.NameSuffix?.LiteralTokens, + node.EqualsToken == null ? new SyntaxList() : new SyntaxList(node.EqualsToken), + node.ValuePrefix?.LiteralTokens); + var prefix = (MarkupTextLiteralSyntax)SyntaxFactory.MarkupTextLiteral(prefixTokens).Green.CreateRed(node, node.NamePrefix?.Position ?? node.Name.Position); + + var name = node.Name.GetContent(); + if (name.StartsWith("data-", StringComparison.OrdinalIgnoreCase) && + !_featureFlags.EXPERIMENTAL_AllowConditionalDataDashAttributes) + { + Visit(prefix); + Visit(node.Value); + Visit(node.ValueSuffix); + } + else + { + if (node.Value != null && node.Value.ChildNodes().All(c => c is MarkupLiteralAttributeValueSyntax)) + { + // We need to do what ConditionalAttributeCollapser used to do. + var literalAttributeValueNodes = node.Value.ChildNodes().Cast().ToArray(); + var valueTokens = SyntaxListBuilder.Create(); + for (var i = 0; i < literalAttributeValueNodes.Length; i++) + { + var mergedValue = MergeAttributeValue(literalAttributeValueNodes[i]); + valueTokens.AddRange(mergedValue.LiteralTokens); + } + var rewritten = SyntaxFactory.MarkupTextLiteral(valueTokens.ToList()); + + var mergedLiterals = MergeLiterals(prefix?.LiteralTokens, rewritten.LiteralTokens, node.ValueSuffix?.LiteralTokens); + var mergedAttribute = SyntaxFactory.MarkupTextLiteral(mergedLiterals).Green.CreateRed(node.Parent, node.Position); + Visit(mergedAttribute); + } + else + { + _builder.Push(new HtmlAttributeIntermediateNode() + { + AttributeName = node.Name.GetContent(), + Prefix = prefix.GetContent(), + Suffix = node.ValueSuffix?.GetContent() ?? string.Empty, + Source = BuildSourceSpanFromNode(node), + }); + + VisitAttributeValue(node.Value); + + _builder.Pop(); + } + } + } + + public override void VisitMarkupMinimizedAttributeBlock(MarkupMinimizedAttributeBlockSyntax node) + { + var name = node.Name.GetContent(); + if (name.StartsWith("data-", StringComparison.OrdinalIgnoreCase) && + !_featureFlags.EXPERIMENTAL_AllowConditionalDataDashAttributes) + { + base.VisitMarkupMinimizedAttributeBlock(node); + return; + } + + // Minimized attributes are just html content. + var literals = MergeLiterals( + node.NamePrefix?.LiteralTokens, + node.Name?.LiteralTokens); + var literal = SyntaxFactory.MarkupTextLiteral(literals).Green.CreateRed(node.Parent, node.Position); + + Visit(literal); + } + + // Example + // + // Prefix= (space) + // Children will contain a token for @false. + public override void VisitMarkupDynamicAttributeValue(MarkupDynamicAttributeValueSyntax node) + { + var containsExpression = false; + var descendantNodes = node.DescendantNodes(n => + { + // Don't go into sub block. They may contain expressions but we only care about the top level. + return !(n.Parent is CSharpCodeBlockSyntax); + }); + foreach (var child in descendantNodes) + { + if (child is CSharpImplicitExpressionSyntax || child is CSharpExplicitExpressionSyntax) + { + containsExpression = true; + } + } + + if (containsExpression) + { + _builder.Push(new CSharpExpressionAttributeValueIntermediateNode() + { + Prefix = node.Prefix?.GetContent() ?? string.Empty, + Source = BuildSourceSpanFromNode(node), + }); + } + else + { + _builder.Push(new CSharpCodeAttributeValueIntermediateNode() + { + Prefix = node.Prefix?.GetContent() ?? string.Empty, + Source = BuildSourceSpanFromNode(node), + }); + } + + Visit(node.Value); + + _builder.Pop(); + } + + public override void VisitMarkupLiteralAttributeValue(MarkupLiteralAttributeValueSyntax node) + { + _builder.Push(new HtmlAttributeValueIntermediateNode() + { + Prefix = node.Prefix?.GetContent() ?? string.Empty, + Source = BuildSourceSpanFromNode(node), + }); + + _builder.Add(new IntermediateToken() + { + Content = node.Value?.GetContent() ?? string.Empty, + Kind = TokenKind.Html, + Source = BuildSourceSpanFromNode(node.Value) + }); + + _builder.Pop(); + } + + public override void VisitCSharpTemplateBlock(CSharpTemplateBlockSyntax node) + { + var templateNode = new TemplateIntermediateNode(); + _builder.Push(templateNode); + + base.VisitCSharpTemplateBlock(node); + + _builder.Pop(); + + if (templateNode.Children.Count > 0) + { + var sourceRangeStart = templateNode + .Children + .FirstOrDefault(child => child.Source != null) + ?.Source; + + if (sourceRangeStart != null) + { + var contentLength = templateNode.Children.Sum(child => child.Source?.Length ?? 0); + + templateNode.Source = new SourceSpan( + sourceRangeStart.Value.FilePath ?? SourceDocument.FilePath, + sourceRangeStart.Value.AbsoluteIndex, + sourceRangeStart.Value.LineIndex, + sourceRangeStart.Value.CharacterIndex, + contentLength); + } + } + } + + // CSharp expressions are broken up into blocks and spans because Razor allows Razor comments + // inside an expression. + // Ex: + // @DateTime.@*This is a comment*@Now + // + // We need to capture this in the IR so that we can give each piece the correct source mappings + public override void VisitCSharpExplicitExpression(CSharpExplicitExpressionSyntax node) + { + if (_builder.Current is CSharpExpressionAttributeValueIntermediateNode) + { + base.VisitCSharpExplicitExpression(node); + return; + } + + var expressionNode = new CSharpExpressionIntermediateNode(); + + _builder.Push(expressionNode); + + base.VisitCSharpExplicitExpression(node); + + _builder.Pop(); + + if (expressionNode.Children.Count > 0) + { + var sourceRangeStart = expressionNode + .Children + .FirstOrDefault(child => child.Source != null) + ?.Source; + + if (sourceRangeStart != null) + { + var contentLength = expressionNode.Children.Sum(child => child.Source?.Length ?? 0); + + expressionNode.Source = new SourceSpan( + sourceRangeStart.Value.FilePath ?? SourceDocument.FilePath, + sourceRangeStart.Value.AbsoluteIndex, + sourceRangeStart.Value.LineIndex, + sourceRangeStart.Value.CharacterIndex, + contentLength); + } + } + } + + public override void VisitCSharpImplicitExpression(CSharpImplicitExpressionSyntax node) + { + if (_builder.Current is CSharpExpressionAttributeValueIntermediateNode) + { + base.VisitCSharpImplicitExpression(node); + return; + } + + var expressionNode = new CSharpExpressionIntermediateNode(); + + _builder.Push(expressionNode); + + base.VisitCSharpImplicitExpression(node); + + _builder.Pop(); + + if (expressionNode.Children.Count > 0) + { + var sourceRangeStart = expressionNode + .Children + .FirstOrDefault(child => child.Source != null) + ?.Source; + + if (sourceRangeStart != null) + { + var contentLength = expressionNode.Children.Sum(child => child.Source?.Length ?? 0); + + expressionNode.Source = new SourceSpan( + sourceRangeStart.Value.FilePath ?? SourceDocument.FilePath, + sourceRangeStart.Value.AbsoluteIndex, + sourceRangeStart.Value.LineIndex, + sourceRangeStart.Value.CharacterIndex, + contentLength); + } + } + } + + public override void VisitCSharpExpressionLiteral(CSharpExpressionLiteralSyntax node) + { + if (_builder.Current is TagHelperHtmlAttributeIntermediateNode) + { + // If we are top level in a tag helper HTML attribute, we want to be rendered as markup. + // This case happens for duplicate non-string bound attributes. They would be initially be categorized as + // CSharp but since they are duplicate, they should just be markup. + var markupLiteral = SyntaxFactory.MarkupTextLiteral(node.LiteralTokens).Green.CreateRed(node.Parent, node.Position); + Visit(markupLiteral); + return; + } + + _builder.Add(new IntermediateToken() + { + Content = node.GetContent(), + Kind = TokenKind.CSharp, + Source = BuildSourceSpanFromNode(node), + }); + + base.VisitCSharpExpressionLiteral(node); + } + + public override void VisitCSharpStatementLiteral(CSharpStatementLiteralSyntax node) + { + var context = node.GetSpanContext(); + if (context == null || context.ChunkGenerator is StatementChunkGenerator) + { + var isAttributeValue = _builder.Current is CSharpCodeAttributeValueIntermediateNode; + + if (!isAttributeValue) + { + var statementNode = new CSharpCodeIntermediateNode() + { + Source = BuildSourceSpanFromNode(node) + }; + _builder.Push(statementNode); + } + + _builder.Add(new IntermediateToken() + { + Content = node.GetContent(), + Kind = TokenKind.CSharp, + Source = BuildSourceSpanFromNode(node), + }); + + if (!isAttributeValue) + { + _builder.Pop(); + } + } + + base.VisitCSharpStatementLiteral(node); + } + + public override void VisitMarkupTextLiteral(MarkupTextLiteralSyntax node) + { + var context = node.GetSpanContext(); + if (context != null && context.ChunkGenerator == SpanChunkGenerator.Null) + { + base.VisitMarkupTextLiteral(node); + return; + } + + if (node.LiteralTokens.Count == 1) + { + var token = node.LiteralTokens[0]; + if (token != null && + token.Kind == SyntaxKind.Marker && + token.Content.Length == 0) + { + // We don't want to create IR nodes for marker tokens. + base.VisitMarkupTextLiteral(node); + return; + } + } + + var source = BuildSourceSpanFromNode(node); + var currentChildren = _builder.Current.Children; + if (currentChildren.Count > 0 && currentChildren[currentChildren.Count - 1] is HtmlContentIntermediateNode) + { + var existingHtmlContent = (HtmlContentIntermediateNode)currentChildren[currentChildren.Count - 1]; + + if (existingHtmlContent.Source == null && source == null) + { + Combine(existingHtmlContent, node); + base.VisitMarkupTextLiteral(node); + return; + } + + if (source != null && + existingHtmlContent.Source != null && + existingHtmlContent.Source.Value.FilePath == source.Value.FilePath && + existingHtmlContent.Source.Value.AbsoluteIndex + existingHtmlContent.Source.Value.Length == source.Value.AbsoluteIndex) + { + Combine(existingHtmlContent, node); + base.VisitMarkupTextLiteral(node); + return; + } + } + + var contentNode = new HtmlContentIntermediateNode() + { + Source = source + }; + _builder.Push(contentNode); + + _builder.Add(new IntermediateToken() + { + Content = node.GetContent(), + Kind = TokenKind.Html, + Source = source, + }); + + _builder.Pop(); + + base.VisitMarkupTextLiteral(node); + } + + public override void VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node) + { + var info = node.TagHelperInfo; + var tagName = info.TagName; + if (_tagHelperPrefix != null) + { + tagName = tagName.Substring(_tagHelperPrefix.Length); + } + + var tagHelperNode = new TagHelperIntermediateNode() + { + TagName = tagName, + TagMode = info.TagMode, + Source = BuildSourceSpanFromNode(node) + }; + + foreach (var tagHelper in info.BindingResult.Descriptors) + { + tagHelperNode.TagHelpers.Add(tagHelper); + } + + _builder.Push(tagHelperNode); + + _builder.Push(new TagHelperBodyIntermediateNode()); + + foreach (var item in node.Body) + { + Visit(item); + } + + _builder.Pop(); // Pop InitializeTagHelperStructureIntermediateNode + + Visit(node.StartTag); + + _builder.Pop(); // Pop TagHelperIntermediateNode + + // No need to visit the end tag because we don't write any IR for it. + + // We don't want to track attributes from a previous tag helper element. + _renderedBoundAttributeNames.Clear(); + } + + public override void VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node) + { + foreach (var child in node.Children) + { + if (child is MarkupTagHelperAttributeSyntax || child is MarkupMinimizedTagHelperAttributeSyntax) + { + Visit(child); + } + } + } + + public override void VisitMarkupMinimizedTagHelperAttribute(MarkupMinimizedTagHelperAttributeSyntax node) + { + if (!_featureFlags.AllowMinimizedBooleanTagHelperAttributes) + { + // Minimized attributes are not valid for non-boolean bound attributes. TagHelperBlockRewriter + // has already logged an error if it was a non-boolean bound attribute; so we can skip. + return; + } + + var element = node.FirstAncestorOrSelf(); + var descriptors = element.TagHelperInfo.BindingResult.Descriptors; + var attributeName = node.Name.GetContent(); + var associatedDescriptors = descriptors.Where(descriptor => + descriptor.BoundAttributes.Any(attributeDescriptor => TagHelperMatchingConventions.CanSatisfyBoundAttribute(attributeName, attributeDescriptor))); + + if (associatedDescriptors.Any() && _renderedBoundAttributeNames.Add(attributeName)) + { + foreach (var associatedDescriptor in associatedDescriptors) + { + var associatedAttributeDescriptor = associatedDescriptor.BoundAttributes.First(a => + { + return TagHelperMatchingConventions.CanSatisfyBoundAttribute(attributeName, a); + }); + + var expectsBooleanValue = associatedAttributeDescriptor.ExpectsBooleanValue(attributeName); + + if (!expectsBooleanValue) + { + // We do not allow minimized non-boolean bound attributes. + return; + } + + var setTagHelperProperty = new TagHelperPropertyIntermediateNode() + { + AttributeName = attributeName, + BoundAttribute = associatedAttributeDescriptor, + TagHelper = associatedDescriptor, + AttributeStructure = node.TagHelperAttributeInfo.AttributeStructure, + Source = null, + IsIndexerNameMatch = TagHelperMatchingConventions.SatisfiesBoundAttributeIndexer(attributeName, associatedAttributeDescriptor), + }; + + _builder.Add(setTagHelperProperty); + } + } + else + { + var addHtmlAttribute = new TagHelperHtmlAttributeIntermediateNode() + { + AttributeName = attributeName, + AttributeStructure = node.TagHelperAttributeInfo.AttributeStructure + }; + + _builder.Add(addHtmlAttribute); + } + } + + public override void VisitMarkupTagHelperAttribute(MarkupTagHelperAttributeSyntax node) + { + var element = node.FirstAncestorOrSelf(); + var descriptors = element.TagHelperInfo.BindingResult.Descriptors; + var attributeName = node.Name.GetContent(); + var attributeValueNode = node.Value; + var associatedDescriptors = descriptors.Where(descriptor => + descriptor.BoundAttributes.Any(attributeDescriptor => TagHelperMatchingConventions.CanSatisfyBoundAttribute(attributeName, attributeDescriptor))); + + if (associatedDescriptors.Any() && _renderedBoundAttributeNames.Add(attributeName)) + { + foreach (var associatedDescriptor in associatedDescriptors) + { + var associatedAttributeDescriptor = associatedDescriptor.BoundAttributes.First(a => + { + return TagHelperMatchingConventions.CanSatisfyBoundAttribute(attributeName, a); + }); + + var setTagHelperProperty = new TagHelperPropertyIntermediateNode() + { + AttributeName = attributeName, + BoundAttribute = associatedAttributeDescriptor, + TagHelper = associatedDescriptor, + AttributeStructure = node.TagHelperAttributeInfo.AttributeStructure, + Source = BuildSourceSpanFromNode(attributeValueNode), + IsIndexerNameMatch = TagHelperMatchingConventions.SatisfiesBoundAttributeIndexer(attributeName, associatedAttributeDescriptor), + }; + + _builder.Push(setTagHelperProperty); + VisitAttributeValue(attributeValueNode); + _builder.Pop(); + } + } + else + { + var addHtmlAttribute = new TagHelperHtmlAttributeIntermediateNode() + { + AttributeName = attributeName, + AttributeStructure = node.TagHelperAttributeInfo.AttributeStructure + }; + + _builder.Push(addHtmlAttribute); + VisitAttributeValue(attributeValueNode); + _builder.Pop(); + } + } + + private void VisitAttributeValue(SyntaxNode node) + { + if (node == null) + { + return; + } + + IReadOnlyList children = node.ChildNodes(); + var position = node.Position; + if (children.First() is MarkupBlockSyntax markupBlock && + markupBlock.Children.Count == 2 && + markupBlock.Children[0] is MarkupTextLiteralSyntax && + markupBlock.Children[1] is MarkupEphemeralTextLiteralSyntax) + { + // This is a special case when we have an attribute like attr="@@foo". + // In this case, we want the foo to be written out as HtmlContent and not HtmlAttributeValue. + Visit(markupBlock); + children = children.Skip(1).ToList(); + position = children.Count > 0 ? children[0].Position : position; + } + + if (children.All(c => c is MarkupLiteralAttributeValueSyntax)) + { + var literalAttributeValueNodes = children.Cast().ToArray(); + var valueTokens = SyntaxListBuilder.Create(); + for (var i = 0; i < literalAttributeValueNodes.Length; i++) + { + var mergedValue = MergeAttributeValue(literalAttributeValueNodes[i]); + valueTokens.AddRange(mergedValue.LiteralTokens); + } + var rewritten = SyntaxFactory.MarkupTextLiteral(valueTokens.ToList()).Green.CreateRed(node.Parent, position); + Visit(rewritten); + } + else if (children.All(c => c is MarkupTextLiteralSyntax)) + { + var builder = SyntaxListBuilder.Create(); + var markupLiteralArray = children.Cast(); + foreach (var literal in markupLiteralArray) + { + builder.AddRange(literal.LiteralTokens); + } + var rewritten = SyntaxFactory.MarkupTextLiteral(builder.ToList()).Green.CreateRed(node.Parent, position); + Visit(rewritten); + } + else if (children.All(c => c is CSharpExpressionLiteralSyntax)) + { + var builder = SyntaxListBuilder.Create(); + var expressionLiteralArray = children.Cast(); + SpanContext context = null; + foreach (var literal in expressionLiteralArray) + { + context = literal.GetSpanContext(); + builder.AddRange(literal.LiteralTokens); + } + var rewritten = SyntaxFactory.CSharpExpressionLiteral(builder.ToList()).Green.CreateRed(node.Parent, position); + rewritten = context != null ? rewritten.WithSpanContext(context) : rewritten; + Visit(rewritten); + } + else + { + Visit(node); + } + } + + private MarkupTextLiteralSyntax MergeAttributeValue(MarkupLiteralAttributeValueSyntax node) + { + var valueTokens = MergeLiterals(node.Prefix?.LiteralTokens, node.Value?.LiteralTokens); + var rewritten = node.Prefix?.Update(valueTokens) ?? node.Value?.Update(valueTokens); + rewritten = (MarkupTextLiteralSyntax)rewritten?.Green.CreateRed(node, node.Position); + var originalContext = rewritten.GetSpanContext(); + if (originalContext != null) + { + rewritten = rewritten.WithSpanContext(new SpanContext(new MarkupChunkGenerator(), originalContext.EditHandler)); + } + + return rewritten; + } + + private void Combine(HtmlContentIntermediateNode node, SyntaxNode item) + { + node.Children.Add(new IntermediateToken() + { + Content = item.GetContent(), + Kind = TokenKind.Html, + Source = BuildSourceSpanFromNode(item), + }); + + if (node.Source != null) + { + Debug.Assert(node.Source.Value.FilePath != null); + + node.Source = new SourceSpan( + node.Source.Value.FilePath, + node.Source.Value.AbsoluteIndex, + node.Source.Value.LineIndex, + node.Source.Value.CharacterIndex, + node.Source.Value.Length + item.FullWidth); + } + } + + private SyntaxList MergeLiterals(params SyntaxList?[] literals) + { + var builder = SyntaxListBuilder.Create(); + for (var i = 0; i < literals.Length; i++) + { + var literal = literals[i]; + if (!literal.HasValue) + { + continue; + } + + builder.AddRange(literal.Value); + } + + return builder.ToList(); + } + } + + private class ImportsVisitor : LoweringVisitor + { + public ImportsVisitor(DocumentIntermediateNode document, IntermediateNodeBuilder builder, RazorParserFeatureFlags featureFlags) + : base(document, new ImportBuilder(builder), featureFlags) + { + } + + private class ImportBuilder : IntermediateNodeBuilder + { + private readonly IntermediateNodeBuilder _innerBuilder; + + public ImportBuilder(IntermediateNodeBuilder innerBuilder) + { + _innerBuilder = innerBuilder; + } + + public override IntermediateNode Current => _innerBuilder.Current; + + public override void Add(IntermediateNode node) + { + node.Annotations[CommonAnnotations.Imported] = CommonAnnotations.Imported; + _innerBuilder.Add(node); + } + + public override IntermediateNode Build() => _innerBuilder.Build(); + + public override void Insert(int index, IntermediateNode node) + { + node.Annotations[CommonAnnotations.Imported] = CommonAnnotations.Imported; + _innerBuilder.Insert(index, node); + } + + public override IntermediateNode Pop() => _innerBuilder.Pop(); + + public override void Push(IntermediateNode node) + { + node.Annotations[CommonAnnotations.Imported] = CommonAnnotations.Imported; + _innerBuilder.Push(node); + } + } + } + + private class DirectiveVisitor : IntermediateNodeWalker + { + public List Directives = new List(); + + public override void VisitDirective(DirectiveIntermediateNode node) + { + Directives.Add(new IntermediateNodeReference(Parent, node)); + + base.VisitDirective(node); + } + } + + private static bool IsMalformed(IEnumerable diagnostics) + => diagnostics.Any(diagnostic => diagnostic.Severity == RazorDiagnosticSeverity.Error); + } +#pragma warning restore CS0618 // Type or member is obsolete +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorOptimizationPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorOptimizationPhase.cs new file mode 100644 index 0000000000..6b1f7c271a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorOptimizationPhase.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. + +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorOptimizationPhase : RazorEnginePhaseBase, IRazorOptimizationPhase + { + public IRazorOptimizationPass[] Passes { get; private set; } + + protected override void OnIntialized() + { + Passes = Engine.Features.OfType().OrderBy(p => p.Order).ToArray(); + } + + protected override void ExecuteCore(RazorCodeDocument codeDocument) + { + var documentNode = codeDocument.GetDocumentIntermediateNode(); + ThrowForMissingDocumentDependency(documentNode); + + foreach (var pass in Passes) + { + pass.Execute(codeDocument, documentNode); + } + + codeDocument.SetDocumentIntermediateNode(documentNode); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptions.cs new file mode 100644 index 0000000000..6bb6d2c284 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptions.cs @@ -0,0 +1,35 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorParserOptions : RazorParserOptions + { + public DefaultRazorParserOptions(DirectiveDescriptor[] directives, bool designTime, bool parseLeadingDirectives, RazorLanguageVersion version) + { + if (directives == null) + { + throw new ArgumentNullException(nameof(directives)); + } + + Directives = directives; + DesignTime = designTime; + ParseLeadingDirectives = parseLeadingDirectives; + Version = version; + FeatureFlags = RazorParserFeatureFlags.Create(Version); + } + + public override bool DesignTime { get; } + + public override IReadOnlyCollection Directives { get; } + + public override bool ParseLeadingDirectives { get; } + + public override RazorLanguageVersion Version { get; } + + internal override RazorParserFeatureFlags FeatureFlags { get; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsBuilder.cs new file mode 100644 index 0000000000..2e4d3273d2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsBuilder.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 System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorParserOptionsBuilder : RazorParserOptionsBuilder + { + private bool _designTime; + + public DefaultRazorParserOptionsBuilder(RazorConfiguration configuration) + { + if (configuration == null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + Configuration = configuration; + LanguageVersion = configuration.LanguageVersion; + } + + public DefaultRazorParserOptionsBuilder(bool designTime, RazorLanguageVersion version) + { + _designTime = designTime; + LanguageVersion = version; + } + + public override RazorConfiguration Configuration { get; } + + public override bool DesignTime => _designTime; + + public override ICollection Directives { get; } = new List(); + + public override bool ParseLeadingDirectives { get; set; } + + public override RazorLanguageVersion LanguageVersion { get; } + + public override RazorParserOptions Build() + { + return new DefaultRazorParserOptions(Directives.ToArray(), DesignTime, ParseLeadingDirectives, LanguageVersion); + } + + public override void SetDesignTime(bool designTime) + { + _designTime = designTime; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsFactoryProjectFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsFactoryProjectFeature.cs new file mode 100644 index 0000000000..32fb04af7f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsFactoryProjectFeature.cs @@ -0,0 +1,32 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorParserOptionsFactoryProjectFeature : RazorProjectEngineFeatureBase, IRazorParserOptionsFactoryProjectFeature + { + private IConfigureRazorParserOptionsFeature[] _configureOptions; + + protected override void OnInitialized() + { + _configureOptions = ProjectEngine.EngineFeatures.OfType().ToArray(); + } + + public RazorParserOptions Create(Action configure) + { + var builder = new DefaultRazorParserOptionsBuilder(ProjectEngine.Configuration); + configure?.Invoke(builder); + + for (var i = 0; i < _configureOptions.Length; i++) + { + _configureOptions[i].Configure(builder); + } + + var options = builder.Build(); + return options; + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsFeature.cs new file mode 100644 index 0000000000..eecb9bd9cc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParserOptionsFeature.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 System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ +#pragma warning disable CS0618 // Type or member is obsolete + internal class DefaultRazorParserOptionsFeature : RazorEngineFeatureBase, IRazorParserOptionsFeature +#pragma warning restore CS0618 // Type or member is obsolete + { + private readonly bool _designTime; + private readonly RazorLanguageVersion _version; + private IConfigureRazorParserOptionsFeature[] _configureOptions; + + public DefaultRazorParserOptionsFeature(bool designTime, RazorLanguageVersion version) + { + _designTime = designTime; + _version = version; + } + + protected override void OnInitialized() + { + _configureOptions = Engine.Features.OfType().ToArray(); + } + + public RazorParserOptions GetOptions() + { + var builder = new DefaultRazorParserOptionsBuilder(_designTime, _version); + for (var i = 0; i < _configureOptions.Length; i++) + { + _configureOptions[i].Configure(builder); + } + + var options = builder.Build(); + + return options; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParsingPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParsingPhase.cs new file mode 100644 index 0000000000..8264201271 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorParsingPhase.cs @@ -0,0 +1,31 @@ +// 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 +{ +#pragma warning disable CS0618 // Type or member is obsolete + internal class DefaultRazorParsingPhase : RazorEnginePhaseBase, IRazorParsingPhase + { + private IRazorParserOptionsFeature _optionsFeature; + + protected override void OnIntialized() + { + _optionsFeature = GetRequiredFeature(); + } + + protected override void ExecuteCore(RazorCodeDocument codeDocument) + { + var options = codeDocument.GetParserOptions() ??_optionsFeature.GetOptions(); + var syntaxTree = RazorSyntaxTree.Parse(codeDocument.Source, options); + codeDocument.SetSyntaxTree(syntaxTree); + + var importSyntaxTrees = new RazorSyntaxTree[codeDocument.Imports.Count]; + for (var i = 0; i < codeDocument.Imports.Count; i++) + { + importSyntaxTrees[i] = RazorSyntaxTree.Parse(codeDocument.Imports[i], options); + } + codeDocument.SetImportSyntaxTrees(importSyntaxTrees); + } + } +#pragma warning restore CS0618 // Type or member is obsolete +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngine.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngine.cs new file mode 100644 index 0000000000..a560a0030a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngine.cs @@ -0,0 +1,195 @@ +// 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.IO; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorProjectEngine : RazorProjectEngine + { + public DefaultRazorProjectEngine( + RazorConfiguration configuration, + RazorEngine engine, + RazorProjectFileSystem fileSystem, + IReadOnlyList projectFeatures) + { + if (configuration == null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + if (engine == null) + { + throw new ArgumentNullException(nameof(engine)); + } + + if (fileSystem == null) + { + throw new ArgumentNullException(nameof(fileSystem)); + } + + if (projectFeatures == null) + { + throw new ArgumentNullException(nameof(projectFeatures)); + } + + Configuration = configuration; + Engine = engine; + FileSystem = fileSystem; + ProjectFeatures = projectFeatures; + + for (var i = 0; i < projectFeatures.Count; i++) + { + projectFeatures[i].ProjectEngine = this; + } + } + + public override RazorConfiguration Configuration { get; } + + public override RazorProjectFileSystem FileSystem { get; } + + public override RazorEngine Engine { get; } + + public override IReadOnlyList ProjectFeatures { get; } + + protected override RazorCodeDocument CreateCodeDocumentCore(RazorProjectItem projectItem) + { + if (projectItem == null) + { + throw new ArgumentNullException(nameof(projectItem)); + } + + var sourceDocument = RazorSourceDocument.ReadFrom(projectItem); + + var importFeature = GetRequiredFeature(); + var importItems = importFeature.GetImports(projectItem); + var importSourceDocuments = GetImportSourceDocuments(importItems); + + return CreateCodeDocumentCore(sourceDocument, importSourceDocuments, tagHelpers: null); + } + + internal override RazorCodeDocument CreateCodeDocumentCore(RazorSourceDocument sourceDocument, IReadOnlyList importSourceDocuments, IReadOnlyList tagHelpers) + { + if (sourceDocument == null) + { + throw new ArgumentNullException(nameof(sourceDocument)); + } + + var parserOptions = GetRequiredFeature().Create(ConfigureParserOptions); + var codeGenerationOptions = GetRequiredFeature().Create(ConfigureCodeGenerationOptions); + + var codeDocument = RazorCodeDocument.Create(sourceDocument, importSourceDocuments, parserOptions, codeGenerationOptions); + codeDocument.SetTagHelpers(tagHelpers); + + return codeDocument; + } + + protected override RazorCodeDocument CreateCodeDocumentDesignTimeCore(RazorProjectItem projectItem) + { + if (projectItem == null) + { + throw new ArgumentNullException(nameof(projectItem)); + } + + var sourceDocument = RazorSourceDocument.ReadFrom(projectItem); + + var importFeature = GetRequiredFeature(); + var importItems = importFeature.GetImports(projectItem); + var importSourceDocuments = GetImportSourceDocuments(importItems, suppressExceptions: true); + + return CreateCodeDocumentDesignTimeCore(sourceDocument, importSourceDocuments, tagHelpers: null); + } + + internal override RazorCodeDocument CreateCodeDocumentDesignTimeCore(RazorSourceDocument sourceDocument, IReadOnlyList importSourceDocuments, IReadOnlyList tagHelpers) + { + if (sourceDocument == null) + { + throw new ArgumentNullException(nameof(sourceDocument)); + } + + var parserOptions = GetRequiredFeature().Create(ConfigureDesignTimeParserOptions); + var codeGenerationOptions = GetRequiredFeature().Create(ConfigureDesignTimeCodeGenerationOptions); + + var codeDocument = RazorCodeDocument.Create(sourceDocument, importSourceDocuments, parserOptions, codeGenerationOptions); + codeDocument.SetTagHelpers(tagHelpers); + + return codeDocument; + } + + protected override void ProcessCore(RazorCodeDocument codeDocument) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + Engine.Process(codeDocument); + } + + private TFeature GetRequiredFeature() where TFeature : IRazorProjectEngineFeature + { + var feature = ProjectFeatures.OfType().FirstOrDefault(); + if (feature == null) + { + throw new InvalidOperationException( + Resources.FormatRazorProjectEngineMissingFeatureDependency( + typeof(RazorProjectEngine).FullName, + typeof(TFeature).FullName)); + } + + return feature; + } + + private void ConfigureParserOptions(RazorParserOptionsBuilder builder) + { + } + + private void ConfigureDesignTimeParserOptions(RazorParserOptionsBuilder builder) + { + builder.SetDesignTime(true); + } + + private void ConfigureCodeGenerationOptions(RazorCodeGenerationOptionsBuilder builder) + { + } + + private void ConfigureDesignTimeCodeGenerationOptions(RazorCodeGenerationOptionsBuilder builder) + { + builder.SetDesignTime(true); + builder.SuppressChecksum = true; + builder.SuppressMetadataAttributes = true; + } + + // Internal for testing + internal static IReadOnlyList GetImportSourceDocuments( + IReadOnlyList importItems, + bool suppressExceptions = false) + { + var imports = new List(); + for (var i = 0; i < importItems.Count; i++) + { + var importItem = importItems[i]; + + if (importItem.Exists) + { + try + { + // Normal import, has file paths, content etc. + var sourceDocument = RazorSourceDocument.ReadFrom(importItem); + imports.Add(sourceDocument); + } + catch (IOException) when (suppressExceptions) + { + // Something happened when trying to read the item from disk. + // Catch the exception so we don't crash the editor. + } + } + } + + return imports; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngineBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngineBuilder.cs new file mode 100644 index 0000000000..4c79c767d8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngineBuilder.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 System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorProjectEngineBuilder : RazorProjectEngineBuilder + { + public DefaultRazorProjectEngineBuilder(RazorConfiguration configuration, RazorProjectFileSystem fileSystem) + { + if (fileSystem == null) + { + throw new ArgumentNullException(nameof(fileSystem)); + } + + Configuration = configuration; + FileSystem = fileSystem; + Features = new List(); + Phases = new List(); + } + + public override RazorConfiguration Configuration { get; } + + public override RazorProjectFileSystem FileSystem { get; } + + public override ICollection Features { get; } + + public override IList Phases { get; } + + public override RazorProjectEngine Build() + { +#pragma warning disable CS0618 // Type or member is obsolete + var engine = RazorEngine.CreateEmpty(ConfigureRazorEngine); +#pragma warning restore CS0618 // Type or member is obsolete + var projectFeatures = Features.OfType().ToArray(); + var projectEngine = new DefaultRazorProjectEngine(Configuration, engine, FileSystem, projectFeatures); + + return projectEngine; + } + +#pragma warning disable CS0618 // Type or member is obsolete + private void ConfigureRazorEngine(IRazorEngineBuilder engineBuilder) +#pragma warning disable CS0618 // Type or member is obsolete + { + var engineFeatures = Features.OfType(); + foreach (var engineFeature in engineFeatures) + { + engineBuilder.Features.Add(engineFeature); + } + + for (var i = 0; i < Phases.Count; i++) + { + engineBuilder.Phases.Add(Phases[i]); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectFileSystem.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectFileSystem.cs new file mode 100644 index 0000000000..9283088cd1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectFileSystem.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; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorProjectFileSystem : RazorProjectFileSystem + { + public DefaultRazorProjectFileSystem(string root) + { + if (string.IsNullOrEmpty(root)) + { + throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(root)); + } + + Root = root.Replace('\\', '/').TrimEnd('/'); + } + + public string Root { get; } + + public override IEnumerable EnumerateItems(string basePath) + { + var absoluteBasePath = NormalizeAndEnsureValidPath(basePath); + + var directory = new DirectoryInfo(absoluteBasePath); + if (!directory.Exists) + { + return Enumerable.Empty(); + } + + return directory + .EnumerateFiles("*.cshtml", SearchOption.AllDirectories) + .Select(file => + { + var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator + var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/'); + + return new DefaultRazorProjectItem(basePath, filePath, relativePhysicalPath, file); + }); + } + + public override RazorProjectItem GetItem(string path) + { + var absoluteBasePath = NormalizeAndEnsureValidPath("/"); + var absolutePath = NormalizeAndEnsureValidPath(path); + + var file = new FileInfo(absolutePath); + if (!absolutePath.StartsWith(absoluteBasePath)) + { + throw new InvalidOperationException($"The file '{file.FullName}' is not a descendent of the base path '{absoluteBasePath}'."); + } + + var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator + var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/'); + + return new DefaultRazorProjectItem("/", filePath, relativePhysicalPath, new FileInfo(absolutePath)); + } + + protected override string NormalizeAndEnsureValidPath(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(path)); + } + + var absolutePath = path; + if (!absolutePath.StartsWith(Root, StringComparison.OrdinalIgnoreCase)) + { + if (path[0] == '/' || path[0] == '\\') + { + path = path.Substring(1); + } + + absolutePath = Path.Combine(Root, path); + } + + absolutePath = absolutePath.Replace('\\', '/'); + + return absolutePath; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectItem.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectItem.cs new file mode 100644 index 0000000000..5a3590a121 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectItem.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 System.IO; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorProjectItem : RazorProjectItem + { + /// + /// Initializes a new instance of . + /// + /// The base path. + /// The physical path of the base path. + /// The path. + /// The . + public DefaultRazorProjectItem(string basePath, string filePath, string relativePhysicalPath, FileInfo file) + { + BasePath = basePath; + FilePath = filePath; + RelativePhysicalPath = relativePhysicalPath; + File = file; + } + + public FileInfo File { get; } + + public override string BasePath { get; } + + public override string FilePath { get; } + + public override bool Exists => File.Exists; + + public override string PhysicalPath => File.FullName; + + public override string RelativePhysicalPath { get; } + + public override Stream Read() => new FileStream(PhysicalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSourceLineCollection.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSourceLineCollection.cs new file mode 100644 index 0000000000..37b5e156f1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSourceLineCollection.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 System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorSourceLineCollection : RazorSourceLineCollection + { + private readonly RazorSourceDocument _document; + private readonly int[] _lineStarts; + + public DefaultRazorSourceLineCollection(RazorSourceDocument document) + { + _document = document; + _lineStarts = GetLineStarts(); + } + + public override int Count => _lineStarts.Length; + + public override int GetLineLength(int index) + { + if (index < 0 || index >= _lineStarts.Length) + { + throw new IndexOutOfRangeException(nameof(index)); + } + + if (index == _lineStarts.Length - 1) + { + // Last line is special. + return _document.Length - _lineStarts[index]; + } + + return _lineStarts[index + 1] - _lineStarts[index]; + } + + internal override SourceLocation GetLocation(int position) + { + if (position < 0 || position >= _document.Length) + { + throw new IndexOutOfRangeException(nameof(position)); + } + + var index = Array.BinarySearch(_lineStarts, position); + if (index >= 0) + { + // We have an exact match for the start of a line. + Debug.Assert(_lineStarts[index] == position); + + return new SourceLocation(_document.GetFilePathForDisplay(), position, index, characterIndex: 0); + } + + + // Index is the complement of the line *after* the one we want, because BinarySearch tells + // us where we'd put position *if* it were the start of a line. + index = (~index) - 1; + if (index == -1) + { + // There's no preceding line, so it's based on the start of the string + return new SourceLocation(_document.GetFilePathForDisplay(), position, 0, position); + } + else + { + var characterIndex = position - _lineStarts[index]; + return new SourceLocation(_document.GetFilePathForDisplay(), position, index, characterIndex); + } + } + + private int[] GetLineStarts() + { + var starts = new List(); + + // We always consider a document to have at least a 0th line, even if it's empty. + starts.Add(0); + + var unprocessedCR = false; + + // Length - 1 because we don't care if there was a linebreak as the last character. + var length = _document.Length; + for (var i = 0; i < length - 1; i++) + { + var c = _document[i]; + var isLineBreak = false; + + switch (c) + { + case '\r': + unprocessedCR = true; + continue; + + case '\n': + unprocessedCR = false; + isLineBreak = true; + break; + + case '\u0085': + case '\u2028': + case '\u2029': + isLineBreak = true; + break; + + } + + if (unprocessedCR) + { + // If we get here it means that we had a CR followed by something other than an LF. + // Add the CR as a line break. + starts.Add(i); + unprocessedCR = false; + } + + if (isLineBreak) + { + starts.Add(i + 1); + } + } + + return starts.ToArray(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSyntaxTree.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSyntaxTree.cs new file mode 100644 index 0000000000..018dbfe5fb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSyntaxTree.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 System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Microsoft.AspNetCore.Razor.Language.Syntax; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorSyntaxTree : RazorSyntaxTree + { + public DefaultRazorSyntaxTree( + SyntaxNode root, + RazorSourceDocument source, + IReadOnlyList diagnostics, + RazorParserOptions options) + { + Root = root; + Source = source; + Diagnostics = diagnostics; + Options = options; + } + + public override IReadOnlyList Diagnostics { get; } + + public override RazorParserOptions Options { get; } + + internal override SyntaxNode Root { get; } + + public override RazorSourceDocument Source { get; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSyntaxTreePhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSyntaxTreePhase.cs new file mode 100644 index 0000000000..5c0df33dfb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorSyntaxTreePhase.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. + +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorSyntaxTreePhase : RazorEnginePhaseBase, IRazorSyntaxTreePhase + { + public IRazorSyntaxTreePass[] Passes { get; private set; } + + protected override void OnIntialized() + { + Passes = Engine.Features.OfType().OrderBy(p => p.Order).ToArray(); + } + + protected override void ExecuteCore(RazorCodeDocument codeDocument) + { + var syntaxTree = codeDocument.GetSyntaxTree(); + ThrowForMissingDocumentDependency(syntaxTree); + + foreach (var pass in Passes) + { + syntaxTree = pass.Execute(codeDocument, syntaxTree); + } + + codeDocument.SetSyntaxTree(syntaxTree); + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperBinderPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperBinderPhase.cs new file mode 100644 index 0000000000..c15aaff04e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperBinderPhase.cs @@ -0,0 +1,192 @@ +// 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 Microsoft.AspNetCore.Razor.Language.Syntax; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorTagHelperBinderPhase : RazorEnginePhaseBase, IRazorTagHelperBinderPhase + { + protected override void ExecuteCore(RazorCodeDocument codeDocument) + { + var syntaxTree = codeDocument.GetSyntaxTree(); + ThrowForMissingDocumentDependency(syntaxTree); + + var descriptors = codeDocument.GetTagHelpers(); + if (descriptors == null) + { + var feature = Engine.Features.OfType().FirstOrDefault(); + if (feature == null) + { + // No feature, nothing to do. + return; + } + + descriptors = feature.GetDescriptors(); + } + + // We need to find directives in all of the *imports* as well as in the main razor file + // + // The imports come logically before the main razor file and are in the order they + // should be processed. + var visitor = new DirectiveVisitor(descriptors); + var imports = codeDocument.GetImportSyntaxTrees(); + if (imports != null) + { + for (var i = 0; i < imports.Count; i++) + { + var import = imports[i]; + visitor.Visit(import.Root); + } + } + + visitor.Visit(syntaxTree.Root); + + var tagHelperPrefix = visitor.TagHelperPrefix; + descriptors = visitor.Matches.ToArray(); + + var context = TagHelperDocumentContext.Create(tagHelperPrefix, descriptors); + codeDocument.SetTagHelperContext(context); + + if (descriptors.Count == 0) + { + // No descriptors, no-op. + return; + } + + var rewrittenSyntaxTree = TagHelperParseTreeRewriter.Rewrite(syntaxTree, tagHelperPrefix, descriptors); + + codeDocument.SetSyntaxTree(rewrittenSyntaxTree); + } + + private static bool MatchesDirective(TagHelperDescriptor descriptor, string typePattern, string assemblyName) + { + if (!string.Equals(descriptor.AssemblyName, assemblyName, StringComparison.Ordinal)) + { + return false; + } + + if (typePattern.EndsWith("*", StringComparison.Ordinal)) + { + if (typePattern.Length == 1) + { + // TypePattern is "*". + return true; + } + + var lookupTypeName = typePattern.Substring(0, typePattern.Length - 1); + + return descriptor.Name.StartsWith(lookupTypeName, StringComparison.Ordinal); + } + + return string.Equals(descriptor.Name, typePattern, StringComparison.Ordinal); + } + + internal class DirectiveVisitor : SyntaxRewriter + { + private IReadOnlyList _tagHelpers; + + public DirectiveVisitor(IReadOnlyList tagHelpers) + { + _tagHelpers = tagHelpers; + } + + public string TagHelperPrefix { get; private set; } + + public HashSet Matches { get; } = new HashSet(); + + public override SyntaxNode VisitRazorDirective(RazorDirectiveSyntax node) + { + var descendantLiterals = node.DescendantNodes(); + foreach (var child in descendantLiterals) + { + if (!(child is CSharpStatementLiteralSyntax literal)) + { + continue; + } + + var context = literal.GetSpanContext(); + if (context == null) + { + // We can't find a chunk generator. + continue; + } + else if (context.ChunkGenerator is AddTagHelperChunkGenerator addTagHelper) + { + if (addTagHelper.AssemblyName == null) + { + // Skip this one, it's an error + continue; + } + + if (!AssemblyContainsTagHelpers(addTagHelper.AssemblyName, _tagHelpers)) + { + // No tag helpers in the assembly. + continue; + } + + for (var i = 0; i < _tagHelpers.Count; i++) + { + var tagHelper = _tagHelpers[i]; + if (MatchesDirective(tagHelper, addTagHelper.TypePattern, addTagHelper.AssemblyName)) + { + Matches.Add(tagHelper); + } + } + } + else if (context.ChunkGenerator is RemoveTagHelperChunkGenerator removeTagHelper) + { + if (removeTagHelper.AssemblyName == null) + { + // Skip this one, it's an error + continue; + } + + + if (!AssemblyContainsTagHelpers(removeTagHelper.AssemblyName, _tagHelpers)) + { + // No tag helpers in the assembly. + continue; + } + + for (var i = 0; i < _tagHelpers.Count; i++) + { + var tagHelper = _tagHelpers[i]; + if (MatchesDirective(tagHelper, removeTagHelper.TypePattern, removeTagHelper.AssemblyName)) + { + Matches.Remove(tagHelper); + } + } + } + else if (context.ChunkGenerator is TagHelperPrefixDirectiveChunkGenerator tagHelperPrefix) + { + if (!string.IsNullOrEmpty(tagHelperPrefix.DirectiveText)) + { + // We only expect to see a single one of these per file, but that's enforced at another level. + TagHelperPrefix = tagHelperPrefix.DirectiveText; + } + } + } + + return base.VisitRazorDirective(node); + } + + private bool AssemblyContainsTagHelpers(string assemblyName, IReadOnlyList tagHelpers) + { + for (var i = 0; i < tagHelpers.Count; i++) + { + if (string.Equals(tagHelpers[i].AssemblyName, assemblyName, StringComparison.Ordinal)) + { + return true; + } + } + + return false; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTargetExtensionFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTargetExtensionFeature.cs new file mode 100644 index 0000000000..076dac88a1 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTargetExtensionFeature.cs @@ -0,0 +1,13 @@ +// 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.CodeGeneration; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRazorTargetExtensionFeature : RazorEngineFeatureBase, IRazorTargetExtensionFeature + { + public ICollection TargetExtensions { get; } = new List(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRequiredAttributeDescriptor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRequiredAttributeDescriptor.cs new file mode 100644 index 0000000000..8802abcf7a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRequiredAttributeDescriptor.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. + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRequiredAttributeDescriptor : RequiredAttributeDescriptor + { + public DefaultRequiredAttributeDescriptor( + string name, + NameComparisonMode nameComparison, + string value, + ValueComparisonMode valueComparison, + string displayName, + RazorDiagnostic[] diagnostics) + { + Name = name; + NameComparison = nameComparison; + Value = value; + ValueComparison = valueComparison; + DisplayName = displayName; + Diagnostics = diagnostics; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRequiredAttributeDescriptorBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRequiredAttributeDescriptorBuilder.cs new file mode 100644 index 0000000000..5b611b7b20 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRequiredAttributeDescriptorBuilder.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 System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultRequiredAttributeDescriptorBuilder : RequiredAttributeDescriptorBuilder + { + private RazorDiagnosticCollection _diagnostics; + + public override string Name { get; set; } + + public override RequiredAttributeDescriptor.NameComparisonMode NameComparisonMode { get; set; } + + public override string Value { get; set; } + + public override RequiredAttributeDescriptor.ValueComparisonMode ValueComparisonMode { get; set; } + + public override RazorDiagnosticCollection Diagnostics + { + get + { + if (_diagnostics == null) + { + _diagnostics = new RazorDiagnosticCollection(); + } + + return _diagnostics; + } + } + + public RequiredAttributeDescriptor Build() + { + var validationDiagnostics = Validate(); + var diagnostics = new HashSet(validationDiagnostics); + if (_diagnostics != null) + { + diagnostics.UnionWith(_diagnostics); + } + + var displayName = NameComparisonMode == RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch ? string.Concat(Name, "...") : Name; + var rule = new DefaultRequiredAttributeDescriptor( + Name, + NameComparisonMode, + Value, + ValueComparisonMode, + displayName, + diagnostics?.ToArray() ?? Array.Empty()); + + return rule; + } + + private IEnumerable Validate() + { + if (string.IsNullOrWhiteSpace(Name)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedAttributeNameNullOrWhitespace(); + + yield return diagnostic; + } + else + { + foreach (var character in Name) + { + if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedAttributeName(Name, character); + + yield return diagnostic; + } + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs new file mode 100644 index 0000000000..f9da39f401 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs @@ -0,0 +1,36 @@ +// 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 +{ + internal class DefaultTagHelperDescriptor : TagHelperDescriptor + { + public DefaultTagHelperDescriptor( + string kind, + string name, + string assemblyName, + string displayName, + string documentation, + string tagOutputHint, + TagMatchingRuleDescriptor[] tagMatchingRules, + BoundAttributeDescriptor[] attributeDescriptors, + AllowedChildTagDescriptor[] allowedChildTags, + Dictionary metadata, + RazorDiagnostic[] diagnostics) + : base(kind) + { + Name = name; + AssemblyName = assemblyName; + DisplayName = displayName; + Documentation = documentation; + TagOutputHint = tagOutputHint; + TagMatchingRules = tagMatchingRules; + BoundAttributes = attributeDescriptors; + AllowedChildTags = allowedChildTags; + Diagnostics = diagnostics; + Metadata = metadata; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs new file mode 100644 index 0000000000..3dcd280a11 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs @@ -0,0 +1,237 @@ +// 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 +{ + internal class DefaultTagHelperDescriptorBuilder : TagHelperDescriptorBuilder + { + // Required values + private readonly Dictionary _metadata; + + private List _allowedChildTags; + private List _attributeBuilders; + private List _tagMatchingRuleBuilders; + private RazorDiagnosticCollection _diagnostics; + + public DefaultTagHelperDescriptorBuilder(string kind, string name, string assemblyName) + { + Kind = kind; + Name = name; + AssemblyName = assemblyName; + + _metadata = new Dictionary(StringComparer.Ordinal); + + // Tells code generation that these tag helpers are compatible with ITagHelper. + // For now that's all we support. + _metadata.Add(TagHelperMetadata.Runtime.Name, TagHelperConventions.DefaultKind); + } + + public override string Name { get; } + + public override string AssemblyName { get; } + + public override string Kind { get; } + + public override string DisplayName { get; set; } + + public override string TagOutputHint { get; set; } + + public override string Documentation { get; set; } + + public override IDictionary Metadata => _metadata; + + public override RazorDiagnosticCollection Diagnostics + { + get + { + if (_diagnostics == null) + { + _diagnostics = new RazorDiagnosticCollection(); + } + + return _diagnostics; + } + } + + public override IReadOnlyList AllowedChildTags + { + get + { + EnsureAllowedChildTags(); + + return _allowedChildTags; + } + } + + public override IReadOnlyList BoundAttributes + { + get + { + EnsureAttributeBuilders(); + + return _attributeBuilders; + } + } + + public override IReadOnlyList TagMatchingRules + { + get + { + EnsureTagMatchingRuleBuilders(); + + return _tagMatchingRuleBuilders; + } + } + + public override void AllowChildTag(Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + EnsureAllowedChildTags(); + + var builder = new DefaultAllowedChildTagDescriptorBuilder(this); + configure(builder); + _allowedChildTags.Add(builder); + } + + public override void BindAttribute(Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + EnsureAttributeBuilders(); + + var builder = new DefaultBoundAttributeDescriptorBuilder(this, Kind); + configure(builder); + _attributeBuilders.Add(builder); + } + + public override void TagMatchingRule(Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + EnsureTagMatchingRuleBuilders(); + + var builder = new DefaultTagMatchingRuleDescriptorBuilder(); + configure(builder); + _tagMatchingRuleBuilders.Add(builder); + } + + public override TagHelperDescriptor Build() + { + var diagnostics = new HashSet(); + if (_diagnostics != null) + { + diagnostics.UnionWith(_diagnostics); + } + + var allowedChildTags = Array.Empty(); + if (_allowedChildTags != null) + { + var allowedChildTagsSet = new HashSet(AllowedChildTagDescriptorComparer.Default); + for (var i = 0; i < _allowedChildTags.Count; i++) + { + allowedChildTagsSet.Add(_allowedChildTags[i].Build()); + } + + allowedChildTags = allowedChildTagsSet.ToArray(); + } + + var tagMatchingRules = Array.Empty(); + if (_tagMatchingRuleBuilders != null) + { + var tagMatchingRuleSet = new HashSet(TagMatchingRuleDescriptorComparer.Default); + for (var i = 0; i < _tagMatchingRuleBuilders.Count; i++) + { + tagMatchingRuleSet.Add(_tagMatchingRuleBuilders[i].Build()); + } + + tagMatchingRules = tagMatchingRuleSet.ToArray(); + } + + var attributes = Array.Empty(); + if (_attributeBuilders != null) + { + var attributeSet = new HashSet(BoundAttributeDescriptorComparer.Default); + for (var i = 0; i < _attributeBuilders.Count; i++) + { + attributeSet.Add(_attributeBuilders[i].Build()); + } + + attributes = attributeSet.ToArray(); + } + + var descriptor = new DefaultTagHelperDescriptor( + Kind, + Name, + AssemblyName, + GetDisplayName(), + Documentation, + TagOutputHint, + tagMatchingRules, + attributes, + allowedChildTags, + new Dictionary(_metadata), + diagnostics.ToArray()); + + return descriptor; + } + + public override void Reset() + { + Documentation = null; + TagOutputHint = null; + _allowedChildTags?.Clear(); + _attributeBuilders?.Clear(); + _tagMatchingRuleBuilders?.Clear(); + _metadata.Clear(); + _diagnostics?.Clear(); + } + + public string GetDisplayName() + { + if (DisplayName != null) + { + return DisplayName; + } + + return this.GetTypeName() ?? Name; + } + + private void EnsureAllowedChildTags() + { + if (_allowedChildTags == null) + { + _allowedChildTags = new List(); + } + } + + private void EnsureAttributeBuilders() + { + if (_attributeBuilders == null) + { + _attributeBuilders = new List(); + } + } + + private void EnsureTagMatchingRuleBuilders() + { + if (_tagMatchingRuleBuilders == null) + { + _tagMatchingRuleBuilders = new List(); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagMatchingRuleDescriptor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagMatchingRuleDescriptor.cs new file mode 100644 index 0000000000..78595a9165 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagMatchingRuleDescriptor.cs @@ -0,0 +1,22 @@ +// 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 +{ + internal class DefaultTagMatchingRuleDescriptor : TagMatchingRuleDescriptor + { + public DefaultTagMatchingRuleDescriptor( + string tagName, + string parentTag, + TagStructure tagStructure, + RequiredAttributeDescriptor[] attributes, + RazorDiagnostic[] diagnostics) + { + TagName = tagName; + ParentTag = parentTag; + TagStructure = tagStructure; + Attributes = attributes; + Diagnostics = diagnostics; + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagMatchingRuleDescriptorBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagMatchingRuleDescriptorBuilder.cs new file mode 100644 index 0000000000..7cfb80eebc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultTagMatchingRuleDescriptorBuilder.cs @@ -0,0 +1,146 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DefaultTagMatchingRuleDescriptorBuilder : TagMatchingRuleDescriptorBuilder + { + private List _requiredAttributeBuilders; + private RazorDiagnosticCollection _diagnostics; + + internal DefaultTagMatchingRuleDescriptorBuilder() + { + } + + public override string TagName { get; set; } + + public override string ParentTag { get; set; } + + public override TagStructure TagStructure { get; set; } + + public override RazorDiagnosticCollection Diagnostics + { + get + { + if (_diagnostics == null) + { + _diagnostics = new RazorDiagnosticCollection(); + } + + return _diagnostics; + } + } + + public override IReadOnlyList Attributes + { + get + { + EnsureRequiredAttributeBuilders(); + + return _requiredAttributeBuilders; + } + } + + public override void Attribute(Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + EnsureRequiredAttributeBuilders(); + + var builder = new DefaultRequiredAttributeDescriptorBuilder(); + configure(builder); + _requiredAttributeBuilders.Add(builder); + } + + public TagMatchingRuleDescriptor Build() + { + var validationDiagnostics = Validate(); + var diagnostics = new HashSet(validationDiagnostics); + if (_diagnostics != null) + { + diagnostics.UnionWith(_diagnostics); + } + + var requiredAttributes = Array.Empty(); + if (_requiredAttributeBuilders != null) + { + var requiredAttributeSet = new HashSet(RequiredAttributeDescriptorComparer.Default); + for (var i = 0; i < _requiredAttributeBuilders.Count; i++) + { + requiredAttributeSet.Add(_requiredAttributeBuilders[i].Build()); + } + + requiredAttributes = requiredAttributeSet.ToArray(); + } + + var rule = new DefaultTagMatchingRuleDescriptor( + TagName, + ParentTag, + TagStructure, + requiredAttributes, + diagnostics.ToArray()); + + return rule; + } + + private IEnumerable Validate() + { + if (string.IsNullOrWhiteSpace(TagName)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedTagNameNullOrWhitespace(); + + yield return diagnostic; + } + else if (TagName != TagHelperMatchingConventions.ElementCatchAllName) + { + foreach (var character in TagName) + { + if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedTagName(TagName, character); + + yield return diagnostic; + } + } + } + + if (ParentTag != null) + { + if (string.IsNullOrWhiteSpace(ParentTag)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedParentTagNameNullOrWhitespace(); + + yield return diagnostic; + } + else + { + foreach (var character in ParentTag) + { + if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character)) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedParentTagName(ParentTag, character); + + yield return diagnostic; + } + } + } + } + } + + private void EnsureRequiredAttributeBuilders() + { + if (_requiredAttributeBuilders == null) + { + _requiredAttributeBuilders = new List(); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptor.cs new file mode 100644 index 0000000000..f2591b9f68 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptor.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; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language +{ + /// + /// A descriptor type for a directive that can be parsed by the Razor parser. + /// + public abstract class DirectiveDescriptor + { + /// + /// Gets the description of the directive. + /// + /// + /// The description is used for information purposes, and has no effect on parsing. + /// + public abstract string Description { get; } + + /// + /// Gets the directive keyword without the leading @ token. + /// + public abstract string Directive { get; } + + /// + /// Gets the display name of the directive. + /// + /// + /// The display name is used for information purposes, and has no effect on parsing. + /// + public abstract string DisplayName { get; } + + /// + /// Gets the kind of the directive. The kind determines whether or not a directive has an associated block. + /// + public abstract DirectiveKind Kind { get; } + + /// + /// Gets the way a directive can be used. The usage determines how many, and where directives can exist per document. + /// + public abstract DirectiveUsage Usage { get; } + + /// + /// Gets the list of directive tokens that can follow the directive keyword. + /// + public abstract IReadOnlyList Tokens { get; } + + /// + /// Creates a new . + /// + /// The directive keyword. + /// The directive kind. + /// A for the created directive. + public static DirectiveDescriptor CreateDirective(string directive, DirectiveKind kind) + { + if (directive == null) + { + throw new ArgumentNullException(nameof(directive)); + } + + return CreateDirective(directive, kind, configure: null); + } + + /// + /// Creates a new . + /// + /// The directive keyword. + /// The directive kind. + /// A configuration delegate for the directive. + /// A for the created directive. + public static DirectiveDescriptor CreateDirective(string directive, DirectiveKind kind, Action configure) + { + if (directive == null) + { + throw new ArgumentNullException(nameof(directive)); + } + + var builder = new DefaultDirectiveDescriptorBuilder(directive, kind); + configure?.Invoke(builder); + return builder.Build(); + } + + /// + /// Creates a new with set to + /// + /// The directive keyword. + /// A for the created directive. + public static DirectiveDescriptor CreateSingleLineDirective(string directive) + { + if (directive == null) + { + throw new ArgumentNullException(nameof(directive)); + } + + return CreateDirective(directive, DirectiveKind.SingleLine, configure: null); + } + + /// + /// Creates a new with set to + /// + /// The directive keyword. + /// A configuration delegate for the directive. + /// A for the created directive. + public static DirectiveDescriptor CreateSingleLineDirective(string directive, Action configure) + { + if (directive == null) + { + throw new ArgumentNullException(nameof(directive)); + } + + return CreateDirective(directive, DirectiveKind.SingleLine, configure); + } + + /// + /// Creates a new with set to + /// + /// The directive keyword. + /// A for the created directive. + public static DirectiveDescriptor CreateRazorBlockDirective(string directive) + { + if (directive == null) + { + throw new ArgumentNullException(nameof(directive)); + } + + return CreateDirective(directive, DirectiveKind.RazorBlock, configure: null); + } + + /// + /// Creates a new with set to + /// + /// The directive keyword. + /// A configuration delegate for the directive. + /// A for the created directive. + public static DirectiveDescriptor CreateRazorBlockDirective(string directive, Action configure) + { + if (directive == null) + { + throw new ArgumentNullException(nameof(directive)); + } + + return CreateDirective(directive, DirectiveKind.RazorBlock, configure); + } + + /// + /// Creates a new with set to + /// + /// The directive keyword. + /// A for the created directive. + public static DirectiveDescriptor CreateCodeBlockDirective(string directive) + { + if (directive == null) + { + throw new ArgumentNullException(nameof(directive)); + } + + return CreateDirective(directive, DirectiveKind.CodeBlock, configure: null); + } + + /// + /// Creates a new with set to + /// + /// The directive keyword. + /// A configuration delegate for the directive. + /// A for the created directive. + public static DirectiveDescriptor CreateCodeBlockDirective(string directive, Action configure) + { + if (directive == null) + { + throw new ArgumentNullException(nameof(directive)); + } + + return CreateDirective(directive, DirectiveKind.CodeBlock, configure); + } + + private class DefaultDirectiveDescriptorBuilder : IDirectiveDescriptorBuilder + { + public DefaultDirectiveDescriptorBuilder(string name, DirectiveKind kind) + { + Directive = name; + Kind = kind; + + Tokens = new List(); + } + + public string Description { get; set; } + + public string Directive { get; } + + public string DisplayName { get; set; } + + public DirectiveKind Kind { get; } + + public DirectiveUsage Usage { get; set; } + + public IList Tokens { get; } + + public DirectiveDescriptor Build() + { + if (Directive.Length == 0) + { + throw new InvalidOperationException(Resources.FormatDirectiveDescriptor_InvalidDirectiveKeyword(Directive)); + } + + for (var i = 0; i < Directive.Length; i++) + { + if (!char.IsLetter(Directive[i])) + { + throw new InvalidOperationException(Resources.FormatDirectiveDescriptor_InvalidDirectiveKeyword(Directive)); + } + } + + var foundOptionalToken = false; + for (var i = 0; i < Tokens.Count; i++) + { + var token = Tokens[i]; + foundOptionalToken |= token.Optional; + + if (foundOptionalToken && !token.Optional) + { + throw new InvalidOperationException(Resources.DirectiveDescriptor_InvalidNonOptionalToken); + } + } + + return new DefaultDirectiveDescriptor(Directive, Kind, Usage, Tokens.ToArray(), DisplayName, Description); + } + } + + private class DefaultDirectiveDescriptor : DirectiveDescriptor + { + public DefaultDirectiveDescriptor( + string directive, + DirectiveKind kind, + DirectiveUsage usage, + DirectiveTokenDescriptor[] tokens, + string displayName, + string description) + { + Directive = directive; + Kind = kind; + Usage = usage; + Tokens = tokens; + DisplayName = displayName; + Description = description; + } + + public override string Description { get; } + + public override string Directive { get; } + + public override string DisplayName { get; } + + public override DirectiveKind Kind { get; } + + public override DirectiveUsage Usage { get; } + + public override IReadOnlyList Tokens { get; } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptorBuilderExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptorBuilderExtensions.cs new file mode 100644 index 0000000000..1744475609 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptorBuilderExtensions.cs @@ -0,0 +1,186 @@ +// 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 +{ + public static class DirectiveDescriptorBuilderExtensions + { + public static IDirectiveDescriptorBuilder AddMemberToken(this IDirectiveDescriptorBuilder builder) + { + return AddMemberToken(builder, name: null, description: null); + } + + public static IDirectiveDescriptorBuilder AddMemberToken(this IDirectiveDescriptorBuilder builder, string name, string description) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Tokens.Add( + DirectiveTokenDescriptor.CreateToken( + DirectiveTokenKind.Member, + optional: false, + name: name, + description: description)); + + return builder; + } + + public static IDirectiveDescriptorBuilder AddNamespaceToken(this IDirectiveDescriptorBuilder builder) + { + return AddNamespaceToken(builder, name: null, description: null); + } + + public static IDirectiveDescriptorBuilder AddNamespaceToken(this IDirectiveDescriptorBuilder builder, string name, string description) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Tokens.Add( + DirectiveTokenDescriptor.CreateToken( + DirectiveTokenKind.Namespace, + optional: false, + name: name, + description: description)); + + return builder; + } + + public static IDirectiveDescriptorBuilder AddStringToken(this IDirectiveDescriptorBuilder builder) + { + return AddStringToken(builder, name: null, description: null); + } + + public static IDirectiveDescriptorBuilder AddStringToken(this IDirectiveDescriptorBuilder builder, string name, string description) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Tokens.Add( + DirectiveTokenDescriptor.CreateToken( + DirectiveTokenKind.String, + optional: false, + name: name, + description: description)); + + return builder; + } + + public static IDirectiveDescriptorBuilder AddTypeToken(this IDirectiveDescriptorBuilder builder) + { + return AddTypeToken(builder, name: null, description: null); + } + + public static IDirectiveDescriptorBuilder AddTypeToken(this IDirectiveDescriptorBuilder builder, string name, string description) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Tokens.Add( + DirectiveTokenDescriptor.CreateToken( + DirectiveTokenKind.Type, + optional: false, + name: name, + description: description)); + + return builder; + } + + public static IDirectiveDescriptorBuilder AddOptionalMemberToken(this IDirectiveDescriptorBuilder builder) + { + return AddOptionalMemberToken(builder, name: null, description: null); + } + + public static IDirectiveDescriptorBuilder AddOptionalMemberToken(this IDirectiveDescriptorBuilder builder, string name, string description) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Tokens.Add( + DirectiveTokenDescriptor.CreateToken( + DirectiveTokenKind.Member, + optional: true, + name: name, + description: description)); + + return builder; + } + + public static IDirectiveDescriptorBuilder AddOptionalNamespaceToken(this IDirectiveDescriptorBuilder builder) + { + return AddOptionalNamespaceToken(builder, name: null, description: null); + } + + public static IDirectiveDescriptorBuilder AddOptionalNamespaceToken(this IDirectiveDescriptorBuilder builder, string name, string description) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Tokens.Add( + DirectiveTokenDescriptor.CreateToken( + DirectiveTokenKind.Namespace, + optional: true, + name: name, + description: description)); + + return builder; + } + + public static IDirectiveDescriptorBuilder AddOptionalStringToken(this IDirectiveDescriptorBuilder builder) + { + return AddOptionalStringToken(builder, name: null, description: null); + } + + public static IDirectiveDescriptorBuilder AddOptionalStringToken(this IDirectiveDescriptorBuilder builder, string name, string description) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Tokens.Add( + DirectiveTokenDescriptor.CreateToken( + DirectiveTokenKind.String, + optional: true, + name: name, + description: description)); + + return builder; + } + + public static IDirectiveDescriptorBuilder AddOptionalTypeToken(this IDirectiveDescriptorBuilder builder) + { + return AddOptionalTypeToken(builder, name: null, description: null); + } + + public static IDirectiveDescriptorBuilder AddOptionalTypeToken(this IDirectiveDescriptorBuilder builder, string name, string description) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Tokens.Add( + DirectiveTokenDescriptor.CreateToken( + DirectiveTokenKind.Type, + optional: true, + name: name, + description: description)); + + return builder; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptorComparer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptorComparer.cs new file mode 100644 index 0000000000..c3a9590231 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveDescriptorComparer.cs @@ -0,0 +1,49 @@ +// 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.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DirectiveDescriptorComparer : IEqualityComparer + { + public static readonly DirectiveDescriptorComparer Default = new DirectiveDescriptorComparer(); + + protected DirectiveDescriptorComparer() + { + } + + public bool Equals(DirectiveDescriptor descriptorX, DirectiveDescriptor descriptorY) + { + if (descriptorX == descriptorY) + { + return true; + } + + return descriptorX != null && + string.Equals(descriptorX.Directive, descriptorY.Directive, StringComparison.Ordinal) && + descriptorX.Kind == descriptorY.Kind && + Enumerable.SequenceEqual( + descriptorX.Tokens, + descriptorY.Tokens, + DirectiveTokenDescriptorComparer.Default); + } + + public int GetHashCode(DirectiveDescriptor descriptor) + { + if (descriptor == null) + { + throw new ArgumentNullException(nameof(descriptor)); + } + + var hashCodeCombiner = HashCodeCombiner.Start(); + hashCodeCombiner.Add(descriptor.Directive, StringComparer.Ordinal); + hashCodeCombiner.Add(descriptor.Kind); + + return hashCodeCombiner.CombinedHash; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveKind.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveKind.cs new file mode 100644 index 0000000000..4c26a3c2af --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveKind.cs @@ -0,0 +1,12 @@ +// 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 +{ + public enum DirectiveKind + { + SingleLine, + RazorBlock, + CodeBlock + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveRemovalOptimizationPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveRemovalOptimizationPass.cs new file mode 100644 index 0000000000..5b7e136d3b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveRemovalOptimizationPass.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 System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DirectiveRemovalOptimizationPass : IntermediateNodePassBase, IRazorOptimizationPass + { + public override int Order => DefaultFeatureOrder + 50; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var visitor = new Visitor(); + visitor.VisitDocument(documentNode); + + foreach (var nodeReference in visitor.DirectiveNodes) + { + // Lift the diagnostics in the directive node up to the document node. + for (var i = 0; i < nodeReference.Node.Diagnostics.Count; i++) + { + documentNode.Diagnostics.Add(nodeReference.Node.Diagnostics[i]); + } + + nodeReference.Remove(); + } + } + + private class Visitor : IntermediateNodeWalker + { + public IList DirectiveNodes { get; } = new List(); + + public override void VisitDirective(DirectiveIntermediateNode node) + { + DirectiveNodes.Add(new IntermediateNodeReference(Parent, node)); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenDescriptor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenDescriptor.cs new file mode 100644 index 0000000000..1b6e63762d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenDescriptor.cs @@ -0,0 +1,50 @@ +// 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 +{ + public abstract class DirectiveTokenDescriptor + { + public abstract DirectiveTokenKind Kind { get; } + + public abstract bool Optional { get; } + + public virtual string Name { get; } + + public virtual string Description { get; } + + public static DirectiveTokenDescriptor CreateToken(DirectiveTokenKind kind) + { + return CreateToken(kind, optional: false); + } + + public static DirectiveTokenDescriptor CreateToken(DirectiveTokenKind kind, bool optional) + { + return CreateToken(kind, optional, name: null, description: null); + } + + public static DirectiveTokenDescriptor CreateToken(DirectiveTokenKind kind, bool optional, string name, string description) + { + return new DefaultDirectiveTokenDescriptor(kind, optional, name, description); + } + + private class DefaultDirectiveTokenDescriptor : DirectiveTokenDescriptor + { + public DefaultDirectiveTokenDescriptor(DirectiveTokenKind kind, bool optional, string name, string description) + { + Kind = kind; + Optional = optional; + Name = name; + Description = description; + } + + public override DirectiveTokenKind Kind { get; } + + public override bool Optional { get; } + + public override string Name { get; } + + public override string Description { get; } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenDescriptorComparer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenDescriptorComparer.cs new file mode 100644 index 0000000000..4ec1ba70d6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenDescriptorComparer.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 System; +using System.Collections.Generic; +using Microsoft.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DirectiveTokenDescriptorComparer : IEqualityComparer + { + public static readonly DirectiveTokenDescriptorComparer Default = new DirectiveTokenDescriptorComparer(); + + protected DirectiveTokenDescriptorComparer() + { + } + + public bool Equals(DirectiveTokenDescriptor descriptorX, DirectiveTokenDescriptor descriptorY) + { + if (descriptorX == descriptorY) + { + return true; + } + + return descriptorX != null && + descriptorX.Kind == descriptorY.Kind && + descriptorX.Optional == descriptorY.Optional; + } + + public int GetHashCode(DirectiveTokenDescriptor descriptor) + { + if (descriptor == null) + { + throw new ArgumentNullException(nameof(descriptor)); + } + + var hashCodeCombiner = HashCodeCombiner.Start(); + hashCodeCombiner.Add(descriptor.Kind); + hashCodeCombiner.Add(descriptor.Optional ? 1 : 0); + + return hashCodeCombiner.CombinedHash; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenEditHandler.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenEditHandler.cs new file mode 100644 index 0000000000..c84d8b0c67 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenEditHandler.cs @@ -0,0 +1,49 @@ +// 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.Syntax; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DirectiveTokenEditHandler : SpanEditHandler + { + public DirectiveTokenEditHandler(Func> tokenizer) : base(tokenizer) + { + } + + protected override PartialParseResultInternal CanAcceptChange(SyntaxNode target, SourceChange change) + { + if (AcceptedCharacters == AcceptedCharactersInternal.NonWhitespace) + { + var originalText = change.GetOriginalText(target); + var editedContent = change.GetEditedContent(target); + + if (!ContainsWhitespace(originalText) && !ContainsWhitespace(editedContent)) + { + // Did not modify whitespace, directive format should be the same. + // Return provisional so extensible IR/code gen pieces can see the full directive text + // once the user stops editing the document. + return PartialParseResultInternal.Accepted | PartialParseResultInternal.Provisional; + } + } + + return PartialParseResultInternal.Rejected; + } + + private static bool ContainsWhitespace(string content) + { + for (var i = 0; i < content.Length; i++) + { + if (char.IsWhiteSpace(content[i])) + { + return true; + } + } + + return false; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenKind.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenKind.cs new file mode 100644 index 0000000000..4ee292c083 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveTokenKind.cs @@ -0,0 +1,13 @@ +// 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 +{ + public enum DirectiveTokenKind + { + Type, + Namespace, + Member, + String, + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveUsage.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveUsage.cs new file mode 100644 index 0000000000..40e2eee78a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DirectiveUsage.cs @@ -0,0 +1,27 @@ +// 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 +{ + /// + /// The way a directive can be used. The usage determines how many, and where directives can exist per file. + /// + public enum DirectiveUsage + { + /// + /// Directive can exist anywhere in the file. + /// + Unrestricted, + + /// + /// Directive must exist prior to any HTML or code and have no duplicates. When importing the directive, if it is + /// , the last occurrence of the directive is imported. + /// + FileScopedSinglyOccurring, + + /// + /// Directive must exist prior to any HTML or code. + /// + FileScopedMultipleOccurring, + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DocumentClassifierPassBase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DocumentClassifierPassBase.cs new file mode 100644 index 0000000000..b72c90dd2f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DocumentClassifierPassBase.cs @@ -0,0 +1,153 @@ +// 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.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public abstract class DocumentClassifierPassBase : IntermediateNodePassBase, IRazorDocumentClassifierPass + { + private static readonly ICodeTargetExtension[] EmptyExtensionArray = new ICodeTargetExtension[0]; + private ICodeTargetExtension[] _targetExtensions; + + protected abstract string DocumentKind { get; } + + protected override void OnInitialized() + { + var feature = Engine.Features.OfType(); + _targetExtensions = feature.FirstOrDefault()?.TargetExtensions.ToArray() ?? EmptyExtensionArray; + } + + protected sealed override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.DocumentKind != null) + { + return; + } + + if (!IsMatch(codeDocument, documentNode)) + { + return; + } + + documentNode.DocumentKind = DocumentKind; + documentNode.Target = CreateTarget(codeDocument, documentNode.Options); + + Rewrite(codeDocument, documentNode); + } + + private void Rewrite(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + // Rewrite the document from a flat structure to use a sensible default structure, + // a namespace and class declaration with a single 'razor' method. + var children = new List(documentNode.Children); + documentNode.Children.Clear(); + + var @namespace = new NamespaceDeclarationIntermediateNode(); + @namespace.Annotations[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace; + + var @class = new ClassDeclarationIntermediateNode(); + @class.Annotations[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass; + + var method = new MethodDeclarationIntermediateNode(); + method.Annotations[CommonAnnotations.PrimaryMethod] = CommonAnnotations.PrimaryMethod; + + var documentBuilder = IntermediateNodeBuilder.Create(documentNode); + + var namespaceBuilder = IntermediateNodeBuilder.Create(documentBuilder.Current); + namespaceBuilder.Push(@namespace); + + var classBuilder = IntermediateNodeBuilder.Create(namespaceBuilder.Current); + classBuilder.Push(@class); + + var methodBuilder = IntermediateNodeBuilder.Create(classBuilder.Current); + methodBuilder.Push(method); + + var visitor = new Visitor(documentBuilder, namespaceBuilder, classBuilder, methodBuilder); + + for (var i = 0; i < children.Count; i++) + { + visitor.Visit(children[i]); + } + + // Note that this is called at the *end* of rewriting so that user code can see the tree + // and look at its content to make a decision. + OnDocumentStructureCreated(codeDocument, @namespace, @class, method); + } + + protected abstract bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode); + + private CodeTarget CreateTarget(RazorCodeDocument codeDocument, RazorCodeGenerationOptions options) + { + return CodeTarget.CreateDefault(codeDocument, options, (builder) => + { + for (var i = 0; i < _targetExtensions.Length; i++) + { + builder.TargetExtensions.Add(_targetExtensions[i]); + } + + ConfigureTarget(builder); + }); + } + + protected virtual void ConfigureTarget(CodeTargetBuilder builder) + { + // Intentionally empty. + } + + protected virtual void OnDocumentStructureCreated( + RazorCodeDocument codeDocument, + NamespaceDeclarationIntermediateNode @namespace, + ClassDeclarationIntermediateNode @class, + MethodDeclarationIntermediateNode @method) + { + // Intentionally empty. + } + + private class Visitor : IntermediateNodeVisitor + { + private readonly IntermediateNodeBuilder _document; + private readonly IntermediateNodeBuilder _namespace; + private readonly IntermediateNodeBuilder _class; + private readonly IntermediateNodeBuilder _method; + + public Visitor(IntermediateNodeBuilder document, IntermediateNodeBuilder @namespace, IntermediateNodeBuilder @class, IntermediateNodeBuilder method) + { + _document = document; + _namespace = @namespace; + _class = @class; + _method = method; + } + + public override void VisitUsingDirective(UsingDirectiveIntermediateNode node) + { + var children = _namespace.Current.Children; + var i = children.Count - 1; + for (; i >= 0; i--) + { + var child = children[i]; + if (child is UsingDirectiveIntermediateNode) + { + break; + } + } + + _namespace.Insert(i + 1, node); + } + + public override void VisitDefault(IntermediateNode node) + { + if (node is MemberDeclarationIntermediateNode) + { + _class.Add(node); + return; + } + + _method.Add(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/EmptyProjectFileSystem.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/EmptyProjectFileSystem.cs new file mode 100644 index 0000000000..61ced1271b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/EmptyProjectFileSystem.cs @@ -0,0 +1,23 @@ +// 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 +{ + internal class EmptyProjectFileSystem : RazorProjectFileSystem + { + public override IEnumerable EnumerateItems(string basePath) + { + NormalizeAndEnsureValidPath(basePath); + return Enumerable.Empty(); + } + + public override RazorProjectItem GetItem(string path) + { + NormalizeAndEnsureValidPath(path); + return new NotFoundProjectItem(string.Empty, path); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultMetadataIdentifierFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultMetadataIdentifierFeature.cs new file mode 100644 index 0000000000..89dc56c469 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultMetadataIdentifierFeature.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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + // The default scheme for identifiers matches MVC's view engine paths: + // 1. Normalize backslash to forward-slash + // 2. Always include leading slash + // 3. Always include file name and extensions + internal class DefaultMetadataIdentifierFeature : RazorEngineFeatureBase, IMetadataIdentifierFeature + { + public string GetIdentifier(RazorCodeDocument codeDocument, RazorSourceDocument sourceDocument) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (sourceDocument == null) + { + throw new ArgumentNullException(nameof(sourceDocument)); + } + + if (string.IsNullOrEmpty(sourceDocument.RelativePath)) + { + return null; + } + + var identifier = sourceDocument.RelativePath; + identifier = identifier.Replace("\\", "/"); + if (!identifier.StartsWith("/")) + { + identifier = "/" + identifier; + } + + return identifier; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperBodyIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperBodyIntermediateNode.cs new file mode 100644 index 0000000000..461df52991 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperBodyIntermediateNode.cs @@ -0,0 +1,74 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class DefaultTagHelperBodyIntermediateNode : ExtensionIntermediateNode + { + public DefaultTagHelperBodyIntermediateNode() + { + } + + public DefaultTagHelperBodyIntermediateNode(TagHelperBodyIntermediateNode bodyNode) + { + if (bodyNode == null) + { + throw new ArgumentNullException(nameof(bodyNode)); + } + + Source = bodyNode.Source; + + for (var i = 0; i < bodyNode.Children.Count; i++) + { + Children.Add(bodyNode.Children[i]); + } + + for (var i = 0; i < bodyNode.Diagnostics.Count; i++) + { + Diagnostics.Add(bodyNode.Diagnostics[i]); + } + } + + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public TagMode TagMode { get; set; } + + public string TagName { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperBody(context, this); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperCreateIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperCreateIntermediateNode.cs new file mode 100644 index 0000000000..0ef75f1b7a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperCreateIntermediateNode.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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class DefaultTagHelperCreateIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = IntermediateNodeCollection.ReadOnly; + + public string FieldName { get; set; } + + public TagHelperDescriptor TagHelper { get; set; } + + public string TypeName { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperCreate(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(TypeName); + + formatter.WriteProperty(nameof(FieldName), FieldName); + formatter.WriteProperty(nameof(TagHelper), TagHelper?.DisplayName); + formatter.WriteProperty(nameof(TypeName), TypeName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperExecuteIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperExecuteIntermediateNode.cs new file mode 100644 index 0000000000..35d4fa195c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperExecuteIntermediateNode.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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class DefaultTagHelperExecuteIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = IntermediateNodeCollection.ReadOnly; + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperExecute(context, this); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperHtmlAttributeIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperHtmlAttributeIntermediateNode.cs new file mode 100644 index 0000000000..0290be8323 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperHtmlAttributeIntermediateNode.cs @@ -0,0 +1,84 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class DefaultTagHelperHtmlAttributeIntermediateNode : ExtensionIntermediateNode + { + public DefaultTagHelperHtmlAttributeIntermediateNode() + { + } + + public DefaultTagHelperHtmlAttributeIntermediateNode(TagHelperHtmlAttributeIntermediateNode htmlAttributeNode) + { + if (htmlAttributeNode == null) + { + throw new ArgumentNullException(nameof(htmlAttributeNode)); + } + + AttributeName = htmlAttributeNode.AttributeName; + AttributeStructure = htmlAttributeNode.AttributeStructure; + Source = htmlAttributeNode.Source; + + for (var i = 0; i < htmlAttributeNode.Children.Count; i++) + { + Children.Add(htmlAttributeNode.Children[i]); + } + + for (var i = 0; i < htmlAttributeNode.Diagnostics.Count; i++) + { + Diagnostics.Add(htmlAttributeNode.Diagnostics[i]); + } + } + + public string AttributeName { get; set; } + + public AttributeStructure AttributeStructure { get; set; } + + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperHtmlAttribute(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(AttributeName); + + formatter.WriteProperty(nameof(AttributeName), AttributeName); + formatter.WriteProperty(nameof(AttributeStructure), AttributeStructure.ToString()); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperOptimizationPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperOptimizationPass.cs new file mode 100644 index 0000000000..ef777ff754 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperOptimizationPass.cs @@ -0,0 +1,259 @@ +// 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.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal class DefaultTagHelperOptimizationPass : IntermediateNodePassBase, IRazorOptimizationPass + { + // Run later than default order for user code so other passes have a chance to modify the + // tag helper nodes. + public override int Order => DefaultFeatureOrder + 1000; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var @class = documentNode.FindPrimaryClass(); + if (@class == null) + { + // Bail if we can't find a class node, we need to be able to create fields. + return; + } + + var context = new Context(@class); + + // First find all tag helper nodes that require the default tag helper runtime. + // + // This phase lowers the conceptual nodes to default runtime nodes we only care about those. + var tagHelperNodes = documentNode + .FindDescendantNodes() + .Where(IsTagHelperRuntimeNode) + .ToArray(); + + if (tagHelperNodes.Length == 0) + { + // If nothing uses the default runtime then we're done. + return; + } + + AddDefaultRuntime(context); + + // Each tagHelperNode should be rewritten to use the default tag helper runtime. That doesn't necessarily + // mean that all of these tag helpers are the default kind, just that them are compatible with ITagHelper. + for (var i = 0; i < tagHelperNodes.Length; i++) + { + var tagHelperNode = tagHelperNodes[i]; + + RewriteBody(tagHelperNode); + RewriteHtmlAttributes(tagHelperNode); + AddExecute(tagHelperNode); + + // We need to find all of the 'default' kind tag helpers and rewrite their usage site to use the + // extension nodes for the default tag helper runtime (ITagHelper). + foreach (var tagHelper in tagHelperNode.TagHelpers) + { + RewriteUsage(context, tagHelperNode, tagHelper); + } + } + + // Then for each 'default' kind tag helper we need to generate the field that will hold it. + foreach (var tagHelper in context.TagHelpers) + { + AddField(context, tagHelper); + } + } + + private void AddDefaultRuntime(Context context) + { + // We need to insert a node for the field that will hold the tag helper. We've already generated a field name + // at this time and use it for all uses of the same tag helper type. + // + // We also want to preserve the ordering of the nodes for testability. So insert at the end of any existing + // field nodes. + var i = 0; + while (i < context.Class.Children.Count && context.Class.Children[i] is FieldDeclarationIntermediateNode) + { + i++; + } + + context.Class.Children.Insert(i, new DefaultTagHelperRuntimeIntermediateNode()); + } + + private void RewriteBody(TagHelperIntermediateNode node) + { + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is TagHelperBodyIntermediateNode bodyNode) + { + // We only expect one body node. + node.Children[i] = new DefaultTagHelperBodyIntermediateNode(bodyNode) + { + TagMode = node.TagMode, + TagName = node.TagName, + }; + break; + } + } + } + + private void AddExecute(TagHelperIntermediateNode node) + { + // Execute the tag helpers at the end, before leaving scope. + node.Children.Add(new DefaultTagHelperExecuteIntermediateNode()); + } + + private void RewriteHtmlAttributes(TagHelperIntermediateNode node) + { + // We need to rewrite each html attribute, so that it will get added to the execution context. + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is TagHelperHtmlAttributeIntermediateNode htmlAttributeNode) + { + node.Children[i] = new DefaultTagHelperHtmlAttributeIntermediateNode(htmlAttributeNode); + } + } + } + + private void RewriteUsage(Context context, TagHelperIntermediateNode node, TagHelperDescriptor tagHelper) + { + if (!tagHelper.IsDefaultKind()) + { + return; + } + + context.Add(tagHelper); + + // First we need to insert a node for the creation of the tag helper, and the hook up to the execution + // context. This should come after the body node and any existing create nodes. + // + // If we're dealing with something totally malformed, then we'll end up just inserting at the end, and that's not + // so bad. + var i = 0; + + // Find the body node. + while (i < node.Children.Count && node.Children[i] is TagHelperBodyIntermediateNode) + { + i++; + } + while (i < node.Children.Count && node.Children[i] is DefaultTagHelperBodyIntermediateNode) + { + i++; + } + + // Now find the last create node. + while (i < node.Children.Count && node.Children[i] is DefaultTagHelperCreateIntermediateNode) + { + i++; + } + + // Now i has the right insertion point. + node.Children.Insert(i, new DefaultTagHelperCreateIntermediateNode() + { + FieldName = context.GetFieldName(tagHelper), + TagHelper = tagHelper, + TypeName = tagHelper.GetTypeName(), + }); + + // Next we need to rewrite any property nodes to use the field and property name for this + // tag helper. + for (i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode && + propertyNode.TagHelper == tagHelper) + { + // This belongs to the current tag helper, replace it. + node.Children[i] = new DefaultTagHelperPropertyIntermediateNode(propertyNode) + { + FieldName = context.GetFieldName(tagHelper), + PropertyName = propertyNode.BoundAttribute.GetPropertyName(), + }; + } + } + } + + private void AddField(Context context, TagHelperDescriptor tagHelper) + { + // We need to insert a node for the field that will hold the tag helper. We've already generated a field name + // at this time and use it for all uses of the same tag helper type. + // + // We also want to preserve the ordering of the nodes for testability. So insert at the end of any existing + // field nodes. + var i = 0; + while (i < context.Class.Children.Count && context.Class.Children[i] is DefaultTagHelperRuntimeIntermediateNode) + { + i++; + } + + while (i < context.Class.Children.Count && context.Class.Children[i] is FieldDeclarationIntermediateNode) + { + i++; + } + + context.Class.Children.Insert(i, new FieldDeclarationIntermediateNode() + { + Annotations = + { + { CommonAnnotations.DefaultTagHelperExtension.TagHelperField, bool.TrueString }, + }, + Modifiers = + { + "private", + }, + FieldName = context.GetFieldName(tagHelper), + FieldType = "global::" + tagHelper.GetTypeName(), + }); + } + + private bool IsTagHelperRuntimeNode(TagHelperIntermediateNode node) + { + foreach (var tagHelper in node.TagHelpers) + { + if (tagHelper.KindUsesDefaultTagHelperRuntime()) + { + return true; + } + } + + return false; + } + + private struct Context + { + private readonly Dictionary _tagHelpers; + + public Context(ClassDeclarationIntermediateNode @class) + { + Class = @class; + + _tagHelpers = new Dictionary(TagHelperDescriptorComparer.Default); + } + + public ClassDeclarationIntermediateNode Class { get; } + + public IEnumerable TagHelpers => _tagHelpers.Keys; + + public bool Add(TagHelperDescriptor tagHelper) + { + if (_tagHelpers.ContainsKey(tagHelper)) + { + return false; + } + + _tagHelpers.Add(tagHelper, GenerateFieldName(tagHelper)); + return true; + } + + public string GetFieldName(TagHelperDescriptor tagHelper) + { + return _tagHelpers[tagHelper]; + } + + private static string GenerateFieldName(TagHelperDescriptor tagHelper) + { + return "__" + tagHelper.GetTypeName().Replace('.', '_'); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperPropertyIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperPropertyIntermediateNode.cs new file mode 100644 index 0000000000..c0362f0d60 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperPropertyIntermediateNode.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.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class DefaultTagHelperPropertyIntermediateNode : ExtensionIntermediateNode + { + public DefaultTagHelperPropertyIntermediateNode() + { + } + + public DefaultTagHelperPropertyIntermediateNode(TagHelperPropertyIntermediateNode propertyNode) + { + if (propertyNode == null) + { + throw new ArgumentNullException(nameof(propertyNode)); + } + + AttributeName = propertyNode.AttributeName; + AttributeStructure = propertyNode.AttributeStructure; + BoundAttribute = propertyNode.BoundAttribute; + IsIndexerNameMatch = propertyNode.IsIndexerNameMatch; + Source = propertyNode.Source; + TagHelper = propertyNode.TagHelper; + + for (var i = 0; i < propertyNode.Children.Count; i++) + { + Children.Add(propertyNode.Children[i]); + } + + for (var i = 0; i < propertyNode.Diagnostics.Count; i++) + { + Diagnostics.Add(propertyNode.Diagnostics[i]); + } + } + + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string AttributeName { get; set; } + + public AttributeStructure AttributeStructure { get; set; } + + public BoundAttributeDescriptor BoundAttribute { get; set; } + + public string FieldName { get; set; } + + public bool IsIndexerNameMatch { get; set; } + + public string PropertyName { get; set; } + + public TagHelperDescriptor TagHelper { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperProperty(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(AttributeName); + + formatter.WriteProperty(nameof(AttributeName), AttributeName); + formatter.WriteProperty(nameof(AttributeStructure), AttributeStructure.ToString()); + formatter.WriteProperty(nameof(BoundAttribute), BoundAttribute?.DisplayName); + formatter.WriteProperty(nameof(FieldName), FieldName); + formatter.WriteProperty(nameof(IsIndexerNameMatch), IsIndexerNameMatch.ToString()); + formatter.WriteProperty(nameof(PropertyName), PropertyName); + formatter.WriteProperty(nameof(TagHelper), TagHelper?.DisplayName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperRuntimeIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperRuntimeIntermediateNode.cs new file mode 100644 index 0000000000..74f33baddd --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperRuntimeIntermediateNode.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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class DefaultTagHelperRuntimeIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperRuntime(context, this); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperTargetExtension.cs new file mode 100644 index 0000000000..884ef07df5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DefaultTagHelperTargetExtension.cs @@ -0,0 +1,663 @@ +// 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.Globalization; +using System.Linq; +using System.Text; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.Language.Legacy; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal sealed class DefaultTagHelperTargetExtension : IDefaultTagHelperTargetExtension + { + private static readonly string[] PrivateModifiers = new string[] { "private" }; + + public string RunnerVariableName { get; set; } = "__tagHelperRunner"; + + public string StringValueBufferVariableName { get; set; } = "__tagHelperStringValueBuffer"; + + public string CreateTagHelperMethodName { get; set; } = "CreateTagHelper"; + + public string ExecutionContextTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext"; + + public string ExecutionContextVariableName { get; set; } = "__tagHelperExecutionContext"; + + public string ExecutionContextAddMethodName { get; set; } = "Add"; + + public string TagHelperRunnerTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner"; + + public string ExecutionContextOutputPropertyName { get; set; } = "Output"; + + public string ExecutionContextSetOutputContentAsyncMethodName { get; set; } = "SetOutputContentAsync"; + + public string ExecutionContextAddHtmlAttributeMethodName { get; set; } = "AddHtmlAttribute"; + + public string ExecutionContextAddTagHelperAttributeMethodName { get; set; } = "AddTagHelperAttribute"; + + public string RunnerRunAsyncMethodName { get; set; } = "RunAsync"; + + public string ScopeManagerTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager"; + + public string ScopeManagerVariableName { get; set; } = "__tagHelperScopeManager"; + + public string ScopeManagerBeginMethodName { get; set; } = "Begin"; + + public string ScopeManagerEndMethodName { get; set; } = "End"; + + public string StartTagHelperWritingScopeMethodName { get; set; } = "StartTagHelperWritingScope"; + + public string EndTagHelperWritingScopeMethodName { get; set; } = "EndTagHelperWritingScope"; + + public string TagModeTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode"; + + public string HtmlAttributeValueStyleTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle"; + + public string TagHelperOutputIsContentModifiedPropertyName { get; set; } = "IsContentModified"; + + public string BeginAddHtmlAttributeValuesMethodName { get; set; } = "BeginAddHtmlAttributeValues"; + + public string EndAddHtmlAttributeValuesMethodName { get; set; } = "EndAddHtmlAttributeValues"; + + public string BeginWriteTagHelperAttributeMethodName { get; set; } = "BeginWriteTagHelperAttribute"; + + public string EndWriteTagHelperAttributeMethodName { get; set; } = "EndWriteTagHelperAttribute"; + + public string MarkAsHtmlEncodedMethodName { get; set; } = "Html.Raw"; + + public string FormatInvalidIndexerAssignmentMethodName { get; set; } = "InvalidTagHelperIndexerAssignment"; + + public string WriteTagHelperOutputMethod { get; set; } = "Write"; + + public void WriteTagHelperBody(CodeRenderingContext context, DefaultTagHelperBodyIntermediateNode node) + { + if (context.Parent as TagHelperIntermediateNode == null) + { + var message = Resources.FormatIntermediateNodes_InvalidParentNode(node.GetType(), typeof(TagHelperIntermediateNode)); + throw new InvalidOperationException(message); + } + + if (context.Options.DesignTime) + { + context.RenderChildren(node); + } + else + { + // Call into the tag helper scope manager to start a new tag helper scope. + // Also capture the value as the current execution context. + context.CodeWriter + .WriteStartAssignment(ExecutionContextVariableName) + .WriteStartInstanceMethodInvocation( + ScopeManagerVariableName, + ScopeManagerBeginMethodName); + + // Assign a unique ID for this instance of the source HTML tag. This must be unique + // per call site, e.g. if the tag is on the view twice, there should be two IDs. + var uniqueId = (string)context.Items[CodeRenderingContext.SuppressUniqueIds]; + if (uniqueId == null) + { + uniqueId = GetDeterministicId(context); + } + + context.CodeWriter.WriteStringLiteral(node.TagName) + .WriteParameterSeparator() + .Write(TagModeTypeName) + .Write(".") + .Write(node.TagMode.ToString()) + .WriteParameterSeparator() + .WriteStringLiteral(uniqueId) + .WriteParameterSeparator(); + + using (context.CodeWriter.BuildAsyncLambda()) + { + // We remove and redirect writers so TagHelper authors can retrieve content. + context.RenderChildren(node, new RuntimeNodeWriter()); + } + + context.CodeWriter.WriteEndMethodInvocation(); + } + } + + public void WriteTagHelperCreate(CodeRenderingContext context, DefaultTagHelperCreateIntermediateNode node) + { + if (context.Parent as TagHelperIntermediateNode == null) + { + var message = Resources.FormatIntermediateNodes_InvalidParentNode(node.GetType(), typeof(TagHelperIntermediateNode)); + throw new InvalidOperationException(message); + } + + context.CodeWriter + .WriteStartAssignment(node.FieldName) + .Write(CreateTagHelperMethodName) + .WriteLine("();"); + + if (!context.Options.DesignTime) + { + context.CodeWriter.WriteInstanceMethodInvocation( + ExecutionContextVariableName, + ExecutionContextAddMethodName, + node.FieldName); + } + } + + public void WriteTagHelperExecute(CodeRenderingContext context, DefaultTagHelperExecuteIntermediateNode node) + { + if (context.Parent as TagHelperIntermediateNode == null) + { + var message = Resources.FormatIntermediateNodes_InvalidParentNode(node.GetType(), typeof(TagHelperIntermediateNode)); + throw new InvalidOperationException(message); + } + + if (!context.Options.DesignTime) + { + context.CodeWriter + .Write("await ") + .WriteStartInstanceMethodInvocation( + RunnerVariableName, + RunnerRunAsyncMethodName) + .Write(ExecutionContextVariableName) + .WriteEndMethodInvocation(); + + var tagHelperOutputAccessor = $"{ExecutionContextVariableName}.{ExecutionContextOutputPropertyName}"; + + context.CodeWriter + .Write("if (!") + .Write(tagHelperOutputAccessor) + .Write(".") + .Write(TagHelperOutputIsContentModifiedPropertyName) + .WriteLine(")"); + + using (context.CodeWriter.BuildScope()) + { + context.CodeWriter + .Write("await ") + .WriteInstanceMethodInvocation( + ExecutionContextVariableName, + ExecutionContextSetOutputContentAsyncMethodName); + } + + context.CodeWriter + .WriteStartMethodInvocation(WriteTagHelperOutputMethod) + .Write(tagHelperOutputAccessor) + .WriteEndMethodInvocation() + .WriteStartAssignment(ExecutionContextVariableName) + .WriteInstanceMethodInvocation( + ScopeManagerVariableName, + ScopeManagerEndMethodName); + } + } + + public void WriteTagHelperHtmlAttribute(CodeRenderingContext context, DefaultTagHelperHtmlAttributeIntermediateNode node) + { + if (context.Parent as TagHelperIntermediateNode == null) + { + var message = Resources.FormatIntermediateNodes_InvalidParentNode(node.GetType(), typeof(TagHelperIntermediateNode)); + throw new InvalidOperationException(message); + } + + if (context.Options.DesignTime) + { + context.RenderChildren(node); + } + else + { + var attributeValueStyleParameter = $"{HtmlAttributeValueStyleTypeName}.{node.AttributeStructure}"; + var isConditionalAttributeValue = node.Children.Any( + child => child is CSharpExpressionAttributeValueIntermediateNode || child is CSharpCodeAttributeValueIntermediateNode); + + // All simple text and minimized attributes will be pre-allocated. + if (isConditionalAttributeValue) + { + // Dynamic attribute value should be run through the conditional attribute removal system. It's + // unbound and contains C#. + + // TagHelper attribute rendering is buffered by default. We do not want to write to the current + // writer. + var valuePieceCount = node.Children.Count( + child => + child is HtmlAttributeValueIntermediateNode || + child is CSharpExpressionAttributeValueIntermediateNode || + child is CSharpCodeAttributeValueIntermediateNode || + child is ExtensionIntermediateNode); + + context.CodeWriter + .WriteStartMethodInvocation(BeginAddHtmlAttributeValuesMethodName) + .Write(ExecutionContextVariableName) + .WriteParameterSeparator() + .WriteStringLiteral(node.AttributeName) + .WriteParameterSeparator() + .Write(valuePieceCount.ToString(CultureInfo.InvariantCulture)) + .WriteParameterSeparator() + .Write(attributeValueStyleParameter) + .WriteEndMethodInvocation(); + + context.RenderChildren(node, new TagHelperHtmlAttributeRuntimeNodeWriter()); + + context.CodeWriter + .WriteMethodInvocation( + EndAddHtmlAttributeValuesMethodName, + ExecutionContextVariableName); + } + else + { + // This is a data-* attribute which includes C#. Do not perform the conditional attribute removal or + // other special cases used when IsDynamicAttributeValue(). But the attribute must still be buffered to + // determine its final value. + + // Attribute value is not plain text, must be buffered to determine its final value. + context.CodeWriter.WriteMethodInvocation(BeginWriteTagHelperAttributeMethodName); + + // We're building a writing scope around the provided chunks which captures everything written from the + // page. Therefore, we do not want to write to any other buffer since we're using the pages buffer to + // ensure we capture all content that's written, directly or indirectly. + context.RenderChildren(node, new RuntimeNodeWriter()); + + context.CodeWriter + .WriteStartAssignment(StringValueBufferVariableName) + .WriteMethodInvocation(EndWriteTagHelperAttributeMethodName) + .WriteStartInstanceMethodInvocation( + ExecutionContextVariableName, + ExecutionContextAddHtmlAttributeMethodName) + .WriteStringLiteral(node.AttributeName) + .WriteParameterSeparator() + .WriteStartMethodInvocation(MarkAsHtmlEncodedMethodName) + .Write(StringValueBufferVariableName) + .WriteEndMethodInvocation(endLine: false) + .WriteParameterSeparator() + .Write(attributeValueStyleParameter) + .WriteEndMethodInvocation(); + } + } + } + + public void WriteTagHelperProperty(CodeRenderingContext context, DefaultTagHelperPropertyIntermediateNode node) + { + var tagHelperNode = context.Parent as TagHelperIntermediateNode; + if (context.Parent == null) + { + var message = Resources.FormatIntermediateNodes_InvalidParentNode(node.GetType(), typeof(TagHelperIntermediateNode)); + throw new InvalidOperationException(message); + } + + if (!context.Options.DesignTime) + { + // Ensure that the property we're trying to set has initialized its dictionary bound properties. + if (node.IsIndexerNameMatch && + object.ReferenceEquals(FindFirstUseOfIndexer(tagHelperNode, node), node)) + { + // Throw a reasonable Exception at runtime if the dictionary property is null. + context.CodeWriter + .Write("if (") + .Write(node.FieldName) + .Write(".") + .Write(node.PropertyName) + .WriteLine(" == null)"); + using (context.CodeWriter.BuildScope()) + { + // System is in Host.NamespaceImports for all MVC scenarios. No need to generate FullName + // of InvalidOperationException type. + context.CodeWriter + .Write("throw ") + .WriteStartNewObject(nameof(InvalidOperationException)) + .WriteStartMethodInvocation(FormatInvalidIndexerAssignmentMethodName) + .WriteStringLiteral(node.AttributeName) + .WriteParameterSeparator() + .WriteStringLiteral(node.TagHelper.GetTypeName()) + .WriteParameterSeparator() + .WriteStringLiteral(node.PropertyName) + .WriteEndMethodInvocation(endLine: false) // End of method call + .WriteEndMethodInvocation(); // End of new expression / throw statement + } + } + } + + // If this is not the first use of the attribute value, we need to evaluate the expression and assign it to + // the tag helper property. + // + // Otherwise, the value has already been computed and assigned to another tag helper. We just need to + // copy from that tag helper to this one. + // + // This is important because we can't evaluate the expression twice due to side-effects. + var firstUseOfAttribute = FindFirstUseOfAttribute(tagHelperNode, node); + if (!object.ReferenceEquals(firstUseOfAttribute, node)) + { + // If we get here, this value has already been used. We just need to copy the value. + context.CodeWriter + .WriteStartAssignment(GetPropertyAccessor(node)) + .Write(GetPropertyAccessor(firstUseOfAttribute)) + .WriteLine(";"); + + return; + } + + // If we get there, this is the first time seeing this property so we need to evaluate the expression. + if (node.BoundAttribute.ExpectsStringValue(node.AttributeName)) + { + if (context.Options.DesignTime) + { + context.RenderChildren(node); + + context.CodeWriter.WriteStartAssignment(GetPropertyAccessor(node)); + if (node.Children.Count == 1 && node.Children.First() is HtmlContentIntermediateNode htmlNode) + { + var content = GetContent(htmlNode); + context.CodeWriter.WriteStringLiteral(content); + } + else + { + context.CodeWriter.Write("string.Empty"); + } + context.CodeWriter.WriteLine(";"); + } + else + { + context.CodeWriter.WriteMethodInvocation(BeginWriteTagHelperAttributeMethodName); + + context.RenderChildren(node, new LiteralRuntimeNodeWriter()); + + context.CodeWriter + .WriteStartAssignment(StringValueBufferVariableName) + .WriteMethodInvocation(EndWriteTagHelperAttributeMethodName) + .WriteStartAssignment(GetPropertyAccessor(node)) + .Write(StringValueBufferVariableName) + .WriteLine(";"); + } + } + else + { + if (context.Options.DesignTime) + { + var firstMappedChild = node.Children.FirstOrDefault(child => child.Source != null) as IntermediateNode; + var valueStart = firstMappedChild?.Source; + + using (context.CodeWriter.BuildLinePragma(node.Source)) + { + var accessor = GetPropertyAccessor(node); + var assignmentPrefixLength = accessor.Length + " = ".Length; + if (node.BoundAttribute.IsEnum && + node.Children.Count == 1 && + node.Children.First() is IntermediateToken token && + token.IsCSharp) + { + assignmentPrefixLength += $"global::{node.BoundAttribute.TypeName}.".Length; + + if (valueStart != null) + { + context.CodeWriter.WritePadding(assignmentPrefixLength, node.Source, context); + } + + context.CodeWriter + .WriteStartAssignment(accessor) + .Write("global::") + .Write(node.BoundAttribute.TypeName) + .Write("."); + } + else + { + if (valueStart != null) + { + context.CodeWriter.WritePadding(assignmentPrefixLength, node.Source, context); + } + + context.CodeWriter.WriteStartAssignment(GetPropertyAccessor(node)); + } + + if (node.Children.Count == 0 && + node.AttributeStructure == AttributeStructure.Minimized && + node.BoundAttribute.ExpectsBooleanValue(node.AttributeName)) + { + // If this is a minimized boolean attribute, set the value to true. + context.CodeWriter.Write("true"); + } + else + { + RenderTagHelperAttributeInline(context, node, node.Source); + } + + context.CodeWriter.WriteLine(";"); + } + } + else + { + using (context.CodeWriter.BuildLinePragma(node.Source)) + { + context.CodeWriter.WriteStartAssignment(GetPropertyAccessor(node)); + + if (node.BoundAttribute.IsEnum && + node.Children.Count == 1 && + node.Children.First() is IntermediateToken token && + token.IsCSharp) + { + context.CodeWriter + .Write("global::") + .Write(node.BoundAttribute.TypeName) + .Write("."); + } + + if (node.Children.Count == 0 && + node.AttributeStructure == AttributeStructure.Minimized && + node.BoundAttribute.ExpectsBooleanValue(node.AttributeName)) + { + // If this is a minimized boolean attribute, set the value to true. + context.CodeWriter.Write("true"); + } + else + { + RenderTagHelperAttributeInline(context, node, node.Source); + } + + context.CodeWriter.WriteLine(";"); + } + } + } + + if (!context.Options.DesignTime) + { + // We need to inform the context of the attribute value. + context.CodeWriter + .WriteStartInstanceMethodInvocation( + ExecutionContextVariableName, + ExecutionContextAddTagHelperAttributeMethodName) + .WriteStringLiteral(node.AttributeName) + .WriteParameterSeparator() + .Write(GetPropertyAccessor(node)) + .WriteParameterSeparator() + .Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.AttributeStructure}") + .WriteEndMethodInvocation(); + } + } + + public void WriteTagHelperRuntime(CodeRenderingContext context, DefaultTagHelperRuntimeIntermediateNode node) + { + if (!context.Options.DesignTime) + { + context.CodeWriter.WriteLine("#line hidden"); + + // Need to disable the warning "X is never used." for the value buffer since + // whether it's used depends on how a TagHelper is used. + context.CodeWriter.WriteLine("#pragma warning disable 0169"); + context.CodeWriter.WriteField(PrivateModifiers, "string", StringValueBufferVariableName); + context.CodeWriter.WriteLine("#pragma warning restore 0169"); + + context.CodeWriter.WriteField(PrivateModifiers, ExecutionContextTypeName, ExecutionContextVariableName); + + context.CodeWriter + .Write("private ") + .Write(TagHelperRunnerTypeName) + .Write(" ") + .Write(RunnerVariableName) + .Write(" = new ") + .Write(TagHelperRunnerTypeName) + .WriteLine("();"); + + var backedScopeManageVariableName = "__backed" + ScopeManagerVariableName; + context.CodeWriter + .Write("private ") + .WriteVariableDeclaration( + ScopeManagerTypeName, + backedScopeManageVariableName, + value: null); + + context.CodeWriter + .Write("private ") + .Write(ScopeManagerTypeName) + .Write(" ") + .WriteLine(ScopeManagerVariableName); + + using (context.CodeWriter.BuildScope()) + { + context.CodeWriter.WriteLine("get"); + using (context.CodeWriter.BuildScope()) + { + context.CodeWriter + .Write("if (") + .Write(backedScopeManageVariableName) + .WriteLine(" == null)"); + + using (context.CodeWriter.BuildScope()) + { + context.CodeWriter + .WriteStartAssignment(backedScopeManageVariableName) + .WriteStartNewObject(ScopeManagerTypeName) + .Write(StartTagHelperWritingScopeMethodName) + .WriteParameterSeparator() + .Write(EndTagHelperWritingScopeMethodName) + .WriteEndMethodInvocation(); + } + + context.CodeWriter + .Write("return ") + .Write(backedScopeManageVariableName) + .WriteLine(";"); + } + } + } + } + + private void RenderTagHelperAttributeInline( + CodeRenderingContext context, + DefaultTagHelperPropertyIntermediateNode property, + SourceSpan? span) + { + for (var i = 0; i < property.Children.Count; i++) + { + RenderTagHelperAttributeInline(context, property, property.Children[i], span); + } + } + + // Internal for testing + internal void RenderTagHelperAttributeInline( + CodeRenderingContext context, + DefaultTagHelperPropertyIntermediateNode property, + IntermediateNode node, + SourceSpan? span) + { + if (node is CSharpExpressionIntermediateNode || node is HtmlContentIntermediateNode) + { + for (var i = 0; i < node.Children.Count; i++) + { + RenderTagHelperAttributeInline(context, property, node.Children[i], span); + } + } + else if (node is IntermediateToken token) + { + if (context.Options.DesignTime && node.Source != null) + { + context.AddSourceMappingFor(node); + } + + context.CodeWriter.Write(token.Content); + } + else if (node is CSharpCodeIntermediateNode) + { + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_CodeBlocksNotSupportedInAttributes(span ?? SourceSpan.Undefined); + context.Diagnostics.Add(diagnostic); + } + else if (node is TemplateIntermediateNode) + { + var expectedTypeName = property.IsIndexerNameMatch ? property.BoundAttribute.IndexerTypeName : property.BoundAttribute.TypeName; + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(span ?? SourceSpan.Undefined, expectedTypeName); + context.Diagnostics.Add(diagnostic); + } + } + + private static DefaultTagHelperPropertyIntermediateNode FindFirstUseOfIndexer( + TagHelperIntermediateNode tagHelperNode, + DefaultTagHelperPropertyIntermediateNode propertyNode) + { + Debug.Assert(tagHelperNode.Children.Contains(propertyNode)); + Debug.Assert(propertyNode.IsIndexerNameMatch); + + for (var i = 0; i < tagHelperNode.Children.Count; i++) + { + if (tagHelperNode.Children[i] is DefaultTagHelperPropertyIntermediateNode otherPropertyNode && + otherPropertyNode.TagHelper.Equals(propertyNode.TagHelper) && + otherPropertyNode.BoundAttribute.Equals(propertyNode.BoundAttribute) && + otherPropertyNode.IsIndexerNameMatch) + { + return otherPropertyNode; + } + } + + // This is unreachable, we should find 'propertyNode' in the list of children. + throw new InvalidOperationException(); + } + + private static DefaultTagHelperPropertyIntermediateNode FindFirstUseOfAttribute( + TagHelperIntermediateNode tagHelperNode, + DefaultTagHelperPropertyIntermediateNode propertyNode) + { + for (var i = 0; i < tagHelperNode.Children.Count; i++) + { + if (tagHelperNode.Children[i] is DefaultTagHelperPropertyIntermediateNode otherPropertyNode && + string.Equals(otherPropertyNode.AttributeName, propertyNode.AttributeName, StringComparison.Ordinal)) + { + return otherPropertyNode; + } + } + + // This is unreachable, we should find 'propertyNode' in the list of children. + throw new InvalidOperationException(); + } + + private string GetContent(HtmlContentIntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsHtml) + { + builder.Append(token.Content); + } + } + + return builder.ToString(); + } + + // Internal for testing + internal static string GetDeterministicId(CodeRenderingContext context) + { + // Use the file checksum along with the absolute position in the generated code to create a unique id for each tag helper call site. + var checksum = Checksum.BytesToString(context.SourceDocument.GetChecksum()); + var uniqueId = checksum + context.CodeWriter.Location.AbsoluteIndex; + + return uniqueId; + } + + private static string GetPropertyAccessor(DefaultTagHelperPropertyIntermediateNode node) + { + var propertyAccessor = $"{node.FieldName}.{node.PropertyName}"; + + if (node.IsIndexerNameMatch) + { + var dictionaryKey = node.AttributeName.Substring(node.BoundAttribute.IndexerNamePrefix.Length); + propertyAccessor += $"[\"{dictionaryKey}\"]"; + } + + return propertyAccessor; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectiveIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectiveIntermediateNode.cs new file mode 100644 index 0000000000..957e73a17d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectiveIntermediateNode.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 System; +using System.Text; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal sealed class DesignTimeDirectiveIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteDesignTimeDirective(context, this); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectivePass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectivePass.cs new file mode 100644 index 0000000000..6d6d7e261d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectivePass.cs @@ -0,0 +1,82 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal class DesignTimeDirectivePass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + internal const string DesignTimeVariable = "__o"; + + // This needs to run after other directive classifiers. Any DirectiveToken that is not removed + // by the previous classifiers will have auto-generated design time support. + public override int Order => DefaultFeatureOrder; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + // Only supports design time. This pass rewrites directives so they will have the right design time + // behavior and would break things if it ran for runtime. + if (!documentNode.Options.DesignTime) + { + return; + } + + var walker = new DesignTimeHelperWalker(); + walker.VisitDocument(documentNode); + } + + internal class DesignTimeHelperWalker : IntermediateNodeWalker + { + private DesignTimeDirectiveIntermediateNode _directiveNode; + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + node.Children.Insert(0, new CSharpCodeIntermediateNode() + { + Children = + { + new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = "#pragma warning disable 0414", + } + } + }); + node.Children.Insert(1, new CSharpCodeIntermediateNode() + { + Children = + { + new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = $"private static {typeof(object).FullName} {DesignTimeVariable} = null;", + } + } + }); + node.Children.Insert(2, new CSharpCodeIntermediateNode() + { + Children = + { + new IntermediateToken() + { + Kind = TokenKind.CSharp, + Content = "#pragma warning restore 0414", + } + } + }); + + _directiveNode = new DesignTimeDirectiveIntermediateNode(); + + VisitDefault(node); + + node.Children.Insert(0, _directiveNode); + } + + public override void VisitDirectiveToken(DirectiveTokenIntermediateNode node) + { + _directiveNode.Children.Add(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectiveTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectiveTargetExtension.cs new file mode 100644 index 0000000000..29cc438fbb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/DesignTimeDirectiveTargetExtension.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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal class DesignTimeDirectiveTargetExtension : IDesignTimeDirectiveTargetExtension + { + private const string DirectiveTokenHelperMethodName = "__RazorDirectiveTokenHelpers__"; + private const string TypeHelper = "__typeHelper"; + + public void WriteDesignTimeDirective(CodeRenderingContext context, DesignTimeDirectiveIntermediateNode node) + { + context.CodeWriter + .WriteLine("#pragma warning disable 219") + .WriteLine($"private void {DirectiveTokenHelperMethodName}() {{"); + + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is DirectiveTokenIntermediateNode n) + { + WriteDesignTimeDirectiveToken(context, n); + } + } + + context.CodeWriter + .WriteLine("}") + .WriteLine("#pragma warning restore 219"); + } + + private void WriteDesignTimeDirectiveToken(CodeRenderingContext context, DirectiveTokenIntermediateNode node) + { + var tokenKind = node.DirectiveToken.Kind; + if (!node.Source.HasValue || + !string.Equals( + context.SourceDocument?.FilePath, + node.Source.Value.FilePath, + StringComparison.OrdinalIgnoreCase)) + { + // We don't want to handle directives from imports. + return; + } + + // Wrap the directive token in a lambda to isolate variable names. + context.CodeWriter + .Write("((") + .Write(typeof(Action).FullName) + .Write(")("); + using (context.CodeWriter.BuildLambda()) + { + var originalIndent = context.CodeWriter.CurrentIndent; + context.CodeWriter.CurrentIndent = 0; + switch (tokenKind) + { + case DirectiveTokenKind.Type: + + if (string.IsNullOrEmpty(node.Content)) + { + // This is most likely a marker token. + WriteMarkerToken(context, node); + break; + } + + // {node.Content} __typeHelper = default({node.Content}); + using (context.CodeWriter.BuildLinePragma(node.Source)) + { + context.AddSourceMappingFor(node); + context.CodeWriter + .Write(node.Content) + .Write(" ") + .WriteStartAssignment(TypeHelper) + .Write("default(") + .Write(node.Content) + .WriteLine(");"); + } + break; + + case DirectiveTokenKind.Member: + + if (string.IsNullOrEmpty(node.Content)) + { + // This is most likely a marker token. + WriteMarkerToken(context, node); + break; + } + + // global::System.Object {node.content} = null; + using (context.CodeWriter.BuildLinePragma(node.Source)) + { + context.CodeWriter + .Write("global::") + .Write(typeof(object).FullName) + .Write(" "); + + context.AddSourceMappingFor(node); + context.CodeWriter + .Write(node.Content) + .WriteLine(" = null;"); + } + break; + + case DirectiveTokenKind.Namespace: + + if (string.IsNullOrEmpty(node.Content)) + { + // This is most likely a marker token. + WriteMarkerToken(context, node); + break; + } + + // global::System.Object __typeHelper = nameof({node.Content}); + using (context.CodeWriter.BuildLinePragma(node.Source)) + { + context.CodeWriter + .Write("global::") + .Write(typeof(object).FullName) + .Write(" ") + .WriteStartAssignment(TypeHelper); + + context.CodeWriter.Write("nameof("); + + context.AddSourceMappingFor(node); + context.CodeWriter + .Write(node.Content) + .WriteLine(");"); + } + break; + + case DirectiveTokenKind.String: + + // global::System.Object __typeHelper = "{node.Content}"; + using (context.CodeWriter.BuildLinePragma(node.Source)) + { + context.CodeWriter + .Write("global::") + .Write(typeof(object).FullName) + .Write(" ") + .WriteStartAssignment(TypeHelper); + + if (node.Content.StartsWith("\"", StringComparison.Ordinal)) + { + context.AddSourceMappingFor(node); + context.CodeWriter.Write(node.Content); + } + else + { + context.CodeWriter.Write("\""); + context.AddSourceMappingFor(node); + context.CodeWriter + .Write(node.Content) + .Write("\""); + } + + context.CodeWriter.WriteLine(";"); + } + break; + } + context.CodeWriter.CurrentIndent = originalIndent; + } + context.CodeWriter.WriteLine("))();"); + } + + private void WriteMarkerToken(CodeRenderingContext context, DirectiveTokenIntermediateNode node) + { + // We want to map marker tokens to a location in the generated document + // that will provide CSharp intellisense. + context.AddSourceMappingFor(node); + context.CodeWriter.Write(" "); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/EliminateMethodBodyPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/EliminateMethodBodyPass.cs new file mode 100644 index 0000000000..96d336ca72 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/EliminateMethodBodyPass.cs @@ -0,0 +1,71 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal sealed class EliminateMethodBodyPass : IntermediateNodePassBase, IRazorOptimizationPass + { + // Run early in the optimization phase + public override int Order => int.MinValue; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (documentNode == null) + { + throw new ArgumentNullException(nameof(documentNode)); + } + + var codeGenerationOptions = codeDocument.GetCodeGenerationOptions(); + if (codeGenerationOptions == null || !codeGenerationOptions.SuppressPrimaryMethodBody) + { + return; + } + + var method = documentNode.FindPrimaryMethod(); + if (method == null) + { + return; + } + + method.Children.Clear(); + + // After we clear all of the method body there might be some unused fields, which can be + // blocking if compiling with warnings as errors. Suppress this warning so that it doesn't + // get annoying in VS. + documentNode.Children.Insert(documentNode.Children.IndexOf(documentNode.FindPrimaryNamespace()), new CSharpCodeIntermediateNode() + { + Children = + { + // Field is assigned but never used + new IntermediateToken() + { + Content = "#pragma warning disable 0414" + Environment.NewLine, + Kind = TokenKind.CSharp, + }, + + // Field is never assigned + new IntermediateToken() + { + Content = "#pragma warning disable 0649" + Environment.NewLine, + Kind = TokenKind.CSharp, + }, + + // Field is never used + new IntermediateToken() + { + Content = "#pragma warning disable 0169" + Environment.NewLine, + Kind = TokenKind.CSharp, + }, + }, + }); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/FunctionsDirective.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/FunctionsDirective.cs new file mode 100644 index 0000000000..630272cdef --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/FunctionsDirective.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 System; +using Microsoft.AspNetCore.Razor.Language.Legacy; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public static class FunctionsDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + SyntaxConstants.CSharp.FunctionsKeyword, + DirectiveKind.CodeBlock, + builder => + { + builder.Description = Resources.FunctionsDirective_Description; + }); + + public static void Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new FunctionsDirectivePass()); + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static void Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new FunctionsDirectivePass()); + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/FunctionsDirectivePass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/FunctionsDirectivePass.cs new file mode 100644 index 0000000000..32f79570cb --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/FunctionsDirectivePass.cs @@ -0,0 +1,27 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class FunctionsDirectivePass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var @class = documentNode.FindPrimaryClass(); + if (@class == null) + { + return; + } + + foreach (var functions in documentNode.FindDirectiveReferences(FunctionsDirective.Directive)) + { + for (var i = 0; i < functions.Node.Children.Count; i++) + { + @class.Children.Add(functions.Node.Children[i]); + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IDefaultTagHelperTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IDefaultTagHelperTargetExtension.cs new file mode 100644 index 0000000000..1f7cf9beb4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IDefaultTagHelperTargetExtension.cs @@ -0,0 +1,22 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public interface IDefaultTagHelperTargetExtension : ICodeTargetExtension + { + void WriteTagHelperBody(CodeRenderingContext context, DefaultTagHelperBodyIntermediateNode node); + + void WriteTagHelperCreate(CodeRenderingContext context, DefaultTagHelperCreateIntermediateNode node); + + void WriteTagHelperExecute(CodeRenderingContext context, DefaultTagHelperExecuteIntermediateNode node); + + void WriteTagHelperHtmlAttribute(CodeRenderingContext context, DefaultTagHelperHtmlAttributeIntermediateNode node); + + void WriteTagHelperProperty(CodeRenderingContext context, DefaultTagHelperPropertyIntermediateNode node); + + void WriteTagHelperRuntime(CodeRenderingContext context, DefaultTagHelperRuntimeIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IDesignTimeDirectiveTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IDesignTimeDirectiveTargetExtension.cs new file mode 100644 index 0000000000..d99ef10241 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IDesignTimeDirectiveTargetExtension.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal interface IDesignTimeDirectiveTargetExtension : ICodeTargetExtension + { + void WriteDesignTimeDirective(CodeRenderingContext context, DesignTimeDirectiveIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IMetadataAttributeTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IMetadataAttributeTargetExtension.cs new file mode 100644 index 0000000000..db2955fadd --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IMetadataAttributeTargetExtension.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 Microsoft.AspNetCore.Razor.Language.CodeGeneration; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal interface IMetadataAttributeTargetExtension : ICodeTargetExtension + { + void WriteRazorCompiledItemAttribute(CodeRenderingContext context, RazorCompiledItemAttributeIntermediateNode node); + + void WriteRazorSourceChecksumAttribute(CodeRenderingContext context, RazorSourceChecksumAttributeIntermediateNode node); + + void WriteRazorCompiledItemMetadataAttribute(CodeRenderingContext context, RazorCompiledItemMetadataAttributeIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IMetadataIdentifierFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IMetadataIdentifierFeature.cs new file mode 100644 index 0000000000..6948c33a67 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IMetadataIdentifierFeature.cs @@ -0,0 +1,10 @@ +// 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.Extensions +{ + internal interface IMetadataIdentifierFeature : IRazorEngineFeature + { + string GetIdentifier(RazorCodeDocument codeDocument, RazorSourceDocument sourceDocument); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IPreallocatedAttributeTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IPreallocatedAttributeTargetExtension.cs new file mode 100644 index 0000000000..3a3dce2f06 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/IPreallocatedAttributeTargetExtension.cs @@ -0,0 +1,18 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal interface IPreallocatedAttributeTargetExtension : ICodeTargetExtension + { + void WriteTagHelperHtmlAttribute(CodeRenderingContext context, PreallocatedTagHelperHtmlAttributeIntermediateNode node); + + void WriteTagHelperHtmlAttributeValue(CodeRenderingContext context, PreallocatedTagHelperHtmlAttributeValueIntermediateNode node); + + void WriteTagHelperProperty(CodeRenderingContext context, PreallocatedTagHelperPropertyIntermediateNode node); + + void WriteTagHelperPropertyValue(CodeRenderingContext context, PreallocatedTagHelperPropertyValueIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/ISectionTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/ISectionTargetExtension.cs new file mode 100644 index 0000000000..1398eeb9da --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/ISectionTargetExtension.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public interface ISectionTargetExtension : ICodeTargetExtension + { + void WriteSection(CodeRenderingContext context, SectionIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/ITemplateTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/ITemplateTargetExtension.cs new file mode 100644 index 0000000000..8d1568e624 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/ITemplateTargetExtension.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public interface ITemplateTargetExtension : ICodeTargetExtension + { + void WriteTemplate(CodeRenderingContext context, TemplateIntermediateNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/InheritsDirective.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/InheritsDirective.cs new file mode 100644 index 0000000000..12cdb3708a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/InheritsDirective.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; +using Microsoft.AspNetCore.Razor.Language.Legacy; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public static class InheritsDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + SyntaxConstants.CSharp.InheritsKeyword, + DirectiveKind.SingleLine, + builder => + { + builder.AddTypeToken(Resources.InheritsDirective_TypeToken_Name, Resources.InheritsDirective_TypeToken_Description); + builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; + builder.Description = Resources.InheritsDirective_Description; + }); + + public static void Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new InheritsDirectivePass()); + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static void Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new InheritsDirectivePass()); + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/InheritsDirectivePass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/InheritsDirectivePass.cs new file mode 100644 index 0000000000..f45d6fb982 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/InheritsDirectivePass.cs @@ -0,0 +1,31 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class InheritsDirectivePass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var @class = documentNode.FindPrimaryClass(); + if (@class == null) + { + return; + } + + foreach (var inherits in documentNode.FindDirectiveReferences(InheritsDirective.Directive)) + { + var token = ((DirectiveIntermediateNode)inherits.Node).Tokens.FirstOrDefault(); + if (token != null) + { + @class.BaseType = token.Content; + break; + } + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/MetadataAttributePass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/MetadataAttributePass.cs new file mode 100644 index 0000000000..4383b2e27a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/MetadataAttributePass.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.Diagnostics; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + // Optimization pass is the best choice for this class. It's not an optimization, but it also doesn't add semantically + // meaningful information. + internal class MetadataAttributePass : IntermediateNodePassBase, IRazorOptimizationPass + { + private IMetadataIdentifierFeature _identifierFeature; + + protected override void OnInitialized() + { + _identifierFeature = Engine.Features.OfType().FirstOrDefault(); + } + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (documentNode.Options == null || documentNode.Options.SuppressMetadataAttributes) + { + // Metadata attributes are turned off (or options not populated), nothing to do. + return; + } + + // We need to be able to compute the data we need for the [RazorCompiledItem] attribute - that includes + // a full type name, and a document kind, and optionally an identifier. + // + // If we can't use [RazorCompiledItem] then we don't care about the rest of the attributes. + var @namespace = documentNode.FindPrimaryNamespace(); + if (@namespace == null || string.IsNullOrEmpty(@namespace.Content)) + { + // No namespace node or it's incomplete. Skip. + return; + } + + var @class = documentNode.FindPrimaryClass(); + if (@class == null || string.IsNullOrEmpty(@class.ClassName)) + { + // No class node or it's incomplete. Skip. + return; + } + + if (documentNode.DocumentKind == null) + { + // No document kind. Skip. + return; + } + + var identifier = _identifierFeature?.GetIdentifier(codeDocument, codeDocument.Source); + if (identifier == null) + { + // No identifier. Skip + return; + } + + // [RazorCompiledItem] is an [assembly: ... ] attribute, so it needs to be applied at the global scope. + documentNode.Children.Insert(0, new RazorCompiledItemAttributeIntermediateNode() + { + TypeName = @namespace.Content + "." + @class.ClassName, + Kind = documentNode.DocumentKind, + Identifier = identifier, + }); + + // Now we need to add a [RazorSourceChecksum] for the source and for each import + // these are class attributes, so we need to find the insertion point to put them + // right before the class. + var insert = (int?)null; + for (var j = 0; j < @namespace.Children.Count; j++) + { + if (object.ReferenceEquals(@namespace.Children[j], @class)) + { + insert = j; + break; + } + } + + if (insert == null) + { + // Can't find a place to put the attributes, just bail. + return; + } + + // Checksum of the main source + var checksum = codeDocument.Source.GetChecksum(); + var checksumAlgorithm = codeDocument.Source.GetChecksumAlgorithm(); + if (checksum == null || checksum.Length == 0 || checksumAlgorithm == null || identifier == null) + { + // Don't generate anything unless we have all of the required information. + return; + } + + @namespace.Children.Insert((int)insert++, new RazorSourceChecksumAttributeIntermediateNode() + { + Checksum = checksum, + ChecksumAlgorithm = checksumAlgorithm, + Identifier = identifier, + }); + + // Now process the checksums of the imports + Debug.Assert(_identifierFeature != null); + for (var i = 0; i < codeDocument.Imports.Count; i++) + { + var import = codeDocument.Imports[i]; + + checksum = import.GetChecksum(); + checksumAlgorithm = import.GetChecksumAlgorithm(); + identifier = _identifierFeature.GetIdentifier(codeDocument, import); + + if (checksum == null || checksum.Length == 0 || checksumAlgorithm == null || identifier == null) + { + // It's ok to skip an import if we don't have all of the required information. + continue; + } + + @namespace.Children.Insert((int)insert++, new RazorSourceChecksumAttributeIntermediateNode() + { + Checksum = checksum, + ChecksumAlgorithm = checksumAlgorithm, + Identifier = identifier, + }); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/MetadataAttributeTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/MetadataAttributeTargetExtension.cs new file mode 100644 index 0000000000..7c702bb1a0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/MetadataAttributeTargetExtension.cs @@ -0,0 +1,88 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal class MetadataAttributeTargetExtension : IMetadataAttributeTargetExtension + { + public string CompiledItemAttributeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute"; + + public string SourceChecksumAttributeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute"; + + public string CompiledItemMetadataAttributeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute"; + + + public void WriteRazorCompiledItemAttribute(CodeRenderingContext context, RazorCompiledItemAttributeIntermediateNode node) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + // [assembly: global::...RazorCompiledItem(typeof({node.TypeName}), @"{node.Kind}", @"{node.Identifier}")] + context.CodeWriter.Write("[assembly: "); + context.CodeWriter.Write(CompiledItemAttributeName); + context.CodeWriter.Write("(typeof("); + context.CodeWriter.Write(node.TypeName); + context.CodeWriter.Write("), @\""); + context.CodeWriter.Write(node.Kind); + context.CodeWriter.Write("\", @\""); + context.CodeWriter.Write(node.Identifier); + context.CodeWriter.WriteLine("\")]"); + } + + public void WriteRazorCompiledItemMetadataAttribute(CodeRenderingContext context, RazorCompiledItemMetadataAttributeIntermediateNode node) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + // [assembly: global::...RazorCompiledItemAttribute(@"{node.Key}", @"{node.Value}")] + context.CodeWriter.Write("["); + context.CodeWriter.Write(CompiledItemMetadataAttributeName); + context.CodeWriter.Write("("); + context.CodeWriter.WriteStringLiteral(node.Key); + context.CodeWriter.Write(", "); + context.CodeWriter.WriteStringLiteral(node.Value); + context.CodeWriter.WriteLine(")]"); + } + + public void WriteRazorSourceChecksumAttribute(CodeRenderingContext context, RazorSourceChecksumAttributeIntermediateNode node) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + // [global::...RazorSourceChecksum(@"{node.ChecksumAlgorithm}", @"{node.Checksum}", @"{node.Identifier}")] + context.CodeWriter.Write("["); + context.CodeWriter.Write(SourceChecksumAttributeName); + context.CodeWriter.Write("(@\""); + context.CodeWriter.Write(node.ChecksumAlgorithm); + context.CodeWriter.Write("\", @\""); + context.CodeWriter.Write(Checksum.BytesToString(node.Checksum)); + context.CodeWriter.Write("\", @\""); + context.CodeWriter.Write(node.Identifier); + context.CodeWriter.WriteLine("\")]"); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedAttributeTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedAttributeTargetExtension.cs new file mode 100644 index 0000000000..c371361f4c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedAttributeTargetExtension.cs @@ -0,0 +1,167 @@ +// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal class PreallocatedAttributeTargetExtension : IPreallocatedAttributeTargetExtension + { + public string TagHelperAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute"; + + public string EncodedHtmlStringTypeName { get; set; } = "Microsoft.AspNetCore.Html.HtmlString"; + + public string ExecutionContextVariableName { get; set; } = "__tagHelperExecutionContext"; + + public string ExecutionContextAddHtmlAttributeMethodName { get; set; } = "AddHtmlAttribute"; + + public string ExecutionContextAddTagHelperAttributeMethodName { get; set; } = "AddTagHelperAttribute"; + + public string FormatInvalidIndexerAssignmentMethodName { get; set; } = "InvalidTagHelperIndexerAssignment"; + + public void WriteTagHelperHtmlAttributeValue(CodeRenderingContext context, PreallocatedTagHelperHtmlAttributeValueIntermediateNode node) + { + context.CodeWriter + .Write("private static readonly global::") + .Write(TagHelperAttributeTypeName) + .Write(" ") + .Write(node.VariableName) + .Write(" = ") + .WriteStartNewObject("global::" + TagHelperAttributeTypeName) + .WriteStringLiteral(node.AttributeName); + + if (node.AttributeStructure == AttributeStructure.Minimized) + { + context.CodeWriter.WriteEndMethodInvocation(); + } + else + { + context.CodeWriter + .WriteParameterSeparator() + .WriteStartNewObject("global::" + EncodedHtmlStringTypeName) + .WriteStringLiteral(node.Value) + .WriteEndMethodInvocation(endLine: false) + .WriteParameterSeparator() + .Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.AttributeStructure}") + .WriteEndMethodInvocation(); + } + } + + public void WriteTagHelperHtmlAttribute(CodeRenderingContext context, PreallocatedTagHelperHtmlAttributeIntermediateNode node) + { + if (context.Parent as TagHelperIntermediateNode == null) + { + var message = Resources.FormatIntermediateNodes_InvalidParentNode(node.GetType(), typeof(TagHelperIntermediateNode)); + throw new InvalidOperationException(message); + } + + context.CodeWriter + .WriteStartInstanceMethodInvocation(ExecutionContextVariableName, ExecutionContextAddHtmlAttributeMethodName) + .Write(node.VariableName) + .WriteEndMethodInvocation(); + } + + public void WriteTagHelperPropertyValue(CodeRenderingContext context, PreallocatedTagHelperPropertyValueIntermediateNode node) + { + context.CodeWriter + .Write("private static readonly global::") + .Write(TagHelperAttributeTypeName) + .Write(" ") + .Write(node.VariableName) + .Write(" = ") + .WriteStartNewObject("global::" + TagHelperAttributeTypeName) + .WriteStringLiteral(node.AttributeName) + .WriteParameterSeparator() + .WriteStringLiteral(node.Value) + .WriteParameterSeparator() + .Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.AttributeStructure}") + .WriteEndMethodInvocation(); + } + + public void WriteTagHelperProperty(CodeRenderingContext context, PreallocatedTagHelperPropertyIntermediateNode node) + { + var tagHelperNode = context.Parent as TagHelperIntermediateNode; + if (tagHelperNode == null) + { + var message = Resources.FormatIntermediateNodes_InvalidParentNode(node.GetType(), typeof(TagHelperIntermediateNode)); + throw new InvalidOperationException(message); + } + + // Ensure that the property we're trying to set has initialized its dictionary bound properties. + if (node.IsIndexerNameMatch && + object.ReferenceEquals(FindFirstUseOfIndexer(tagHelperNode, node), node)) + { + // Throw a reasonable Exception at runtime if the dictionary property is null. + context.CodeWriter + .Write("if (") + .Write(node.FieldName) + .Write(".") + .Write(node.PropertyName) + .WriteLine(" == null)"); + using (context.CodeWriter.BuildScope()) + { + // System is in Host.NamespaceImports for all MVC scenarios. No need to generate FullName + // of InvalidOperationException type. + context.CodeWriter + .Write("throw ") + .WriteStartNewObject(nameof(InvalidOperationException)) + .WriteStartMethodInvocation(FormatInvalidIndexerAssignmentMethodName) + .WriteStringLiteral(node.AttributeName) + .WriteParameterSeparator() + .WriteStringLiteral(node.TagHelper.GetTypeName()) + .WriteParameterSeparator() + .WriteStringLiteral(node.PropertyName) + .WriteEndMethodInvocation(endLine: false) // End of method call + .WriteEndMethodInvocation(); // End of new expression / throw statement + } + } + + context.CodeWriter + .WriteStartAssignment(GetPropertyAccessor(node)) + .Write("(string)") + .Write($"{node.VariableName}.Value") + .WriteLine(";") + .WriteStartInstanceMethodInvocation(ExecutionContextVariableName, ExecutionContextAddTagHelperAttributeMethodName) + .Write(node.VariableName) + .WriteEndMethodInvocation(); + } + + private static PreallocatedTagHelperPropertyIntermediateNode FindFirstUseOfIndexer( + TagHelperIntermediateNode tagHelperNode, + PreallocatedTagHelperPropertyIntermediateNode propertyNode) + { + Debug.Assert(tagHelperNode.Children.Contains(propertyNode)); + Debug.Assert(propertyNode.IsIndexerNameMatch); + + for (var i = 0; i < tagHelperNode.Children.Count; i++) + { + if (tagHelperNode.Children[i] is PreallocatedTagHelperPropertyIntermediateNode otherPropertyNode && + otherPropertyNode.TagHelper.Equals(propertyNode.TagHelper) && + otherPropertyNode.BoundAttribute.Equals(propertyNode.BoundAttribute) && + otherPropertyNode.IsIndexerNameMatch) + { + return otherPropertyNode; + } + } + + // This is unreachable, we should find 'propertyNode' in the list of children. + throw new InvalidOperationException(); + } + + private static string GetPropertyAccessor(PreallocatedTagHelperPropertyIntermediateNode node) + { + var propertyAccessor = $"{node.FieldName}.{node.PropertyName}"; + + if (node.IsIndexerNameMatch) + { + var dictionaryKey = node.AttributeName.Substring(node.BoundAttribute.IndexerNamePrefix.Length); + propertyAccessor += $"[\"{dictionaryKey}\"]"; + } + + return propertyAccessor; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperAttributeOptimizationPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperAttributeOptimizationPass.cs new file mode 100644 index 0000000000..ccac531732 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperAttributeOptimizationPass.cs @@ -0,0 +1,166 @@ +// 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 System.Text; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal class PreallocatedTagHelperAttributeOptimizationPass : IntermediateNodePassBase, IRazorOptimizationPass + { + // We want to run after the passes that 'lower' tag helpers. We also want this to run after DefaultTagHelperOptimizationPass. + public override int Order => DefaultFeatureOrder + 1010; + + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + // There's no value in executing this pass at design time, it just prevents some allocations. + if (documentNode.Options.DesignTime) + { + return; + } + + var walker = new PreallocatedTagHelperWalker(); + walker.VisitDocument(documentNode); + } + + internal class PreallocatedTagHelperWalker : + IntermediateNodeWalker, + IExtensionIntermediateNodeVisitor, + IExtensionIntermediateNodeVisitor + { + private const string PreAllocatedAttributeVariablePrefix = "__tagHelperAttribute_"; + + private ClassDeclarationIntermediateNode _classDeclaration; + private int _variableCountOffset; + private int _preallocatedDeclarationCount = 0; + + public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + _classDeclaration = node; + _variableCountOffset = node.Children.Count; + + VisitDefault(node); + } + + public void VisitExtension(DefaultTagHelperHtmlAttributeIntermediateNode node) + { + if (node.Children.Count != 1 || !(node.Children.First() is HtmlContentIntermediateNode)) + { + return; + } + + var htmlContentNode = node.Children.First() as HtmlContentIntermediateNode; + var plainTextValue = GetContent(htmlContentNode); + + PreallocatedTagHelperHtmlAttributeValueIntermediateNode declaration = null; + + for (var i = 0; i < _classDeclaration.Children.Count; i++) + { + var current = _classDeclaration.Children[i]; + + if (current is PreallocatedTagHelperHtmlAttributeValueIntermediateNode existingDeclaration) + { + if (string.Equals(existingDeclaration.AttributeName, node.AttributeName, StringComparison.Ordinal) && + string.Equals(existingDeclaration.Value, plainTextValue, StringComparison.Ordinal) && + existingDeclaration.AttributeStructure == node.AttributeStructure) + { + declaration = existingDeclaration; + break; + } + } + } + + if (declaration == null) + { + var variableCount = _classDeclaration.Children.Count - _variableCountOffset; + var preAllocatedAttributeVariableName = PreAllocatedAttributeVariablePrefix + variableCount; + declaration = new PreallocatedTagHelperHtmlAttributeValueIntermediateNode + { + VariableName = preAllocatedAttributeVariableName, + AttributeName = node.AttributeName, + Value = plainTextValue, + AttributeStructure = node.AttributeStructure, + }; + _classDeclaration.Children.Insert(_preallocatedDeclarationCount++, declaration); + } + + var addPreAllocatedAttribute = new PreallocatedTagHelperHtmlAttributeIntermediateNode + { + VariableName = declaration.VariableName, + }; + + var nodeIndex = Parent.Children.IndexOf(node); + Parent.Children[nodeIndex] = addPreAllocatedAttribute; + } + + public void VisitExtension(DefaultTagHelperPropertyIntermediateNode node) + { + if (!(node.BoundAttribute.IsStringProperty || (node.IsIndexerNameMatch && node.BoundAttribute.IsIndexerStringProperty)) || + node.Children.Count != 1 || + !(node.Children.First() is HtmlContentIntermediateNode)) + { + return; + } + + var htmlContentNode = node.Children.First() as HtmlContentIntermediateNode; + var plainTextValue = GetContent(htmlContentNode); + + PreallocatedTagHelperPropertyValueIntermediateNode declaration = null; + + for (var i = 0; i < _classDeclaration.Children.Count; i++) + { + var current = _classDeclaration.Children[i]; + + if (current is PreallocatedTagHelperPropertyValueIntermediateNode existingDeclaration) + { + if (string.Equals(existingDeclaration.AttributeName, node.AttributeName, StringComparison.Ordinal) && + string.Equals(existingDeclaration.Value, plainTextValue, StringComparison.Ordinal) && + existingDeclaration.AttributeStructure == node.AttributeStructure) + { + declaration = existingDeclaration; + break; + } + } + } + + if (declaration == null) + { + var variableCount = _classDeclaration.Children.Count - _variableCountOffset; + var preAllocatedAttributeVariableName = PreAllocatedAttributeVariablePrefix + variableCount; + declaration = new PreallocatedTagHelperPropertyValueIntermediateNode() + { + VariableName = preAllocatedAttributeVariableName, + AttributeName = node.AttributeName, + Value = plainTextValue, + AttributeStructure = node.AttributeStructure, + }; + _classDeclaration.Children.Insert(_preallocatedDeclarationCount++, declaration); + } + + var setPreallocatedProperty = new PreallocatedTagHelperPropertyIntermediateNode(node) + { + VariableName = declaration.VariableName, + }; + + var nodeIndex = Parent.Children.IndexOf(node); + Parent.Children[nodeIndex] = setPreallocatedProperty; + } + + private string GetContent(HtmlContentIntermediateNode node) + { + var builder = new StringBuilder(); + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is IntermediateToken token && token.IsHtml) + { + builder.Append(token.Content); + } + } + + return builder.ToString(); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperHtmlAttributeIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperHtmlAttributeIntermediateNode.cs new file mode 100644 index 0000000000..70a9c61fa6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperHtmlAttributeIntermediateNode.cs @@ -0,0 +1,55 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal sealed class PreallocatedTagHelperHtmlAttributeIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public string VariableName { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperHtmlAttribute(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(VariableName); + + formatter.WriteProperty(nameof(VariableName), VariableName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperHtmlAttributeValueIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperHtmlAttributeValueIntermediateNode.cs new file mode 100644 index 0000000000..5faed5344b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperHtmlAttributeValueIntermediateNode.cs @@ -0,0 +1,88 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal sealed class PreallocatedTagHelperHtmlAttributeValueIntermediateNode : ExtensionIntermediateNode + { + public PreallocatedTagHelperHtmlAttributeValueIntermediateNode() + { + } + + public PreallocatedTagHelperHtmlAttributeValueIntermediateNode(DefaultTagHelperHtmlAttributeIntermediateNode htmlAttributeNode) + { + if (htmlAttributeNode == null) + { + throw new ArgumentNullException(nameof(htmlAttributeNode)); + } + + Source = htmlAttributeNode.Source; + + for (var i = 0; i < htmlAttributeNode.Children.Count; i++) + { + Children.Add(htmlAttributeNode.Children[i]); + } + + for (var i = 0; i < htmlAttributeNode.Diagnostics.Count; i++) + { + Diagnostics.Add(htmlAttributeNode.Diagnostics[i]); + } + } + + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public string VariableName { get; set; } + + public string AttributeName { get; set; } + + public string Value { get; set; } + + public AttributeStructure AttributeStructure { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperHtmlAttributeValue(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(AttributeName); + + formatter.WriteProperty(nameof(AttributeName), AttributeName); + formatter.WriteProperty(nameof(AttributeStructure), AttributeStructure.ToString()); + formatter.WriteProperty(nameof(Value), Value); + formatter.WriteProperty(nameof(VariableName), VariableName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperPropertyIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperPropertyIntermediateNode.cs new file mode 100644 index 0000000000..7db273a1d6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperPropertyIntermediateNode.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 System; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal sealed class PreallocatedTagHelperPropertyIntermediateNode : ExtensionIntermediateNode + { + public PreallocatedTagHelperPropertyIntermediateNode() + { + } + + public PreallocatedTagHelperPropertyIntermediateNode(DefaultTagHelperPropertyIntermediateNode propertyNode) + { + if (propertyNode == null) + { + throw new ArgumentNullException(nameof(propertyNode)); + } + + AttributeName = propertyNode.AttributeName; + AttributeStructure = propertyNode.AttributeStructure; + BoundAttribute = propertyNode.BoundAttribute; + FieldName = propertyNode.FieldName; + IsIndexerNameMatch = propertyNode.IsIndexerNameMatch; + PropertyName = propertyNode.PropertyName; + Source = propertyNode.Source; + TagHelper = propertyNode.TagHelper; + } + + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public string AttributeName { get; set; } + + public AttributeStructure AttributeStructure { get; set; } + + public BoundAttributeDescriptor BoundAttribute { get; set; } + + public string FieldName { get; set; } + + public bool IsIndexerNameMatch { get; set; } + + public string PropertyName { get; set; } + + public TagHelperDescriptor TagHelper { get; set; } + + public string VariableName { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperProperty(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(AttributeName); + + formatter.WriteProperty(nameof(AttributeName), AttributeName); + formatter.WriteProperty(nameof(AttributeStructure), AttributeStructure.ToString()); + formatter.WriteProperty(nameof(BoundAttribute), BoundAttribute?.DisplayName); + formatter.WriteProperty(nameof(FieldName), FieldName); + formatter.WriteProperty(nameof(IsIndexerNameMatch), IsIndexerNameMatch.ToString()); + formatter.WriteProperty(nameof(PropertyName), PropertyName); + formatter.WriteProperty(nameof(TagHelper), TagHelper?.DisplayName); + formatter.WriteProperty(nameof(VariableName), VariableName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperPropertyValueIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperPropertyValueIntermediateNode.cs new file mode 100644 index 0000000000..6516a22133 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/PreallocatedTagHelperPropertyValueIntermediateNode.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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal sealed class PreallocatedTagHelperPropertyValueIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public string VariableName { get; set; } + + public string AttributeName { get; set; } + + public string Value { get; set; } + + public AttributeStructure AttributeStructure { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTagHelperPropertyValue(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(AttributeName); + + formatter.WriteProperty(nameof(AttributeName), AttributeName); + formatter.WriteProperty(nameof(AttributeStructure), AttributeStructure.ToString()); + formatter.WriteProperty(nameof(Value), Value); + formatter.WriteProperty(nameof(VariableName), VariableName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorCompiledItemAttributeIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorCompiledItemAttributeIntermediateNode.cs new file mode 100644 index 0000000000..ee82fca81a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorCompiledItemAttributeIntermediateNode.cs @@ -0,0 +1,59 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal sealed class RazorCompiledItemAttributeIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public string TypeName { get; set; } + + public string Kind { get; set; } + + public string Identifier { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteRazorCompiledItemAttribute(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteProperty(nameof(Identifier), Identifier); + formatter.WriteProperty(nameof(Kind), Kind); + formatter.WriteProperty(nameof(TypeName), TypeName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorCompiledItemMetadataAttributeIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorCompiledItemMetadataAttributeIntermediateNode.cs new file mode 100644 index 0000000000..52f7b92012 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorCompiledItemMetadataAttributeIntermediateNode.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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + /// + /// An that generates code for RazorCompiledItemMetadataAttribute. + /// + public class RazorCompiledItemMetadataAttributeIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + /// + /// Gets or sets the attribute key. + /// + public string Key { get; set; } + + /// + /// Gets or sets the attribute value. + /// + public string Value { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteRazorCompiledItemMetadataAttribute(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteProperty(nameof(Key), Key); + formatter.WriteProperty(nameof(Value), Value); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorSourceChecksumAttributeIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorSourceChecksumAttributeIntermediateNode.cs new file mode 100644 index 0000000000..4aa8d3f978 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/RazorSourceChecksumAttributeIntermediateNode.cs @@ -0,0 +1,52 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + internal sealed class RazorSourceChecksumAttributeIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public byte[] Checksum { get; set; } + + public string ChecksumAlgorithm { get; set; } + + public string Identifier { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteRazorSourceChecksumAttribute(context, this); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionDirective.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionDirective.cs new file mode 100644 index 0000000000..b1f8633122 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionDirective.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 System; +using Microsoft.AspNetCore.Razor.Language.Legacy; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public static class SectionDirective + { + public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective( + SyntaxConstants.CSharp.SectionKeyword, + DirectiveKind.RazorBlock, + builder => + { + builder.AddMemberToken(Resources.SectionDirective_NameToken_Name, Resources.SectionDirective_NameToken_Description); + builder.Description = Resources.SectionDirective_Description; + }); + + public static void Register(RazorProjectEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new SectionDirectivePass()); + builder.AddTargetExtension(new SectionTargetExtension()); + } + + #region Obsolete + [Obsolete("This method is obsolete and will be removed in a future version.")] + public static void Register(IRazorEngineBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddDirective(Directive); + builder.Features.Add(new SectionDirectivePass()); + builder.AddTargetExtension(new SectionTargetExtension()); + } + #endregion + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionDirectivePass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionDirectivePass.cs new file mode 100644 index 0000000000..ea2ad395ff --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionDirectivePass.cs @@ -0,0 +1,49 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class SectionDirectivePass : IntermediateNodePassBase, IRazorDirectiveClassifierPass + { + protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + var @class = documentNode.FindPrimaryClass(); + if (@class == null) + { + return; + } + + foreach (var directive in documentNode.FindDirectiveReferences(SectionDirective.Directive)) + { + var sectionName = ((DirectiveIntermediateNode)directive.Node).Tokens.FirstOrDefault()?.Content; + + var section = new SectionIntermediateNode() + { + SectionName = sectionName, + }; + + var i = 0; + for (; i < directive.Node.Children.Count; i++) + { + if (!(directive.Node.Children[i] is DirectiveTokenIntermediateNode)) + { + break; + } + } + + while (i != directive.Node.Children.Count) + { + // Move non-token children over to the section node so we don't have double references to children nodes. + section.Children.Add(directive.Node.Children[i]); + directive.Node.Children.RemoveAt(i); + } + + directive.InsertAfter(section); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionIntermediateNode.cs new file mode 100644 index 0000000000..d3d4c10557 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionIntermediateNode.cs @@ -0,0 +1,55 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class SectionIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string SectionName { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteSection(context, this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(SectionName); + + formatter.WriteProperty(nameof(SectionName), SectionName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionTargetExtension.cs new file mode 100644 index 0000000000..ba1f637ad6 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/SectionTargetExtension.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 Microsoft.AspNetCore.Razor.Language.CodeGeneration; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class SectionTargetExtension : ISectionTargetExtension + { + // Compatibility for 1.X projects + private const string DefaultWriterName = "__razor_section_writer"; + + public static readonly string DefaultSectionMethodName = "DefineSection"; + + public string SectionMethodName { get; set; } = DefaultSectionMethodName; + + public void WriteSection(CodeRenderingContext context, SectionIntermediateNode node) + { + context.CodeWriter + .WriteStartMethodInvocation(SectionMethodName) + .Write("\"") + .Write(node.SectionName) + .Write("\", "); + + if (context.Options.DesignTime) + { + using (context.CodeWriter.BuildAsyncLambda(DefaultWriterName)) + { + context.RenderChildren(node); + } + } + else + { + using (context.CodeWriter.BuildAsyncLambda()) + { + context.RenderChildren(node); + } + } + + context.CodeWriter.WriteEndMethodInvocation(endLine: true); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/TemplateIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/TemplateIntermediateNode.cs new file mode 100644 index 0000000000..76c81a94a3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/TemplateIntermediateNode.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; +using Microsoft.AspNetCore.Razor.Language.CodeGeneration; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class TemplateIntermediateNode : ExtensionIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + AcceptExtensionNode(this, visitor); + } + + public override void WriteNode(CodeTarget target, CodeRenderingContext context) + { + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var extension = target.GetExtension(); + if (extension == null) + { + ReportMissingCodeTargetExtension(context); + return; + } + + extension.WriteTemplate(context, this); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/TemplateTargetExtension.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/TemplateTargetExtension.cs new file mode 100644 index 0000000000..8ec532e21a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Extensions/TemplateTargetExtension.cs @@ -0,0 +1,35 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Extensions +{ + public sealed class TemplateTargetExtension : ITemplateTargetExtension + { + public static readonly string DefaultTemplateTypeName = "Template"; + + public string TemplateTypeName { get; set; } = DefaultTemplateTypeName; + + public void WriteTemplate(CodeRenderingContext context, TemplateIntermediateNode node) + { + const string ItemParameterName = "item"; + const string TemplateWriterName = "__razor_template_writer"; + + context.CodeWriter + .Write(ItemParameterName).Write(" => ") + .WriteStartNewObject(TemplateTypeName); + + using (context.CodeWriter.BuildAsyncLambda(TemplateWriterName)) + { + context.NodeWriter.BeginWriterScope(context, TemplateWriterName); + + context.RenderChildren(node); + + context.NodeWriter.EndWriterScope(context); + } + + context.CodeWriter.WriteEndMethodInvocation(endLine: false); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/HtmlConventions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/HtmlConventions.cs new file mode 100644 index 0000000000..be2530cae3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/HtmlConventions.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 System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public static class HtmlConventions + { + private const string HtmlCaseRegexReplacement = "-$1$2"; + + // This matches the following AFTER the start of the input string (MATCH). + // Any letter/number followed by an uppercase letter then lowercase letter: 1(Aa), a(Aa), A(Aa) + // Any lowercase letter followed by an uppercase letter: a(A) + // Each match is then prefixed by a "-" via the ToHtmlCase method. + private static readonly Regex HtmlCaseRegex = + new Regex( + "(? InvalidNonWhitespaceHtmlCharacters { get; } = new List( + new[] { '@', '!', '<', '/', '?', '[', '>', ']', '=', '"', '\'', '*' }); + + /// + /// Converts from pascal/camel case to lower kebab-case. + /// + /// + /// SomeThing => some-thing + /// capsONInside => caps-on-inside + /// CAPSOnOUTSIDE => caps-on-outside + /// ALLCAPS => allcaps + /// One1Two2Three3 => one1-two2-three3 + /// ONE1TWO2THREE3 => one1two2three3 + /// First_Second_ThirdHi => first_second_third-hi + /// + public static string ToHtmlCase(string name) + { + return HtmlCaseRegex.Replace(name, HtmlCaseRegexReplacement).ToLowerInvariant(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/HtmlNodeOptimizationPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/HtmlNodeOptimizationPass.cs new file mode 100644 index 0000000000..1b327aa032 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/HtmlNodeOptimizationPass.cs @@ -0,0 +1,32 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class HtmlNodeOptimizationPass : RazorEngineFeatureBase, IRazorSyntaxTreePass + { + public int Order => 100; + + public RazorSyntaxTree Execute(RazorCodeDocument codeDocument, RazorSyntaxTree syntaxTree) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (syntaxTree == null) + { + throw new ArgumentNullException(nameof(syntaxTree)); + } + + var whitespaceRewriter = new WhitespaceRewriter(); + var rewritten = whitespaceRewriter.Visit(syntaxTree.Root); + + var rewrittenSyntaxTree = RazorSyntaxTree.Create(rewritten, syntaxTree.Source, syntaxTree.Diagnostics, syntaxTree.Options); + return rewrittenSyntaxTree; + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IConfigureRazorCodeGenerationOptionsFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IConfigureRazorCodeGenerationOptionsFeature.cs new file mode 100644 index 0000000000..e1f50c0fab --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IConfigureRazorCodeGenerationOptionsFeature.cs @@ -0,0 +1,12 @@ +// 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 +{ + public interface IConfigureRazorCodeGenerationOptionsFeature : IRazorEngineFeature + { + int Order { get; } + + void Configure(RazorCodeGenerationOptionsBuilder options); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IConfigureRazorParserOptionsFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IConfigureRazorParserOptionsFeature.cs new file mode 100644 index 0000000000..541243ca06 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IConfigureRazorParserOptionsFeature.cs @@ -0,0 +1,12 @@ +// 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 +{ + public interface IConfigureRazorParserOptionsFeature : IRazorEngineFeature + { + int Order { get; } + + void Configure(RazorParserOptionsBuilder options); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IDirectiveDescriptorBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IDirectiveDescriptorBuilder.cs new file mode 100644 index 0000000000..465069dbcf --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IDirectiveDescriptorBuilder.cs @@ -0,0 +1,49 @@ +// 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 +{ + /// + /// A builder interface for configuring a . + /// + public interface IDirectiveDescriptorBuilder + { + /// + /// Gets or sets the description of the directive. + /// + string Description { get; set; } + + /// + /// Gets the directive keyword. + /// + string Directive { get; } + + /// + /// Gets or sets the display name of the directive. + /// + string DisplayName { get; set; } + + /// + /// Gets the directive kind. + /// + DirectiveKind Kind { get; } + + /// + /// Gets or sets the directive usage. The usage determines how many, and where directives can exist per document. + /// + DirectiveUsage Usage { get; set; } + + /// + /// Gets a list of the directive tokens. + /// + IList Tokens { get; } + + /// + /// Creates a based on the current property values of the builder. + /// + /// The created . + DirectiveDescriptor Build(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IImportProjectFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IImportProjectFeature.cs new file mode 100644 index 0000000000..98d8ffe558 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IImportProjectFeature.cs @@ -0,0 +1,12 @@ +// 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 +{ + public interface IImportProjectFeature : IRazorProjectEngineFeature + { + IReadOnlyList GetImports(RazorProjectItem projectItem); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCSharpLoweringPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCSharpLoweringPhase.cs new file mode 100644 index 0000000000..265e4bc494 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCSharpLoweringPhase.cs @@ -0,0 +1,17 @@ +// 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 +{ + /// + /// Generates C# code using the intermediate node document. + /// + /// + /// After IR processing, the transforms the intermediate node document into + /// generated C# code. At this time any directives or other constructs that cannot be understood by code generation + /// will result in an error. + /// + public interface IRazorCSharpLoweringPhase : IRazorEnginePhase + { + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCodeGenerationOptionsFactoryProjectFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCodeGenerationOptionsFactoryProjectFeature.cs new file mode 100644 index 0000000000..6d3ed5156c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCodeGenerationOptionsFactoryProjectFeature.cs @@ -0,0 +1,12 @@ +// 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 +{ + internal interface IRazorCodeGenerationOptionsFactoryProjectFeature : IRazorProjectEngineFeature + { + RazorCodeGenerationOptions Create(Action configure); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCodeGenerationOptionsFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCodeGenerationOptionsFeature.cs new file mode 100644 index 0000000000..b74bcc3d8d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorCodeGenerationOptionsFeature.cs @@ -0,0 +1,13 @@ +// 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 +{ + [Obsolete("In Razor 2.1 and newer, use RazorCodeDocument.GetCodeGenerationOptions().")] + public interface IRazorCodeGenerationOptionsFeature : IRazorEngineFeature + { + RazorCodeGenerationOptions GetOptions(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveClassifierPass.cs new file mode 100644 index 0000000000..0adaa290a9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveClassifierPass.cs @@ -0,0 +1,14 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public interface IRazorDirectiveClassifierPass : IRazorEngineFeature + { + int Order { get; } + + void Execute(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveClassifierPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveClassifierPhase.cs new file mode 100644 index 0000000000..41594a66a4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveClassifierPhase.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. + +namespace Microsoft.AspNetCore.Razor.Language +{ + /// + /// Understands directive nodes and performs the necessary modifications to the document. + /// + /// + /// + /// The second phase of intermediate node processing is directive classification. Passes in this phase should interpret + /// directives and processing them accordingly by transforming nodes or adding diagnostics. At this time the document + /// kind has been identified, so any directive that can't be applied should trigger + /// errors. If implementing a document kind that diverges from the standard structure of Razor documents + /// it may be necessary to reimplement processing of default directives. + /// + /// + /// objects are executed according to an ascending ordering of the + /// property. + /// + /// + public interface IRazorDirectiveClassifierPhase : IRazorEnginePhase + { + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveFeature.cs new file mode 100644 index 0000000000..5483fd4941 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDirectiveFeature.cs @@ -0,0 +1,12 @@ +// 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 +{ + public interface IRazorDirectiveFeature : IRazorEngineFeature + { + ICollection Directives { get; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDocumentClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDocumentClassifierPass.cs new file mode 100644 index 0000000000..0893eaeead --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDocumentClassifierPass.cs @@ -0,0 +1,14 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public interface IRazorDocumentClassifierPass : IRazorEngineFeature + { + int Order { get; } + + void Execute(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDocumentClassifierPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDocumentClassifierPhase.cs new file mode 100644 index 0000000000..37a957419e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorDocumentClassifierPhase.cs @@ -0,0 +1,28 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + /// + /// Modifies the intermediate node document to a desired structure. + /// + /// + /// + /// The first phase of intermediate node procesing is document classification. Passes in this phase should classify the + /// document according to any relevant criteria (project configuration, file extension, directive) and modify + /// the intermediate node document to suit the desired document shape. Document classifiers should also set + /// to prevent other classifiers from running. If no classifier + /// matches the document, then it will be classified as "generic" and processed according to set + /// of reasonable defaults. + /// + /// + /// objects are executed according to an ascending ordering of the + /// property. + /// + /// + public interface IRazorDocumentClassifierPhase : IRazorEnginePhase + { + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEngineBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEngineBuilder.cs new file mode 100644 index 0000000000..38c411296b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEngineBuilder.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; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language +{ + [Obsolete("This class is obsolete and will be removed in a future version. The recommended alternative is " + nameof(RazorProjectEngineBuilder) + ".")] + public interface IRazorEngineBuilder + { + ICollection Features { get; } + + IList Phases { get; } + + bool DesignTime { get; } + + RazorEngine Build(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEngineFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEngineFeature.cs new file mode 100644 index 0000000000..e06f3a65ce --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEngineFeature.cs @@ -0,0 +1,10 @@ +// 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 +{ + public interface IRazorEngineFeature : IRazorFeature + { + RazorEngine Engine { get; set; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEnginePhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEnginePhase.cs new file mode 100644 index 0000000000..0afcaaaa15 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorEnginePhase.cs @@ -0,0 +1,12 @@ +// 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 +{ + public interface IRazorEnginePhase + { + RazorEngine Engine { get; set; } + + void Execute(RazorCodeDocument codeDocument); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorFeature.cs new file mode 100644 index 0000000000..4b8d602601 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorFeature.cs @@ -0,0 +1,9 @@ +// 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 +{ + public interface IRazorFeature + { + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorIntermediateNodeLoweringPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorIntermediateNodeLoweringPhase.cs new file mode 100644 index 0000000000..6a7bfa05ec --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorIntermediateNodeLoweringPhase.cs @@ -0,0 +1,19 @@ +// 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 +{ + /// + /// Generates the intermediate node document from . + /// + /// + /// The document is first produced by . At this point no intermediate node + /// passes have been executed. The default will perform a mechanical + /// transformation of the syntax tree to intermediate nodes, resulting in a mostly flat structure. It is up to later phases + /// to give the document structure and semantics according to a document kind. The default + /// is also responsible for merging nodes from imported documents. + /// + public interface IRazorIntermediateNodeLoweringPhase : IRazorEnginePhase + { + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorOptimizationPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorOptimizationPass.cs new file mode 100644 index 0000000000..693cf96a02 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorOptimizationPass.cs @@ -0,0 +1,14 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public interface IRazorOptimizationPass : IRazorEngineFeature + { + int Order { get; } + + void Execute(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorOptimizationPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorOptimizationPhase.cs new file mode 100644 index 0000000000..e0c7cccd5d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorOptimizationPhase.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. + +namespace Microsoft.AspNetCore.Razor.Language +{ + /// + /// Performs necessary modifications to the to complete and + /// optimize code generation. + /// + /// + /// + /// The last phase of intermediate node document processing is optimization. Passes in this phase perform some + /// kind of transformation on the intermediate node document that optimizes the generated code. The key distinction + /// here is that information may be discarded during this phase. + /// + /// + /// objects are executed according to an ascending ordering of the + /// property. + /// + /// + public interface IRazorOptimizationPhase : IRazorEnginePhase + { + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParserOptionsFactoryProjectFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParserOptionsFactoryProjectFeature.cs new file mode 100644 index 0000000000..e73bf8babc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParserOptionsFactoryProjectFeature.cs @@ -0,0 +1,12 @@ +// 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 +{ + internal interface IRazorParserOptionsFactoryProjectFeature : IRazorProjectEngineFeature + { + RazorParserOptions Create(Action configure); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParserOptionsFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParserOptionsFeature.cs new file mode 100644 index 0000000000..b2c1e9ec3e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParserOptionsFeature.cs @@ -0,0 +1,13 @@ +// 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 +{ + [Obsolete("In Razor 2.1 and newer, use RazorCodeDocument.GetParserOptions().")] + public interface IRazorParserOptionsFeature : IRazorEngineFeature + { + RazorParserOptions GetOptions(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParsingPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParsingPhase.cs new file mode 100644 index 0000000000..fb409ec33f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorParsingPhase.cs @@ -0,0 +1,9 @@ +// 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 +{ + public interface IRazorParsingPhase : IRazorEnginePhase + { + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorProjectEngineFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorProjectEngineFeature.cs new file mode 100644 index 0000000000..3b97dbefd2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorProjectEngineFeature.cs @@ -0,0 +1,10 @@ +// 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 +{ + public interface IRazorProjectEngineFeature : IRazorFeature + { + RazorProjectEngine ProjectEngine { get; set; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorSyntaxTreePass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorSyntaxTreePass.cs new file mode 100644 index 0000000000..aa4ba84650 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorSyntaxTreePass.cs @@ -0,0 +1,13 @@ +// 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 +{ + // Internal until we flesh out public RazorSyntaxTree API + internal interface IRazorSyntaxTreePass : IRazorEngineFeature + { + int Order { get; } + + RazorSyntaxTree Execute(RazorCodeDocument codeDocument, RazorSyntaxTree syntaxTree); + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorSyntaxTreePhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorSyntaxTreePhase.cs new file mode 100644 index 0000000000..f75baab74a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorSyntaxTreePhase.cs @@ -0,0 +1,10 @@ +// 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 +{ + // Internal until we flesh out public RazorSyntaxTree API. + internal interface IRazorSyntaxTreePhase : IRazorEnginePhase + { + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorTagHelperBinderPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorTagHelperBinderPhase.cs new file mode 100644 index 0000000000..1cea097fbd --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorTagHelperBinderPhase.cs @@ -0,0 +1,9 @@ +// 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 +{ + public interface IRazorTagHelperBinderPhase : IRazorEnginePhase + { + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorTargetExtensionFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorTargetExtensionFeature.cs new file mode 100644 index 0000000000..33f30c8193 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IRazorTargetExtensionFeature.cs @@ -0,0 +1,13 @@ +// 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.CodeGeneration; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public interface IRazorTargetExtensionFeature : IRazorEngineFeature + { + ICollection TargetExtensions { get; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ITagHelperDescriptorProvider.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ITagHelperDescriptorProvider.cs new file mode 100644 index 0000000000..1b061f59ba --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ITagHelperDescriptorProvider.cs @@ -0,0 +1,12 @@ +// 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 +{ + public interface ITagHelperDescriptorProvider : IRazorEngineFeature + { + int Order { get; } + + void Execute(TagHelperDescriptorProviderContext context); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ITagHelperFeature.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ITagHelperFeature.cs new file mode 100644 index 0000000000..1f33f948dc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ITagHelperFeature.cs @@ -0,0 +1,12 @@ +// 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 +{ + public interface ITagHelperFeature : IRazorEngineFeature + { + IReadOnlyList GetDescriptors(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpCodeAttributeValueIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpCodeAttributeValueIntermediateNode.cs new file mode 100644 index 0000000000..4a9ce5d1a9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpCodeAttributeValueIntermediateNode.cs @@ -0,0 +1,31 @@ +// 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.Intermediate +{ + public sealed class CSharpCodeAttributeValueIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string Prefix { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitCSharpCodeAttributeValue(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteChildren(Children); + + formatter.WriteProperty(nameof(Prefix), Prefix); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpCodeIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpCodeIntermediateNode.cs new file mode 100644 index 0000000000..f888a561f8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpCodeIntermediateNode.cs @@ -0,0 +1,27 @@ +// 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.Intermediate +{ + public sealed class CSharpCodeIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitCSharpCode(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteChildren(Children); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpExpressionAttributeValueIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpExpressionAttributeValueIntermediateNode.cs new file mode 100644 index 0000000000..c058b67acc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpExpressionAttributeValueIntermediateNode.cs @@ -0,0 +1,31 @@ +// 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.Intermediate +{ + public sealed class CSharpExpressionAttributeValueIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string Prefix { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitCSharpExpressionAttributeValue(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteChildren(Children); + + formatter.WriteProperty(nameof(Prefix), Prefix); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpExpressionIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpExpressionIntermediateNode.cs new file mode 100644 index 0000000000..c4c9e02962 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CSharpExpressionIntermediateNode.cs @@ -0,0 +1,27 @@ +// 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.Intermediate +{ + public sealed class CSharpExpressionIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitCSharpExpression(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteChildren(Children); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/ClassDeclarationIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/ClassDeclarationIntermediateNode.cs new file mode 100644 index 0000000000..ea178228c3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/ClassDeclarationIntermediateNode.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 System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public sealed class ClassDeclarationIntermediateNode : MemberDeclarationIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public IList Modifiers { get; } = new List(); + + public string ClassName { get; set; } + + public string BaseType { get; set; } + + public IList Interfaces { get; set; } = new List(); + + public IList TypeParameters { get; set; } = new List(); + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitClassDeclaration(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(ClassName); + + formatter.WriteProperty(nameof(BaseType), BaseType); + formatter.WriteProperty(nameof(ClassName), ClassName); + formatter.WriteProperty(nameof(Interfaces), string.Join(", ", Interfaces)); + formatter.WriteProperty(nameof(Modifiers), string.Join(", ", Modifiers)); + formatter.WriteProperty(nameof(TypeParameters), string.Join(", ", TypeParameters.Select(t => t.ParameterName))); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CommonAnnotations.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CommonAnnotations.cs new file mode 100644 index 0000000000..fb2f02fc69 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/CommonAnnotations.cs @@ -0,0 +1,21 @@ +// 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.Intermediate +{ + public static class CommonAnnotations + { + public static readonly object Imported = "Imported"; + + public static readonly object PrimaryClass = "PrimaryClass"; + + public static readonly object PrimaryMethod = "PrimaryMethod"; + + public static readonly object PrimaryNamespace = "PrimaryNamespace"; + + public static class DefaultTagHelperExtension + { + public static readonly object TagHelperField = "TagHelperField"; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DebuggerDisplayFormatter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DebuggerDisplayFormatter.cs new file mode 100644 index 0000000000..705148b8ab --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DebuggerDisplayFormatter.cs @@ -0,0 +1,21 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + internal class DebuggerDisplayFormatter : IntermediateNodeFormatterBase + { + public DebuggerDisplayFormatter() + { + Writer = new StringWriter(); + ContentMode = FormatterContentMode.PreferContent; + } + + public override string ToString() + { + return Writer.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DefaultRazorIntermediateNodeBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DefaultRazorIntermediateNodeBuilder.cs new file mode 100644 index 0000000000..abee297973 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DefaultRazorIntermediateNodeBuilder.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 System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + internal class DefaultRazorIntermediateNodeBuilder : IntermediateNodeBuilder + { + private readonly List _stack; + private int _depth; + + public DefaultRazorIntermediateNodeBuilder() + { + _stack = new List(); + } + + public override IntermediateNode Current + { + get + { + return _depth > 0 ? _stack[_depth - 1] : null; + } + } + + public override void Add(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + Current.Children.Add(node); + } + + public override void Insert(int index, IntermediateNode node) + { + if (index < 0 || index - Current.Children.Count > 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (index == Current.Children.Count) + { + // Allow inserting at 'Children.Count' to be friendlier than List<> typically is. + Current.Children.Add(node); + } + else + { + Current.Children.Insert(index, node); + } + } + + public override IntermediateNode Build() + { + IntermediateNode node = null; + while (_depth > 0) + { + node = Pop(); + } + + return node; + } + + public override IntermediateNode Pop() + { + if (_depth == 0) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeBuilder_PopInvalid(nameof(Pop))); + } + + var node = _stack[--_depth]; + return node; + } + + public override void Push(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (_depth >= _stack.Count) + { + _stack.Add(node); + } + else + { + _stack[_depth] = node; + } + + if (_depth > 0) + { + var parent = _stack[_depth - 1]; + parent.Children.Add(node); + } + + _depth++; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DirectiveIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DirectiveIntermediateNode.cs new file mode 100644 index 0000000000..6f954a89f8 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DirectiveIntermediateNode.cs @@ -0,0 +1,32 @@ +// 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.Intermediate +{ + public sealed class DirectiveIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string DirectiveName { get; set; } + + public IEnumerable Tokens => Children.OfType(); + + public DirectiveDescriptor Directive { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + visitor.VisitDirective(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(DirectiveName); + + formatter.WriteProperty(nameof(Directive), Directive?.DisplayName); + formatter.WriteProperty(nameof(DirectiveName), DirectiveName); + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DirectiveTokenIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DirectiveTokenIntermediateNode.cs new file mode 100644 index 0000000000..a01ed25b80 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DirectiveTokenIntermediateNode.cs @@ -0,0 +1,28 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public sealed class DirectiveTokenIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public string Content { get; set; } + + public DirectiveTokenDescriptor DirectiveToken { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + visitor.VisitDirectiveToken(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(Content); + + formatter.WriteProperty(nameof(Content), Content); + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DocumentIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DocumentIntermediateNode.cs new file mode 100644 index 0000000000..9570092e46 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DocumentIntermediateNode.cs @@ -0,0 +1,36 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public sealed class DocumentIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string DocumentKind { get; set; } + + public RazorCodeGenerationOptions Options { get; set; } + + public CodeTarget Target { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitDocument(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(DocumentKind); + + formatter.WriteProperty(nameof(DocumentKind), DocumentKind); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DocumentIntermediateNodeExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DocumentIntermediateNodeExtensions.cs new file mode 100644 index 0000000000..c1482fbb67 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/DocumentIntermediateNodeExtensions.cs @@ -0,0 +1,99 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public static class DocumentIntermediateNodeExtensions + { + public static ClassDeclarationIntermediateNode FindPrimaryClass(this DocumentIntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + return FindWithAnnotation(node, CommonAnnotations.PrimaryClass); + } + + public static MethodDeclarationIntermediateNode FindPrimaryMethod(this DocumentIntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + return FindWithAnnotation(node, CommonAnnotations.PrimaryMethod); + } + + public static NamespaceDeclarationIntermediateNode FindPrimaryNamespace(this DocumentIntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + return FindWithAnnotation(node, CommonAnnotations.PrimaryNamespace); + } + + public static IReadOnlyList FindDirectiveReferences(this DocumentIntermediateNode node, DirectiveDescriptor directive) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (directive == null) + { + throw new ArgumentNullException(nameof(directive)); + } + + var visitor = new DirectiveVisitor(directive); + visitor.Visit(node); + return visitor.Directives; + } + + private static T FindWithAnnotation(IntermediateNode node, object annotation) where T : IntermediateNode + { + if (node is T target && object.ReferenceEquals(target.Annotations[annotation], annotation)) + { + return target; + } + + for (var i = 0; i < node.Children.Count; i++) + { + var result = FindWithAnnotation(node.Children[i], annotation); + if (result != null) + { + return result; + } + } + + return null; + } + + private class DirectiveVisitor : IntermediateNodeWalker + { + private readonly DirectiveDescriptor _directive; + + public DirectiveVisitor(DirectiveDescriptor directive) + { + _directive = directive; + } + + public List Directives = new List(); + + public override void VisitDirective(DirectiveIntermediateNode node) + { + if (_directive == node.Directive) + { + Directives.Add(new IntermediateNodeReference(Parent, node)); + } + + base.VisitDirective(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/ExtensionIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/ExtensionIntermediateNode.cs new file mode 100644 index 0000000000..2b909da7ae --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/ExtensionIntermediateNode.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 Microsoft.AspNetCore.Razor.Language.CodeGeneration; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public abstract class ExtensionIntermediateNode : IntermediateNode + { + public abstract void WriteNode(CodeTarget target, CodeRenderingContext context); + + protected static void AcceptExtensionNode(TNode node, IntermediateNodeVisitor visitor) + where TNode : ExtensionIntermediateNode + { + var typedVisitor = visitor as IExtensionIntermediateNodeVisitor; + if (typedVisitor == null) + { + visitor.VisitExtension(node); + } + else + { + typedVisitor.VisitExtension(node); + } + } + + protected void ReportMissingCodeTargetExtension(CodeRenderingContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var documentKind = context.DocumentKind ?? string.Empty; + context.Diagnostics.Add( + RazorDiagnosticFactory.CreateCodeTarget_UnsupportedExtension( + documentKind, + typeof(TDependency))); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/FieldDeclarationIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/FieldDeclarationIntermediateNode.cs new file mode 100644 index 0000000000..0d6b731390 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/FieldDeclarationIntermediateNode.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 System; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public sealed class FieldDeclarationIntermediateNode : MemberDeclarationIntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public IList Modifiers { get; } = new List(); + + public string FieldName { get; set; } + + public string FieldType { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitFieldDeclaration(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(FieldName); + + formatter.WriteProperty(nameof(FieldName), FieldName); + formatter.WriteProperty(nameof(FieldType), FieldType); + formatter.WriteProperty(nameof(Modifiers), string.Join(" ", Modifiers)); + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlAttributeIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlAttributeIntermediateNode.cs new file mode 100644 index 0000000000..861b14b227 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlAttributeIntermediateNode.cs @@ -0,0 +1,37 @@ +// 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.Intermediate +{ + public sealed class HtmlAttributeIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string AttributeName { get; set; } + + public string Prefix { get; set; } + + public string Suffix { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitHtmlAttribute(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(AttributeName); + + formatter.WriteProperty(nameof(AttributeName), AttributeName); + formatter.WriteProperty(nameof(Prefix), Prefix); + formatter.WriteProperty(nameof(Suffix), Suffix); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlAttributeValueIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlAttributeValueIntermediateNode.cs new file mode 100644 index 0000000000..6fdc5247a3 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlAttributeValueIntermediateNode.cs @@ -0,0 +1,31 @@ +// 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.Intermediate +{ + public sealed class HtmlAttributeValueIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string Prefix { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitHtmlAttributeValue(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteChildren(Children); + + formatter.WriteProperty(nameof(Prefix), Prefix); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlContentIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlContentIntermediateNode.cs new file mode 100644 index 0000000000..3a213fe460 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/HtmlContentIntermediateNode.cs @@ -0,0 +1,27 @@ +// 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.Intermediate +{ + public sealed class HtmlContentIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitHtml(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteChildren(Children); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IExtensionIntermediateNodeVisitor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IExtensionIntermediateNodeVisitor.cs new file mode 100644 index 0000000000..817439d0ba --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IExtensionIntermediateNodeVisitor.cs @@ -0,0 +1,10 @@ +// 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.Intermediate +{ + public interface IExtensionIntermediateNodeVisitor where TNode : ExtensionIntermediateNode + { + void VisitExtension(TNode node); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/InputDocumentKind.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/InputDocumentKind.cs new file mode 100644 index 0000000000..7adf2bd8b5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/InputDocumentKind.cs @@ -0,0 +1,12 @@ +// 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.Intermediate +{ + internal static class InputDocumentKind + { + public static readonly string Component = "component"; + + public static readonly string MvcFile = "mvc"; + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNode.cs new file mode 100644 index 0000000000..02c2976c55 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNode.cs @@ -0,0 +1,71 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + [DebuggerDisplay("{DebuggerToString(),nq}")] + public abstract class IntermediateNode + { + private ItemCollection _annotations; + private RazorDiagnosticCollection _diagnostics; + + public ItemCollection Annotations + { + get + { + if (_annotations == null) + { + _annotations = new ItemCollection(); + } + + return _annotations; + } + } + + public abstract IntermediateNodeCollection Children { get; } + + public RazorDiagnosticCollection Diagnostics + { + get + { + if (_diagnostics == null) + { + _diagnostics = new RazorDiagnosticCollection(); + } + + return _diagnostics; + } + } + + public bool HasDiagnostics => _diagnostics != null && _diagnostics.Count > 0; + + public SourceSpan? Source { get; set; } + + public abstract void Accept(IntermediateNodeVisitor visitor); + + [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)] + private string Tree + { + get + { + var formatter = new DebuggerDisplayFormatter(); + formatter.FormatTree(this); + return formatter.ToString(); + } + } + + private string DebuggerToString() + { + var formatter = new DebuggerDisplayFormatter(); + formatter.FormatNode(this); + return formatter.ToString(); + } + + + public virtual void FormatNode(IntermediateNodeFormatter formatter) + { + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeBuilder.cs new file mode 100644 index 0000000000..24e72f5065 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeBuilder.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; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + internal abstract class IntermediateNodeBuilder + { + public static IntermediateNodeBuilder Create(IntermediateNode root) + { + if (root == null) + { + throw new ArgumentNullException(nameof(root)); + } + + var builder = new DefaultRazorIntermediateNodeBuilder(); + builder.Push(root); + return builder; + } + + public abstract IntermediateNode Current { get; } + + public abstract void Add(IntermediateNode node); + + public abstract void Insert(int index, IntermediateNode node); + + public abstract IntermediateNode Build(); + + public abstract void Push(IntermediateNode node); + + public abstract IntermediateNode Pop(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeCollection.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeCollection.cs new file mode 100644 index 0000000000..4c50fa1240 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeCollection.cs @@ -0,0 +1,198 @@ +// 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; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public sealed class IntermediateNodeCollection : IList + { + public static readonly IntermediateNodeCollection ReadOnly = new IntermediateNodeCollection(new List().AsReadOnly()); + + private readonly IList _inner; + + public IntermediateNodeCollection() + : this(new List()) + { + } + + private IntermediateNodeCollection(IList inner) + { + _inner = inner; + } + + public IntermediateNode this[int index] + { + get + { + if (index < 0 || index >= Count) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + return _inner[index]; + } + set + { + if (index < 0 || index >= Count) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + _inner[index] = value; + } + } + + public int Count => _inner.Count; + + public bool IsReadOnly => _inner.IsReadOnly; + + public void Add(IntermediateNode item) + { + if (item == null) + { + throw new ArgumentNullException(nameof(item)); + } + + _inner.Add(item); + } + + public void Clear() + { + _inner.Clear(); + } + + public bool Contains(IntermediateNode item) + { + return _inner.Contains(item); + } + + public void CopyTo(IntermediateNode[] array, int arrayIndex) + { + if (array == null) + { + throw new ArgumentNullException(nameof(array)); + } + + if (arrayIndex < 0 || arrayIndex > array.Length) + { + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + } + else if (array.Length - arrayIndex < Count) + { + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + } + + _inner.CopyTo(array, arrayIndex); + } + + public Enumerator GetEnumerator() + { + return new Enumerator(this); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public int IndexOf(IntermediateNode item) + { + if (item == null) + { + throw new ArgumentNullException(nameof(item)); + } + + return _inner.IndexOf(item); + } + + public void Insert(int index, IntermediateNode item) + { + if (index < 0 || index > Count) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + if (item == null) + { + throw new ArgumentNullException(nameof(item)); + } + + _inner.Insert(index, item); + } + + public bool Remove(IntermediateNode item) + { + if (item == null) + { + throw new ArgumentNullException(nameof(item)); + } + + return _inner.Remove(item); + } + + public void RemoveAt(int index) + { + if (index < 0 || index >= Count) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + _inner.RemoveAt(index); + } + + public struct Enumerator : IEnumerator + { + private readonly IList _items; + private int _index; + + public Enumerator(IntermediateNodeCollection collection) + { + if (collection == null) + { + throw new ArgumentNullException(nameof(collection)); + } + + _items = collection._inner; + _index = -1; + } + + public IntermediateNode Current + { + get + { + if (_index < 0 || _index >= _items.Count) + { + return null; + } + + return _items[_index]; + } + } + + object IEnumerator.Current => Current; + + public void Dispose() + { + } + + public bool MoveNext() + { + _index++; + return _index < _items.Count; + } + + public void Reset() + { + _index = -1; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeExtensions.cs new file mode 100644 index 0000000000..6af13aab2c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeExtensions.cs @@ -0,0 +1,81 @@ +// 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.Intermediate +{ + public static class IntermediateNodeExtensions + { + private static readonly IReadOnlyList EmptyDiagnostics = Array.Empty(); + + public static bool IsImported(this IntermediateNode node) + { + return ReferenceEquals(node.Annotations[CommonAnnotations.Imported], CommonAnnotations.Imported); + } + + public static IReadOnlyList GetAllDiagnostics(this IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + HashSet diagnostics = null; + + AddAllDiagnostics(node); + + return diagnostics?.ToList() ?? EmptyDiagnostics; + + void AddAllDiagnostics(IntermediateNode n) + { + if (n.HasDiagnostics) + { + if (diagnostics == null) + { + diagnostics = new HashSet(); + } + + diagnostics.UnionWith(n.Diagnostics); + } + + for (var i = 0; i < n.Children.Count; i++) + { + AddAllDiagnostics(n.Children[i]); + } + } + } + + public static IReadOnlyList FindDescendantNodes(this IntermediateNode node) + where TNode : IntermediateNode + { + var visitor = new Visitor(); + visitor.Visit(node); + + if (visitor.Results.Count > 0 && visitor.Results[0] == node) + { + // Don't put the node itself in the results + visitor.Results.Remove((TNode)node); + } + + return visitor.Results; + } + + private class Visitor : IntermediateNodeWalker where TNode : IntermediateNode + { + public List Results { get; } = new List(); + + public override void VisitDefault(IntermediateNode node) + { + if (node is TNode match) + { + Results.Add(match); + } + + base.VisitDefault(node); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeFormatter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeFormatter.cs new file mode 100644 index 0000000000..c453dbe6e9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeFormatter.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.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public abstract class IntermediateNodeFormatter + { + public abstract void WriteChildren(IntermediateNodeCollection children); + + public abstract void WriteContent(string content); + + public abstract void WriteProperty(string key, string value); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeFormatterBase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeFormatterBase.cs new file mode 100644 index 0000000000..54846acaaf --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeFormatterBase.cs @@ -0,0 +1,180 @@ +// 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.IO; +using System.Linq; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + internal class IntermediateNodeFormatterBase : IntermediateNodeFormatter + { + private string _content; + private Dictionary _properties = new Dictionary(StringComparer.Ordinal); + + protected FormatterContentMode ContentMode { get; set; } + + protected bool IncludeSource { get; set; } + + protected TextWriter Writer { get; set; } + + public override void WriteChildren(IntermediateNodeCollection children) + { + if (children == null) + { + throw new ArgumentNullException(nameof(children)); + } + + Writer.Write(" "); + Writer.Write("\""); + for (var i = 0; i < children.Count; i++) + { + var child = children[i] as IntermediateToken; + if (child != null) + { + Writer.Write(EscapeNewlines(child.Content)); + } + } + Writer.Write("\""); + } + + public override void WriteContent(string content) + { + if (content == null) + { + return; + } + + _content = EscapeNewlines(content); + } + + public override void WriteProperty(string key, string value) + { + if (key == null) + { + throw new ArgumentNullException(nameof(key)); + } + + if (value == null) + { + return; + } + + _properties.Add(key, EscapeNewlines(value)); + } + + public void FormatNode(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + BeginNode(node); + node.FormatNode(this); + EndNode(node); + } + + public void FormatTree(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + var visitor = new FormatterVisitor(this); + visitor.Visit(node); + } + + private void BeginNode(IntermediateNode node) + { + Writer.Write(GetShortName(node)); + + if (IncludeSource) + { + Writer.Write(" "); + Writer.Write(node.Source?.ToString() ?? "(n/a)"); + } + } + + private void EndNode(IntermediateNode node) + { + if (_content != null && (_properties.Count == 0 || ContentMode == FormatterContentMode.PreferContent)) + { + Writer.Write(" "); + Writer.Write("\""); + Writer.Write(EscapeNewlines(_content)); + Writer.Write("\""); + } + + if (_properties.Count > 0 && (_content == null || ContentMode == FormatterContentMode.PreferProperties)) + { + Writer.Write(" "); + Writer.Write("{ "); + Writer.Write(string.Join(", ", _properties.Select(kvp => $"{kvp.Key}: \"{kvp.Value}\""))); + Writer.Write(" }"); + } + + _content = null; + _properties.Clear(); + } + + private string GetShortName(IntermediateNode node) + { + var typeName = node.GetType().Name; + return + typeName.EndsWith(nameof(IntermediateNode), StringComparison.Ordinal) ? + typeName.Substring(0, typeName.Length - nameof(IntermediateNode).Length) : + typeName; + } + + private string EscapeNewlines(string content) + { + return content.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t"); + } + + // Depending on the usage of the formatter we might prefer thoroughness (properties) + // or brevity (content). Generally if a node has a single string that provides value + // it has content. + // + // Some nodes have neither: TagHelperBody + // Some nodes have content: HtmlContent + // Some nodes have properties: Document + // Some nodes have both: TagHelperProperty + protected enum FormatterContentMode + { + PreferContent, + PreferProperties, + } + + protected class FormatterVisitor : IntermediateNodeWalker + { + private const int IndentSize = 2; + + private readonly IntermediateNodeFormatterBase _formatter; + private int _indent = 0; + + public FormatterVisitor(IntermediateNodeFormatterBase formatter) + { + _formatter = formatter; + } + + public override void VisitDefault(IntermediateNode node) + { + // Indent + for (var i = 0; i < _indent; i++) + { + _formatter.Writer.Write(' '); + } + _formatter.FormatNode(node); + _formatter.Writer.WriteLine(); + + // Process children + _indent += IndentSize; + base.VisitDefault(node); + _indent -= IndentSize; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeReference.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeReference.cs new file mode 100644 index 0000000000..230ca17484 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeReference.cs @@ -0,0 +1,209 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public struct IntermediateNodeReference + { + public IntermediateNodeReference(IntermediateNode parent, IntermediateNode node) + { + if (parent == null) + { + throw new ArgumentNullException(nameof(parent)); + } + + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + Parent = parent; + Node = node; + } + + public void Deconstruct(out IntermediateNode parent, out IntermediateNode node) + { + parent = Parent; + node = Node; + } + + public IntermediateNode Node { get; } + + public IntermediateNode Parent { get; } + + public IntermediateNodeReference InsertAfter(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (Parent == null) + { + throw new InvalidOperationException(Resources.IntermediateNodeReference_NotInitialized); + } + + if (Parent.Children.IsReadOnly) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_CollectionIsReadOnly(Parent)); + } + + var index = Parent.Children.IndexOf(Node); + if (index == -1) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_NodeNotFound( + Node, + Parent)); + } + + Parent.Children.Insert(index + 1, node); + return new IntermediateNodeReference(Parent, node); + } + + public void InsertAfter(IEnumerable nodes) + { + if (nodes == null) + { + throw new ArgumentNullException(nameof(nodes)); + } + + if (Parent == null) + { + throw new InvalidOperationException(Resources.IntermediateNodeReference_NotInitialized); + } + + if (Parent.Children.IsReadOnly) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_CollectionIsReadOnly(Parent)); + } + + var index = Parent.Children.IndexOf(Node); + if (index == -1) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_NodeNotFound( + Node, + Parent)); + } + + foreach (var node in nodes) + { + Parent.Children.Insert(++index, node); + } + } + + public IntermediateNodeReference InsertBefore(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (Parent == null) + { + throw new InvalidOperationException(Resources.IntermediateNodeReference_NotInitialized); + } + + if (Parent.Children.IsReadOnly) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_CollectionIsReadOnly(Parent)); + } + + var index = Parent.Children.IndexOf(Node); + if (index == -1) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_NodeNotFound( + Node, + Parent)); + } + + Parent.Children.Insert(index, node); + return new IntermediateNodeReference(Parent, node); + } + + public void InsertBefore(IEnumerable nodes) + { + if (nodes == null) + { + throw new ArgumentNullException(nameof(nodes)); + } + + if (Parent == null) + { + throw new InvalidOperationException(Resources.IntermediateNodeReference_NotInitialized); + } + + if (Parent.Children.IsReadOnly) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_CollectionIsReadOnly(Parent)); + } + + var index = Parent.Children.IndexOf(Node); + if (index == -1) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_NodeNotFound( + Node, + Parent)); + } + + foreach (var node in nodes) + { + Parent.Children.Insert(index++, node); + } + } + + public void Remove() + { + if (Parent == null) + { + throw new InvalidOperationException(Resources.IntermediateNodeReference_NotInitialized); + } + + if (Parent.Children.IsReadOnly) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_CollectionIsReadOnly(Parent)); + } + + var index = Parent.Children.IndexOf(Node); + if (index == -1) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_NodeNotFound( + Node, + Parent)); + } + + Parent.Children.RemoveAt(index); + } + + public IntermediateNodeReference Replace(IntermediateNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + if (Parent == null) + { + throw new InvalidOperationException(Resources.IntermediateNodeReference_NotInitialized); + } + + if (Parent.Children.IsReadOnly) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_CollectionIsReadOnly(Parent)); + } + + var index = Parent.Children.IndexOf(Node); + if (index == -1) + { + throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_NodeNotFound( + Node, + Parent)); + } + + Parent.Children[index] = node; + return new IntermediateNodeReference(Parent, node); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeVisitor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeVisitor.cs new file mode 100644 index 0000000000..bb2c2687a2 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeVisitor.cs @@ -0,0 +1,132 @@ +// 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.Intermediate +{ + public abstract class IntermediateNodeVisitor + { + public virtual void Visit(IntermediateNode node) + { + node.Accept(this); + } + + public virtual void VisitDefault(IntermediateNode node) + { + } + + public virtual void VisitToken(IntermediateToken node) + { + VisitDefault(node); + } + + public virtual void VisitDirectiveToken(DirectiveTokenIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitDirective(DirectiveIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitMalformedDirective(MalformedDirectiveIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitExtension(ExtensionIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitCSharpCode(CSharpCodeIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitCSharpExpression(CSharpExpressionIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitHtmlAttributeValue(HtmlAttributeValueIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitCSharpExpressionAttributeValue(CSharpExpressionAttributeValueIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitCSharpCodeAttributeValue(CSharpCodeAttributeValueIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitHtmlAttribute(HtmlAttributeIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitClassDeclaration(ClassDeclarationIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitMethodDeclaration(MethodDeclarationIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitFieldDeclaration(FieldDeclarationIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitPropertyDeclaration(PropertyDeclarationIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitDocument(DocumentIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitHtml(HtmlContentIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitUsingDirective(UsingDirectiveIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitTagHelper(TagHelperIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitTagHelperBody(TagHelperBodyIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitTagHelperProperty(TagHelperPropertyIntermediateNode node) + { + VisitDefault(node); + } + + public virtual void VisitTagHelperHtmlAttribute(TagHelperHtmlAttributeIntermediateNode node) + { + VisitDefault(node); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeWalker.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeWalker.cs new file mode 100644 index 0000000000..8cafe05a9a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateNodeWalker.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 System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public abstract class IntermediateNodeWalker : IntermediateNodeVisitor + { + private readonly List _ancestors = new List(); + + protected IReadOnlyList Ancestors => _ancestors; + + protected IntermediateNode Parent => _ancestors.Count > 0 ? _ancestors[0] : null; + + public override void VisitDefault(IntermediateNode node) + { + var children = node.Children; + if (node.Children.Count == 0) + { + return; + } + + _ancestors.Insert(0, node); + + try + { + for (var i = 0; i < node.Children.Count; i++) + { + var child = children[i]; + Visit(child); + } + } + finally + { + _ancestors.RemoveAt(0); + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateToken.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateToken.cs new file mode 100644 index 0000000000..d60643d24a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/IntermediateToken.cs @@ -0,0 +1,37 @@ +// 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.Intermediate +{ + public sealed class IntermediateToken : IntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public string Content { get; set; } + + public bool IsCSharp => Kind == TokenKind.CSharp; + + public bool IsHtml => Kind == TokenKind.Html; + + public TokenKind Kind { get; set; } = TokenKind.Unknown; + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitToken(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(Content); + + formatter.WriteProperty(nameof(Content), Content); + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MalformedDirectiveIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MalformedDirectiveIntermediateNode.cs new file mode 100644 index 0000000000..d37a2316a5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MalformedDirectiveIntermediateNode.cs @@ -0,0 +1,32 @@ +// 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.Intermediate +{ + public sealed class MalformedDirectiveIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string DirectiveName { get; set; } + + public IEnumerable Tokens => Children.OfType(); + + public DirectiveDescriptor Directive { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + visitor.VisitMalformedDirective(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(DirectiveName); + + formatter.WriteProperty(nameof(Directive), Directive?.DisplayName); + formatter.WriteProperty(nameof(DirectiveName), DirectiveName); + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MemberDeclarationIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MemberDeclarationIntermediateNode.cs new file mode 100644 index 0000000000..b506fec616 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MemberDeclarationIntermediateNode.cs @@ -0,0 +1,9 @@ +// 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.Intermediate +{ + public abstract class MemberDeclarationIntermediateNode : IntermediateNode + { + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MethodDeclarationIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MethodDeclarationIntermediateNode.cs new file mode 100644 index 0000000000..ad15636824 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/MethodDeclarationIntermediateNode.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 System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public sealed class MethodDeclarationIntermediateNode : MemberDeclarationIntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public IList Modifiers { get; } = new List(); + + public string MethodName { get; set; } + + public IList Parameters { get; } = new List(); + + public string ReturnType { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitMethodDeclaration(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(MethodName); + + formatter.WriteProperty(nameof(MethodName), MethodName); + formatter.WriteProperty(nameof(Modifiers), string.Join(", ", Modifiers)); + formatter.WriteProperty(nameof(Parameters), string.Join(", ", Parameters.Select(FormatMethodParameter))); + formatter.WriteProperty(nameof(ReturnType), ReturnType); + } + + private static string FormatMethodParameter(MethodParameter parameter) + { + var builder = new StringBuilder(); + for (var i = 0; i Modifiers { get; } = new List(); + + public string TypeName { get; set; } + + public string ParameterName { get; set; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/NamespaceDeclarationIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/NamespaceDeclarationIntermediateNode.cs new file mode 100644 index 0000000000..4a828102ae --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/NamespaceDeclarationIntermediateNode.cs @@ -0,0 +1,31 @@ +// 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.Intermediate +{ + public sealed class NamespaceDeclarationIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string Content { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitNamespaceDeclaration(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(Content); + + formatter.WriteProperty(nameof(Content), Content); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/PropertyDeclarationIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/PropertyDeclarationIntermediateNode.cs new file mode 100644 index 0000000000..3b7242c5bd --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/PropertyDeclarationIntermediateNode.cs @@ -0,0 +1,29 @@ +// 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; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public sealed class PropertyDeclarationIntermediateNode : MemberDeclarationIntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public IList Modifiers { get; } = new List(); + + public string PropertyName { get; set; } + + public string PropertyType { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitPropertyDeclaration(this); + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperBodyIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperBodyIntermediateNode.cs new file mode 100644 index 0000000000..ebf5b0eac0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperBodyIntermediateNode.cs @@ -0,0 +1,22 @@ +// 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.Intermediate +{ + public sealed class TagHelperBodyIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitTagHelperBody(this); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperHtmlAttributeIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperHtmlAttributeIntermediateNode.cs new file mode 100644 index 0000000000..bdbf136384 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperHtmlAttributeIntermediateNode.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; + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public sealed class TagHelperHtmlAttributeIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string AttributeName { get; set; } + + public AttributeStructure AttributeStructure { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitTagHelperHtmlAttribute(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(AttributeName); + + formatter.WriteProperty(nameof(AttributeName), AttributeName); + formatter.WriteProperty(nameof(AttributeStructure), AttributeStructure.ToString()); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperIntermediateNode.cs new file mode 100644 index 0000000000..9fcd9a645d --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperIntermediateNode.cs @@ -0,0 +1,57 @@ +// 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.Intermediate +{ + public sealed class TagHelperIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public TagMode TagMode { get; set; } + + public string TagName { get; set; } + + public IList TagHelpers { get; } = new List(); + + public TagHelperBodyIntermediateNode Body => Children.OfType().SingleOrDefault(); + + public IEnumerable Properties + { + get + { + return Children.OfType(); + } + } + + public IEnumerable HtmlAttributes + { + get + { + return Children.OfType(); + } + } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitTagHelper(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(TagName); + + formatter.WriteProperty(nameof(TagHelpers), string.Join(", ", TagHelpers.Select(t => t.DisplayName))); + formatter.WriteProperty(nameof(TagMode), TagMode.ToString()); + formatter.WriteProperty(nameof(TagName), TagName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperPropertyIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperPropertyIntermediateNode.cs new file mode 100644 index 0000000000..1a755fe6f9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TagHelperPropertyIntermediateNode.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.Intermediate +{ + public sealed class TagHelperPropertyIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection(); + + public string AttributeName { get; set; } + + public AttributeStructure AttributeStructure { get; set; } + + public BoundAttributeDescriptor BoundAttribute { get; set; } + + public TagHelperDescriptor TagHelper { get; set; } + + public bool IsIndexerNameMatch { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitTagHelperProperty(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(AttributeName); + + formatter.WriteProperty(nameof(AttributeName), AttributeName); + formatter.WriteProperty(nameof(AttributeStructure), AttributeStructure.ToString()); + formatter.WriteProperty(nameof(BoundAttribute), BoundAttribute?.DisplayName); + formatter.WriteProperty(nameof(IsIndexerNameMatch), IsIndexerNameMatch.ToString()); + formatter.WriteProperty(nameof(TagHelper), TagHelper?.DisplayName); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TokenKind.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TokenKind.cs new file mode 100644 index 0000000000..b73d6797cd --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TokenKind.cs @@ -0,0 +1,12 @@ +// 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.Intermediate +{ + public enum TokenKind + { + Unknown, + CSharp, + Html, + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TypeParameter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TypeParameter.cs new file mode 100644 index 0000000000..08f953e23a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/TypeParameter.cs @@ -0,0 +1,10 @@ +// 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.Intermediate +{ + public sealed class TypeParameter + { + public string ParameterName { get; set; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/UsingDirectiveIntermediateNode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/UsingDirectiveIntermediateNode.cs new file mode 100644 index 0000000000..67c64f79e7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Intermediate/UsingDirectiveIntermediateNode.cs @@ -0,0 +1,31 @@ +// 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.Intermediate +{ + public sealed class UsingDirectiveIntermediateNode : IntermediateNode + { + public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly; + + public string Content { get; set; } + + public override void Accept(IntermediateNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitUsingDirective(this); + } + + public override void FormatNode(IntermediateNodeFormatter formatter) + { + formatter.WriteContent(Content); + + formatter.WriteProperty(nameof(Content), Content); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IntermediateNodePassBase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IntermediateNodePassBase.cs new file mode 100644 index 0000000000..c9024fea52 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/IntermediateNodePassBase.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 System; +using Microsoft.AspNetCore.Razor.Language.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public abstract class IntermediateNodePassBase : RazorEngineFeatureBase + { + /// + /// The default implementation of the s that run in a + /// will use this value for its Order property. + /// + /// + /// This value is chosen in such a way that the default implementation runs after the other + /// custom implementations for a particular . + /// + public static readonly int DefaultFeatureOrder = 1000; + + public virtual int Order { get; } + + public void Execute(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + if (documentNode == null) + { + throw new ArgumentNullException(nameof(documentNode)); + } + + if (Engine == null) + { + throw new InvalidOperationException(Resources.FormatPhaseMustBeInitialized(nameof(Engine))); + } + + ExecuteCore(codeDocument, documentNode); + } + + protected abstract void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ItemCollection.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ItemCollection.cs new file mode 100644 index 0000000000..dc6ab9723f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ItemCollection.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; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language +{ + public sealed class ItemCollection : ICollection> + { + private readonly Dictionary _inner; + + public ItemCollection() + { + _inner = new Dictionary(); + } + + public object this[object key] + { + get + { + if (key == null) + { + throw new ArgumentNullException(nameof(key)); + } + + _inner.TryGetValue(key, out var value); + return value; + } + set + { + if (key == null) + { + throw new ArgumentNullException(nameof(key)); + } + + _inner[key] = value; + } + } + + public int Count => _inner.Count; + + public bool IsReadOnly => _inner != null; + + int ICollection>.Count => throw new NotImplementedException(); + + bool ICollection>.IsReadOnly => throw new NotImplementedException(); + + public void Add(KeyValuePair item) + { + if (item.Key == null) + { + throw new ArgumentException(Resources.KeyMustNotBeNull, nameof(item)); + } + + ((ICollection>)_inner).Add(item); + } + + public void Add(object key, object value) + { + if (key == null) + { + throw new ArgumentNullException(nameof(key)); + } + + _inner.Add(key, value); + } + + public void Clear() + { + _inner.Clear(); + } + + public bool Contains(KeyValuePair item) + { + if (item.Key == null) + { + throw new ArgumentException(Resources.KeyMustNotBeNull, nameof(item)); + } + + return ((ICollection>)_inner).Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + if (array == null) + { + throw new ArgumentNullException(nameof(array)); + } + + if (arrayIndex < 0 || arrayIndex > array.Length) + { + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + } + else if (array.Length - arrayIndex < Count) + { + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + } + + ((ICollection>)_inner).CopyTo(array, arrayIndex); + } + + public IEnumerator> GetEnumerator() + { + return _inner.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public bool Remove(KeyValuePair item) + { + if (item.Key == null) + { + throw new ArgumentException(Resources.KeyMustNotBeNull, nameof(item)); + } + + return ((ICollection>)_inner).Remove(item); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/LargeTextSourceDocument.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/LargeTextSourceDocument.cs new file mode 100644 index 0000000000..34e72ad984 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/LargeTextSourceDocument.cs @@ -0,0 +1,159 @@ +// 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.IO; +using System.Security.Cryptography; +using System.Text; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class LargeTextSourceDocument : RazorSourceDocument + { + private readonly List _chunks; + + private readonly int _chunkMaxLength; + + private readonly RazorSourceLineCollection _lines; + + private readonly int _length; + private byte[] _checksum; + + public LargeTextSourceDocument(StreamReader reader, int chunkMaxLength, Encoding encoding, RazorSourceDocumentProperties properties) + { + if (reader == null) + { + throw new ArgumentNullException(nameof(reader)); + } + + if (encoding == null) + { + throw new ArgumentNullException(nameof(encoding)); + } + + if (properties == null) + { + throw new ArgumentNullException(nameof(properties)); + } + + _chunkMaxLength = chunkMaxLength; + Encoding = encoding; + FilePath = properties.FilePath; + RelativePath = properties.RelativePath; + + ReadChunks(reader, _chunkMaxLength, out _length, out _chunks); + _lines = new DefaultRazorSourceLineCollection(this); + } + + public override char this[int position] + { + get + { + var chunkIndex = position / _chunkMaxLength; + var insideChunkPosition = position % _chunkMaxLength; + + return _chunks[chunkIndex][insideChunkPosition]; + } + } + + public override Encoding Encoding { get; } + + public override string FilePath { get; } + + public override int Length => _length; + + public override RazorSourceLineCollection Lines => _lines; + + public override string RelativePath { get; } + + public override void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) + { + if (destination == null) + { + throw new ArgumentNullException(nameof(destination)); + } + + if (sourceIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(sourceIndex)); + } + + if (destinationIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(destinationIndex)); + } + + if (count < 0 || count > Length - sourceIndex || count > destination.Length - destinationIndex) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (count == 0) + { + return; + } + + var chunkIndex = sourceIndex / _chunkMaxLength; + var insideChunkPosition = sourceIndex % _chunkMaxLength; + var remaining = count; + var currentDestIndex = destinationIndex; + + while (remaining > 0) + { + var toCopy = Math.Min(remaining, _chunkMaxLength - insideChunkPosition); + Array.Copy(_chunks[chunkIndex], insideChunkPosition, destination, currentDestIndex, toCopy); + + remaining -= toCopy; + currentDestIndex += toCopy; + chunkIndex++; + insideChunkPosition = 0; + } + } + + public override byte[] GetChecksum() + { + if (_checksum == null) + { + var charBuffer = new char[Length]; + CopyTo(0, charBuffer, 0, Length); + + var encoder = Encoding.GetEncoder(); + var byteCount = encoder.GetByteCount(charBuffer, 0, charBuffer.Length, flush: true); + var bytes = new byte[byteCount]; + encoder.GetBytes(charBuffer, 0, charBuffer.Length, bytes, 0, flush: true); + + using (var hashAlgorithm = SHA1.Create()) + { + _checksum = hashAlgorithm.ComputeHash(bytes); + } + } + + var copiedChecksum = new byte[_checksum.Length]; + _checksum.CopyTo(copiedChecksum, 0); + + return copiedChecksum; + } + + private static void ReadChunks(StreamReader reader, int chunkMaxLength, out int length, out List chunks) + { + length = 0; + chunks = new List(); + + int read; + do + { + var chunk = new char[chunkMaxLength]; + read = reader.ReadBlock(chunk, 0, chunkMaxLength); + + length += read; + + if (read > 0) + { + chunks.Add(chunk); + } + } + while (read == chunkMaxLength); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AcceptedCharactersInternal.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AcceptedCharactersInternal.cs new file mode 100644 index 0000000000..9838a182b5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AcceptedCharactersInternal.cs @@ -0,0 +1,22 @@ +// 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 +{ + [Flags] + internal enum AcceptedCharactersInternal + { + None = 0, + NewLine = 1, + Whitespace = 2, + + NonWhitespace = 4, + + AllWhitespace = NewLine | Whitespace, + Any = AllWhitespace | NonWhitespace, + + AnyExceptNewline = NonWhitespace | Whitespace + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AddImportChunkGenerator.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AddImportChunkGenerator.cs new file mode 100644 index 0000000000..4cee1abe3e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AddImportChunkGenerator.cs @@ -0,0 +1,35 @@ +// 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 AddImportChunkGenerator : SpanChunkGenerator + { + public AddImportChunkGenerator(string ns) + { + Namespace = ns; + } + + public string Namespace { get; } + + public override string ToString() + { + return "Import:" + Namespace + ";"; + } + + public override bool Equals(object obj) + { + var other = obj as AddImportChunkGenerator; + return other != null && + string.Equals(Namespace, other.Namespace, StringComparison.Ordinal); + } + + public override int GetHashCode() + { + // Hash code should include only immutable properties. + return Namespace == null ? 0 : StringComparer.Ordinal.GetHashCode(Namespace); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AddTagHelperChunkGenerator.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AddTagHelperChunkGenerator.cs new file mode 100644 index 0000000000..2df86b32de --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AddTagHelperChunkGenerator.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; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class AddTagHelperChunkGenerator : SpanChunkGenerator + { + public AddTagHelperChunkGenerator( + string lookupText, + string directiveText, + string typePattern, + string assemblyName, + List diagnostics) + { + LookupText = lookupText; + DirectiveText = directiveText; + AssemblyName = assemblyName; + TypePattern = typePattern; + Diagnostics = diagnostics; + } + + public string LookupText { get; } + + public string DirectiveText { get; set; } + + public string TypePattern { get; set; } + + public string AssemblyName { get; set; } + + public List Diagnostics { get; } + + /// + public override bool Equals(object obj) + { + var other = obj as AddTagHelperChunkGenerator; + return base.Equals(other) && + Enumerable.SequenceEqual(Diagnostics, other.Diagnostics) && + string.Equals(LookupText, other.LookupText, StringComparison.Ordinal) && + string.Equals(DirectiveText, other.DirectiveText, StringComparison.Ordinal) && + string.Equals(TypePattern, other.TypePattern, StringComparison.Ordinal) && + string.Equals(AssemblyName, other.AssemblyName, StringComparison.Ordinal); + } + + /// + public override int GetHashCode() + { + var combiner = HashCodeCombiner.Start(); + combiner.Add(base.GetHashCode()); + combiner.Add(LookupText, StringComparer.Ordinal); + combiner.Add(DirectiveText, StringComparer.Ordinal); + combiner.Add(TypePattern, StringComparer.Ordinal); + combiner.Add(AssemblyName, StringComparer.Ordinal); + + return combiner.CombinedHash; + } + + public override string ToString() + { + var builder = new StringBuilder("AddTagHelper:{"); + builder.Append(LookupText); + builder.Append(";"); + builder.Append(DirectiveText); + builder.Append(";"); + builder.Append(TypePattern); + builder.Append(";"); + builder.Append(AssemblyName); + builder.Append("}"); + + if (Diagnostics.Count > 0) + { + builder.Append(" ["); + var ids = string.Join(", ", Diagnostics.Select(diagnostic => $"{diagnostic.Id}{diagnostic.Span}")); + builder.Append(ids); + builder.Append("]"); + } + + return builder.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AutoCompleteEditHandler.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AutoCompleteEditHandler.cs new file mode 100644 index 0000000000..2514377780 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/AutoCompleteEditHandler.cs @@ -0,0 +1,70 @@ +// 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.Syntax; +using Microsoft.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class AutoCompleteEditHandler : SpanEditHandler + { + private static readonly int TypeHashCode = typeof(AutoCompleteEditHandler).GetHashCode(); + + public AutoCompleteEditHandler(Func> tokenizer) + : base(tokenizer) + { + } + + public AutoCompleteEditHandler(Func> tokenizer, bool autoCompleteAtEndOfSpan) + : this(tokenizer) + { + AutoCompleteAtEndOfSpan = autoCompleteAtEndOfSpan; + } + + public AutoCompleteEditHandler(Func> tokenizer, AcceptedCharactersInternal accepted) + : base(tokenizer, accepted) + { + } + + public bool AutoCompleteAtEndOfSpan { get; } + + public string AutoCompleteString { get; set; } + + protected override PartialParseResultInternal CanAcceptChange(SyntaxNode target, SourceChange change) + { + if (((AutoCompleteAtEndOfSpan && IsAtEndOfSpan(target, change)) || IsAtEndOfFirstLine(target, change)) && + change.IsInsert && + ParserHelpers.IsNewLine(change.NewText) && + AutoCompleteString != null) + { + return PartialParseResultInternal.Rejected | PartialParseResultInternal.AutoCompleteBlock; + } + return PartialParseResultInternal.Rejected; + } + + public override string ToString() + { + return base.ToString() + ",AutoComplete:[" + (AutoCompleteString ?? "") + "]" + (AutoCompleteAtEndOfSpan ? ";AtEnd" : ";AtEOL"); + } + + public override bool Equals(object obj) + { + var other = obj as AutoCompleteEditHandler; + return base.Equals(other) && + string.Equals(other.AutoCompleteString, AutoCompleteString, StringComparison.Ordinal) && + AutoCompleteAtEndOfSpan == other.AutoCompleteAtEndOfSpan; + } + + public override int GetHashCode() + { + // Hash code should include only immutable properties but Equals also checks the type. + var hashCodeCombiner = HashCodeCombiner.Start(); + hashCodeCombiner.Add(TypeHashCode); + hashCodeCombiner.Add(AutoCompleteAtEndOfSpan); + + return hashCodeCombiner.CombinedHash; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/BalancingModes.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/BalancingModes.cs new file mode 100644 index 0000000000..a5adf88a2a --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/BalancingModes.cs @@ -0,0 +1,17 @@ +// 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 +{ + [Flags] + internal enum BalancingModes + { + None = 0, + BacktrackOnFailure = 1, + NoErrorOnFailure = 2, + AllowCommentsAndTemplates = 4, + AllowEmbeddedTransitions = 8 + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/BlockKindInternal.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/BlockKindInternal.cs new file mode 100644 index 0000000000..6c37427ca7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/BlockKindInternal.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. + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal enum BlockKindInternal + { + // We want this to match the values in BlockKind so that the values are maintained when casting. + + // Code + Statement = 0, + Directive = 1, + Expression = 3, + + // Markup + Markup = 5, + Template = 7, + + // Special + Comment = 8, + Tag = 9, + HtmlComment = 10 + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpCodeParser.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpCodeParser.cs new file mode 100644 index 0000000000..44612ee18c --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpCodeParser.cs @@ -0,0 +1,2471 @@ +// 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.Diagnostics; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class CSharpCodeParser : TokenizerBackedParser + { + private static HashSet InvalidNonWhitespaceNameCharacters = new HashSet(new[] + { + '@', '!', '<', '/', '?', '[', '>', ']', '=', '"', '\'', '*' + }); + + private static readonly Func IsValidStatementSpacingToken = + IsSpacingToken(includeNewLines: true, includeComments: true); + + internal static readonly DirectiveDescriptor AddTagHelperDirectiveDescriptor = DirectiveDescriptor.CreateDirective( + SyntaxConstants.CSharp.AddTagHelperKeyword, + DirectiveKind.SingleLine, + builder => + { + builder.AddStringToken(Resources.AddTagHelperDirective_StringToken_Name, Resources.AddTagHelperDirective_StringToken_Description); + builder.Description = Resources.AddTagHelperDirective_Description; + }); + + internal static readonly DirectiveDescriptor RemoveTagHelperDirectiveDescriptor = DirectiveDescriptor.CreateDirective( + SyntaxConstants.CSharp.RemoveTagHelperKeyword, + DirectiveKind.SingleLine, + builder => + { + builder.AddStringToken(Resources.RemoveTagHelperDirective_StringToken_Name, Resources.RemoveTagHelperDirective_StringToken_Description); + builder.Description = Resources.RemoveTagHelperDirective_Description; + }); + + internal static readonly DirectiveDescriptor TagHelperPrefixDirectiveDescriptor = DirectiveDescriptor.CreateDirective( + SyntaxConstants.CSharp.TagHelperPrefixKeyword, + DirectiveKind.SingleLine, + builder => + { + builder.AddStringToken(Resources.TagHelperPrefixDirective_PrefixToken_Name, Resources.TagHelperPrefixDirective_PrefixToken_Description); + builder.Description = Resources.TagHelperPrefixDirective_Description; + }); + + internal static readonly IEnumerable DefaultDirectiveDescriptors = new DirectiveDescriptor[] + { + }; + + internal static ISet DefaultKeywords = new HashSet() + { + SyntaxConstants.CSharp.TagHelperPrefixKeyword, + SyntaxConstants.CSharp.AddTagHelperKeyword, + SyntaxConstants.CSharp.RemoveTagHelperKeyword, + "if", + "do", + "try", + "for", + "foreach", + "while", + "switch", + "lock", + "using", + "namespace", + "class", + }; + + private readonly ISet CurrentKeywords = new HashSet(DefaultKeywords); + + private Dictionary, CSharpTransitionSyntax>> _keywordParserMap = new Dictionary, CSharpTransitionSyntax>>(); + private Dictionary, CSharpTransitionSyntax>> _directiveParserMap = new Dictionary, CSharpTransitionSyntax>>(StringComparer.Ordinal); + + public CSharpCodeParser(ParserContext context) + : this(directives: Enumerable.Empty(), context: context) + { + } + + public CSharpCodeParser(IEnumerable directives, ParserContext context) + : base(context.ParseLeadingDirectives ? FirstDirectiveCSharpLanguageCharacteristics.Instance : CSharpLanguageCharacteristics.Instance, context) + { + if (directives == null) + { + throw new ArgumentNullException(nameof(directives)); + } + + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + Keywords = new HashSet(); + SetupKeywordParsers(); + SetupExpressionParsers(); + SetupDirectiveParsers(directives); + } + + public HtmlMarkupParser HtmlParser { get; set; } + + protected internal ISet Keywords { get; private set; } + + public bool IsNested { get; set; } + + public CSharpCodeBlockSyntax ParseBlock() + { + if (Context == null) + { + throw new InvalidOperationException(Resources.Parser_Context_Not_Set); + } + + if (EndOfFile) + { + // Nothing to parse. + return null; + } + + using (var pooledResult = Pool.Allocate()) + using (PushSpanContextConfig(DefaultSpanContextConfig)) + { + var builder = pooledResult.Builder; + try + { + NextToken(); + + // Unless changed, the block is a statement block + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + builder.Add(OutputTokensAsStatementLiteral()); + + // We are usually called when the other parser sees a transition '@'. Look for it. + SyntaxToken transitionToken = null; + if (At(SyntaxKind.StringLiteral) && + CurrentToken.Content.Length > 0 && + CurrentToken.Content[0] == SyntaxConstants.TransitionCharacter) + { + var split = Language.SplitToken(CurrentToken, 1, SyntaxKind.Transition); + transitionToken = split.Item1; + + // Back up to the end of the transition + Context.Source.Position -= split.Item2.Content.Length; + NextToken(); + } + else if (At(SyntaxKind.Transition)) + { + transitionToken = EatCurrentToken(); + } + + if (transitionToken == null) + { + transitionToken = SyntaxFactory.MissingToken(SyntaxKind.Transition); + } + + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None; + var transition = GetNodeWithSpanContext(SyntaxFactory.CSharpTransition(transitionToken)); + + if (At(SyntaxKind.LeftBrace)) + { + var statementBody = ParseStatementBody(); + var statement = SyntaxFactory.CSharpStatement(transition, statementBody); + builder.Add(statement); + } + else if (At(SyntaxKind.LeftParenthesis)) + { + var expressionBody = ParseExplicitExpressionBody(); + var expression = SyntaxFactory.CSharpExplicitExpression(transition, expressionBody); + builder.Add(expression); + } + else if (At(SyntaxKind.Identifier)) + { + if (!TryParseDirective(builder, transition, CurrentToken.Content)) + { + if (string.Equals( + CurrentToken.Content, + SyntaxConstants.CSharp.HelperKeyword, + StringComparison.Ordinal)) + { + var diagnostic = RazorDiagnosticFactory.CreateParsing_HelperDirectiveNotAvailable( + new SourceSpan(CurrentStart, CurrentToken.Content.Length)); + CurrentToken.SetDiagnostics(new[] { diagnostic }); + Context.ErrorSink.OnError(diagnostic); + } + + var implicitExpressionBody = ParseImplicitExpressionBody(); + var implicitExpression = SyntaxFactory.CSharpImplicitExpression(transition, implicitExpressionBody); + builder.Add(implicitExpression); + } + } + else if (At(SyntaxKind.Keyword)) + { + if (!TryParseDirective(builder, transition, CurrentToken.Content) && + !TryParseKeyword(builder, transition)) + { + // Not a directive or a special keyword. Just parse as an implicit expression. + var implicitExpressionBody = ParseImplicitExpressionBody(); + var implicitExpression = SyntaxFactory.CSharpImplicitExpression(transition, implicitExpressionBody); + builder.Add(implicitExpression); + } + + builder.Add(OutputTokensAsStatementLiteral()); + } + else + { + // Invalid character + SpanContext.ChunkGenerator = new ExpressionChunkGenerator(); + SpanContext.EditHandler = new ImplicitExpressionEditHandler( + Language.TokenizeString, + CurrentKeywords, + acceptTrailingDot: IsNested) + { + AcceptedCharacters = AcceptedCharactersInternal.NonWhitespace + }; + + AcceptMarkerTokenIfNecessary(); + var expressionLiteral = SyntaxFactory.CSharpCodeBlock(OutputTokensAsExpressionLiteral()); + var expressionBody = SyntaxFactory.CSharpImplicitExpressionBody(expressionLiteral); + var expressionBlock = SyntaxFactory.CSharpImplicitExpression(transition, expressionBody); + builder.Add(expressionBlock); + + if (At(SyntaxKind.Whitespace) || At(SyntaxKind.NewLine)) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_UnexpectedWhiteSpaceAtStartOfCodeBlock( + new SourceSpan(CurrentStart, CurrentToken.Content.Length))); + } + else if (EndOfFile) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_UnexpectedEndOfFileAtStartOfCodeBlock( + new SourceSpan(CurrentStart, contentLength: 1 /* end of file */))); + } + else + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock( + new SourceSpan(CurrentStart, CurrentToken.Content.Length), + CurrentToken.Content)); + } + } + + Debug.Assert(TokenBuilder.Count == 0, "We should not have any tokens left."); + + var codeBlock = SyntaxFactory.CSharpCodeBlock(builder.ToList()); + return codeBlock; + } + finally + { + // Always put current character back in the buffer for the next parser. + PutCurrentBack(); + } + } + } + + private CSharpExplicitExpressionBodySyntax ParseExplicitExpressionBody() + { + var block = new Block(Resources.BlockName_ExplicitExpression, CurrentStart); + Assert(SyntaxKind.LeftParenthesis); + var leftParenToken = EatCurrentToken(); + var leftParen = OutputAsMetaCode(leftParenToken); + + using (var pooledResult = Pool.Allocate()) + { + var expressionBuilder = pooledResult.Builder; + using (PushSpanContextConfig(ExplicitExpressionSpanContextConfig)) + { + var success = Balance( + expressionBuilder, + BalancingModes.BacktrackOnFailure | + BalancingModes.NoErrorOnFailure | + BalancingModes.AllowCommentsAndTemplates, + SyntaxKind.LeftParenthesis, + SyntaxKind.RightParenthesis, + block.Start); + + if (!success) + { + AcceptUntil(SyntaxKind.LessThan); + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF( + new SourceSpan(block.Start, contentLength: 1 /* ( */), block.Name, ")", "(")); + } + + // If necessary, put an empty-content marker token here + AcceptMarkerTokenIfNecessary(); + expressionBuilder.Add(OutputTokensAsExpressionLiteral()); + } + + var expressionBlock = SyntaxFactory.CSharpCodeBlock(expressionBuilder.ToList()); + + RazorMetaCodeSyntax rightParen = null; + if (At(SyntaxKind.RightParenthesis)) + { + rightParen = OutputAsMetaCode(EatCurrentToken()); + } + else + { + var missingToken = SyntaxFactory.MissingToken(SyntaxKind.RightParenthesis); + rightParen = OutputAsMetaCode(missingToken, SpanContext.EditHandler.AcceptedCharacters); + } + if (!EndOfFile) + { + PutCurrentBack(); + } + + return SyntaxFactory.CSharpExplicitExpressionBody(leftParen, expressionBlock, rightParen); + } + } + + private CSharpImplicitExpressionBodySyntax ParseImplicitExpressionBody(bool async = false) + { + var accepted = AcceptedCharactersInternal.NonWhitespace; + if (async) + { + // Async implicit expressions include the "await" keyword and therefore need to allow spaces to + // separate the "await" and the following code. + accepted = AcceptedCharactersInternal.AnyExceptNewline; + } + + using (var pooledResult = Pool.Allocate()) + { + var expressionBuilder = pooledResult.Builder; + ParseImplicitExpression(expressionBuilder, accepted); + var codeBlock = SyntaxFactory.CSharpCodeBlock(expressionBuilder.ToList()); + return SyntaxFactory.CSharpImplicitExpressionBody(codeBlock); + } + } + + private void ParseImplicitExpression(in SyntaxListBuilder builder, AcceptedCharactersInternal acceptedCharacters) + { + using (PushSpanContextConfig(spanContext => + { + spanContext.EditHandler = new ImplicitExpressionEditHandler( + Language.TokenizeString, + Keywords, + acceptTrailingDot: IsNested); + spanContext.EditHandler.AcceptedCharacters = acceptedCharacters; + spanContext.ChunkGenerator = new ExpressionChunkGenerator(); + })) + { + do + { + if (AtIdentifier(allowKeywords: true)) + { + AcceptAndMoveNext(); + } + } + while (ParseMethodCallOrArrayIndex(builder, acceptedCharacters)); + + PutCurrentBack(); + builder.Add(OutputTokensAsExpressionLiteral()); + } + } + + private bool ParseMethodCallOrArrayIndex(in SyntaxListBuilder builder, AcceptedCharactersInternal acceptedCharacters) + { + if (!EndOfFile) + { + if (CurrentToken.Kind == SyntaxKind.LeftParenthesis || + CurrentToken.Kind == SyntaxKind.LeftBracket) + { + // If we end within "(", whitespace is fine + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; + + SyntaxKind right; + bool success; + + using (PushSpanContextConfig((spanContext, prev) => + { + prev(spanContext); + spanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; + })) + { + right = Language.FlipBracket(CurrentToken.Kind); + success = Balance(builder, BalancingModes.BacktrackOnFailure | BalancingModes.AllowCommentsAndTemplates); + } + + if (!success) + { + AcceptUntil(SyntaxKind.LessThan); + } + if (At(right)) + { + AcceptAndMoveNext(); + + // At the ending brace, restore the initial accepted characters. + SpanContext.EditHandler.AcceptedCharacters = acceptedCharacters; + } + return ParseMethodCallOrArrayIndex(builder, acceptedCharacters); + } + if (At(SyntaxKind.QuestionMark)) + { + var next = Lookahead(count: 1); + + if (next != null) + { + if (next.Kind == SyntaxKind.Dot) + { + // Accept null conditional dot operator (?.). + AcceptAndMoveNext(); + AcceptAndMoveNext(); + + // If the next piece after the ?. is a keyword or identifier then we want to continue. + return At(SyntaxKind.Identifier) || At(SyntaxKind.Keyword); + } + else if (next.Kind == SyntaxKind.LeftBracket) + { + // We're at the ? for a null conditional bracket operator (?[). + AcceptAndMoveNext(); + + // Accept the [ and any content inside (it will attempt to balance). + return ParseMethodCallOrArrayIndex(builder, acceptedCharacters); + } + } + } + else if (At(SyntaxKind.Dot)) + { + var dot = CurrentToken; + if (NextToken()) + { + if (At(SyntaxKind.Identifier) || At(SyntaxKind.Keyword)) + { + // Accept the dot and return to the start + Accept(dot); + return true; // continue + } + else + { + // Put the token back + PutCurrentBack(); + } + } + if (!IsNested) + { + // Put the "." back + PutBack(dot); + } + else + { + Accept(dot); + } + } + else if (!At(SyntaxKind.Whitespace) && !At(SyntaxKind.NewLine)) + { + PutCurrentBack(); + } + } + + // Implicit Expression is complete + return false; + } + + private CSharpStatementBodySyntax ParseStatementBody(Block block = null) + { + Assert(SyntaxKind.LeftBrace); + block = block ?? new Block(Resources.BlockName_Code, CurrentStart); + var leftBrace = OutputAsMetaCode(EatExpectedToken(SyntaxKind.LeftBrace)); + CSharpCodeBlockSyntax codeBlock = null; + using (var pooledResult = Pool.Allocate()) + { + var builder = pooledResult.Builder; + // Set up auto-complete and parse the code block + var editHandler = new AutoCompleteEditHandler(Language.TokenizeString); + SpanContext.EditHandler = editHandler; + ParseCodeBlock(builder, block, acceptTerminatingBrace: false); + + EnsureCurrent(); + SpanContext.ChunkGenerator = new StatementChunkGenerator(); + AcceptMarkerTokenIfNecessary(); + if (!At(SyntaxKind.RightBrace)) + { + editHandler.AutoCompleteString = "}"; + } + builder.Add(OutputTokensAsStatementLiteral()); + + codeBlock = SyntaxFactory.CSharpCodeBlock(builder.ToList()); + } + + RazorMetaCodeSyntax rightBrace = null; + if (At(SyntaxKind.RightBrace)) + { + rightBrace = OutputAsMetaCode(EatCurrentToken()); + } + else + { + rightBrace = OutputAsMetaCode( + SyntaxFactory.MissingToken(SyntaxKind.RightBrace), + SpanContext.EditHandler.AcceptedCharacters); + } + + if (!IsNested) + { + EnsureCurrent(); + if (At(SyntaxKind.NewLine) || + (At(SyntaxKind.Whitespace) && NextIs(SyntaxKind.NewLine))) + { + Context.NullGenerateWhitespaceAndNewLine = true; + } + } + + return SyntaxFactory.CSharpStatementBody(leftBrace, codeBlock, rightBrace); + } + + private void ParseCodeBlock(in SyntaxListBuilder builder, Block block, bool acceptTerminatingBrace = true) + { + EnsureCurrent(); + while (!EndOfFile && !At(SyntaxKind.RightBrace)) + { + // Parse a statement, then return here + ParseStatement(builder, block: block); + EnsureCurrent(); + } + + if (EndOfFile) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF( + new SourceSpan(block.Start, contentLength: 1 /* { OR } */), block.Name, "}", "{")); + } + else if (acceptTerminatingBrace) + { + Assert(SyntaxKind.RightBrace); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None; + AcceptAndMoveNext(); + } + } + + private void ParseStatement(in SyntaxListBuilder builder, Block block) + { + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; + // Accept whitespace but always keep the last whitespace node so we can put it back if necessary + var lastWhitespace = AcceptWhitespaceInLines(); + if (EndOfFile) + { + if (lastWhitespace != null) + { + Accept(lastWhitespace); + } + + builder.Add(OutputTokensAsStatementLiteral()); + return; + } + + var kind = CurrentToken.Kind; + var location = CurrentStart; + + // Both cases @: and @:: are triggered as markup, second colon in second case will be triggered as a plain text + var isSingleLineMarkup = kind == SyntaxKind.Transition && + (NextIs(SyntaxKind.Colon, SyntaxKind.DoubleColon)); + + var isMarkup = isSingleLineMarkup || + kind == SyntaxKind.LessThan || + (kind == SyntaxKind.Transition && NextIs(SyntaxKind.LessThan)); + + if (Context.DesignTimeMode || !isMarkup) + { + // CODE owns whitespace, MARKUP owns it ONLY in DesignTimeMode. + if (lastWhitespace != null) + { + Accept(lastWhitespace); + } + } + else + { + var nextToken = Lookahead(1); + + // MARKUP owns whitespace EXCEPT in DesignTimeMode. + PutCurrentBack(); + + // Put back the whitespace unless it precedes a '' tag. + if (nextToken != null && + !string.Equals(nextToken.Content, SyntaxConstants.TextTagName, StringComparison.Ordinal)) + { + PutBack(lastWhitespace); + } + else + { + // If it precedes a '' tag, it should be accepted as code. + Accept(lastWhitespace); + } + } + + if (isMarkup) + { + if (kind == SyntaxKind.Transition && !isSingleLineMarkup) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_AtInCodeMustBeFollowedByColonParenOrIdentifierStart( + new SourceSpan(location, contentLength: 1 /* @ */))); + } + + // Markup block + builder.Add(OutputTokensAsStatementLiteral()); + if (Context.DesignTimeMode && CurrentToken != null && + (CurrentToken.Kind == SyntaxKind.LessThan || CurrentToken.Kind == SyntaxKind.Transition)) + { + PutCurrentBack(); + } + OtherParserBlock(builder); + } + else + { + // What kind of statement is this? + switch (kind) + { + case SyntaxKind.RazorCommentTransition: + AcceptMarkerTokenIfNecessary(); + builder.Add(OutputTokensAsStatementLiteral()); + var comment = ParseRazorComment(); + builder.Add(comment); + ParseStatement(builder, block); + break; + case SyntaxKind.LeftBrace: + // Verbatim Block + AcceptAndMoveNext(); + ParseCodeBlock(builder, block); + break; + case SyntaxKind.Keyword: + if (!TryParseKeyword(builder, transition: null)) + { + ParseStandardStatement(builder); + } + break; + case SyntaxKind.Transition: + // Embedded Expression block + ParseEmbeddedExpression(builder); + break; + case SyntaxKind.RightBrace: + // Possible end of Code Block, just run the continuation + break; + case SyntaxKind.CSharpComment: + Accept(CurrentToken); + NextToken(); + break; + default: + // Other statement + ParseStandardStatement(builder); + break; + } + } + } + + private void ParseEmbeddedExpression(in SyntaxListBuilder builder) + { + // First, verify the type of the block + Assert(SyntaxKind.Transition); + var transition = CurrentToken; + NextToken(); + + if (At(SyntaxKind.Transition)) + { + // Escaped "@" + builder.Add(OutputTokensAsStatementLiteral()); + + // Output "@" as hidden span + Accept(transition); + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + builder.Add(OutputTokensAsEphemeralLiteral()); + + Assert(SyntaxKind.Transition); + AcceptAndMoveNext(); + ParseStandardStatement(builder); + } + else + { + // Throw errors as necessary, but continue parsing + if (At(SyntaxKind.LeftBrace)) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_UnexpectedNestedCodeBlock( + new SourceSpan(CurrentStart, contentLength: 1 /* { */))); + } + + // @( or @foo - Nested expression, parse a child block + PutCurrentBack(); + PutBack(transition); + + // Before exiting, add a marker span if necessary + AcceptMarkerTokenIfNecessary(); + builder.Add(OutputTokensAsStatementLiteral()); + + var nestedBlock = ParseNestedBlock(); + builder.Add(nestedBlock); + } + } + + private RazorSyntaxNode ParseNestedBlock() + { + var wasNested = IsNested; + IsNested = true; + + RazorSyntaxNode nestedBlock; + using (PushSpanContextConfig()) + { + nestedBlock = ParseBlock(); + } + + InitializeContext(SpanContext); + IsNested = wasNested; + NextToken(); + + return nestedBlock; + } + + private void ParseStandardStatement(in SyntaxListBuilder builder) + { + while (!EndOfFile) + { + var bookmark = CurrentStart.AbsoluteIndex; + var read = ReadWhile(token => + token.Kind != SyntaxKind.Semicolon && + token.Kind != SyntaxKind.RazorCommentTransition && + token.Kind != SyntaxKind.Transition && + token.Kind != SyntaxKind.LeftBrace && + token.Kind != SyntaxKind.LeftParenthesis && + token.Kind != SyntaxKind.LeftBracket && + token.Kind != SyntaxKind.RightBrace); + + if (At(SyntaxKind.LeftBrace) || + At(SyntaxKind.LeftParenthesis) || + At(SyntaxKind.LeftBracket)) + { + Accept(read); + if (Balance(builder, BalancingModes.AllowCommentsAndTemplates | BalancingModes.BacktrackOnFailure)) + { + TryAccept(SyntaxKind.RightBrace); + } + else + { + // Recovery + AcceptUntil(SyntaxKind.LessThan, SyntaxKind.RightBrace); + return; + } + } + else if (At(SyntaxKind.Transition) && (NextIs(SyntaxKind.LessThan, SyntaxKind.Colon))) + { + Accept(read); + builder.Add(OutputTokensAsStatementLiteral()); + ParseTemplate(builder); + } + else if (At(SyntaxKind.RazorCommentTransition)) + { + Accept(read); + AcceptMarkerTokenIfNecessary(); + builder.Add(OutputTokensAsStatementLiteral()); + builder.Add(ParseRazorComment()); + } + else if (At(SyntaxKind.Semicolon)) + { + Accept(read); + AcceptAndMoveNext(); + return; + } + else if (At(SyntaxKind.RightBrace)) + { + Accept(read); + return; + } + else + { + Context.Source.Position = bookmark; + NextToken(); + AcceptUntil(SyntaxKind.LessThan, SyntaxKind.LeftBrace, SyntaxKind.RightBrace); + return; + } + } + } + + private void ParseTemplate(in SyntaxListBuilder builder) + { + if (Context.InTemplateContext) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_InlineMarkupBlocksCannotBeNested( + new SourceSpan(CurrentStart, contentLength: 1 /* @ */))); + } + if (SpanContext.ChunkGenerator is ExpressionChunkGenerator) + { + builder.Add(OutputTokensAsExpressionLiteral()); + } + else + { + builder.Add(OutputTokensAsStatementLiteral()); + } + + using (var pooledResult = Pool.Allocate()) + { + var templateBuilder = pooledResult.Builder; + Context.InTemplateContext = true; + PutCurrentBack(); + OtherParserBlock(templateBuilder); + + var template = SyntaxFactory.CSharpTemplateBlock(templateBuilder.ToList()); + builder.Add(template); + + Context.InTemplateContext = false; + } + } + + protected bool TryParseDirective(in SyntaxListBuilder builder, CSharpTransitionSyntax transition, string directive) + { + if (_directiveParserMap.TryGetValue(directive, out var handler)) + { + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + handler(builder, transition); + return true; + } + + return false; + } + + private void SetupDirectiveParsers(IEnumerable directiveDescriptors) + { + var allDirectives = directiveDescriptors.Concat(DefaultDirectiveDescriptors).ToList(); + + for (var i = 0; i < allDirectives.Count; i++) + { + var directiveDescriptor = allDirectives[i]; + CurrentKeywords.Add(directiveDescriptor.Directive); + MapDirectives((builder, transition) => ParseExtensibleDirective(builder, transition, directiveDescriptor), directiveDescriptor.Directive); + } + + MapDirectives(ParseTagHelperPrefixDirective, SyntaxConstants.CSharp.TagHelperPrefixKeyword); + MapDirectives(ParseAddTagHelperDirective, SyntaxConstants.CSharp.AddTagHelperKeyword); + MapDirectives(ParseRemoveTagHelperDirective, SyntaxConstants.CSharp.RemoveTagHelperKeyword); + } + + private void EnsureDirectiveIsAtStartOfLine() + { + // 1 is the offset of the @ transition for the directive. + if (CurrentStart.CharacterIndex > 1) + { + var index = CurrentStart.AbsoluteIndex - 1; + var lineStart = CurrentStart.AbsoluteIndex - CurrentStart.CharacterIndex; + while (--index >= lineStart) + { + var @char = Context.SourceDocument[index]; + + if (!char.IsWhiteSpace(@char)) + { + var currentDirective = CurrentToken.Content; + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_DirectiveMustAppearAtStartOfLine( + new SourceSpan(CurrentStart, currentDirective.Length), currentDirective)); + break; + } + } + } + } + + protected void MapDirectives(Action, CSharpTransitionSyntax> handler, params string[] directives) + { + foreach (var directive in directives) + { + _directiveParserMap.Add(directive, (builder, transition) => + { + handler(builder, transition); + Context.SeenDirectives.Add(directive); + }); + + Keywords.Add(directive); + + // These C# keywords are reserved for use in directives. It's an error to use them outside of + // a directive. This code removes the error generation if the directive *is* registered. + if (string.Equals(directive, "class", StringComparison.OrdinalIgnoreCase)) + { + _keywordParserMap.Remove(CSharpKeyword.Class); + } + else if (string.Equals(directive, "namespace", StringComparison.OrdinalIgnoreCase)) + { + _keywordParserMap.Remove(CSharpKeyword.Namespace); + } + } + } + + private void ParseTagHelperPrefixDirective(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + RazorDiagnostic duplicateDiagnostic = null; + if (Context.SeenDirectives.Contains(SyntaxConstants.CSharp.TagHelperPrefixKeyword)) + { + var directiveStart = CurrentStart; + if (transition != null) + { + // Start the error from the Transition '@'. + directiveStart = new SourceLocation( + directiveStart.FilePath, + directiveStart.AbsoluteIndex - 1, + directiveStart.LineIndex, + directiveStart.CharacterIndex - 1); + } + var errorLength = /* @ */ 1 + SyntaxConstants.CSharp.TagHelperPrefixKeyword.Length; + duplicateDiagnostic = RazorDiagnosticFactory.CreateParsing_DuplicateDirective( + new SourceSpan(directiveStart, errorLength), + SyntaxConstants.CSharp.TagHelperPrefixKeyword); + } + + var directiveBody = ParseTagHelperDirective( + SyntaxConstants.CSharp.TagHelperPrefixKeyword, + (prefix, errors, startLocation) => + { + if (duplicateDiagnostic != null) + { + errors.Add(duplicateDiagnostic); + } + + var parsedDirective = ParseDirective(prefix, startLocation, TagHelperDirectiveType.TagHelperPrefix, errors); + + return new TagHelperPrefixDirectiveChunkGenerator( + prefix, + parsedDirective.DirectiveText, + errors); + }); + + var directive = SyntaxFactory.RazorDirective(transition, directiveBody); + builder.Add(directive); + } + + private void ParseAddTagHelperDirective(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + var directiveBody = ParseTagHelperDirective( + SyntaxConstants.CSharp.AddTagHelperKeyword, + (lookupText, errors, startLocation) => + { + var parsedDirective = ParseDirective(lookupText, startLocation, TagHelperDirectiveType.AddTagHelper, errors); + + return new AddTagHelperChunkGenerator( + lookupText, + parsedDirective.DirectiveText, + parsedDirective.TypePattern, + parsedDirective.AssemblyName, + errors); + }); + + var directive = SyntaxFactory.RazorDirective(transition, directiveBody); + builder.Add(directive); + } + + private void ParseRemoveTagHelperDirective(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + var directiveBody = ParseTagHelperDirective( + SyntaxConstants.CSharp.RemoveTagHelperKeyword, + (lookupText, errors, startLocation) => + { + var parsedDirective = ParseDirective(lookupText, startLocation, TagHelperDirectiveType.RemoveTagHelper, errors); + + return new RemoveTagHelperChunkGenerator( + lookupText, + parsedDirective.DirectiveText, + parsedDirective.TypePattern, + parsedDirective.AssemblyName, + errors); + }); + + var directive = SyntaxFactory.RazorDirective(transition, directiveBody); + builder.Add(directive); + } + + [Conditional("DEBUG")] + protected void AssertDirective(string directive) + { + Debug.Assert(CurrentToken.Kind == SyntaxKind.Identifier || CurrentToken.Kind == SyntaxKind.Keyword); + Debug.Assert(string.Equals(CurrentToken.Content, directive, StringComparison.Ordinal)); + } + + private RazorDirectiveBodySyntax ParseTagHelperDirective( + string keyword, + Func, SourceLocation, ISpanChunkGenerator> chunkGeneratorFactory) + { + AssertDirective(keyword); + + var savedErrorSink = Context.ErrorSink; + var directiveErrorSink = new ErrorSink(); + RazorMetaCodeSyntax keywordBlock = null; + using (var pooledResult = Pool.Allocate()) + { + var directiveBuilder = pooledResult.Builder; + Context.ErrorSink = directiveErrorSink; + + string directiveValue = null; + SourceLocation? valueStartLocation = null; + try + { + EnsureDirectiveIsAtStartOfLine(); + + var keywordStartLocation = CurrentStart; + + // Accept the directive name + var keywordToken = EatCurrentToken(); + var keywordLength = keywordToken.FullWidth + 1 /* @ */; + + var foundWhitespace = At(SyntaxKind.Whitespace); + + // If we found whitespace then any content placed within the whitespace MAY cause a destructive change + // to the document. We can't accept it. + var acceptedCharacters = foundWhitespace ? AcceptedCharactersInternal.None : AcceptedCharactersInternal.AnyExceptNewline; + Accept(keywordToken); + keywordBlock = OutputAsMetaCode(Output(), acceptedCharacters); + + AcceptWhile(SyntaxKind.Whitespace); + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + SpanContext.EditHandler.AcceptedCharacters = acceptedCharacters; + directiveBuilder.Add(OutputAsMarkupLiteral()); + + if (EndOfFile || At(SyntaxKind.NewLine)) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_DirectiveMustHaveValue( + new SourceSpan(keywordStartLocation, keywordLength), keyword)); + + directiveValue = string.Empty; + } + else + { + // Need to grab the current location before we accept until the end of the line. + valueStartLocation = CurrentStart; + + // Parse to the end of the line. Essentially accepts anything until end of line, comments, invalid code + // etc. + AcceptUntil(SyntaxKind.NewLine); + + // Pull out the value and remove whitespaces and optional quotes + var rawValue = string.Concat(TokenBuilder.ToList().Nodes.Select(s => s.Content)).Trim(); + + var startsWithQuote = rawValue.StartsWith("\"", StringComparison.Ordinal); + var endsWithQuote = rawValue.EndsWith("\"", StringComparison.Ordinal); + if (startsWithQuote != endsWithQuote) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_IncompleteQuotesAroundDirective( + new SourceSpan(valueStartLocation.Value, rawValue.Length), keyword)); + } + + directiveValue = rawValue; + } + } + finally + { + SpanContext.ChunkGenerator = chunkGeneratorFactory( + directiveValue, + directiveErrorSink.Errors.ToList(), + valueStartLocation ?? CurrentStart); + Context.ErrorSink = savedErrorSink; + } + + // Finish the block and output the tokens + CompleteBlock(); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.AnyExceptNewline; + + directiveBuilder.Add(OutputTokensAsStatementLiteral()); + var directiveCodeBlock = SyntaxFactory.CSharpCodeBlock(directiveBuilder.ToList()); + + return SyntaxFactory.RazorDirectiveBody(keywordBlock, directiveCodeBlock); + } + } + + private ParsedDirective ParseDirective( + string directiveText, + SourceLocation directiveLocation, + TagHelperDirectiveType directiveType, + List errors) + { + var offset = 0; + directiveText = directiveText.Trim(); + if (directiveText.Length >= 2 && + directiveText.StartsWith("\"", StringComparison.Ordinal) && + directiveText.EndsWith("\"", StringComparison.Ordinal)) + { + directiveText = directiveText.Substring(1, directiveText.Length - 2); + if (string.IsNullOrEmpty(directiveText)) + { + offset = 1; + } + } + + // If this is the "string literal" form of a directive, we'll need to postprocess the location + // and content. + // + // Ex: @addTagHelper "*, Microsoft.AspNetCore.CoolLibrary" + // ^ ^ + // Start End + if (TokenBuilder.Count == 1 && + TokenBuilder[0] is SyntaxToken token && + token.Kind == SyntaxKind.StringLiteral) + { + offset += token.Content.IndexOf(directiveText, StringComparison.Ordinal); + + // This is safe because inside one of these directives all of the text needs to be on the + // same line. + var original = directiveLocation; + directiveLocation = new SourceLocation( + original.FilePath, + original.AbsoluteIndex + offset, + original.LineIndex, + original.CharacterIndex + offset); + } + + var parsedDirective = new ParsedDirective() + { + DirectiveText = directiveText + }; + + if (directiveType == TagHelperDirectiveType.TagHelperPrefix) + { + ValidateTagHelperPrefix(parsedDirective.DirectiveText, directiveLocation, errors); + + return parsedDirective; + } + + return ParseAddOrRemoveDirective(parsedDirective, directiveLocation, errors); + } + + // Internal for testing. + internal ParsedDirective ParseAddOrRemoveDirective(ParsedDirective directive, SourceLocation directiveLocation, List errors) + { + var text = directive.DirectiveText; + var lookupStrings = text?.Split(new[] { ',' }); + + // Ensure that we have valid lookupStrings to work with. The valid format is "typeName, assemblyName" + if (lookupStrings == null || + lookupStrings.Any(string.IsNullOrWhiteSpace) || + lookupStrings.Length != 2 || + text.StartsWith("'") || + text.EndsWith("'")) + { + errors.Add( + RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText( + new SourceSpan(directiveLocation, Math.Max(text.Length, 1)), text)); + + return directive; + } + + var trimmedAssemblyName = lookupStrings[1].Trim(); + + // + 1 is for the comma separator in the lookup text. + var assemblyNameIndex = + lookupStrings[0].Length + 1 + lookupStrings[1].IndexOf(trimmedAssemblyName, StringComparison.Ordinal); + var assemblyNamePrefix = directive.DirectiveText.Substring(0, assemblyNameIndex); + + directive.TypePattern = lookupStrings[0].Trim(); + directive.AssemblyName = trimmedAssemblyName; + + return directive; + } + + // Internal for testing. + internal void ValidateTagHelperPrefix( + string prefix, + SourceLocation directiveLocation, + List diagnostics) + { + foreach (var character in prefix) + { + // Prefixes are correlated with tag names, tag names cannot have whitespace. + if (char.IsWhiteSpace(character) || InvalidNonWhitespaceNameCharacters.Contains(character)) + { + diagnostics.Add( + RazorDiagnosticFactory.CreateParsing_InvalidTagHelperPrefixValue( + new SourceSpan(directiveLocation, prefix.Length), + SyntaxConstants.CSharp.TagHelperPrefixKeyword, + character, + prefix)); + + return; + } + } + } + + private void ParseExtensibleDirective(in SyntaxListBuilder builder, CSharpTransitionSyntax transition, DirectiveDescriptor descriptor) + { + AssertDirective(descriptor.Directive); + + var directiveErrorSink = new ErrorSink(); + var savedErrorSink = Context.ErrorSink; + Context.ErrorSink = directiveErrorSink; + + using (var pooledResult = Pool.Allocate()) + { + var directiveBuilder = pooledResult.Builder; + RazorMetaCodeSyntax keywordBlock = null; + + try + { + EnsureDirectiveIsAtStartOfLine(); + var directiveStart = CurrentStart; + if (transition != null) + { + // Start the error from the Transition '@'. + directiveStart = new SourceLocation( + directiveStart.FilePath, + directiveStart.AbsoluteIndex - 1, + directiveStart.LineIndex, + directiveStart.CharacterIndex - 1); + } + + AcceptAndMoveNext(); + keywordBlock = OutputAsMetaCode(Output()); + + // Even if an error was logged do not bail out early. If a directive was used incorrectly it doesn't mean it can't be parsed. + ValidateDirectiveUsage(descriptor, directiveStart); + + for (var i = 0; i < descriptor.Tokens.Count; i++) + { + if (!At(SyntaxKind.Whitespace) && + !At(SyntaxKind.NewLine) && + !EndOfFile) + { + // This case should never happen in a real scenario. We're just being defensive. + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_DirectiveTokensMustBeSeparatedByWhitespace( + new SourceSpan(CurrentStart, CurrentToken.Content.Length), descriptor.Directive)); + + builder.Add(BuildDirective()); + return; + } + + var tokenDescriptor = descriptor.Tokens[i]; + AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + + if (tokenDescriptor.Kind == DirectiveTokenKind.Member || + tokenDescriptor.Kind == DirectiveTokenKind.Namespace || + tokenDescriptor.Kind == DirectiveTokenKind.Type) + { + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Whitespace; + directiveBuilder.Add(OutputTokensAsStatementLiteral()); + + if (EndOfFile || At(SyntaxKind.NewLine)) + { + // Add a marker token to provide CSharp intellisense when we start typing the directive token. + AcceptMarkerTokenIfNecessary(); + SpanContext.ChunkGenerator = new DirectiveTokenChunkGenerator(tokenDescriptor); + SpanContext.EditHandler = new DirectiveTokenEditHandler(Language.TokenizeString); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.NonWhitespace; + directiveBuilder.Add(OutputTokensAsStatementLiteral()); + } + } + else + { + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Whitespace; + directiveBuilder.Add(OutputAsMarkupEphemeralLiteral()); + } + + if (tokenDescriptor.Optional && (EndOfFile || At(SyntaxKind.NewLine))) + { + break; + } + else if (EndOfFile) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_UnexpectedEOFAfterDirective( + new SourceSpan(CurrentStart, contentLength: 1), + descriptor.Directive, + tokenDescriptor.Kind.ToString().ToLowerInvariant())); + builder.Add(BuildDirective()); + return; + } + + switch (tokenDescriptor.Kind) + { + case DirectiveTokenKind.Type: + if (!TryParseNamespaceOrTypeName(directiveBuilder)) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_DirectiveExpectsTypeName( + new SourceSpan(CurrentStart, CurrentToken.Content.Length), descriptor.Directive)); + + builder.Add(BuildDirective()); + return; + } + break; + + case DirectiveTokenKind.Namespace: + if (!TryParseQualifiedIdentifier(out var identifierLength)) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_DirectiveExpectsNamespace( + new SourceSpan(CurrentStart, identifierLength), descriptor.Directive)); + + builder.Add(BuildDirective()); + return; + } + break; + + case DirectiveTokenKind.Member: + if (At(SyntaxKind.Identifier)) + { + AcceptAndMoveNext(); + } + else + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_DirectiveExpectsIdentifier( + new SourceSpan(CurrentStart, CurrentToken.Content.Length), descriptor.Directive)); + builder.Add(BuildDirective()); + return; + } + break; + + case DirectiveTokenKind.String: + if (At(SyntaxKind.StringLiteral) && !CurrentToken.ContainsDiagnostics) + { + AcceptAndMoveNext(); + } + else + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_DirectiveExpectsQuotedStringLiteral( + new SourceSpan(CurrentStart, CurrentToken.Content.Length), descriptor.Directive)); + builder.Add(BuildDirective()); + return; + } + break; + } + + SpanContext.ChunkGenerator = new DirectiveTokenChunkGenerator(tokenDescriptor); + SpanContext.EditHandler = new DirectiveTokenEditHandler(Language.TokenizeString); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.NonWhitespace; + directiveBuilder.Add(OutputTokensAsStatementLiteral()); + } + + AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + + switch (descriptor.Kind) + { + case DirectiveKind.SingleLine: + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Whitespace; + directiveBuilder.Add(OutputTokensAsUnclassifiedLiteral()); + + TryAccept(SyntaxKind.Semicolon); + directiveBuilder.Add(OutputAsMetaCode(Output(), AcceptedCharactersInternal.Whitespace)); + + AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + + if (At(SyntaxKind.NewLine)) + { + AcceptAndMoveNext(); + } + else if (!EndOfFile) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_UnexpectedDirectiveLiteral( + new SourceSpan(CurrentStart, CurrentToken.Content.Length), + descriptor.Directive, + Resources.ErrorComponent_Newline)); + } + + + // This should contain the optional whitespace after the optional semicolon and the new line. + // Output as Markup as we want intellisense here. + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Whitespace; + directiveBuilder.Add(OutputAsMarkupEphemeralLiteral()); + break; + case DirectiveKind.RazorBlock: + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.AllWhitespace; + directiveBuilder.Add(OutputAsMarkupLiteral()); + + ParseDirectiveBlock(directiveBuilder, descriptor, parseChildren: (childBuilder, startingBraceLocation) => + { + // When transitioning to the HTML parser we no longer want to act as if we're in a nested C# state. + // For instance, if
@hello.
is in a nested C# block we don't want the trailing '.' to be handled + // as C#; it should be handled as a period because it's wrapped in markup. + var wasNested = IsNested; + IsNested = false; + + using (PushSpanContextConfig()) + { + var razorBlock = HtmlParser.ParseRazorBlock(Tuple.Create("{", "}"), caseSensitive: true); + directiveBuilder.Add(razorBlock); + } + + InitializeContext(SpanContext); + IsNested = wasNested; + NextToken(); + }); + break; + case DirectiveKind.CodeBlock: + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.AllWhitespace; + directiveBuilder.Add(OutputAsMarkupLiteral()); + + ParseDirectiveBlock(directiveBuilder, descriptor, parseChildren: (childBuilder, startingBraceLocation) => + { + NextToken(); + Balance(childBuilder, BalancingModes.NoErrorOnFailure, SyntaxKind.LeftBrace, SyntaxKind.RightBrace, startingBraceLocation); + SpanContext.ChunkGenerator = new StatementChunkGenerator(); + var existingEditHandler = SpanContext.EditHandler; + SpanContext.EditHandler = new CodeBlockEditHandler(Language.TokenizeString); + + AcceptMarkerTokenIfNecessary(); + + childBuilder.Add(OutputTokensAsStatementLiteral()); + + SpanContext.EditHandler = existingEditHandler; + }); + break; + } + } + finally + { + Context.ErrorSink = savedErrorSink; + } + + builder.Add(BuildDirective()); + + RazorDirectiveSyntax BuildDirective() + { + directiveBuilder.Add(OutputTokensAsStatementLiteral()); + var directiveCodeBlock = SyntaxFactory.CSharpCodeBlock(directiveBuilder.ToList()); + + var directiveBody = SyntaxFactory.RazorDirectiveBody(keywordBlock, directiveCodeBlock); + var directive = SyntaxFactory.RazorDirective(transition, directiveBody); + directive = (RazorDirectiveSyntax)directive.SetDiagnostics(directiveErrorSink.Errors.ToArray()); + directive = directive.WithDirectiveDescriptor(descriptor); + return directive; + } + } + } + + private void ValidateDirectiveUsage(DirectiveDescriptor descriptor, SourceLocation directiveStart) + { + if (descriptor.Usage == DirectiveUsage.FileScopedSinglyOccurring) + { + if (Context.SeenDirectives.Contains(descriptor.Directive)) + { + // There will always be at least 1 child because of the `@` transition. + var errorLength = /* @ */ 1 + descriptor.Directive.Length; + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_DuplicateDirective( + new SourceSpan(directiveStart, errorLength), descriptor.Directive)); + + return; + } + } + } + + // Used for parsing a qualified name like that which follows the `namespace` keyword. + // + // qualified-identifier: + // identifier + // qualified-identifier . identifier + protected bool TryParseQualifiedIdentifier(out int identifierLength) + { + var currentIdentifierLength = 0; + var expectingDot = false; + var tokens = ReadWhile(token => + { + var type = token.Kind; + if ((expectingDot && type == SyntaxKind.Dot) || + (!expectingDot && type == SyntaxKind.Identifier)) + { + expectingDot = !expectingDot; + return true; + } + + if (type != SyntaxKind.Whitespace && + type != SyntaxKind.NewLine) + { + expectingDot = false; + currentIdentifierLength += token.Content.Length; + } + + return false; + }); + + identifierLength = currentIdentifierLength; + var validQualifiedIdentifier = expectingDot; + if (validQualifiedIdentifier) + { + foreach (var token in tokens) + { + identifierLength += token.Content.Length; + Accept(token); + } + + return true; + } + else + { + PutCurrentBack(); + + foreach (var token in tokens) + { + identifierLength += token.Content.Length; + PutBack(token); + } + + EnsureCurrent(); + return false; + } + } + + private void ParseDirectiveBlock(in SyntaxListBuilder builder, DirectiveDescriptor descriptor, Action, SourceLocation> parseChildren) + { + if (EndOfFile) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_UnexpectedEOFAfterDirective( + new SourceSpan(CurrentStart, contentLength: 1 /* { */), descriptor.Directive, "{")); + } + else if (!At(SyntaxKind.LeftBrace)) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_UnexpectedDirectiveLiteral( + new SourceSpan(CurrentStart, CurrentToken.Content.Length), descriptor.Directive, "{")); + } + else + { + var editHandler = new AutoCompleteEditHandler(Language.TokenizeString, autoCompleteAtEndOfSpan: true); + SpanContext.EditHandler = editHandler; + var startingBraceLocation = CurrentStart; + Accept(CurrentToken); + builder.Add(OutputAsMetaCode(Output())); + + using (var pooledResult = Pool.Allocate()) + { + var childBuilder = pooledResult.Builder; + parseChildren(childBuilder, startingBraceLocation); + if (childBuilder.Count > 0) + { + builder.Add(SyntaxFactory.CSharpCodeBlock(childBuilder.ToList())); + } + } + + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + if (!TryAccept(SyntaxKind.RightBrace)) + { + editHandler.AutoCompleteString = "}"; + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF( + new SourceSpan(startingBraceLocation, contentLength: 1 /* } */), descriptor.Directive, "}", "{")); + + Accept(SyntaxFactory.MissingToken(SyntaxKind.RightBrace)); + } + else + { + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None; + } + CompleteBlock(insertMarkerIfNecessary: false, captureWhitespaceToEndOfLine: true); + builder.Add(OutputAsMetaCode(Output(), SpanContext.EditHandler.AcceptedCharacters)); + } + } + + private bool TryParseKeyword(in SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + var result = CSharpTokenizer.GetTokenKeyword(CurrentToken); + Debug.Assert(CurrentToken.Kind == SyntaxKind.Keyword && result.HasValue); + if (_keywordParserMap.TryGetValue(result.Value, out var handler)) + { + handler(builder, transition); + return true; + } + + return false; + } + + private void SetupExpressionParsers() + { + MapExpressionKeyword(ParseAwaitExpression, CSharpKeyword.Await); + } + + private void SetupKeywordParsers() + { + MapKeywords( + ParseConditionalBlock, + CSharpKeyword.For, + CSharpKeyword.Foreach, + CSharpKeyword.While, + CSharpKeyword.Switch, + CSharpKeyword.Lock); + MapKeywords(ParseCaseStatement, false, CSharpKeyword.Case, CSharpKeyword.Default); + MapKeywords(ParseIfStatement, CSharpKeyword.If); + MapKeywords(ParseTryStatement, CSharpKeyword.Try); + MapKeywords(ParseDoStatement, CSharpKeyword.Do); + MapKeywords(ParseUsingKeyword, CSharpKeyword.Using); + MapKeywords(ParseReservedDirective, CSharpKeyword.Class, CSharpKeyword.Namespace); + } + + private void MapExpressionKeyword(Action, CSharpTransitionSyntax> handler, CSharpKeyword keyword) + { + _keywordParserMap.Add(keyword, handler); + + // Expression keywords don't belong in the regular keyword list + } + + private void MapKeywords(Action, CSharpTransitionSyntax> handler, params CSharpKeyword[] keywords) + { + MapKeywords(handler, topLevel: true, keywords: keywords); + } + + private void MapKeywords(Action, CSharpTransitionSyntax> handler, bool topLevel, params CSharpKeyword[] keywords) + { + foreach (var keyword in keywords) + { + _keywordParserMap.Add(keyword, handler); + if (topLevel) + { + Keywords.Add(CSharpLanguageCharacteristics.GetKeyword(keyword)); + } + } + } + + private void ParseAwaitExpression(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + // Ensure that we're on the await statement (only runs in debug) + Assert(CSharpKeyword.Await); + + // Accept the "await" and move on + AcceptAndMoveNext(); + + // Accept 1 or more spaces between the await and the following code. + AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + + // Top level basically indicates if we're within an expression or statement. + // Ex: topLevel true = @await Foo() | topLevel false = @{ await Foo(); } + // Note that in this case @{ @await Foo() } top level is true for await. + // Therefore, if we're top level then we want to act like an implicit expression, + // otherwise just act as whatever we're contained in. + var topLevel = transition != null; + if (topLevel) + { + // Setup the Span to be an async implicit expression (an implicit expresison that allows spaces). + // Spaces are allowed because of "@await Foo()". + var implicitExpressionBody = ParseImplicitExpressionBody(async: true); + builder.Add(SyntaxFactory.CSharpImplicitExpression(transition, implicitExpressionBody)); + } + } + + private void ParseConditionalBlock(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + var topLevel = transition != null; + ParseConditionalBlock(builder, transition, topLevel); + } + + private void ParseConditionalBlock(in SyntaxListBuilder builder, CSharpTransitionSyntax transition, bool topLevel) + { + Assert(SyntaxKind.Keyword); + if (transition != null) + { + builder.Add(transition); + } + + var block = new Block(CurrentToken, CurrentStart); + ParseConditionalBlock(builder, block); + if (topLevel) + { + CompleteBlock(); + } + } + + private void ParseConditionalBlock(in SyntaxListBuilder builder, Block block) + { + AcceptAndMoveNext(); + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + + // Parse the condition, if present (if not present, we'll let the C# compiler complain) + if (TryParseCondition(builder)) + { + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + + ParseExpectedCodeBlock(builder, block); + } + } + + private bool TryParseCondition(in SyntaxListBuilder builder) + { + if (At(SyntaxKind.LeftParenthesis)) + { + var complete = Balance(builder, BalancingModes.BacktrackOnFailure | BalancingModes.AllowCommentsAndTemplates); + if (!complete) + { + AcceptUntil(SyntaxKind.NewLine); + } + else + { + TryAccept(SyntaxKind.RightParenthesis); + } + return complete; + } + return true; + } + + private void ParseExpectedCodeBlock(in SyntaxListBuilder builder, Block block) + { + if (!EndOfFile) + { + // Check for "{" to make sure we're at a block + if (!At(SyntaxKind.LeftBrace)) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_SingleLineControlFlowStatementsNotAllowed( + new SourceSpan(CurrentStart, CurrentToken.Content.Length), + Language.GetSample(SyntaxKind.LeftBrace), + CurrentToken.Content)); + } + + // Parse the statement and then we're done + ParseStatement(builder, block); + } + } + + private void ParseUnconditionalBlock(in SyntaxListBuilder builder) + { + Assert(SyntaxKind.Keyword); + var block = new Block(CurrentToken, CurrentStart); + AcceptAndMoveNext(); + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + ParseExpectedCodeBlock(builder, block); + } + + private void ParseCaseStatement(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + Assert(SyntaxKind.Keyword); + if (transition != null) + { + // Normally, case statement won't start with a transition in a valid scenario. + // If it does, just accept it and let the compiler complain. + builder.Add(transition); + } + var result = CSharpTokenizer.GetTokenKeyword(CurrentToken); + Debug.Assert(result.HasValue && + (result.Value == CSharpKeyword.Case || + result.Value == CSharpKeyword.Default)); + AcceptUntil(SyntaxKind.Colon); + TryAccept(SyntaxKind.Colon); + } + + private void ParseIfStatement(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + Assert(CSharpKeyword.If); + ParseConditionalBlock(builder, transition, topLevel: false); + ParseAfterIfClause(builder); + var topLevel = transition != null; + if (topLevel) + { + CompleteBlock(); + } + } + + private void ParseAfterIfClause(SyntaxListBuilder builder) + { + // Grab whitespace and razor comments + var whitespace = SkipToNextImportantToken(builder); + + // Check for an else part + if (At(CSharpKeyword.Else)) + { + Accept(whitespace); + Assert(CSharpKeyword.Else); + ParseElseClause(builder); + } + else + { + // No else, return whitespace + PutCurrentBack(); + PutBack(whitespace); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; + } + } + + private void ParseElseClause(in SyntaxListBuilder builder) + { + if (!At(CSharpKeyword.Else)) + { + return; + } + var block = new Block(CurrentToken, CurrentStart); + + AcceptAndMoveNext(); + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + if (At(CSharpKeyword.If)) + { + // ElseIf + block.Name = SyntaxConstants.CSharp.ElseIfKeyword; + ParseConditionalBlock(builder, block); + ParseAfterIfClause(builder); + } + else if (!EndOfFile) + { + // Else + ParseExpectedCodeBlock(builder, block); + } + } + + private void ParseTryStatement(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + Assert(CSharpKeyword.Try); + var topLevel = transition != null; + if (topLevel) + { + builder.Add(transition); + } + + ParseUnconditionalBlock(builder); + ParseAfterTryClause(builder); + if (topLevel) + { + CompleteBlock(); + } + } + + private void ParseAfterTryClause(in SyntaxListBuilder builder) + { + // Grab whitespace + var whitespace = SkipToNextImportantToken(builder); + + // Check for a catch or finally part + if (At(CSharpKeyword.Catch)) + { + Accept(whitespace); + Assert(CSharpKeyword.Catch); + ParseFilterableCatchBlock(builder); + ParseAfterTryClause(builder); + } + else if (At(CSharpKeyword.Finally)) + { + Accept(whitespace); + Assert(CSharpKeyword.Finally); + ParseUnconditionalBlock(builder); + } + else + { + // Return whitespace and end the block + PutCurrentBack(); + PutBack(whitespace); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; + } + } + + private void ParseFilterableCatchBlock(in SyntaxListBuilder builder) + { + Assert(CSharpKeyword.Catch); + + var block = new Block(CurrentToken, CurrentStart); + + // Accept "catch" + AcceptAndMoveNext(); + AcceptWhile(IsValidStatementSpacingToken); + + // Parse the catch condition if present. If not present, let the C# compiler complain. + if (TryParseCondition(builder)) + { + AcceptWhile(IsValidStatementSpacingToken); + + if (At(CSharpKeyword.When)) + { + // Accept "when". + AcceptAndMoveNext(); + AcceptWhile(IsValidStatementSpacingToken); + + // Parse the filter condition if present. If not present, let the C# compiler complain. + if (!TryParseCondition(builder)) + { + // Incomplete condition. + return; + } + + AcceptWhile(IsValidStatementSpacingToken); + } + + ParseExpectedCodeBlock(builder, block); + } + } + + private void ParseDoStatement(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + Assert(CSharpKeyword.Do); + if (transition != null) + { + builder.Add(transition); + } + + ParseUnconditionalBlock(builder); + ParseWhileClause(builder); + var topLevel = transition != null; + if (topLevel) + { + CompleteBlock(); + } + } + + private void ParseWhileClause(in SyntaxListBuilder builder) + { + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; + var whitespace = SkipToNextImportantToken(builder); + + if (At(CSharpKeyword.While)) + { + Accept(whitespace); + Assert(CSharpKeyword.While); + AcceptAndMoveNext(); + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + if (TryParseCondition(builder) && TryAccept(SyntaxKind.Semicolon)) + { + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None; + } + } + else + { + PutCurrentBack(); + PutBack(whitespace); + } + } + + private void ParseUsingKeyword(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + Assert(CSharpKeyword.Using); + var topLevel = transition != null; + var block = new Block(CurrentToken, CurrentStart); + var usingToken = EatCurrentToken(); + var whitespaceOrComments = ReadWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + var atLeftParen = At(SyntaxKind.LeftParenthesis); + var atIdentifier = At(SyntaxKind.Identifier); + var atStatic = At(CSharpKeyword.Static); + + // Put the read tokens back and let them be handled later. + PutCurrentBack(); + PutBack(whitespaceOrComments); + PutBack(usingToken); + EnsureCurrent(); + + if (atLeftParen) + { + // using ( ==> Using Statement + ParseUsingStatement(builder, transition, block); + } + else if (atIdentifier || atStatic) + { + // using Identifier ==> Using Declaration + if (!topLevel) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_NamespaceImportAndTypeAliasCannotExistWithinCodeBlock( + new SourceSpan(block.Start, block.Name.Length))); + if (transition != null) + { + builder.Add(transition); + } + AcceptAndMoveNext(); + AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + ParseStandardStatement(builder); + } + else + { + ParseUsingDeclaration(builder, transition); + return; + } + } + else + { + AcceptAndMoveNext(); + AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + } + + if (topLevel) + { + CompleteBlock(); + } + } + + private void ParseUsingStatement(in SyntaxListBuilder builder, CSharpTransitionSyntax transition, Block block) + { + Assert(CSharpKeyword.Using); + AcceptAndMoveNext(); + AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + + Assert(SyntaxKind.LeftParenthesis); + if (transition != null) + { + builder.Add(transition); + } + + // Parse condition + if (TryParseCondition(builder)) + { + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + + // Parse code block + ParseExpectedCodeBlock(builder, block); + } + } + + private void ParseUsingDeclaration(in SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + // Using declarations should always be top level. The error case is handled in a different code path. + Debug.Assert(transition != null); + using (var pooledResult = Pool.Allocate()) + { + var directiveBuilder = pooledResult.Builder; + Assert(CSharpKeyword.Using); + AcceptAndMoveNext(); + AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + var start = CurrentStart; + if (At(SyntaxKind.Identifier)) + { + // non-static using + TryParseNamespaceOrTypeName(directiveBuilder); + var whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + if (At(SyntaxKind.Assign)) + { + // Alias + Accept(whitespace); + Assert(SyntaxKind.Assign); + AcceptAndMoveNext(); + + AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + + // One more namespace or type name + TryParseNamespaceOrTypeName(directiveBuilder); + } + else + { + PutCurrentBack(); + PutBack(whitespace); + } + } + else if (At(CSharpKeyword.Static)) + { + // static using + AcceptAndMoveNext(); + AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); + TryParseNamespaceOrTypeName(directiveBuilder); + } + + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.AnyExceptNewline; + SpanContext.ChunkGenerator = new AddImportChunkGenerator(new LocationTagged( + string.Concat(TokenBuilder.ToList().Nodes.Skip(1).Select(s => s.Content)), + start)); + + // Optional ";" + if (EnsureCurrent()) + { + TryAccept(SyntaxKind.Semicolon); + } + + CompleteBlock(); + Debug.Assert(directiveBuilder.Count == 0, "We should not have built any blocks so far."); + var keywordTokens = OutputTokensAsStatementLiteral(); + var directiveBody = SyntaxFactory.RazorDirectiveBody(keywordTokens, null); + builder.Add(SyntaxFactory.RazorDirective(transition, directiveBody)); + } + } + + private bool TryParseNamespaceOrTypeName(in SyntaxListBuilder builder) + { + if (TryAccept(SyntaxKind.LeftParenthesis)) + { + while (!TryAccept(SyntaxKind.RightParenthesis) && !EndOfFile) + { + TryAccept(SyntaxKind.Whitespace); + + if (!TryParseNamespaceOrTypeName(builder)) + { + return false; + } + + TryAccept(SyntaxKind.Whitespace); + TryAccept(SyntaxKind.Identifier); + TryAccept(SyntaxKind.Whitespace); + TryAccept(SyntaxKind.Comma); + } + + if (At(SyntaxKind.Whitespace) && NextIs(SyntaxKind.QuestionMark)) + { + // Only accept the whitespace if we are going to consume the next token. + AcceptAndMoveNext(); + } + + TryAccept(SyntaxKind.QuestionMark); // Nullable + + return true; + } + else if (TryAccept(SyntaxKind.Identifier) || TryAccept(SyntaxKind.Keyword)) + { + if (TryAccept(SyntaxKind.DoubleColon)) + { + if (!TryAccept(SyntaxKind.Identifier)) + { + TryAccept(SyntaxKind.Keyword); + } + } + if (At(SyntaxKind.LessThan)) + { + ParseTypeArgumentList(builder); + } + if (TryAccept(SyntaxKind.Dot)) + { + TryParseNamespaceOrTypeName(builder); + } + + if (At(SyntaxKind.Whitespace) && NextIs(SyntaxKind.QuestionMark)) + { + // Only accept the whitespace if we are going to consume the next token. + AcceptAndMoveNext(); + } + + TryAccept(SyntaxKind.QuestionMark); // Nullable + + if (At(SyntaxKind.Whitespace) && NextIs(SyntaxKind.LeftBracket)) + { + // Only accept the whitespace if we are going to consume the next token. + AcceptAndMoveNext(); + } + + while (At(SyntaxKind.LeftBracket)) + { + Balance(builder, BalancingModes.None); + if (!TryAccept(SyntaxKind.RightBracket)) + { + Accept(SyntaxFactory.MissingToken(SyntaxKind.RightBracket)); + } + } + return true; + } + else + { + return false; + } + } + + private void ParseTypeArgumentList(in SyntaxListBuilder builder) + { + Assert(SyntaxKind.LessThan); + Balance(builder, BalancingModes.None); + if (!TryAccept(SyntaxKind.GreaterThan)) + { + Accept(SyntaxFactory.MissingToken(SyntaxKind.GreaterThan)); + } + } + + private void ParseReservedDirective(SyntaxListBuilder builder, CSharpTransitionSyntax transition) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_ReservedWord( + new SourceSpan(CurrentStart, CurrentToken.Content.Length), CurrentToken.Content)); + + AcceptAndMoveNext(); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None; + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + CompleteBlock(); + var keyword = OutputAsMetaCode(Output()); + var directiveBody = SyntaxFactory.RazorDirectiveBody(keyword, cSharpCode: null); + var directive = SyntaxFactory.RazorDirective(transition, directiveBody); + builder.Add(directive); + } + + protected void CompleteBlock() + { + CompleteBlock(insertMarkerIfNecessary: true); + } + + protected void CompleteBlock(bool insertMarkerIfNecessary) + { + CompleteBlock(insertMarkerIfNecessary, captureWhitespaceToEndOfLine: insertMarkerIfNecessary); + } + + protected void CompleteBlock(bool insertMarkerIfNecessary, bool captureWhitespaceToEndOfLine) + { + if (insertMarkerIfNecessary && Context.LastAcceptedCharacters != AcceptedCharactersInternal.Any) + { + AcceptMarkerTokenIfNecessary(); + } + + EnsureCurrent(); + + // Read whitespace, but not newlines + // If we're not inserting a marker span, we don't need to capture whitespace + if (!Context.WhiteSpaceIsSignificantToAncestorBlock && + captureWhitespaceToEndOfLine && + !Context.DesignTimeMode && + !IsNested) + { + var whitespace = ReadWhile(token => token.Kind == SyntaxKind.Whitespace); + if (At(SyntaxKind.NewLine)) + { + Accept(whitespace); + AcceptAndMoveNext(); + PutCurrentBack(); + } + else + { + PutCurrentBack(); + PutBack(whitespace); + } + } + else + { + PutCurrentBack(); + } + } + + private IEnumerable SkipToNextImportantToken(in SyntaxListBuilder builder) + { + while (!EndOfFile) + { + var whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); + if (At(SyntaxKind.RazorCommentTransition)) + { + Accept(whitespace); + SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; + AcceptMarkerTokenIfNecessary(); + builder.Add(OutputTokensAsStatementLiteral()); + var comment = ParseRazorComment(); + builder.Add(comment); + } + else + { + return whitespace; + } + } + return Enumerable.Empty(); + } + + private void DefaultSpanContextConfig(SpanContextBuilder spanContext) + { + spanContext.EditHandler = SpanEditHandler.CreateDefault(Language.TokenizeString); + spanContext.ChunkGenerator = new StatementChunkGenerator(); + } + + private void ExplicitExpressionSpanContextConfig(SpanContextBuilder spanContext) + { + spanContext.EditHandler = SpanEditHandler.CreateDefault(Language.TokenizeString); + spanContext.ChunkGenerator = new ExpressionChunkGenerator(); + } + + private CSharpStatementLiteralSyntax OutputTokensAsStatementLiteral() + { + var tokens = Output(); + if (tokens.Count == 0) + { + return null; + } + + return GetNodeWithSpanContext(SyntaxFactory.CSharpStatementLiteral(tokens)); + } + + private CSharpExpressionLiteralSyntax OutputTokensAsExpressionLiteral() + { + var tokens = Output(); + if (tokens.Count == 0) + { + return null; + } + + return GetNodeWithSpanContext(SyntaxFactory.CSharpExpressionLiteral(tokens)); + } + + private CSharpEphemeralTextLiteralSyntax OutputTokensAsEphemeralLiteral() + { + var tokens = Output(); + if (tokens.Count == 0) + { + return null; + } + + return GetNodeWithSpanContext(SyntaxFactory.CSharpEphemeralTextLiteral(tokens)); + } + + private UnclassifiedTextLiteralSyntax OutputTokensAsUnclassifiedLiteral() + { + var tokens = Output(); + if (tokens.Count == 0) + { + return null; + } + + + return GetNodeWithSpanContext(SyntaxFactory.UnclassifiedTextLiteral(tokens)); + } + + private void OtherParserBlock(in SyntaxListBuilder builder) + { + // When transitioning to the HTML parser we no longer want to act as if we're in a nested C# state. + // For instance, if
@hello.
is in a nested C# block we don't want the trailing '.' to be handled + // as C#; it should be handled as a period because it's wrapped in markup. + var wasNested = IsNested; + IsNested = false; + + RazorSyntaxNode htmlBlock = null; + using (PushSpanContextConfig()) + { + htmlBlock = HtmlParser.ParseBlock(); + } + + builder.Add(htmlBlock); + InitializeContext(SpanContext); + + IsNested = wasNested; + NextToken(); + } + + private bool Balance(SyntaxListBuilder builder, BalancingModes mode) + { + var left = CurrentToken.Kind; + var right = Language.FlipBracket(left); + var start = CurrentStart; + AcceptAndMoveNext(); + if (EndOfFile && ((mode & BalancingModes.NoErrorOnFailure) != BalancingModes.NoErrorOnFailure)) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF( + new SourceSpan(start, contentLength: 1 /* { OR } */), + Language.GetSample(left), + Language.GetSample(right))); + } + + return Balance(builder, mode, left, right, start); + } + + private bool Balance(SyntaxListBuilder builder, BalancingModes mode, SyntaxKind left, SyntaxKind right, SourceLocation start) + { + var startPosition = CurrentStart.AbsoluteIndex; + var nesting = 1; + if (!EndOfFile) + { + var tokens = new List(); + do + { + if (IsAtEmbeddedTransition( + (mode & BalancingModes.AllowCommentsAndTemplates) == BalancingModes.AllowCommentsAndTemplates, + (mode & BalancingModes.AllowEmbeddedTransitions) == BalancingModes.AllowEmbeddedTransitions)) + { + Accept(tokens); + tokens.Clear(); + ParseEmbeddedTransition(builder); + + // Reset backtracking since we've already outputted some spans. + startPosition = CurrentStart.AbsoluteIndex; + } + if (At(left)) + { + nesting++; + } + else if (At(right)) + { + nesting--; + } + if (nesting > 0) + { + tokens.Add(CurrentToken); + } + } + while (nesting > 0 && NextToken()); + + if (nesting > 0) + { + if ((mode & BalancingModes.NoErrorOnFailure) != BalancingModes.NoErrorOnFailure) + { + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF( + new SourceSpan(start, contentLength: 1 /* { OR } */), + Language.GetSample(left), + Language.GetSample(right))); + } + if ((mode & BalancingModes.BacktrackOnFailure) == BalancingModes.BacktrackOnFailure) + { + Context.Source.Position = startPosition; + NextToken(); + } + else + { + Accept(tokens); + } + } + else + { + // Accept all the tokens we saw + Accept(tokens); + } + } + return nesting == 0; + } + + private bool IsAtEmbeddedTransition(bool allowTemplatesAndComments, bool allowTransitions) + { + // No embedded transitions in C#, so ignore that param + return allowTemplatesAndComments + && ((Language.IsTransition(CurrentToken) + && NextIs(SyntaxKind.LessThan, SyntaxKind.Colon, SyntaxKind.DoubleColon)) + || Language.IsCommentStart(CurrentToken)); + } + + private void ParseEmbeddedTransition(in SyntaxListBuilder builder) + { + if (Language.IsTransition(CurrentToken)) + { + PutCurrentBack(); + ParseTemplate(builder); + } + else if (Language.IsCommentStart(CurrentToken)) + { + // Output tokens before parsing the comment. + AcceptMarkerTokenIfNecessary(); + if (SpanContext.ChunkGenerator is ExpressionChunkGenerator) + { + builder.Add(OutputTokensAsExpressionLiteral()); + } + else + { + builder.Add(OutputTokensAsStatementLiteral()); + } + + var comment = ParseRazorComment(); + builder.Add(comment); + } + } + + [Conditional("DEBUG")] + internal void Assert(CSharpKeyword expectedKeyword) + { + var result = CSharpTokenizer.GetTokenKeyword(CurrentToken); + Debug.Assert(CurrentToken.Kind == SyntaxKind.Keyword && + result.HasValue && + result.Value == expectedKeyword); + } + + protected internal bool At(CSharpKeyword keyword) + { + var result = CSharpTokenizer.GetTokenKeyword(CurrentToken); + return At(SyntaxKind.Keyword) && + result.HasValue && + result.Value == keyword; + } + + protected static Func IsSpacingToken(bool includeNewLines, bool includeComments) + { + return token => token.Kind == SyntaxKind.Whitespace || + (includeNewLines && token.Kind == SyntaxKind.NewLine) || + (includeComments && token.Kind == SyntaxKind.CSharpComment); + } + + protected class Block + { + public Block(string name, SourceLocation start) + { + Name = name; + Start = start; + } + + public Block(SyntaxToken token, SourceLocation start) + : this(GetName(token), start) + { + } + + public string Name { get; set; } + public SourceLocation Start { get; set; } + + private static string GetName(SyntaxToken token) + { + var result = CSharpTokenizer.GetTokenKeyword(token); + if (result.HasValue && token.Kind == SyntaxKind.Keyword) + { + return CSharpLanguageCharacteristics.GetKeyword(result.Value); + } + return token.Content; + } + } + + internal class ParsedDirective + { + public string DirectiveText { get; set; } + + public string AssemblyName { get; set; } + + public string TypePattern { get; set; } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpKeyword.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpKeyword.cs new file mode 100644 index 0000000000..b37807377b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpKeyword.cs @@ -0,0 +1,88 @@ +// 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 +{ + internal enum CSharpKeyword + { + Await, + Abstract, + Byte, + Class, + Delegate, + Event, + Fixed, + If, + Internal, + New, + Override, + Readonly, + Short, + Struct, + Try, + Unsafe, + Volatile, + As, + Do, + Is, + Params, + Ref, + Switch, + Ushort, + While, + Case, + Const, + Explicit, + Float, + Null, + Sizeof, + Typeof, + Implicit, + Private, + This, + Using, + Extern, + Return, + Stackalloc, + Uint, + Base, + Catch, + Continue, + Double, + For, + In, + Lock, + Object, + Protected, + Static, + False, + Public, + Sbyte, + Throw, + Virtual, + Decimal, + Else, + Operator, + String, + Ulong, + Bool, + Char, + Default, + Foreach, + Long, + Void, + Enum, + Finally, + Int, + Out, + Sealed, + True, + Goto, + Unchecked, + Interface, + Break, + Checked, + Namespace, + When + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpLanguageCharacteristics.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpLanguageCharacteristics.cs new file mode 100644 index 0000000000..3a017b54de --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpLanguageCharacteristics.cs @@ -0,0 +1,176 @@ +// 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.Diagnostics; +using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class CSharpLanguageCharacteristics : LanguageCharacteristics + { + private static readonly CSharpLanguageCharacteristics _instance = new CSharpLanguageCharacteristics(); + + private static Dictionary _tokenSamples = new Dictionary() + { + { SyntaxKind.Arrow, "->" }, + { SyntaxKind.Minus, "-" }, + { SyntaxKind.Decrement, "--" }, + { SyntaxKind.MinusAssign, "-=" }, + { SyntaxKind.NotEqual, "!=" }, + { SyntaxKind.Not, "!" }, + { SyntaxKind.Modulo, "%" }, + { SyntaxKind.ModuloAssign, "%=" }, + { SyntaxKind.AndAssign, "&=" }, + { SyntaxKind.And, "&" }, + { SyntaxKind.DoubleAnd, "&&" }, + { SyntaxKind.LeftParenthesis, "(" }, + { SyntaxKind.RightParenthesis, ")" }, + { SyntaxKind.Star, "*" }, + { SyntaxKind.MultiplyAssign, "*=" }, + { SyntaxKind.Comma, "," }, + { SyntaxKind.Dot, "." }, + { SyntaxKind.Slash, "/" }, + { SyntaxKind.DivideAssign, "/=" }, + { SyntaxKind.DoubleColon, "::" }, + { SyntaxKind.Colon, ":" }, + { SyntaxKind.Semicolon, ";" }, + { SyntaxKind.QuestionMark, "?" }, + { SyntaxKind.NullCoalesce, "??" }, + { SyntaxKind.RightBracket, "]" }, + { SyntaxKind.LeftBracket, "[" }, + { SyntaxKind.XorAssign, "^=" }, + { SyntaxKind.Xor, "^" }, + { SyntaxKind.LeftBrace, "{" }, + { SyntaxKind.OrAssign, "|=" }, + { SyntaxKind.DoubleOr, "||" }, + { SyntaxKind.Or, "|" }, + { SyntaxKind.RightBrace, "}" }, + { SyntaxKind.Tilde, "~" }, + { SyntaxKind.Plus, "+" }, + { SyntaxKind.PlusAssign, "+=" }, + { SyntaxKind.Increment, "++" }, + { SyntaxKind.LessThan, "<" }, + { SyntaxKind.LessThanEqual, "<=" }, + { SyntaxKind.LeftShift, "<<" }, + { SyntaxKind.LeftShiftAssign, "<<=" }, + { SyntaxKind.Assign, "=" }, + { SyntaxKind.Equals, "==" }, + { SyntaxKind.GreaterThan, ">" }, + { SyntaxKind.GreaterThanEqual, ">=" }, + { SyntaxKind.RightShift, ">>" }, + { SyntaxKind.RightShiftAssign, ">>=" }, + { SyntaxKind.Hash, "#" }, + { SyntaxKind.Transition, "@" }, + }; + + protected CSharpLanguageCharacteristics() + { + } + + public static CSharpLanguageCharacteristics Instance => _instance; + + public override CSharpTokenizer CreateTokenizer(ITextDocument source) + { + return new CSharpTokenizer(source); + } + + protected override SyntaxToken CreateToken(string content, SyntaxKind kind, IReadOnlyList errors) + { + return SyntaxFactory.Token(kind, content, errors); + } + + public override string GetSample(SyntaxKind kind) + { + string sample; + if (!_tokenSamples.TryGetValue(kind, out sample)) + { + switch (kind) + { + case SyntaxKind.Identifier: + return Resources.CSharpToken_Identifier; + case SyntaxKind.Keyword: + return Resources.CSharpToken_Keyword; + case SyntaxKind.IntegerLiteral: + return Resources.CSharpToken_IntegerLiteral; + case SyntaxKind.NewLine: + return Resources.CSharpToken_Newline; + case SyntaxKind.Whitespace: + return Resources.CSharpToken_Whitespace; + case SyntaxKind.CSharpComment: + return Resources.CSharpToken_Comment; + case SyntaxKind.RealLiteral: + return Resources.CSharpToken_RealLiteral; + case SyntaxKind.CharacterLiteral: + return Resources.CSharpToken_CharacterLiteral; + case SyntaxKind.StringLiteral: + return Resources.CSharpToken_StringLiteral; + default: + return Resources.Token_Unknown; + } + } + return sample; + } + + public override SyntaxToken CreateMarkerToken() + { + return SyntaxFactory.Token(SyntaxKind.Marker, string.Empty); + } + + public override SyntaxKind GetKnownTokenType(KnownTokenType type) + { + switch (type) + { + case KnownTokenType.Identifier: + return SyntaxKind.Identifier; + case KnownTokenType.Keyword: + return SyntaxKind.Keyword; + case KnownTokenType.NewLine: + return SyntaxKind.NewLine; + case KnownTokenType.Whitespace: + return SyntaxKind.Whitespace; + case KnownTokenType.Transition: + return SyntaxKind.Transition; + case KnownTokenType.CommentStart: + return SyntaxKind.RazorCommentTransition; + case KnownTokenType.CommentStar: + return SyntaxKind.RazorCommentStar; + case KnownTokenType.CommentBody: + return SyntaxKind.RazorCommentLiteral; + default: + return SyntaxKind.Marker; + } + } + + public override SyntaxKind FlipBracket(SyntaxKind bracket) + { + switch (bracket) + { + case SyntaxKind.LeftBrace: + return SyntaxKind.RightBrace; + case SyntaxKind.LeftBracket: + return SyntaxKind.RightBracket; + case SyntaxKind.LeftParenthesis: + return SyntaxKind.RightParenthesis; + case SyntaxKind.LessThan: + return SyntaxKind.GreaterThan; + case SyntaxKind.RightBrace: + return SyntaxKind.LeftBrace; + case SyntaxKind.RightBracket: + return SyntaxKind.LeftBracket; + case SyntaxKind.RightParenthesis: + return SyntaxKind.LeftParenthesis; + case SyntaxKind.GreaterThan: + return SyntaxKind.LessThan; + default: + Debug.Fail("FlipBracket must be called with a bracket character"); + return SyntaxKind.Marker; + } + } + + public static string GetKeyword(CSharpKeyword keyword) + { + return keyword.ToString().ToLowerInvariant(); + } + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpTokenizer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpTokenizer.cs new file mode 100644 index 0000000000..21cd0dc00b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpTokenizer.cs @@ -0,0 +1,807 @@ +// 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.Diagnostics; +using System.Globalization; +using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class CSharpTokenizer : Tokenizer + { + private Dictionary> _operatorHandlers; + + private static readonly Dictionary _keywords = new Dictionary(StringComparer.Ordinal) + { + { "await", CSharpKeyword.Await }, + { "abstract", CSharpKeyword.Abstract }, + { "byte", CSharpKeyword.Byte }, + { "class", CSharpKeyword.Class }, + { "delegate", CSharpKeyword.Delegate }, + { "event", CSharpKeyword.Event }, + { "fixed", CSharpKeyword.Fixed }, + { "if", CSharpKeyword.If }, + { "internal", CSharpKeyword.Internal }, + { "new", CSharpKeyword.New }, + { "override", CSharpKeyword.Override }, + { "readonly", CSharpKeyword.Readonly }, + { "short", CSharpKeyword.Short }, + { "struct", CSharpKeyword.Struct }, + { "try", CSharpKeyword.Try }, + { "unsafe", CSharpKeyword.Unsafe }, + { "volatile", CSharpKeyword.Volatile }, + { "as", CSharpKeyword.As }, + { "do", CSharpKeyword.Do }, + { "is", CSharpKeyword.Is }, + { "params", CSharpKeyword.Params }, + { "ref", CSharpKeyword.Ref }, + { "switch", CSharpKeyword.Switch }, + { "ushort", CSharpKeyword.Ushort }, + { "while", CSharpKeyword.While }, + { "case", CSharpKeyword.Case }, + { "const", CSharpKeyword.Const }, + { "explicit", CSharpKeyword.Explicit }, + { "float", CSharpKeyword.Float }, + { "null", CSharpKeyword.Null }, + { "sizeof", CSharpKeyword.Sizeof }, + { "typeof", CSharpKeyword.Typeof }, + { "implicit", CSharpKeyword.Implicit }, + { "private", CSharpKeyword.Private }, + { "this", CSharpKeyword.This }, + { "using", CSharpKeyword.Using }, + { "extern", CSharpKeyword.Extern }, + { "return", CSharpKeyword.Return }, + { "stackalloc", CSharpKeyword.Stackalloc }, + { "uint", CSharpKeyword.Uint }, + { "base", CSharpKeyword.Base }, + { "catch", CSharpKeyword.Catch }, + { "continue", CSharpKeyword.Continue }, + { "double", CSharpKeyword.Double }, + { "for", CSharpKeyword.For }, + { "in", CSharpKeyword.In }, + { "lock", CSharpKeyword.Lock }, + { "object", CSharpKeyword.Object }, + { "protected", CSharpKeyword.Protected }, + { "static", CSharpKeyword.Static }, + { "false", CSharpKeyword.False }, + { "public", CSharpKeyword.Public }, + { "sbyte", CSharpKeyword.Sbyte }, + { "throw", CSharpKeyword.Throw }, + { "virtual", CSharpKeyword.Virtual }, + { "decimal", CSharpKeyword.Decimal }, + { "else", CSharpKeyword.Else }, + { "operator", CSharpKeyword.Operator }, + { "string", CSharpKeyword.String }, + { "ulong", CSharpKeyword.Ulong }, + { "bool", CSharpKeyword.Bool }, + { "char", CSharpKeyword.Char }, + { "default", CSharpKeyword.Default }, + { "foreach", CSharpKeyword.Foreach }, + { "long", CSharpKeyword.Long }, + { "void", CSharpKeyword.Void }, + { "enum", CSharpKeyword.Enum }, + { "finally", CSharpKeyword.Finally }, + { "int", CSharpKeyword.Int }, + { "out", CSharpKeyword.Out }, + { "sealed", CSharpKeyword.Sealed }, + { "true", CSharpKeyword.True }, + { "goto", CSharpKeyword.Goto }, + { "unchecked", CSharpKeyword.Unchecked }, + { "interface", CSharpKeyword.Interface }, + { "break", CSharpKeyword.Break }, + { "checked", CSharpKeyword.Checked }, + { "namespace", CSharpKeyword.Namespace }, + { "when", CSharpKeyword.When } + }; + + public CSharpTokenizer(ITextDocument source) + : base(source) + { + base.CurrentState = StartState; + + _operatorHandlers = new Dictionary>() + { + { '-', MinusOperator }, + { '<', LessThanOperator }, + { '>', GreaterThanOperator }, + { '&', CreateTwoCharOperatorHandler(SyntaxKind.And, '=', SyntaxKind.AndAssign, '&', SyntaxKind.DoubleAnd) }, + { '|', CreateTwoCharOperatorHandler(SyntaxKind.Or, '=', SyntaxKind.OrAssign, '|', SyntaxKind.DoubleOr) }, + { '+', CreateTwoCharOperatorHandler(SyntaxKind.Plus, '=', SyntaxKind.PlusAssign, '+', SyntaxKind.Increment) }, + { '=', CreateTwoCharOperatorHandler(SyntaxKind.Assign, '=', SyntaxKind.Equals, '>', SyntaxKind.GreaterThanEqual) }, + { '!', CreateTwoCharOperatorHandler(SyntaxKind.Not, '=', SyntaxKind.NotEqual) }, + { '%', CreateTwoCharOperatorHandler(SyntaxKind.Modulo, '=', SyntaxKind.ModuloAssign) }, + { '*', CreateTwoCharOperatorHandler(SyntaxKind.Star, '=', SyntaxKind.MultiplyAssign) }, + { ':', CreateTwoCharOperatorHandler(SyntaxKind.Colon, ':', SyntaxKind.DoubleColon) }, + { '?', CreateTwoCharOperatorHandler(SyntaxKind.QuestionMark, '?', SyntaxKind.NullCoalesce) }, + { '^', CreateTwoCharOperatorHandler(SyntaxKind.Xor, '=', SyntaxKind.XorAssign) }, + { '(', () => SyntaxKind.LeftParenthesis }, + { ')', () => SyntaxKind.RightParenthesis }, + { '{', () => SyntaxKind.LeftBrace }, + { '}', () => SyntaxKind.RightBrace }, + { '[', () => SyntaxKind.LeftBracket }, + { ']', () => SyntaxKind.RightBracket }, + { ',', () => SyntaxKind.Comma }, + { ';', () => SyntaxKind.Semicolon }, + { '~', () => SyntaxKind.Tilde }, + { '#', () => SyntaxKind.Hash } + }; + } + + protected override int StartState => (int)CSharpTokenizerState.Data; + + private new CSharpTokenizerState? CurrentState => (CSharpTokenizerState?)base.CurrentState; + + public override SyntaxKind RazorCommentKind => SyntaxKind.RazorCommentLiteral; + + public override SyntaxKind RazorCommentTransitionKind => SyntaxKind.RazorCommentTransition; + + public override SyntaxKind RazorCommentStarKind => SyntaxKind.RazorCommentStar; + + protected override StateResult Dispatch() + { + switch (CurrentState) + { + case CSharpTokenizerState.Data: + return Data(); + case CSharpTokenizerState.BlockComment: + return BlockComment(); + case CSharpTokenizerState.QuotedCharacterLiteral: + return QuotedCharacterLiteral(); + case CSharpTokenizerState.QuotedStringLiteral: + return QuotedStringLiteral(); + case CSharpTokenizerState.VerbatimStringLiteral: + return VerbatimStringLiteral(); + case CSharpTokenizerState.AfterRazorCommentTransition: + return AfterRazorCommentTransition(); + case CSharpTokenizerState.EscapedRazorCommentTransition: + return EscapedRazorCommentTransition(); + case CSharpTokenizerState.RazorCommentBody: + return RazorCommentBody(); + case CSharpTokenizerState.StarAfterRazorCommentBody: + return StarAfterRazorCommentBody(); + case CSharpTokenizerState.AtTokenAfterRazorCommentBody: + return AtTokenAfterRazorCommentBody(); + default: + Debug.Fail("Invalid TokenizerState"); + return default(StateResult); + } + } + + // Optimize memory allocation by returning constants for the most frequent cases + protected override string GetTokenContent(SyntaxKind type) + { + var tokenLength = Buffer.Length; + + if (tokenLength == 1) + { + switch (type) + { + case SyntaxKind.IntegerLiteral: + switch (Buffer[0]) + { + case '0': + return "0"; + case '1': + return "1"; + case '2': + return "2"; + case '3': + return "3"; + case '4': + return "4"; + case '5': + return "5"; + case '6': + return "6"; + case '7': + return "7"; + case '8': + return "8"; + case '9': + return "9"; + } + break; + case SyntaxKind.NewLine: + if (Buffer[0] == '\n') + { + return "\n"; + } + break; + case SyntaxKind.Whitespace: + if (Buffer[0] == ' ') + { + return " "; + } + if (Buffer[0] == '\t') + { + return "\t"; + } + break; + case SyntaxKind.Minus: + return "-"; + case SyntaxKind.Not: + return "!"; + case SyntaxKind.Modulo: + return "%"; + case SyntaxKind.And: + return "&"; + case SyntaxKind.LeftParenthesis: + return "("; + case SyntaxKind.RightParenthesis: + return ")"; + case SyntaxKind.Star: + return "*"; + case SyntaxKind.Comma: + return ","; + case SyntaxKind.Dot: + return "."; + case SyntaxKind.Slash: + return "/"; + case SyntaxKind.Colon: + return ":"; + case SyntaxKind.Semicolon: + return ";"; + case SyntaxKind.QuestionMark: + return "?"; + case SyntaxKind.RightBracket: + return "]"; + case SyntaxKind.LeftBracket: + return "["; + case SyntaxKind.Xor: + return "^"; + case SyntaxKind.LeftBrace: + return "{"; + case SyntaxKind.Or: + return "|"; + case SyntaxKind.RightBrace: + return "}"; + case SyntaxKind.Tilde: + return "~"; + case SyntaxKind.Plus: + return "+"; + case SyntaxKind.LessThan: + return "<"; + case SyntaxKind.Assign: + return "="; + case SyntaxKind.GreaterThan: + return ">"; + case SyntaxKind.Hash: + return "#"; + case SyntaxKind.Transition: + return "@"; + + } + } + else if (tokenLength == 2) + { + switch (type) + { + case SyntaxKind.NewLine: + return "\r\n"; + case SyntaxKind.Arrow: + return "->"; + case SyntaxKind.Decrement: + return "--"; + case SyntaxKind.MinusAssign: + return "-="; + case SyntaxKind.NotEqual: + return "!="; + case SyntaxKind.ModuloAssign: + return "%="; + case SyntaxKind.AndAssign: + return "&="; + case SyntaxKind.DoubleAnd: + return "&&"; + case SyntaxKind.MultiplyAssign: + return "*="; + case SyntaxKind.DivideAssign: + return "/="; + case SyntaxKind.DoubleColon: + return "::"; + case SyntaxKind.NullCoalesce: + return "??"; + case SyntaxKind.XorAssign: + return "^="; + case SyntaxKind.OrAssign: + return "|="; + case SyntaxKind.DoubleOr: + return "||"; + case SyntaxKind.PlusAssign: + return "+="; + case SyntaxKind.Increment: + return "++"; + case SyntaxKind.LessThanEqual: + return "<="; + case SyntaxKind.LeftShift: + return "<<"; + case SyntaxKind.Equals: + return "=="; + case SyntaxKind.GreaterThanEqual: + if (Buffer[0] == '=') + { + return "=>"; + } + return ">="; + case SyntaxKind.RightShift: + return ">>"; + + + } + } + else if (tokenLength == 3) + { + switch (type) + { + case SyntaxKind.LeftShiftAssign: + return "<<="; + case SyntaxKind.RightShiftAssign: + return ">>="; + } + } + + return base.GetTokenContent(type); + } + + protected override SyntaxToken CreateToken(string content, SyntaxKind kind, IReadOnlyList errors) + { + return SyntaxFactory.Token(kind, content, errors); + } + + private StateResult Data() + { + if (ParserHelpers.IsNewLine(CurrentCharacter)) + { + // CSharp Spec §2.3.1 + var checkTwoCharNewline = CurrentCharacter == '\r'; + TakeCurrent(); + if (checkTwoCharNewline && CurrentCharacter == '\n') + { + TakeCurrent(); + } + return Stay(EndToken(SyntaxKind.NewLine)); + } + else if (ParserHelpers.IsWhitespace(CurrentCharacter)) + { + // CSharp Spec §2.3.3 + TakeUntil(c => !ParserHelpers.IsWhitespace(c)); + return Stay(EndToken(SyntaxKind.Whitespace)); + } + else if (IsIdentifierStart(CurrentCharacter)) + { + return Identifier(); + } + else if (char.IsDigit(CurrentCharacter)) + { + return NumericLiteral(); + } + switch (CurrentCharacter) + { + case '@': + return AtToken(); + case '\'': + TakeCurrent(); + return Transition(CSharpTokenizerState.QuotedCharacterLiteral); + case '"': + TakeCurrent(); + return Transition(CSharpTokenizerState.QuotedStringLiteral); + case '.': + if (char.IsDigit(Peek())) + { + return RealLiteral(); + } + return Stay(Single(SyntaxKind.Dot)); + case '/': + TakeCurrent(); + if (CurrentCharacter == '/') + { + TakeCurrent(); + return SingleLineComment(); + } + else if (CurrentCharacter == '*') + { + TakeCurrent(); + return Transition(CSharpTokenizerState.BlockComment); + } + else if (CurrentCharacter == '=') + { + TakeCurrent(); + return Stay(EndToken(SyntaxKind.DivideAssign)); + } + else + { + return Stay(EndToken(SyntaxKind.Slash)); + } + default: + return Stay(EndToken(Operator())); + } + } + + private StateResult AtToken() + { + TakeCurrent(); + if (CurrentCharacter == '"') + { + TakeCurrent(); + return Transition(CSharpTokenizerState.VerbatimStringLiteral); + } + else if (CurrentCharacter == '*') + { + return Transition( + CSharpTokenizerState.AfterRazorCommentTransition, + EndToken(SyntaxKind.RazorCommentTransition)); + } + else if (CurrentCharacter == '@') + { + // Could be escaped comment transition + return Transition( + CSharpTokenizerState.EscapedRazorCommentTransition, + EndToken(SyntaxKind.Transition)); + } + + return Stay(EndToken(SyntaxKind.Transition)); + } + + private StateResult EscapedRazorCommentTransition() + { + TakeCurrent(); + return Transition(CSharpTokenizerState.Data, EndToken(SyntaxKind.Transition)); + } + + private SyntaxKind Operator() + { + var first = CurrentCharacter; + TakeCurrent(); + Func handler; + if (_operatorHandlers.TryGetValue(first, out handler)) + { + return handler(); + } + return SyntaxKind.Marker; + } + + private SyntaxKind LessThanOperator() + { + if (CurrentCharacter == '=') + { + TakeCurrent(); + return SyntaxKind.LessThanEqual; + } + return SyntaxKind.LessThan; + } + + private SyntaxKind GreaterThanOperator() + { + if (CurrentCharacter == '=') + { + TakeCurrent(); + return SyntaxKind.GreaterThanEqual; + } + return SyntaxKind.GreaterThan; + } + + private SyntaxKind MinusOperator() + { + if (CurrentCharacter == '>') + { + TakeCurrent(); + return SyntaxKind.Arrow; + } + else if (CurrentCharacter == '-') + { + TakeCurrent(); + return SyntaxKind.Decrement; + } + else if (CurrentCharacter == '=') + { + TakeCurrent(); + return SyntaxKind.MinusAssign; + } + return SyntaxKind.Minus; + } + + private Func CreateTwoCharOperatorHandler(SyntaxKind typeIfOnlyFirst, char second, SyntaxKind typeIfBoth) + { + return () => + { + if (CurrentCharacter == second) + { + TakeCurrent(); + return typeIfBoth; + } + return typeIfOnlyFirst; + }; + } + + private Func CreateTwoCharOperatorHandler(SyntaxKind typeIfOnlyFirst, char option1, SyntaxKind typeIfOption1, char option2, SyntaxKind typeIfOption2) + { + return () => + { + if (CurrentCharacter == option1) + { + TakeCurrent(); + return typeIfOption1; + } + else if (CurrentCharacter == option2) + { + TakeCurrent(); + return typeIfOption2; + } + return typeIfOnlyFirst; + }; + } + + private StateResult VerbatimStringLiteral() + { + TakeUntil(c => c == '"'); + if (CurrentCharacter == '"') + { + TakeCurrent(); + if (CurrentCharacter == '"') + { + TakeCurrent(); + // Stay in the literal, this is an escaped " + return Stay(); + } + } + else if (EndOfFile) + { + CurrentErrors.Add( + RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral( + new SourceSpan(CurrentStart, contentLength: 1 /* end of file */))); + } + return Transition(CSharpTokenizerState.Data, EndToken(SyntaxKind.StringLiteral)); + } + + private StateResult QuotedCharacterLiteral() => QuotedLiteral('\'', SyntaxKind.CharacterLiteral); + + private StateResult QuotedStringLiteral() => QuotedLiteral('\"', SyntaxKind.StringLiteral); + + private StateResult QuotedLiteral(char quote, SyntaxKind literalType) + { + TakeUntil(c => c == '\\' || c == quote || ParserHelpers.IsNewLine(c)); + if (CurrentCharacter == '\\') + { + TakeCurrent(); // Take the '\' + + // If the next char is the same quote that started this + if (CurrentCharacter == quote || CurrentCharacter == '\\') + { + TakeCurrent(); // Take it so that we don't prematurely end the literal. + } + return Stay(); + } + else if (EndOfFile || ParserHelpers.IsNewLine(CurrentCharacter)) + { + CurrentErrors.Add( + RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral( + new SourceSpan(CurrentStart, contentLength: 1 /* " */))); + } + else + { + TakeCurrent(); // No-op if at EOF + } + return Transition(CSharpTokenizerState.Data, EndToken(literalType)); + } + + // CSharp Spec §2.3.2 + private StateResult BlockComment() + { + TakeUntil(c => c == '*'); + if (EndOfFile) + { + CurrentErrors.Add( + RazorDiagnosticFactory.CreateParsing_BlockCommentNotTerminated( + new SourceSpan(CurrentStart, contentLength: 1 /* end of file */))); + + return Transition(CSharpTokenizerState.Data, EndToken(SyntaxKind.CSharpComment)); + } + if (CurrentCharacter == '*') + { + TakeCurrent(); + if (CurrentCharacter == '/') + { + TakeCurrent(); + return Transition(CSharpTokenizerState.Data, EndToken(SyntaxKind.CSharpComment)); + } + } + return Stay(); + } + + // CSharp Spec §2.3.2 + private StateResult SingleLineComment() + { + TakeUntil(c => ParserHelpers.IsNewLine(c)); + return Stay(EndToken(SyntaxKind.CSharpComment)); + } + + // CSharp Spec §2.4.4 + private StateResult NumericLiteral() + { + if (TakeAll("0x", caseSensitive: true)) + { + return HexLiteral(); + } + else + { + return DecimalLiteral(); + } + } + + private StateResult HexLiteral() + { + TakeUntil(c => !IsHexDigit(c)); + TakeIntegerSuffix(); + return Stay(EndToken(SyntaxKind.IntegerLiteral)); + } + + private StateResult DecimalLiteral() + { + TakeUntil(c => !Char.IsDigit(c)); + if (CurrentCharacter == '.' && Char.IsDigit(Peek())) + { + return RealLiteral(); + } + else if (IsRealLiteralSuffix(CurrentCharacter) || + CurrentCharacter == 'E' || CurrentCharacter == 'e') + { + return RealLiteralExponentPart(); + } + else + { + TakeIntegerSuffix(); + return Stay(EndToken(SyntaxKind.IntegerLiteral)); + } + } + + private StateResult RealLiteralExponentPart() + { + if (CurrentCharacter == 'E' || CurrentCharacter == 'e') + { + TakeCurrent(); + if (CurrentCharacter == '+' || CurrentCharacter == '-') + { + TakeCurrent(); + } + TakeUntil(c => !Char.IsDigit(c)); + } + if (IsRealLiteralSuffix(CurrentCharacter)) + { + TakeCurrent(); + } + return Stay(EndToken(SyntaxKind.RealLiteral)); + } + + // CSharp Spec §2.4.4.3 + private StateResult RealLiteral() + { + AssertCurrent('.'); + TakeCurrent(); + Debug.Assert(Char.IsDigit(CurrentCharacter)); + TakeUntil(c => !Char.IsDigit(c)); + return RealLiteralExponentPart(); + } + + private void TakeIntegerSuffix() + { + if (Char.ToLowerInvariant(CurrentCharacter) == 'u') + { + TakeCurrent(); + if (Char.ToLowerInvariant(CurrentCharacter) == 'l') + { + TakeCurrent(); + } + } + else if (Char.ToLowerInvariant(CurrentCharacter) == 'l') + { + TakeCurrent(); + if (Char.ToLowerInvariant(CurrentCharacter) == 'u') + { + TakeCurrent(); + } + } + } + + // CSharp Spec §2.4.2 + private StateResult Identifier() + { + Debug.Assert(IsIdentifierStart(CurrentCharacter)); + TakeCurrent(); + TakeUntil(c => !IsIdentifierPart(c)); + SyntaxToken token = null; + if (HaveContent) + { + CSharpKeyword keyword; + var type = SyntaxKind.Identifier; + var tokenContent = Buffer.ToString(); + if (_keywords.TryGetValue(tokenContent, out keyword)) + { + type = SyntaxKind.Keyword; + } + + token = SyntaxFactory.Token(type, tokenContent); + + Buffer.Clear(); + CurrentErrors.Clear(); + } + + return Stay(token); + } + + private StateResult Transition(CSharpTokenizerState state) + { + return Transition((int)state, result: null); + } + + private StateResult Transition(CSharpTokenizerState state, SyntaxToken result) + { + return Transition((int)state, result); + } + + private static bool IsIdentifierStart(char character) + { + return char.IsLetter(character) || + character == '_' || + CharUnicodeInfo.GetUnicodeCategory(character) == UnicodeCategory.LetterNumber; + } + + private static bool IsIdentifierPart(char character) + { + return char.IsDigit(character) || + IsIdentifierStart(character) || + IsIdentifierPartByUnicodeCategory(character); + } + + private static bool IsRealLiteralSuffix(char character) + { + return character == 'F' || + character == 'f' || + character == 'D' || + character == 'd' || + character == 'M' || + character == 'm'; + } + + private static bool IsIdentifierPartByUnicodeCategory(char character) + { + var category = CharUnicodeInfo.GetUnicodeCategory(character); + + return category == UnicodeCategory.NonSpacingMark || // Mn + category == UnicodeCategory.SpacingCombiningMark || // Mc + category == UnicodeCategory.ConnectorPunctuation || // Pc + category == UnicodeCategory.Format; // Cf + } + + private static bool IsHexDigit(char value) + { + return (value >= '0' && value <= '9') || (value >= 'A' && value <= 'F') || (value >= 'a' && value <= 'f'); + } + + internal static CSharpKeyword? GetTokenKeyword(SyntaxToken token) + { + if (token != null && _keywords.TryGetValue(token.Content, out var keyword)) + { + return keyword; + } + + return null; + } + + private enum CSharpTokenizerState + { + Data, + BlockComment, + QuotedCharacterLiteral, + QuotedStringLiteral, + VerbatimStringLiteral, + + // Razor Comments - need to be the same for HTML and CSharp + AfterRazorCommentTransition = RazorCommentTokenizerState.AfterRazorCommentTransition, + EscapedRazorCommentTransition = RazorCommentTokenizerState.EscapedRazorCommentTransition, + RazorCommentBody = RazorCommentTokenizerState.RazorCommentBody, + StarAfterRazorCommentBody = RazorCommentTokenizerState.StarAfterRazorCommentBody, + AtTokenAfterRazorCommentBody = RazorCommentTokenizerState.AtTokenAfterRazorCommentBody, + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ClassifiedSpanInternal.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ClassifiedSpanInternal.cs new file mode 100644 index 0000000000..93c4331923 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ClassifiedSpanInternal.cs @@ -0,0 +1,27 @@ +// 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 +{ + internal struct ClassifiedSpanInternal + { + public ClassifiedSpanInternal(SourceSpan span, SourceSpan blockSpan, SpanKindInternal spanKind, BlockKindInternal blockKind, AcceptedCharactersInternal acceptedCharacters) + { + Span = span; + BlockSpan = blockSpan; + SpanKind = spanKind; + BlockKind = blockKind; + AcceptedCharacters = acceptedCharacters; + } + + public AcceptedCharactersInternal AcceptedCharacters { get; } + + public BlockKindInternal BlockKind { get; } + + public SourceSpan BlockSpan { get; } + + public SourceSpan Span { get; } + + public SpanKindInternal SpanKind { get; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CodeBlockEditHandler.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CodeBlockEditHandler.cs new file mode 100644 index 0000000000..8ecbd85906 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CodeBlockEditHandler.cs @@ -0,0 +1,127 @@ +// 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 Microsoft.AspNetCore.Razor.Language.Syntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class CodeBlockEditHandler : SpanEditHandler + { + public CodeBlockEditHandler(Func> tokenizer) : base(tokenizer) + { + } + + protected override PartialParseResultInternal CanAcceptChange(SyntaxNode target, SourceChange change) + { + if (IsAcceptableDeletion(target, change)) + { + return PartialParseResultInternal.Accepted; + } + + if (IsAcceptableReplacement(target, change)) + { + return PartialParseResultInternal.Accepted; + } + + if (IsAcceptableInsertion(change)) + { + return PartialParseResultInternal.Accepted; + } + + return PartialParseResultInternal.Rejected; + } + + // Internal for testing + internal static bool IsAcceptableReplacement(SyntaxNode target, SourceChange change) + { + if (!change.IsReplace) + { + return false; + } + + if (ContainsInvalidContent(change)) + { + return false; + } + + if (ModifiesInvalidContent(target, change)) + { + return false; + } + + return true; + } + + // Internal for testing + internal static bool IsAcceptableDeletion(SyntaxNode target, SourceChange change) + { + if (!change.IsDelete) + { + return false; + } + + if (ModifiesInvalidContent(target, change)) + { + return false; + } + + return true; + } + + // Internal for testing + internal static bool ModifiesInvalidContent(SyntaxNode target, SourceChange change) + { + var relativePosition = change.Span.AbsoluteIndex - target.Position; + + if (target.GetContent().IndexOfAny(new[] { '{', '}' }, relativePosition, change.Span.Length) >= 0) + { + return true; + } + + return false; + } + + // Internal for testing + internal static bool IsAcceptableInsertion(SourceChange change) + { + if (!change.IsInsert) + { + return false; + } + + if (ContainsInvalidContent(change)) + { + return false; + } + + return true; + } + + // Internal for testing + internal static bool ContainsInvalidContent(SourceChange change) + { + if (change.NewText.IndexOfAny(new[] { '{', '}' }) >= 0) + { + return true; + } + + return false; + } + + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, "{0};CodeBlock", base.ToString()); + } + + public override bool Equals(object obj) + { + return obj is CodeBlockEditHandler other && + base.Equals(other); + } + + public override int GetHashCode() => base.GetHashCode(); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveCSharpTokenizer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveCSharpTokenizer.cs new file mode 100644 index 0000000000..59224e709f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveCSharpTokenizer.cs @@ -0,0 +1,63 @@ +// 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 Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class DirectiveCSharpTokenizer : CSharpTokenizer + { + private bool _visitedFirstTokenStart = false; + private bool _visitedFirstTokenLineEnd = false; + + public DirectiveCSharpTokenizer(ITextDocument source) : base(source) + { + } + + protected override StateResult Dispatch() + { + var result = base.Dispatch(); + if (result.Result != null && !_visitedFirstTokenStart && IsValidTokenType(result.Result.Kind)) + { + _visitedFirstTokenStart = true; + } + else if (result.Result != null && _visitedFirstTokenStart && result.Result.Kind == SyntaxKind.NewLine) + { + _visitedFirstTokenLineEnd = true; + } + + return result; + } + + public override SyntaxToken NextToken() + { + // Post-Condition: Buffer should be empty at the start of Next() + Debug.Assert(Buffer.Length == 0); + StartToken(); + + if (EndOfFile || (_visitedFirstTokenStart && _visitedFirstTokenLineEnd)) + { + return null; + } + + var token = Turn(); + + // Post-Condition: Buffer should be empty at the end of Next() + Debug.Assert(Buffer.Length == 0); + + return token; + } + + private bool IsValidTokenType(SyntaxKind kind) + { + return kind != SyntaxKind.Whitespace && + kind != SyntaxKind.NewLine && + kind != SyntaxKind.CSharpComment && + kind != SyntaxKind.RazorCommentLiteral && + kind != SyntaxKind.RazorCommentStar && + kind != SyntaxKind.RazorCommentTransition && + kind != SyntaxKind.Transition; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveHtmlTokenizer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveHtmlTokenizer.cs new file mode 100644 index 0000000000..4921c8aa1e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveHtmlTokenizer.cs @@ -0,0 +1,57 @@ +// 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 Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class DirectiveHtmlTokenizer : HtmlTokenizer + { + private bool _visitedFirstTokenStart = false; + + public DirectiveHtmlTokenizer(ITextDocument source) : base(source) + { + } + + protected override StateResult Dispatch() + { + var result = base.Dispatch(); + if (result.Result != null && IsValidTokenType(result.Result.Kind)) + { + _visitedFirstTokenStart = true; + } + + return result; + } + + public override SyntaxToken NextToken() + { + // Post-Condition: Buffer should be empty at the start of Next() + Debug.Assert(Buffer.Length == 0); + StartToken(); + + if (EndOfFile || _visitedFirstTokenStart) + { + return null; + } + + var token = Turn(); + + // Post-Condition: Buffer should be empty at the end of Next() + Debug.Assert(Buffer.Length == 0); + + return token; + } + + private bool IsValidTokenType(SyntaxKind kind) + { + return kind != SyntaxKind.Whitespace && + kind != SyntaxKind.NewLine && + kind != SyntaxKind.RazorCommentLiteral && + kind != SyntaxKind.RazorCommentStar && + kind != SyntaxKind.RazorCommentTransition && + kind != SyntaxKind.Transition; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveTokenChunkGenerator.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveTokenChunkGenerator.cs new file mode 100644 index 0000000000..ea1095bd5b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveTokenChunkGenerator.cs @@ -0,0 +1,50 @@ +// 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.Text; +using Microsoft.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class DirectiveTokenChunkGenerator : SpanChunkGenerator + { + private static readonly Type Type = typeof(DirectiveTokenChunkGenerator); + + public DirectiveTokenChunkGenerator(DirectiveTokenDescriptor tokenDescriptor) + { + Descriptor = tokenDescriptor; + } + + public DirectiveTokenDescriptor Descriptor { get; } + + public override bool Equals(object obj) + { + var other = obj as DirectiveTokenChunkGenerator; + return base.Equals(other) && + DirectiveTokenDescriptorComparer.Default.Equals(Descriptor, other.Descriptor); + } + + public override int GetHashCode() + { + var combiner = HashCodeCombiner.Start(); + combiner.Add(base.GetHashCode()); + combiner.Add(Type); + + return combiner.CombinedHash; + } + + public override string ToString() + { + var builder = new StringBuilder("DirectiveToken {"); + builder.Append(Descriptor.Name); + builder.Append(";"); + builder.Append(Descriptor.Kind); + builder.Append(";Opt:"); + builder.Append(Descriptor.Optional); + builder.Append("}"); + + return builder.ToString(); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DisposableAction.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DisposableAction.cs new file mode 100644 index 0000000000..8dbecff0bc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DisposableAction.cs @@ -0,0 +1,32 @@ +// 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 DisposableAction : IDisposable + { + private readonly Action _action; + private bool _invoked; + + public DisposableAction(Action action) + { + if (action == null) + { + throw new ArgumentNullException(nameof(action)); + } + + _action = action; + } + + public void Dispose() + { + if (!_invoked) + { + _action(); + _invoked = true; + } + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/EditResult.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/EditResult.cs new file mode 100644 index 0000000000..13dfb20a71 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/EditResult.cs @@ -0,0 +1,19 @@ +// 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.Syntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class EditResult + { + public EditResult(PartialParseResultInternal result, SyntaxNode editedNode) + { + Result = result; + EditedNode = editedNode; + } + + public PartialParseResultInternal Result { get; set; } + public SyntaxNode EditedNode { get; set; } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ErrorSink.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ErrorSink.cs new file mode 100644 index 0000000000..3b4c057cd7 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ErrorSink.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.Collections.Generic; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + /// + /// Used to manage s encountered during the Razor parsing phase. + /// + internal class ErrorSink + { + private readonly List _errors; + + /// + /// Instantiates a new instance of . + /// + public ErrorSink() + { + _errors = new List(); + } + + /// + /// s collected. + /// + public IReadOnlyList Errors => _errors; + + /// + /// Tracks the given . + /// + /// The to track. + public void OnError(RazorDiagnostic error) =>_errors.Add(error); + } +} \ No newline at end of file diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ExpressionChunkGenerator.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ExpressionChunkGenerator.cs new file mode 100644 index 0000000000..24eb488c1e --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ExpressionChunkGenerator.cs @@ -0,0 +1,28 @@ +// 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 ExpressionChunkGenerator : ISpanChunkGenerator + { + private static readonly int TypeHashCode = typeof(ExpressionChunkGenerator).GetHashCode(); + + public override string ToString() + { + return "Expr"; + } + + public override bool Equals(object obj) + { + return obj != null && + GetType() == obj.GetType(); + } + + public override int GetHashCode() + { + return TypeHashCode; + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/FirstDirectiveCSharpLanguageCharacteristics.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/FirstDirectiveCSharpLanguageCharacteristics.cs new file mode 100644 index 0000000000..c3761ce5c5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/FirstDirectiveCSharpLanguageCharacteristics.cs @@ -0,0 +1,18 @@ +// 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 +{ + internal class FirstDirectiveCSharpLanguageCharacteristics : CSharpLanguageCharacteristics + { + private static readonly FirstDirectiveCSharpLanguageCharacteristics _instance = new FirstDirectiveCSharpLanguageCharacteristics(); + + private FirstDirectiveCSharpLanguageCharacteristics() + { + } + + public new static FirstDirectiveCSharpLanguageCharacteristics Instance => _instance; + + public override CSharpTokenizer CreateTokenizer(ITextDocument source) => new DirectiveCSharpTokenizer(source); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/FirstDirectiveHtmlLanguageCharacteristics.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/FirstDirectiveHtmlLanguageCharacteristics.cs new file mode 100644 index 0000000000..2e2c7bea6b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/FirstDirectiveHtmlLanguageCharacteristics.cs @@ -0,0 +1,18 @@ +// 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 +{ + internal class FirstDirectiveHtmlLanguageCharacteristics : HtmlLanguageCharacteristics + { + private static readonly FirstDirectiveHtmlLanguageCharacteristics _instance = new FirstDirectiveHtmlLanguageCharacteristics(); + + private FirstDirectiveHtmlLanguageCharacteristics() + { + } + + public new static FirstDirectiveHtmlLanguageCharacteristics Instance => _instance; + + public override HtmlTokenizer CreateTokenizer(ITextDocument source) => new DirectiveHtmlTokenizer(source); + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlLanguageCharacteristics.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlLanguageCharacteristics.cs new file mode 100644 index 0000000000..5efd2b80a5 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlLanguageCharacteristics.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.Collections.Generic; +using System.Diagnostics; +using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class HtmlLanguageCharacteristics : LanguageCharacteristics + { + private static readonly HtmlLanguageCharacteristics _instance = new HtmlLanguageCharacteristics(); + + protected HtmlLanguageCharacteristics() + { + } + + public static HtmlLanguageCharacteristics Instance + { + get { return _instance; } + } + + public override string GetSample(SyntaxKind type) + { + switch (type) + { + case SyntaxKind.Text: + return Resources.HtmlToken_Text; + case SyntaxKind.Whitespace: + return Resources.HtmlToken_WhiteSpace; + case SyntaxKind.NewLine: + return Resources.HtmlToken_NewLine; + case SyntaxKind.OpenAngle: + return "<"; + case SyntaxKind.Bang: + return "!"; + case SyntaxKind.ForwardSlash: + return "/"; + case SyntaxKind.QuestionMark: + return "?"; + case SyntaxKind.DoubleHyphen: + return "--"; + case SyntaxKind.LeftBracket: + return "["; + case SyntaxKind.CloseAngle: + return ">"; + case SyntaxKind.RightBracket: + return "]"; + case SyntaxKind.Equals: + return "="; + case SyntaxKind.DoubleQuote: + return "\""; + case SyntaxKind.SingleQuote: + return "'"; + case SyntaxKind.Transition: + return "@"; + case SyntaxKind.Colon: + return ":"; + case SyntaxKind.RazorCommentLiteral: + return Resources.HtmlToken_RazorComment; + case SyntaxKind.RazorCommentStar: + return "*"; + case SyntaxKind.RazorCommentTransition: + return "@"; + default: + return Resources.Token_Unknown; + } + } + + public override HtmlTokenizer CreateTokenizer(ITextDocument source) + { + return new HtmlTokenizer(source); + } + + public override SyntaxKind FlipBracket(SyntaxKind bracket) + { + switch (bracket) + { + case SyntaxKind.LeftBracket: + return SyntaxKind.RightBracket; + case SyntaxKind.OpenAngle: + return SyntaxKind.CloseAngle; + case SyntaxKind.RightBracket: + return SyntaxKind.LeftBracket; + case SyntaxKind.CloseAngle: + return SyntaxKind.OpenAngle; + default: + Debug.Fail("FlipBracket must be called with a bracket character"); + return SyntaxKind.Marker; + } + } + + public override SyntaxToken CreateMarkerToken() + { + return SyntaxFactory.Token(SyntaxKind.Marker, string.Empty); + } + + public override SyntaxKind GetKnownTokenType(KnownTokenType type) + { + switch (type) + { + case KnownTokenType.CommentStart: + return SyntaxKind.RazorCommentTransition; + case KnownTokenType.CommentStar: + return SyntaxKind.RazorCommentStar; + case KnownTokenType.CommentBody: + return SyntaxKind.RazorCommentLiteral; + case KnownTokenType.Identifier: + return SyntaxKind.Text; + case KnownTokenType.Keyword: + return SyntaxKind.Text; + case KnownTokenType.NewLine: + return SyntaxKind.NewLine; + case KnownTokenType.Transition: + return SyntaxKind.Transition; + case KnownTokenType.Whitespace: + return SyntaxKind.Whitespace; + default: + return SyntaxKind.Marker; + } + } + + protected override SyntaxToken CreateToken(string content, SyntaxKind kind, IReadOnlyList errors) + { + return SyntaxFactory.Token(kind, content, errors); + } + } +} diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs new file mode 100644 index 0000000000..f06c8db1bc --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs @@ -0,0 +1,1951 @@ +// 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.Diagnostics; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal class HtmlMarkupParser : TokenizerBackedParser + { + private const string ScriptTagName = "script"; + + private static readonly SyntaxToken[] nonAllowedHtmlCommentEnding = new[] + { + SyntaxFactory.Token(SyntaxKind.Text, "-"), + SyntaxFactory.Token(SyntaxKind.Bang, "!"), + SyntaxFactory.Token(SyntaxKind.OpenAngle, "<"), + }; + + private static readonly char[] ValidAfterTypeAttributeNameCharacters = { ' ', '\t', '\r', '\n', '\f', '=' }; + private SourceLocation _lastTagStart = SourceLocation.Zero; + private SyntaxToken _bufferedOpenAngle; + + //From http://dev.w3.org/html5/spec/Overview.html#elements-0 + private readonly ISet _voidElements = new HashSet(StringComparer.OrdinalIgnoreCase) + { + "area", + "base", + "br", + "col", + "command", + "embed", + "hr", + "img", + "input", + "keygen", + "link", + "meta", + "param", + "source", + "track", + "wbr" + }; + + public HtmlMarkupParser(ParserContext context) + : base(context.ParseLeadingDirectives ? FirstDirectiveHtmlLanguageCharacteristics.Instance : HtmlLanguageCharacteristics.Instance, context) + { + } + + public CSharpCodeParser CodeParser { get; set; } + + public ISet VoidElements + { + get { return _voidElements; } + } + + private bool CaseSensitive { get; set; } + + private StringComparison Comparison + { + get { return CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; } + } + + // Special tags include " As we will be treating this as a comment ending, there is no need to handle this case at all. + // 2.2.3 "--!>" + // 2.3 nor end with the string "" + + if (CurrentToken.Kind != SyntaxKind.DoubleHyphen) + { + return false; + } + + // Check condition 2.1 + if (NextIs(SyntaxKind.CloseAngle) || NextIs(next => IsHyphen(next) && NextIs(SyntaxKind.CloseAngle))) + { + return false; + } + + // Check condition 2.2 + var isValidComment = false; + LookaheadUntil((token, prevTokens) => + { + if (token.Kind == SyntaxKind.DoubleHyphen) + { + if (NextIs(SyntaxKind.CloseAngle)) + { + // Check condition 2.3: We're at the end of a comment. Check to make sure the text ending is allowed. + isValidComment = !IsCommentContentEndingInvalid(prevTokens); + return true; + } + else if (NextIs(ns => IsHyphen(ns) && NextIs(SyntaxKind.CloseAngle))) + { + // Check condition 2.3: we're at the end of a comment, which has an extra dash. + // Need to treat the dash as part of the content and check the ending. + // However, that case would have already been checked as part of check from 2.2.1 which + // would already fail this iteration and we wouldn't get here + isValidComment = true; + return true; + } + else if (NextIs(ns => ns.Kind == SyntaxKind.Bang && NextIs(SyntaxKind.CloseAngle))) + { + // This is condition 2.2.3 + isValidComment = false; + return true; + } + } + else if (token.Kind == SyntaxKind.OpenAngle) + { + // Checking condition 2.2.1 + if (NextIs(ns => ns.Kind == SyntaxKind.Bang && NextIs(SyntaxKind.DoubleHyphen))) + { + isValidComment = false; + return true; + } + } + + return false; + }); + + return isValidComment; + } + + /// + /// Verifies, that the sequence doesn't end with the "<!-" HtmlTokens. Note, the first token is an opening bracket token + /// + internal static bool IsCommentContentEndingInvalid(IEnumerable sequence) + { + var reversedSequence = sequence.Reverse(); + var index = 0; + foreach (var item in reversedSequence) + { + if (!item.IsEquivalentTo(nonAllowedHtmlCommentEnding[index++])) + { + return false; + } + + if (index == nonAllowedHtmlCommentEnding.Length) + { + return true; + } + } + + return false; + } + + private bool TryParseCData(in SyntaxListBuilder builder) + { + if (CurrentToken.Kind == SyntaxKind.Text && string.Equals(CurrentToken.Content, "cdata", StringComparison.OrdinalIgnoreCase)) + { + if (AcceptAndMoveNext()) + { + if (CurrentToken.Kind == SyntaxKind.LeftBracket) + { + return AcceptTokenUntilAll(builder, SyntaxKind.RightBracket, SyntaxKind.RightBracket, SyntaxKind.CloseAngle); + } + } + } + + return false; + } + + private bool TryParseXmlPI(in SyntaxListBuilder builder) + { + // Accept "?" + Assert(SyntaxKind.QuestionMark); + AcceptAndMoveNext(); + return AcceptTokenUntilAll(builder, SyntaxKind.QuestionMark, SyntaxKind.CloseAngle); + } + + private void ParseOptionalBangEscape(in SyntaxListBuilder builder) + { + if (IsBangEscape(lookahead: 0)) + { + builder.Add(OutputAsMarkupLiteral()); + + // Accept the parser escape character '!'. + Assert(SyntaxKind.Bang); + AcceptAndMoveNext(); + + // Setup the metacode span that we will be outputing. + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + builder.Add(OutputAsMetaCode(Output())); + } + } + + private bool IsBangEscape(int lookahead) + { + var potentialBang = Lookahead(lookahead); + + if (potentialBang != null && + potentialBang.Kind == SyntaxKind.Bang) + { + var afterBang = Lookahead(lookahead + 1); + + return afterBang != null && + afterBang.Kind == SyntaxKind.Text && + !string.Equals(afterBang.Content, "DOCTYPE", StringComparison.OrdinalIgnoreCase); + } + + return false; + } + + private void SkipToEndScriptAndParseCode(in SyntaxListBuilder builder, AcceptedCharactersInternal endTagAcceptedCharacters = AcceptedCharactersInternal.Any) + { + // Special case for + + + + + + diff --git a/src/Razor/test/testassets/AppWithP2PReference/Views/_ViewImports.cshtml b/src/Razor/test/testassets/AppWithP2PReference/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..601a427791 --- /dev/null +++ b/src/Razor/test/testassets/AppWithP2PReference/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using AppWithP2PReference +@using AppWithP2PReference.Models +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/AppWithP2PReference/Views/_ViewStart.cshtml b/src/Razor/test/testassets/AppWithP2PReference/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/src/Razor/test/testassets/AppWithP2PReference/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/src/Razor/test/testassets/ClassLibrary/Class1.cs b/src/Razor/test/testassets/ClassLibrary/Class1.cs new file mode 100644 index 0000000000..62a93d35fc --- /dev/null +++ b/src/Razor/test/testassets/ClassLibrary/Class1.cs @@ -0,0 +1,7 @@ +namespace ClassLibrary +{ + public class Class1 + { + // Just here so this assembly has some compilation inputs. + } +} \ No newline at end of file diff --git a/src/Razor/test/testassets/ClassLibrary/ClassLibrary.csproj b/src/Razor/test/testassets/ClassLibrary/ClassLibrary.csproj new file mode 100644 index 0000000000..717524a947 --- /dev/null +++ b/src/Razor/test/testassets/ClassLibrary/ClassLibrary.csproj @@ -0,0 +1,40 @@ + + + + $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + + + + netstandard2.0 + + © Microsoft + Razor Test + Microsoft + ClassLibrary Description + + <_EnableAllInclusiveRazorSdk>true + 3.0 + MVC-3.0 + + + + + false + + + + + + + + + + + + + + + + + + diff --git a/src/Razor/test/testassets/ClassLibrary/Views/Shared/_Layout.cshtml b/src/Razor/test/testassets/ClassLibrary/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..1a9473e464 --- /dev/null +++ b/src/Razor/test/testassets/ClassLibrary/Views/Shared/_Layout.cshtml @@ -0,0 +1,71 @@ + + + + + + @ViewData["Title"] - SimpleMvc + + + + + + + + + + + + +
+ @RenderBody() +
+
+

© 2017 - SimpleMvc

+
+
+ + + + + + + + + + + + + @RenderSection("Scripts", required: false) + + diff --git a/src/Razor/test/testassets/ClassLibrary/Views/_ViewImports.cshtml b/src/Razor/test/testassets/ClassLibrary/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..1dbbe8a4c2 --- /dev/null +++ b/src/Razor/test/testassets/ClassLibrary/Views/_ViewImports.cshtml @@ -0,0 +1,2 @@ +@using ClassLibrary +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/ClassLibrary2/Class2.cs b/src/Razor/test/testassets/ClassLibrary2/Class2.cs new file mode 100644 index 0000000000..76bd2e956f --- /dev/null +++ b/src/Razor/test/testassets/ClassLibrary2/Class2.cs @@ -0,0 +1,13 @@ +using System; +using ClassLibrary; + +namespace ClassLibrary2 +{ + public class Class2 + { + public void Method() + { + Console.WriteLine(typeof(Class1)); + } + } +} diff --git a/src/Razor/test/testassets/ClassLibrary2/ClassLibrary2.csproj b/src/Razor/test/testassets/ClassLibrary2/ClassLibrary2.csproj new file mode 100644 index 0000000000..2576345aa3 --- /dev/null +++ b/src/Razor/test/testassets/ClassLibrary2/ClassLibrary2.csproj @@ -0,0 +1,39 @@ + + + + $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + + + + netstandard2.0 + + <_EnableAllInclusiveRazorSdk>true + 3.0 + MVC-3.0 + + + + + false + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Razor/test/testassets/ClassLibrary2/Views/Shared/Index.cshtml b/src/Razor/test/testassets/ClassLibrary2/Views/Shared/Index.cshtml new file mode 100644 index 0000000000..415ad5c4f8 --- /dev/null +++ b/src/Razor/test/testassets/ClassLibrary2/Views/Shared/Index.cshtml @@ -0,0 +1,2 @@ +@{ var message = "Hello world";} +@message diff --git a/src/Razor/test/testassets/ClassLibrary2/Views/_ViewImports.cshtml b/src/Razor/test/testassets/ClassLibrary2/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..1dbbe8a4c2 --- /dev/null +++ b/src/Razor/test/testassets/ClassLibrary2/Views/_ViewImports.cshtml @@ -0,0 +1,2 @@ +@using ClassLibrary +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/ClassLibraryMvc21/Areas/MyFeature/Pages/Page1.cshtml b/src/Razor/test/testassets/ClassLibraryMvc21/Areas/MyFeature/Pages/Page1.cshtml new file mode 100644 index 0000000000..69112690e7 --- /dev/null +++ b/src/Razor/test/testassets/ClassLibraryMvc21/Areas/MyFeature/Pages/Page1.cshtml @@ -0,0 +1,16 @@ +@page +@model ClassLibraryMvc21.MyFeature.Pages.Page1Model +@{ + Layout = null; +} + + + + + + + Page1 + + + + diff --git a/src/Razor/test/testassets/ClassLibraryMvc21/Areas/MyFeature/Pages/Page1.cshtml.cs b/src/Razor/test/testassets/ClassLibraryMvc21/Areas/MyFeature/Pages/Page1.cshtml.cs new file mode 100644 index 0000000000..c1fe87da2d --- /dev/null +++ b/src/Razor/test/testassets/ClassLibraryMvc21/Areas/MyFeature/Pages/Page1.cshtml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace ClassLibraryMvc21.MyFeature.Pages +{ + public class Page1Model : PageModel + { + public void OnGet() + { + + } + } +} \ No newline at end of file diff --git a/src/Razor/test/testassets/ClassLibraryMvc21/ClassLibraryMvc21.csproj b/src/Razor/test/testassets/ClassLibraryMvc21/ClassLibraryMvc21.csproj new file mode 100644 index 0000000000..04fdcf55f3 --- /dev/null +++ b/src/Razor/test/testassets/ClassLibraryMvc21/ClassLibraryMvc21.csproj @@ -0,0 +1,18 @@ + + + + + + netstandard2.0 + + + + + + All + + + diff --git a/src/Razor/test/testassets/Directory.Build.props b/src/Razor/test/testassets/Directory.Build.props new file mode 100644 index 0000000000..8020d32ee0 --- /dev/null +++ b/src/Razor/test/testassets/Directory.Build.props @@ -0,0 +1,35 @@ + + + + + $(MSBuildThisFileDirectory)..\..\ + $([MSBuild]::EnsureTrailingSlash('$(SolutionRoot)')) + + + $(SolutionRoot)src\Microsoft.NET.Sdk.Razor\ + + $(RazorSdkProjectDirectory)build\netstandard2.0\Sdk.Razor.CurrentVersion.props + $(RazorSdkProjectDirectory)build\netstandard2.0\Sdk.Razor.CurrentVersion.targets + + + + + + + + 99.9 + + $(NETStandardLibrary20PackageVersion) + + + OutOfProcess + + + + + false + + + + + diff --git a/src/Razor/test/testassets/Directory.Build.targets b/src/Razor/test/testassets/Directory.Build.targets new file mode 100644 index 0000000000..39f4f47645 --- /dev/null +++ b/src/Razor/test/testassets/Directory.Build.targets @@ -0,0 +1,9 @@ + + + + + $(MicrosoftNETCoreApp30PackageVersion) + + 99.9 + + diff --git a/src/Razor/test/testassets/LargeProject/LargeProject.csproj b/src/Razor/test/testassets/LargeProject/LargeProject.csproj new file mode 100644 index 0000000000..5f755a4dfd --- /dev/null +++ b/src/Razor/test/testassets/LargeProject/LargeProject.csproj @@ -0,0 +1,31 @@ + + + + $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + + + + netcoreapp3.0 + + + + + false + + + + + + + + + + + + + + + + + + diff --git a/src/Razor/test/testassets/LargeProject/Views/Home/View000.cshtml b/src/Razor/test/testassets/LargeProject/Views/Home/View000.cshtml new file mode 100644 index 0000000000..3b3157002e --- /dev/null +++ b/src/Razor/test/testassets/LargeProject/Views/Home/View000.cshtml @@ -0,0 +1,71 @@ + + + + + + @ViewData["Title"] - SimplePages + + + + + + + + + + + + +
+ @RenderBody() +
+
+

© 2017 - SimplePages

+
+
+ + + + + + + + + + + + + @RenderSection("Scripts", required: false) + + \ No newline at end of file diff --git a/src/Razor/test/testassets/LargeProject/Views/Home/View001.cshtml b/src/Razor/test/testassets/LargeProject/Views/Home/View001.cshtml new file mode 100644 index 0000000000..6229fde63d --- /dev/null +++ b/src/Razor/test/testassets/LargeProject/Views/Home/View001.cshtml @@ -0,0 +1,7 @@ +@{ + ViewData["Title"] = "About"; +} +

@ViewData["Title"]

+

@ViewData["Message"]

+ +

Use this area to provide additional information.

\ No newline at end of file diff --git a/src/Razor/test/testassets/LargeProject/Views/Home/View002.cshtml b/src/Razor/test/testassets/LargeProject/Views/Home/View002.cshtml new file mode 100644 index 0000000000..00afab6a0c --- /dev/null +++ b/src/Razor/test/testassets/LargeProject/Views/Home/View002.cshtml @@ -0,0 +1,108 @@ +@{ + ViewData["Title"] = "Home Page"; +} + + + + diff --git a/src/Razor/test/testassets/LargeProject/Views/Home/View003.cshtml b/src/Razor/test/testassets/LargeProject/Views/Home/View003.cshtml new file mode 100644 index 0000000000..a11a1867cf --- /dev/null +++ b/src/Razor/test/testassets/LargeProject/Views/Home/View003.cshtml @@ -0,0 +1,17 @@ +@{ + ViewData["Title"] = "Contact"; +} +

@ViewData["Title"]

+

@ViewData["Message"]

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ P: + 425.555.0100 +
+ +
+ Support: Support@example.com
+ Marketing: Marketing@example.com +
diff --git a/src/Razor/test/testassets/LargeProject/Views/Shared/_Layout.cshtml b/src/Razor/test/testassets/LargeProject/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..694a3223d1 --- /dev/null +++ b/src/Razor/test/testassets/LargeProject/Views/Shared/_Layout.cshtml @@ -0,0 +1,71 @@ + + + + + + @ViewData["Title"] - SimplePages + + + + + + + + + + + + +
+ @RenderBody() +
+
+

© 2017 - SimplePages

+
+
+ + + + + + + + + + + + + @RenderSection("Scripts", required: false) + + diff --git a/src/Razor/test/testassets/LargeProject/Views/Shared/_ViewImports.cshtml b/src/Razor/test/testassets/LargeProject/Views/Shared/_ViewImports.cshtml new file mode 100644 index 0000000000..46477e769f --- /dev/null +++ b/src/Razor/test/testassets/LargeProject/Views/Shared/_ViewImports.cshtml @@ -0,0 +1,2 @@ +@using LargeProject +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/LargeProject/Views/Shared/_ViewStart.cshtml b/src/Razor/test/testassets/LargeProject/Views/Shared/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/src/Razor/test/testassets/LargeProject/Views/Shared/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/src/Razor/test/testassets/LinkedDir/LinkedErrorFile.cshtml b/src/Razor/test/testassets/LinkedDir/LinkedErrorFile.cshtml new file mode 100644 index 0000000000..2567b2c379 --- /dev/null +++ b/src/Razor/test/testassets/LinkedDir/LinkedErrorFile.cshtml @@ -0,0 +1 @@ +@( \ No newline at end of file diff --git a/src/Razor/test/testassets/LinkedDir/LinkedFile.cshtml b/src/Razor/test/testassets/LinkedDir/LinkedFile.cshtml new file mode 100644 index 0000000000..3611531b13 --- /dev/null +++ b/src/Razor/test/testassets/LinkedDir/LinkedFile.cshtml @@ -0,0 +1 @@ +@DateTime.UtcNow \ No newline at end of file diff --git a/src/Razor/test/testassets/LinkedDir/LinkedFile2.cshtml b/src/Razor/test/testassets/LinkedDir/LinkedFile2.cshtml new file mode 100644 index 0000000000..3611531b13 --- /dev/null +++ b/src/Razor/test/testassets/LinkedDir/LinkedFile2.cshtml @@ -0,0 +1 @@ +@DateTime.UtcNow \ No newline at end of file diff --git a/src/Razor/test/testassets/LinkedDir/LinkedFile3.cshtml b/src/Razor/test/testassets/LinkedDir/LinkedFile3.cshtml new file mode 100644 index 0000000000..3611531b13 --- /dev/null +++ b/src/Razor/test/testassets/LinkedDir/LinkedFile3.cshtml @@ -0,0 +1 @@ +@DateTime.UtcNow \ No newline at end of file diff --git a/src/Razor/test/testassets/MvcWithComponents/Models/ErrorViewModel.cs b/src/Razor/test/testassets/MvcWithComponents/Models/ErrorViewModel.cs new file mode 100644 index 0000000000..df07aa87c0 --- /dev/null +++ b/src/Razor/test/testassets/MvcWithComponents/Models/ErrorViewModel.cs @@ -0,0 +1,11 @@ +using System; + +namespace MvcWithComponents.Models +{ + public class ErrorViewModel + { + public string RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + } +} \ No newline at end of file diff --git a/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj b/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj new file mode 100644 index 0000000000..660a620ff1 --- /dev/null +++ b/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj @@ -0,0 +1,31 @@ + + + + $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + + + + netcoreapp3.0 + + + + + false + + + + + + + + + + + + + + + + + + diff --git a/src/Razor/test/testassets/MvcWithComponents/Program.cs b/src/Razor/test/testassets/MvcWithComponents/Program.cs new file mode 100644 index 0000000000..2011ae9687 --- /dev/null +++ b/src/Razor/test/testassets/MvcWithComponents/Program.cs @@ -0,0 +1,13 @@ + +namespace MvcWithComponents +{ + public class Program + { + public static void Main(string[] args) + { + // Just make sure we have a reference to the MvcShim + var t = typeof(Microsoft.AspNetCore.Mvc.IActionResult); + System.Console.WriteLine(t.FullName); + } + } +} diff --git a/src/Razor/test/testassets/MvcWithComponents/TestComponent.razor b/src/Razor/test/testassets/MvcWithComponents/TestComponent.razor new file mode 100644 index 0000000000..558c8aaa24 --- /dev/null +++ b/src/Razor/test/testassets/MvcWithComponents/TestComponent.razor @@ -0,0 +1 @@ +Hello from component \ No newline at end of file diff --git a/src/Razor/test/testassets/MvcWithComponents/Views/Home/Index.cshtml b/src/Razor/test/testassets/MvcWithComponents/Views/Home/Index.cshtml new file mode 100644 index 0000000000..8832e1ad15 --- /dev/null +++ b/src/Razor/test/testassets/MvcWithComponents/Views/Home/Index.cshtml @@ -0,0 +1,5 @@ +@{ + ViewData["Title"] = "Home Page"; +} + +Hello world! \ No newline at end of file diff --git a/src/Razor/test/testassets/MvcWithComponents/Views/Shared/NavMenu.razor b/src/Razor/test/testassets/MvcWithComponents/Views/Shared/NavMenu.razor new file mode 100644 index 0000000000..d6eede9b18 --- /dev/null +++ b/src/Razor/test/testassets/MvcWithComponents/Views/Shared/NavMenu.razor @@ -0,0 +1,2 @@ +NavMenu content + diff --git a/src/Razor/test/testassets/MvcWithComponents/Views/_ViewImports.cshtml b/src/Razor/test/testassets/MvcWithComponents/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..7e47b2893e --- /dev/null +++ b/src/Razor/test/testassets/MvcWithComponents/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using MvcWithComponents +@using MvcWithComponents.Models +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/MvcWithComponents/Views/_ViewStart.cshtml b/src/Razor/test/testassets/MvcWithComponents/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/src/Razor/test/testassets/MvcWithComponents/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/src/Razor/test/testassets/RazorTest.Introspection.targets b/src/Razor/test/testassets/RazorTest.Introspection.targets new file mode 100644 index 0000000000..a22622b0d6 --- /dev/null +++ b/src/Razor/test/testassets/RazorTest.Introspection.targets @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Razor/test/testassets/SimpleMvc/Models/ErrorViewModel.cs b/src/Razor/test/testassets/SimpleMvc/Models/ErrorViewModel.cs new file mode 100644 index 0000000000..b4aa044914 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Models/ErrorViewModel.cs @@ -0,0 +1,11 @@ +using System; + +namespace SimpleMvc.Models +{ + public class ErrorViewModel + { + public string RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + } +} \ No newline at end of file diff --git a/src/Razor/test/testassets/SimpleMvc/Program.cs b/src/Razor/test/testassets/SimpleMvc/Program.cs new file mode 100644 index 0000000000..e62b11efe5 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Program.cs @@ -0,0 +1,13 @@ + +namespace SimpleMvc +{ + public class Program + { + public static void Main(string[] args) + { + // Just make sure we have a reference to the MvcShim + var t = typeof(Microsoft.AspNetCore.Mvc.IActionResult); + System.Console.WriteLine(t.FullName); + } + } +} diff --git a/src/Razor/test/testassets/SimpleMvc/SimpleMvc.csproj b/src/Razor/test/testassets/SimpleMvc/SimpleMvc.csproj new file mode 100644 index 0000000000..925a8c7194 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/SimpleMvc.csproj @@ -0,0 +1,31 @@ + + + + $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + + + + netcoreapp3.0 + + + + + false + + + + + + + + + + + + + + + + + + diff --git a/src/Razor/test/testassets/SimpleMvc/SimpleTagHelper.cs b/src/Razor/test/testassets/SimpleMvc/SimpleTagHelper.cs new file mode 100644 index 0000000000..7cc52922d9 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/SimpleTagHelper.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; + +namespace SimpleMvc +{ + public class SimpleTagHelper : TagHelper + { + } +} diff --git a/src/Razor/test/testassets/SimpleMvc/Views/Home/About.cshtml b/src/Razor/test/testassets/SimpleMvc/Views/Home/About.cshtml new file mode 100644 index 0000000000..3674e37a86 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Views/Home/About.cshtml @@ -0,0 +1,7 @@ +@{ + ViewData["Title"] = "About"; +} +

@ViewData["Title"]

+

@ViewData["Message"]

+ +

Use this area to provide additional information.

diff --git a/src/Razor/test/testassets/SimpleMvc/Views/Home/Contact.cshtml b/src/Razor/test/testassets/SimpleMvc/Views/Home/Contact.cshtml new file mode 100644 index 0000000000..a11a1867cf --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Views/Home/Contact.cshtml @@ -0,0 +1,17 @@ +@{ + ViewData["Title"] = "Contact"; +} +

@ViewData["Title"]

+

@ViewData["Message"]

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ P: + 425.555.0100 +
+ +
+ Support: Support@example.com
+ Marketing: Marketing@example.com +
diff --git a/src/Razor/test/testassets/SimpleMvc/Views/Home/Index.cshtml b/src/Razor/test/testassets/SimpleMvc/Views/Home/Index.cshtml new file mode 100644 index 0000000000..00afab6a0c --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Views/Home/Index.cshtml @@ -0,0 +1,108 @@ +@{ + ViewData["Title"] = "Home Page"; +} + + + + diff --git a/src/Razor/test/testassets/SimpleMvc/Views/Shared/Error.cshtml b/src/Razor/test/testassets/SimpleMvc/Views/Shared/Error.cshtml new file mode 100644 index 0000000000..ec2ea6bd03 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Views/Shared/Error.cshtml @@ -0,0 +1,22 @@ +@model ErrorViewModel +@{ + ViewData["Title"] = "Error"; +} + +

Error.

+

An error occurred while processing your request.

+ +@if (Model.ShowRequestId) +{ +

+ Request ID: @Model.RequestId +

+} + +

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. +

diff --git a/src/Razor/test/testassets/SimpleMvc/Views/Shared/_Layout.cshtml b/src/Razor/test/testassets/SimpleMvc/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..1a9473e464 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Views/Shared/_Layout.cshtml @@ -0,0 +1,71 @@ + + + + + + @ViewData["Title"] - SimpleMvc + + + + + + + + + + + + +
+ @RenderBody() +
+
+

© 2017 - SimpleMvc

+
+
+ + + + + + + + + + + + + @RenderSection("Scripts", required: false) + + diff --git a/src/Razor/test/testassets/SimpleMvc/Views/Shared/_ValidationScriptsPartial.cshtml b/src/Razor/test/testassets/SimpleMvc/Views/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000000..a699aafa97 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Views/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/src/Razor/test/testassets/SimpleMvc/Views/_ViewImports.cshtml b/src/Razor/test/testassets/SimpleMvc/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..da00289ea5 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using SimpleMvc +@using SimpleMvc.Models +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/SimpleMvc/Views/_ViewStart.cshtml b/src/Razor/test/testassets/SimpleMvc/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/src/Razor/test/testassets/SimpleMvc/wwwroot/css/site.css b/src/Razor/test/testassets/SimpleMvc/wwwroot/css/site.css new file mode 100644 index 0000000000..6b0e6c3ab2 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/wwwroot/css/site.css @@ -0,0 +1,37 @@ +/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\ +for details on configuring this project to bundle and minify static web assets. */ +body { + padding-top: 50px; + padding-bottom: 20px; +} + +/* Wrapping element */ +/* Set some basic padding to keep content from hitting the edges */ +.body-content { + padding-left: 15px; + padding-right: 15px; +} + +/* Carousel */ +.carousel-caption p { + font-size: 20px; + line-height: 1.4; +} + +/* Make .svg files in the carousel display properly in older browsers */ +.carousel-inner .item img[src$=".svg"] { + width: 100%; +} + +/* QR code generator */ +#qrCode { + margin: 15px; +} + +/* Hide/rearrange for smaller screens */ +@media screen and (max-width: 767px) { + /* Hide captions */ + .carousel-caption { + display: none; + } +} diff --git a/src/Razor/test/testassets/SimpleMvc/wwwroot/js/SimpleMvc.js b/src/Razor/test/testassets/SimpleMvc/wwwroot/js/SimpleMvc.js new file mode 100644 index 0000000000..ad51101cd1 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc/wwwroot/js/SimpleMvc.js @@ -0,0 +1 @@ +// This is a test file diff --git a/src/Razor/test/testassets/SimpleMvc21/Models/ErrorViewModel.cs b/src/Razor/test/testassets/SimpleMvc21/Models/ErrorViewModel.cs new file mode 100644 index 0000000000..b4aa044914 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc21/Models/ErrorViewModel.cs @@ -0,0 +1,11 @@ +using System; + +namespace SimpleMvc.Models +{ + public class ErrorViewModel + { + public string RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + } +} \ No newline at end of file diff --git a/src/Razor/test/testassets/SimpleMvc21/Program.cs b/src/Razor/test/testassets/SimpleMvc21/Program.cs new file mode 100644 index 0000000000..39ec364271 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc21/Program.cs @@ -0,0 +1,13 @@ + +namespace SimpleMvc +{ + public class Program + { + public static void Main(string[] args) + { + // Just make sure we have a reference to the MVC 2.1 + var t = typeof(Microsoft.AspNetCore.Mvc.IActionResult); + System.Console.WriteLine(t.FullName); + } + } +} diff --git a/src/Razor/test/testassets/SimpleMvc21/SimpleMvc21.csproj b/src/Razor/test/testassets/SimpleMvc21/SimpleMvc21.csproj new file mode 100644 index 0000000000..2f53950aa6 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc21/SimpleMvc21.csproj @@ -0,0 +1,31 @@ + + + + + + netcoreapp2.1 + + + + + + + false + + + + + + All + + + + + All + + + + diff --git a/src/Razor/test/testassets/SimpleMvc21/Views/Home/About.cshtml b/src/Razor/test/testassets/SimpleMvc21/Views/Home/About.cshtml new file mode 100644 index 0000000000..3674e37a86 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc21/Views/Home/About.cshtml @@ -0,0 +1,7 @@ +@{ + ViewData["Title"] = "About"; +} +

@ViewData["Title"]

+

@ViewData["Message"]

+ +

Use this area to provide additional information.

diff --git a/src/Razor/test/testassets/SimpleMvc21/Views/Home/Index.cshtml b/src/Razor/test/testassets/SimpleMvc21/Views/Home/Index.cshtml new file mode 100644 index 0000000000..00afab6a0c --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc21/Views/Home/Index.cshtml @@ -0,0 +1,108 @@ +@{ + ViewData["Title"] = "Home Page"; +} + + + + diff --git a/src/Razor/test/testassets/SimpleMvc21/Views/Shared/_Layout.cshtml b/src/Razor/test/testassets/SimpleMvc21/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..1a9473e464 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc21/Views/Shared/_Layout.cshtml @@ -0,0 +1,71 @@ + + + + + + @ViewData["Title"] - SimpleMvc + + + + + + + + + + + + +
+ @RenderBody() +
+
+

© 2017 - SimpleMvc

+
+
+ + + + + + + + + + + + + @RenderSection("Scripts", required: false) + + diff --git a/src/Razor/test/testassets/SimpleMvc21/Views/Shared/_ValidationScriptsPartial.cshtml b/src/Razor/test/testassets/SimpleMvc21/Views/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000000..a699aafa97 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc21/Views/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/src/Razor/test/testassets/SimpleMvc21/Views/_ViewImports.cshtml b/src/Razor/test/testassets/SimpleMvc21/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..477d4ba603 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc21/Views/_ViewImports.cshtml @@ -0,0 +1,4 @@ +@using SimpleMvc +@using SimpleMvc.Models +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@namespace SimpleMvc21 diff --git a/src/Razor/test/testassets/SimpleMvc21/Views/_ViewStart.cshtml b/src/Razor/test/testassets/SimpleMvc21/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc21/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/src/Razor/test/testassets/SimpleMvcFSharp/Models/ErrorViewModel.fs b/src/Razor/test/testassets/SimpleMvcFSharp/Models/ErrorViewModel.fs new file mode 100644 index 0000000000..111eba32de --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvcFSharp/Models/ErrorViewModel.fs @@ -0,0 +1,8 @@ +namespace SimpleMvcFSharp + +open System + +type ErrorViewModel private () = + member val RequestId : string = null with get, set + + member val ShowRequestId : bool = true with get, set diff --git a/src/Razor/test/testassets/SimpleMvcFSharp/Program.fs b/src/Razor/test/testassets/SimpleMvcFSharp/Program.fs new file mode 100644 index 0000000000..10f99aa34f --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvcFSharp/Program.fs @@ -0,0 +1,11 @@ +namespace SimpleMvcFSharp + +module Program = + let exitCode = 0 + + [] + let main args = + let t = typeof + System.Console.WriteLine(t.FullName) + + exitCode diff --git a/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj b/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj new file mode 100644 index 0000000000..6f2c4cc5c1 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj @@ -0,0 +1,36 @@ + + + + $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + + + + netcoreapp3.0 + + + + + false + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Razor/test/testassets/SimpleMvcFSharp/Views/Home/About.cshtml b/src/Razor/test/testassets/SimpleMvcFSharp/Views/Home/About.cshtml new file mode 100644 index 0000000000..50476d1fbd --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvcFSharp/Views/Home/About.cshtml @@ -0,0 +1,7 @@ +@{ + ViewData["Title"] = "About"; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +

Use this area to provide additional information.

diff --git a/src/Razor/test/testassets/SimpleMvcFSharp/Views/_ViewImports.cshtml b/src/Razor/test/testassets/SimpleMvcFSharp/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..8df2746fd7 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvcFSharp/Views/_ViewImports.cshtml @@ -0,0 +1,2 @@ +@using SimpleMvcFSharp +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/SimplePages/Areas/Products/Pages/Index.cshtml b/src/Razor/test/testassets/SimplePages/Areas/Products/Pages/Index.cshtml new file mode 100644 index 0000000000..a574e3f403 --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Areas/Products/Pages/Index.cshtml @@ -0,0 +1,107 @@ +@page +@{ + ViewData["Title"] = "Home page"; +} + + + + diff --git a/src/Razor/test/testassets/SimplePages/Areas/Products/Pages/_ViewImports.cshtml b/src/Razor/test/testassets/SimplePages/Areas/Products/Pages/_ViewImports.cshtml new file mode 100644 index 0000000000..6686959c4a --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Areas/Products/Pages/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using SimplePages +@namespace SimplePages.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/SimplePages/Areas/Products/Pages/_ViewStart.cshtml b/src/Razor/test/testassets/SimplePages/Areas/Products/Pages/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Areas/Products/Pages/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/src/Razor/test/testassets/SimplePages/Pages/About.cshtml b/src/Razor/test/testassets/SimplePages/Pages/About.cshtml new file mode 100644 index 0000000000..3c090d15f0 --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Pages/About.cshtml @@ -0,0 +1,9 @@ +@page +@model AboutModel +@{ + ViewData["Title"] = "About"; +} +

@ViewData["Title"]

+

@Model.Message

+ +

Use this area to provide additional information.

diff --git a/src/Razor/test/testassets/SimplePages/Pages/About.cshtml.cs b/src/Razor/test/testassets/SimplePages/Pages/About.cshtml.cs new file mode 100644 index 0000000000..969985072e --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Pages/About.cshtml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace SimplePages.Pages +{ + public class AboutModel : PageModel + { + public string Message { get; set; } + + public void OnGet() + { + Message = "Your application description page."; + } + } +} diff --git a/src/Razor/test/testassets/SimplePages/Pages/Contact.cshtml b/src/Razor/test/testassets/SimplePages/Pages/Contact.cshtml new file mode 100644 index 0000000000..b683c8216c --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Pages/Contact.cshtml @@ -0,0 +1,19 @@ +@page +@model ContactModel +@{ + ViewData["Title"] = "Contact"; +} +

@ViewData["Title"]

+

@Model.Message

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ P: + 425.555.0100 +
+ +
+ Support: Support@example.com
+ Marketing: Marketing@example.com +
diff --git a/src/Razor/test/testassets/SimplePages/Pages/Contact.cshtml.cs b/src/Razor/test/testassets/SimplePages/Pages/Contact.cshtml.cs new file mode 100644 index 0000000000..6444b7e64d --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Pages/Contact.cshtml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace SimplePages.Pages +{ + public class ContactModel : PageModel + { + public string Message { get; set; } + + public void OnGet() + { + Message = "Your contact page."; + } + } +} diff --git a/src/Razor/test/testassets/SimplePages/Pages/Index.cshtml b/src/Razor/test/testassets/SimplePages/Pages/Index.cshtml new file mode 100644 index 0000000000..728fdfc943 --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Pages/Index.cshtml @@ -0,0 +1,108 @@ +@page +@model IndexModel +@{ + ViewData["Title"] = "Home page"; +} + + + + diff --git a/src/Razor/test/testassets/SimplePages/Pages/Index.cshtml.cs b/src/Razor/test/testassets/SimplePages/Pages/Index.cshtml.cs new file mode 100644 index 0000000000..1e507ea24a --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Pages/Index.cshtml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace SimplePages.Pages +{ + public class IndexModel : PageModel + { + public void OnGet() + { + + } + } +} diff --git a/src/Razor/test/testassets/SimplePages/Pages/_Layout.cshtml b/src/Razor/test/testassets/SimplePages/Pages/_Layout.cshtml new file mode 100644 index 0000000000..694a3223d1 --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Pages/_Layout.cshtml @@ -0,0 +1,71 @@ + + + + + + @ViewData["Title"] - SimplePages + + + + + + + + + + + + +
+ @RenderBody() +
+
+

© 2017 - SimplePages

+
+
+ + + + + + + + + + + + + @RenderSection("Scripts", required: false) + + diff --git a/src/Razor/test/testassets/SimplePages/Pages/_ViewImports.cshtml b/src/Razor/test/testassets/SimplePages/Pages/_ViewImports.cshtml new file mode 100644 index 0000000000..6686959c4a --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Pages/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using SimplePages +@namespace SimplePages.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/SimplePages/Pages/_ViewStart.cshtml b/src/Razor/test/testassets/SimplePages/Pages/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Pages/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/src/Razor/test/testassets/SimplePages/Program.cs b/src/Razor/test/testassets/SimplePages/Program.cs new file mode 100644 index 0000000000..16c6459a55 --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/Program.cs @@ -0,0 +1,10 @@ + +namespace SimplePages +{ + public class Program + { + public static void Main(string[] args) + { + } + } +} diff --git a/src/Razor/test/testassets/SimplePages/SimplePages.csproj b/src/Razor/test/testassets/SimplePages/SimplePages.csproj new file mode 100644 index 0000000000..23f9ef1c2e --- /dev/null +++ b/src/Razor/test/testassets/SimplePages/SimplePages.csproj @@ -0,0 +1,31 @@ + + + + $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + + + + netcoreapp3.0 + + + + + false + + + + + + + + + + + + + + + + + + diff --git a/src/Shared/RazorShared/RazorDiagnosticJsonConverter.cs b/src/Shared/RazorShared/RazorDiagnosticJsonConverter.cs new file mode 100644 index 0000000000..029530c471 --- /dev/null +++ b/src/Shared/RazorShared/RazorDiagnosticJsonConverter.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 Microsoft.AspNetCore.Razor.Language; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.VisualStudio.LanguageServices.Razor.Serialization +{ + internal class RazorDiagnosticJsonConverter : JsonConverter + { + public static readonly RazorDiagnosticJsonConverter Instance = new RazorDiagnosticJsonConverter(); + private const string RazorDiagnosticMessageKey = "Message"; + + public override bool CanConvert(Type objectType) + { + return typeof(RazorDiagnostic).IsAssignableFrom(objectType); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType != JsonToken.StartObject) + { + return null; + } + + var diagnostic = JObject.Load(reader); + var span = diagnostic[nameof(RazorDiagnostic.Span)].Value(); + var absoluteIndex = span[nameof(SourceSpan.AbsoluteIndex)].Value(); + var lineIndex = span[nameof(SourceSpan.LineIndex)].Value(); + var characterIndex = span[nameof(SourceSpan.CharacterIndex)].Value(); + var length = span[nameof(SourceSpan.Length)].Value(); + var filePath = span[nameof(SourceSpan.FilePath)].Value(); + var message = diagnostic[RazorDiagnosticMessageKey].Value(); + var id = diagnostic[nameof(RazorDiagnostic.Id)].Value(); + var severity = diagnostic[nameof(RazorDiagnostic.Severity)].Value(); + + var descriptor = new RazorDiagnosticDescriptor(id, () => message, (RazorDiagnosticSeverity)severity); + var sourceSpan = new SourceSpan(filePath, absoluteIndex, lineIndex, characterIndex, length); + + return RazorDiagnostic.Create(descriptor, sourceSpan); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var diagnostic = (RazorDiagnostic)value; + + writer.WriteStartObject(); + WriteProperty(writer, nameof(RazorDiagnostic.Id), diagnostic.Id); + WriteProperty(writer, nameof(RazorDiagnostic.Severity), (int)diagnostic.Severity); + WriteProperty(writer, RazorDiagnosticMessageKey, diagnostic.GetMessage()); + + writer.WritePropertyName(nameof(RazorDiagnostic.Span)); + serializer.Serialize(writer, diagnostic.Span); + + writer.WriteEndObject(); + } + + private void WriteProperty(JsonWriter writer, string key, T value) + { + writer.WritePropertyName(key); + writer.WriteValue(value); + } + } +} From 7df54be754fa7717e4d5792d26091fb335def249 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Sun, 2 Dec 2018 00:25:55 +0000 Subject: [PATCH 002/337] Merged PR 304: Enable local builds with dotnet/Arcade [WIP] Enable local builds with dotnet/Arcade \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/409618521f688ae106e0aa87a444445c4a672980 --- ...ore.Mvc.Razor.Extensions.Version1_X.csproj | 1 + ...vc.Razor.Extensions.Version1_X.Test.csproj | 5 +- ...ore.Mvc.Razor.Extensions.Version2_X.csproj | 1 + ...vc.Razor.Extensions.Version2_X.Test.csproj | 5 +- ...spNetCore.Mvc.Razor.Extensions.Test.csproj | 5 +- .../src/Properties/AssemblyInfo.cs | 2 +- .../Microsoft.AspNetCore.Razor.Tools.csproj | 1 + ...crosoft.AspNetCore.Razor.Tools.Test.csproj | 3 - .../src/Properties/AssemblyInfo.cs | 2 +- .../Microsoft.CodeAnalysis.Razor.Test.csproj | 3 - .../src/Microsoft.NET.Sdk.Razor.csproj | 17 +++--- .../test/BuildVariables.cs.template | 15 ----- .../BuildServerIntegrationTest.cs | 4 +- .../test/IntegrationTests/ProjectDirectory.cs | 30 ++++++++-- .../test/Microsoft.NET.Sdk.Razor.Test.csproj | 58 +++++++++++++++++-- .../Language/TestProject.cs | 27 ++++++--- .../TestCompilation.cs | 24 +++++++- .../AppWithP2PReference.csproj | 2 +- .../ClassLibrary/ClassLibrary.csproj | 2 +- .../ClassLibrary2/ClassLibrary2.csproj | 2 +- .../test/testassets/Directory.Build.props | 6 +- .../LargeProject/LargeProject.csproj | 2 +- .../MvcWithComponents.csproj | 2 +- .../testassets/SimpleMvc/SimpleMvc.csproj | 2 +- .../SimpleMvcFSharp/SimpleMvcFSharp.fsproj | 2 +- .../testassets/SimplePages/SimplePages.csproj | 2 +- 26 files changed, 151 insertions(+), 74 deletions(-) delete mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/BuildVariables.cs.template diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj index 0d61d12b26..f949a8e8ca 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj @@ -5,6 +5,7 @@ netstandard2.0 $(PackageTags);aspnetcoremvc false + false diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj index 808b0f3eea..c6a894ee1f 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj @@ -22,10 +22,7 @@ - - - @@ -42,7 +39,7 @@ - + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj index e77d4c3837..ce96dad3fe 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj @@ -4,6 +4,7 @@ ASP.NET Core design time hosting infrastructure for the Razor view engine. netstandard2.0 $(PackageTags);aspnetcoremvc + false diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj index 0fd06dcdfd..82d2483d0b 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj @@ -22,10 +22,7 @@ - - - @@ -44,7 +41,7 @@ - + diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj index 86d975d404..35bf3f778c 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj @@ -22,10 +22,7 @@ - - - @@ -43,7 +40,7 @@ - + diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs index b749fc7ce3..4eb3dedaa1 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs @@ -11,7 +11,7 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Remote.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] -[assembly: InternalsVisibleTo("Microsoft.VisualStudio.RazorExtension, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] +[assembly: InternalsVisibleTo("RazorDeveloperTools, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Microsoft.AspNetCore.Razor.Tools.csproj b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Microsoft.AspNetCore.Razor.Tools.csproj index a3ab14c41f..cec75baae8 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Microsoft.AspNetCore.Razor.Tools.csproj +++ b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Microsoft.AspNetCore.Razor.Tools.csproj @@ -9,6 +9,7 @@ false + false false diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Microsoft.AspNetCore.Razor.Tools.Test.csproj b/src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Microsoft.AspNetCore.Razor.Tools.Test.csproj index 06aacff48d..48976ae144 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Microsoft.AspNetCore.Razor.Tools.Test.csproj +++ b/src/Razor/Microsoft.AspNetCore.Razor.Tools/test/Microsoft.AspNetCore.Razor.Tools.Test.csproj @@ -12,10 +12,7 @@ - - - diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/AssemblyInfo.cs index 2da745cbad..942ae946b0 100644 --- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/AssemblyInfo.cs +++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/AssemblyInfo.cs @@ -13,5 +13,5 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Remote.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] -[assembly: InternalsVisibleTo("Microsoft.VisualStudio.RazorExtension, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] +[assembly: InternalsVisibleTo("RazorDeveloperTools, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/test/Microsoft.CodeAnalysis.Razor.Test.csproj b/src/Razor/Microsoft.CodeAnalysis.Razor/test/Microsoft.CodeAnalysis.Razor.Test.csproj index d95d005405..fa77866791 100644 --- a/src/Razor/Microsoft.CodeAnalysis.Razor/test/Microsoft.CodeAnalysis.Razor.Test.csproj +++ b/src/Razor/Microsoft.CodeAnalysis.Razor/test/Microsoft.CodeAnalysis.Razor.Test.csproj @@ -22,10 +22,7 @@ - - - diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj index 6f6d4be734..01d37b1b8d 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj @@ -6,8 +6,11 @@ Microsoft.NET.Sdk.Razor.Tasks $(MSBuildProjectName).nuspec true - bin\$(Configuration)\sdk-output\ - + $(ArtifactsBinDir)Microsoft.NET.Sdk.Razor\$(Configuration)\sdk-output\ + + + + $(NoWarn);NU5100 @@ -38,18 +41,18 @@ - + - - + + @@ -70,7 +73,7 @@ - + diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/BuildVariables.cs.template b/src/Razor/Microsoft.NET.Sdk.Razor/test/BuildVariables.cs.template deleted file mode 100644 index 4b0b995bc6..0000000000 --- a/src/Razor/Microsoft.NET.Sdk.Razor/test/BuildVariables.cs.template +++ /dev/null @@ -1,15 +0,0 @@ -// 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.Design.IntegrationTests -{ - internal static partial class BuildVariables - { - static partial void InitializeVariables() - { - _msBuildPath = @"${MSBuildLocation}"; - _microsoftNETCoreApp30PackageVersion = "${MicrosoftNETCoreApp30PackageVersion}"; - _netStandardLibrary20PackageVersion = "${NETStandardLibrary20PackageVersion}"; - } - } -} diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerIntegrationTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerIntegrationTest.cs index 30330b0a5f..cad1a57355 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerIntegrationTest.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerIntegrationTest.cs @@ -1,6 +1,7 @@ // 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.IO; using System.Threading.Tasks; @@ -150,7 +151,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests // when we don't explicitly specify a pipe name. // Publish rzc tool to a temporary path. This is the location based on which the pipe name is generated. - var solutionRoot = TestPathUtilities.GetSolutionRootDirectory("Razor"); + var repositoryRoot = ProjectDirectory.SearchUp(AppContext.BaseDirectory, "global.json"); + var solutionRoot = Path.Combine(repositoryRoot, "src", "Razor"); var toolAssemblyDirectory = Path.Combine(solutionRoot, "src", "Microsoft.AspNetCore.Razor.Tools"); var toolAssemblyPath = Path.Combine(toolAssemblyDirectory, "Microsoft.AspNetCore.Razor.Tools.csproj"); var projectDirectory = new TestProjectDirectory(solutionRoot, toolAssemblyDirectory, toolAssemblyPath); diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/ProjectDirectory.cs b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/ProjectDirectory.cs index 3cdb16592a..6a73ab84cd 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/ProjectDirectory.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/ProjectDirectory.cs @@ -30,12 +30,13 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests throw new InvalidOperationException($"{destinationPath} should be empty"); } - var solutionRoot = TestPathUtilities.GetSolutionRootDirectory("Razor"); - if (solutionRoot == null) + var repositoryRoot = SearchUp(AppContext.BaseDirectory, "global.json"); + if (repositoryRoot == null) { - throw new InvalidOperationException("Could not find solution root."); + throw new InvalidOperationException("Could not find repository root."); } + var solutionRoot = Path.Combine(repositoryRoot, "src", "Razor"); var binariesRoot = Path.GetDirectoryName(typeof(ProjectDirectory).Assembly.Location); foreach (var project in new string[] { originalProjectName, }.Concat(additionalProjects)) @@ -72,7 +73,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests var newProjectFilePath = Path.Combine(directoryPath, targetProjectName + extension); File.Move(oldProjectFilePath, newProjectFilePath); - CopyGlobalJson(solutionRoot, destinationPath); + CopyGlobalJson(repositoryRoot, destinationPath); return new ProjectDirectory( destinationPath, @@ -126,9 +127,9 @@ $@" }); } - void CopyGlobalJson(string solutionRoot, string projectRoot) + void CopyGlobalJson(string repositoryRoot, string projectRoot) { - var srcGlobalJson = Path.Combine(solutionRoot, "global.json"); + var srcGlobalJson = Path.Combine(repositoryRoot, "global.json"); if (!File.Exists(srcGlobalJson)) { throw new InvalidOperationException("global.json at the root of the repository could not be found. Run './build /t:Noop' at the repository root and re-run these tests."); @@ -183,5 +184,22 @@ $@" } } } + + public static string SearchUp(string baseDirectory, string fileName) + { + var directoryInfo = new DirectoryInfo(baseDirectory); + do + { + var fileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, fileName)); + if (fileInfo.Exists) + { + return fileInfo.DirectoryName; + } + directoryInfo = directoryInfo.Parent; + } + while (directoryInfo.Parent != null); + + throw new Exception($"File {fileName} could not be found in {baseDirectory} or its parent directories."); + } } } diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/Microsoft.NET.Sdk.Razor.Test.csproj b/src/Razor/Microsoft.NET.Sdk.Razor/test/Microsoft.NET.Sdk.Razor.Test.csproj index 7cabd6927a..9aee6cab0f 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/test/Microsoft.NET.Sdk.Razor.Test.csproj +++ b/src/Razor/Microsoft.NET.Sdk.Razor/test/Microsoft.NET.Sdk.Razor.Test.csproj @@ -13,7 +13,6 @@ true $(MSBuildProjectDirectory)\obj\BuildVariables.generated.cs - EnsureBuildVariablesGeneratedFile;$(CompileDependsOn) @@ -22,11 +21,9 @@ + - - - @@ -47,8 +44,57 @@ - - + + $(IntermediateOutputPath)BuildVariables.generated.cs + + + + + + + + + + + <_DesktopMSBuildPath Condition="'$(OS)' == 'Windows_NT' and Exists('$(_VSInstallDir)\MSBuild\Current\Bin\msbuild.exe')">$(_VSInstallDir)\MSBuild\Current\Bin\msbuild.exe + <_DesktopMSBuildPath Condition="'$(OS)' == 'Windows_NT' and Exists('$(_VSInstallDir)\MSBuild\15.0\Bin\msbuild.exe')">$(_VSInstallDir)\MSBuild\15.0\Bin\msbuild.exe + <_Content> + + + + + + + + + + false + + + + diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestProject.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestProject.cs index 4cc8d85d61..1f0d079cb9 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestProject.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestProject.cs @@ -3,7 +3,6 @@ using System; using System.IO; -using Microsoft.AspNetCore.Testing; namespace Microsoft.AspNetCore.Razor.Language { @@ -11,18 +10,32 @@ namespace Microsoft.AspNetCore.Razor.Language { public static string GetProjectDirectory(Type type) { - var solutionDir = TestPathUtilities.GetSolutionRootDirectory("Razor"); - + var repoRoot = SearchUp(AppContext.BaseDirectory, "global.json"); var assemblyName = type.Assembly.GetName().Name; - var projectDirectory = Path.Combine(solutionDir, "test", assemblyName); + var projectDirectory = Path.Combine(repoRoot, "src", "Razor", "test", assemblyName); if (!Directory.Exists(projectDirectory)) { - throw new InvalidOperationException( -$@"Could not locate project directory for type {type.FullName}. -Directory probe path: {projectDirectory}."); + throw new InvalidOperationException($@"Could not locate project directory for type {type.FullName}. Directory probe path: {projectDirectory}."); } return projectDirectory; } + + private static string SearchUp(string baseDirectory, string fileName) + { + var directoryInfo = new DirectoryInfo(baseDirectory); + do + { + var fileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, fileName)); + if (fileInfo.Exists) + { + return fileInfo.DirectoryName; + } + directoryInfo = directoryInfo.Parent; + } + while (directoryInfo.Parent != null); + + throw new Exception($"File {fileName} could not be found in {baseDirectory} or its parent directories."); + } } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/TestCompilation.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/TestCompilation.cs index ffa7fd66d4..a3ae5fbed3 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/TestCompilation.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/TestCompilation.cs @@ -23,13 +23,35 @@ namespace Microsoft.CodeAnalysis var dependencyContext = DependencyContext.Load(assembly); var metadataReferences = dependencyContext.CompileLibraries - .SelectMany(l => l.ResolveReferencePaths()) + .SelectMany(l => ResolvePaths(l)) .Select(assemblyPath => MetadataReference.CreateFromFile(assemblyPath)) .ToArray(); return metadataReferences; } + private static IEnumerable ResolvePaths(CompilationLibrary library) + { + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + for (var i = 0; i < assemblies.Length; i++) + { + if (assemblies[i].GetName().Name == library.Name) + { + return new[] { assemblies[i].Location }; + } + } + + try + { + return library.ResolveReferencePaths(); + } + catch (InvalidOperationException) + { + } + + return Array.Empty(); + } + public static string AssemblyName => "TestAssembly"; public static CSharpCompilation Create(Assembly assembly, SyntaxTree syntaxTree = null) diff --git a/src/Razor/test/testassets/AppWithP2PReference/AppWithP2PReference.csproj b/src/Razor/test/testassets/AppWithP2PReference/AppWithP2PReference.csproj index 10866769b7..5fe34308bc 100644 --- a/src/Razor/test/testassets/AppWithP2PReference/AppWithP2PReference.csproj +++ b/src/Razor/test/testassets/AppWithP2PReference/AppWithP2PReference.csproj @@ -1,7 +1,7 @@ - $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ diff --git a/src/Razor/test/testassets/ClassLibrary/ClassLibrary.csproj b/src/Razor/test/testassets/ClassLibrary/ClassLibrary.csproj index 717524a947..3325932c1e 100644 --- a/src/Razor/test/testassets/ClassLibrary/ClassLibrary.csproj +++ b/src/Razor/test/testassets/ClassLibrary/ClassLibrary.csproj @@ -1,7 +1,7 @@ - $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ diff --git a/src/Razor/test/testassets/ClassLibrary2/ClassLibrary2.csproj b/src/Razor/test/testassets/ClassLibrary2/ClassLibrary2.csproj index 2576345aa3..4337c0f72c 100644 --- a/src/Razor/test/testassets/ClassLibrary2/ClassLibrary2.csproj +++ b/src/Razor/test/testassets/ClassLibrary2/ClassLibrary2.csproj @@ -1,7 +1,7 @@ - $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ diff --git a/src/Razor/test/testassets/Directory.Build.props b/src/Razor/test/testassets/Directory.Build.props index 8020d32ee0..4c86b8bd41 100644 --- a/src/Razor/test/testassets/Directory.Build.props +++ b/src/Razor/test/testassets/Directory.Build.props @@ -6,10 +6,10 @@ $([MSBuild]::EnsureTrailingSlash('$(SolutionRoot)')) - $(SolutionRoot)src\Microsoft.NET.Sdk.Razor\ + $(SolutionRoot)..\..\artifacts\bin\Microsoft.NET.Sdk.Razor\ - $(RazorSdkProjectDirectory)build\netstandard2.0\Sdk.Razor.CurrentVersion.props - $(RazorSdkProjectDirectory)build\netstandard2.0\Sdk.Razor.CurrentVersion.targets + $(SolutionRoot)src\Microsoft.NET.Sdk.Razor\build\netstandard2.0\Sdk.Razor.CurrentVersion.props + $(SolutionRoot)src\Microsoft.NET.Sdk.Razor\build\netstandard2.0\Sdk.Razor.CurrentVersion.targets diff --git a/src/Razor/test/testassets/LargeProject/LargeProject.csproj b/src/Razor/test/testassets/LargeProject/LargeProject.csproj index 5f755a4dfd..0d61cb941b 100644 --- a/src/Razor/test/testassets/LargeProject/LargeProject.csproj +++ b/src/Razor/test/testassets/LargeProject/LargeProject.csproj @@ -1,7 +1,7 @@ - $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ diff --git a/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj b/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj index 660a620ff1..723b5fa1d1 100644 --- a/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj +++ b/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj @@ -1,7 +1,7 @@ - $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ diff --git a/src/Razor/test/testassets/SimpleMvc/SimpleMvc.csproj b/src/Razor/test/testassets/SimpleMvc/SimpleMvc.csproj index 925a8c7194..0b62bda87c 100644 --- a/src/Razor/test/testassets/SimpleMvc/SimpleMvc.csproj +++ b/src/Razor/test/testassets/SimpleMvc/SimpleMvc.csproj @@ -1,7 +1,7 @@ - $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ diff --git a/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj b/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj index 6f2c4cc5c1..3e409f1d78 100644 --- a/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj +++ b/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj @@ -1,7 +1,7 @@  - $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ diff --git a/src/Razor/test/testassets/SimplePages/SimplePages.csproj b/src/Razor/test/testassets/SimplePages/SimplePages.csproj index 23f9ef1c2e..304df87d0e 100644 --- a/src/Razor/test/testassets/SimplePages/SimplePages.csproj +++ b/src/Razor/test/testassets/SimplePages/SimplePages.csproj @@ -1,7 +1,7 @@ - $(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\ + $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ From 6fa46903e2cc9ebc0ea43508941ccff73bf6e6b9 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Wed, 28 Nov 2018 12:32:14 -0800 Subject: [PATCH 003/337] Fix DevDiv 736427 When a user builds a 2.1 or 2.2 project with a 3.0 they can get an error due to invalid command line options from rzc. What happens is that the 3.0 tasks (which are a singleton) are talking to the 2.X build tool (which is NOT a singleton). Recently some changes were make to the 3.0 tasks which caused this bug because it did not properly accomodate downlevel versions of rzc. We have an integration test for this scenario for but the regression was not detected, so obviously something is wrong with the test setup. I'll investigate that separately. (cherry picked from commit dotnet/aspnetcore-tooling@1aace2b6c799108ee4b99e7a714b210e01732be5) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/d2654d0847cc90350d37dcb36ce0ffb4264519e0 --- .../src/RazorGenerate.cs | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/RazorGenerate.cs b/src/Razor/Microsoft.NET.Sdk.Razor/src/RazorGenerate.cs index 61246c8484..07892cfa38 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/RazorGenerate.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/RazorGenerate.cs @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Razor.Tasks public ITaskItem[] Configuration { get; set; } [Required] - public ITaskItem[] Extensions { get; set; } + public ITaskItem[] Extensions { get; set; } [Required] public ITaskItem[] Sources { get; set; } @@ -90,6 +90,14 @@ namespace Microsoft.AspNetCore.Razor.Tasks builder.AppendLine(Command); + // We might be talking to a downlevel version of the command line tool, which doesn't + // understand certain parameters. Assume 2.1 if we can't parse the version because 2.1 + // 2.2 are the releases that have command line tool delivered by a package. + if (!System.Version.TryParse(Version, out var parsedVersion)) + { + parsedVersion = new System.Version(2, 1); + } + for (var i = 0; i < Sources.Length; i++) { var input = Sources[i]; @@ -103,11 +111,15 @@ namespace Microsoft.AspNetCore.Razor.Tasks var outputPath = Path.Combine(ProjectRoot, input.GetMetadata(GeneratedOutput)); builder.AppendLine(outputPath); - var kind = input.GetMetadata(DocumentKind); - if (!string.IsNullOrEmpty(kind)) + // Added in 3.0 + if (parsedVersion.Major >= 3) { - builder.AppendLine("-k"); - builder.AppendLine(kind); + var kind = input.GetMetadata(DocumentKind); + if (!string.IsNullOrEmpty(kind)) + { + builder.AppendLine("-k"); + builder.AppendLine(kind); + } } } @@ -123,7 +135,8 @@ namespace Microsoft.AspNetCore.Razor.Tasks builder.AppendLine("-c"); builder.AppendLine(Configuration[0].GetMetadata(Identity)); - if (GenerateDeclaration) + // Added in 3.0 + if (parsedVersion.Major >= 3 && GenerateDeclaration) { builder.AppendLine("--generate-declaration"); } @@ -152,4 +165,4 @@ namespace Microsoft.AspNetCore.Razor.Tasks return true; } } -} +} \ No newline at end of file From 5bb16b1a14196f3d45f33fc6d490c0c8ec031e3e Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Tue, 20 Nov 2018 17:16:07 -0800 Subject: [PATCH 004/337] Refactored Html parser - part 1 (cherry picked from commit dotnet/aspnetcore-tooling@31f53d44b508bef7e3d25b70019dfb2ca64fd5b9) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/b154e53f06106cad9772d13dbe2ec1702b609b7f --- .../src/Legacy/DirectiveHtmlTokenizer.cs | 7 +- .../src/Legacy/HtmlMarkupParser.Legacy.cs | 1745 +++++++++++++ .../src/Legacy/HtmlMarkupParser.cs | 2258 +++++------------ .../src/Legacy/ParserContext.cs | 2 + .../src/Legacy/ParserHelpers.cs | 21 + .../src/Legacy/ParserState.cs | 23 + .../src/Legacy/TokenizerBackedParser.cs | 21 +- .../src/Syntax/SyntaxNodeExtensions.cs | 23 +- 8 files changed, 2408 insertions(+), 1692 deletions(-) create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.Legacy.cs create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ParserState.cs diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveHtmlTokenizer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveHtmlTokenizer.cs index 4921c8aa1e..7c69a1c3b8 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveHtmlTokenizer.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/DirectiveHtmlTokenizer.cs @@ -9,6 +9,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy internal class DirectiveHtmlTokenizer : HtmlTokenizer { private bool _visitedFirstTokenStart = false; + private SourceLocation _firstTokenVisitLocation = SourceLocation.Undefined; public DirectiveHtmlTokenizer(ITextDocument source) : base(source) { @@ -16,10 +17,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy protected override StateResult Dispatch() { + var location = CurrentLocation; var result = base.Dispatch(); if (result.Result != null && IsValidTokenType(result.Result.Kind)) { _visitedFirstTokenStart = true; + _firstTokenVisitLocation = location; } return result; @@ -31,8 +34,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Debug.Assert(Buffer.Length == 0); StartToken(); - if (EndOfFile || _visitedFirstTokenStart) + if (EndOfFile || (_visitedFirstTokenStart && _firstTokenVisitLocation != CurrentLocation)) { + // We also need to make sure we are currently past the position where we found the first token. + // If the position is equal, that means the parser put the token back for later parsing. return null; } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.Legacy.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.Legacy.cs new file mode 100644 index 0000000000..ac7b174c7f --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.Legacy.cs @@ -0,0 +1,1745 @@ +// 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.Diagnostics; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + internal partial class HtmlMarkupParser : TokenizerBackedParser + { + private SourceLocation _lastTagStart = SourceLocation.Zero; + private SyntaxToken _bufferedOpenAngle; + + private bool CaseSensitive { get; set; } + + private StringComparison Comparison + { + get { return CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; } + } + + // Special tags include " As we will be treating this as a comment ending, there is no need to handle this case at all. + // 2.2.3 "--!>" + // 2.3 nor end with the string "" + + if (CurrentToken.Kind != SyntaxKind.DoubleHyphen) + { + return false; + } + + // Check condition 2.1 + if (NextIs(SyntaxKind.CloseAngle) || NextIs(next => IsHyphen(next) && NextIs(SyntaxKind.CloseAngle))) + { + return false; + } + + // Check condition 2.2 + var isValidComment = false; + LookaheadUntil((token, prevTokens) => + { + if (token.Kind == SyntaxKind.DoubleHyphen) + { + if (NextIs(SyntaxKind.CloseAngle)) + { + // Check condition 2.3: We're at the end of a comment. Check to make sure the text ending is allowed. + isValidComment = !IsCommentContentEndingInvalid(prevTokens); + return true; + } + else if (NextIs(ns => IsHyphen(ns) && NextIs(SyntaxKind.CloseAngle))) + { + // Check condition 2.3: we're at the end of a comment, which has an extra dash. + // Need to treat the dash as part of the content and check the ending. + // However, that case would have already been checked as part of check from 2.2.1 which + // would already fail this iteration and we wouldn't get here + isValidComment = true; + return true; + } + else if (NextIs(ns => ns.Kind == SyntaxKind.Bang && NextIs(SyntaxKind.CloseAngle))) + { + // This is condition 2.2.3 + isValidComment = false; + return true; + } + } + else if (token.Kind == SyntaxKind.OpenAngle) + { + // Checking condition 2.2.1 + if (NextIs(ns => ns.Kind == SyntaxKind.Bang && NextIs(SyntaxKind.DoubleHyphen))) + { + isValidComment = false; + return true; + } + } + + return false; + }); + + return isValidComment; + } + + private bool TryParseCData(in SyntaxListBuilder builder) + { + if (CurrentToken.Kind == SyntaxKind.Text && string.Equals(CurrentToken.Content, "cdata", StringComparison.OrdinalIgnoreCase)) + { + if (AcceptAndMoveNext()) + { + if (CurrentToken.Kind == SyntaxKind.LeftBracket) + { + return LegacyAcceptTokenUntilAll(builder, SyntaxKind.RightBracket, SyntaxKind.RightBracket, SyntaxKind.CloseAngle); + } + } + } + + return false; + } + + private bool TryParseXmlPI(in SyntaxListBuilder builder) + { + // Accept "?" + Assert(SyntaxKind.QuestionMark); + AcceptAndMoveNext(); + return LegacyAcceptTokenUntilAll(builder, SyntaxKind.QuestionMark, SyntaxKind.CloseAngle); + } + + private void SkipToEndScriptAndParseCode(in SyntaxListBuilder builder, AcceptedCharactersInternal endTagAcceptedCharacters = AcceptedCharactersInternal.Any) + { + // Special case for + + + + + + + + + + @RenderSection("Scripts", required: false) + + diff --git a/src/Razor/test/testassets/SimpleMvc11/Views/_ViewImports.cshtml b/src/Razor/test/testassets/SimpleMvc11/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..ab07b6cfbc --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc11/Views/_ViewImports.cshtml @@ -0,0 +1,2 @@ +@using SimpleMvc11 +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Razor/test/testassets/SimpleMvc11/Views/_ViewStart.cshtml b/src/Razor/test/testassets/SimpleMvc11/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc11/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} From ebd37599b610bccc03d0b1d25dddd7e60c6c1c1c Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Tue, 4 Dec 2018 13:48:23 -0800 Subject: [PATCH 011/337] PR feedback \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/d38687acf2de2ba43765303fb6bfd6f2ad97d566 --- .../src/Microsoft.NET.Sdk.Razor.csproj | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj index 01d37b1b8d..2c7c8b4de2 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj @@ -58,26 +58,8 @@ - - - - - - - - - - - - - - - - - - true id=$(MSBuildProjectName); version=$(PackageVersion); From ad0f2a5af45f7dc1f48311db3dffd1288fb2c47b Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Tue, 4 Dec 2018 16:04:20 -0800 Subject: [PATCH 012/337] Group HTML tags (dotnet/aspnetcore-tooling#6) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/a2d1ac4cea8c2b77efd3a5a4686bf85466e5ef6c --- .../src/ClassifiedSpanRewriter.cs | 4 +- .../src/ClassifiedSpanVisitor.cs | 9 +- .../src/Legacy/RazorParser.cs | 8 +- .../src/Legacy/TagHelperBlockRewriter.cs | 8 +- .../src/Legacy/TagHelperParseTreeRewriter.cs | 181 ++++++++++---- .../Syntax.xml.Internal.Generated.cs | 230 +++++++++++++++++- .../Generated/Syntax.xml.Main.Generated.cs | 70 +++++- .../Generated/Syntax.xml.Syntax.Generated.cs | 160 +++++++++++- .../src/Syntax/MarkupElementRewriter.cs | 87 +++---- .../src/Syntax/Syntax.xml | 12 +- .../src/Syntax/SyntaxKind.cs | 2 + .../src/Syntax/SyntaxNodeExtensions.cs | 68 ++---- .../src/Syntax/SyntaxSerializer.cs | 3 +- .../Language/Legacy/ParserTestBase.cs | 10 + .../Language/Legacy/SyntaxNodeWriter.cs | 3 +- 15 files changed, 674 insertions(+), 181 deletions(-) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanRewriter.cs index dedb8c22fd..724203bd0a 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanRewriter.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Razor.Language { internal class ClassifiedSpanRewriter : SyntaxRewriter { - public override SyntaxNode VisitMarkupTagBlock(MarkupTagBlockSyntax node) + public override SyntaxNode VisitMarkupStartTag(MarkupStartTagSyntax node) { SpanContext latestSpanContext = null; var newChildren = SyntaxListBuilder.Create(); @@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Razor.Language AddLiteralIfExists(); - return SyntaxFactory.MarkupTagBlock(newChildren.ToList()).Green.CreateRed(node.Parent, node.Position); + return SyntaxFactory.MarkupStartTag(newChildren.ToList()).Green.CreateRed(node.Parent, node.Position); void AddLiteralIfExists() { diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs index 416765c992..f6711c0ed5 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs @@ -106,9 +106,14 @@ namespace Microsoft.AspNetCore.Razor.Language base.VisitMarkupTagHelperAttributeValue(node); } - public override void VisitMarkupTagBlock(MarkupTagBlockSyntax node) + public override void VisitMarkupStartTag(MarkupStartTagSyntax node) { - WriteBlock(node, BlockKindInternal.Tag, base.VisitMarkupTagBlock); + WriteBlock(node, BlockKindInternal.Tag, base.VisitMarkupStartTag); + } + + public override void VisitMarkupEndTag(MarkupEndTagSyntax node) + { + WriteBlock(node, BlockKindInternal.Tag, base.VisitMarkupEndTag); } public override void VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/RazorParser.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/RazorParser.cs index c840bcb707..0caff21144 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/RazorParser.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/RazorParser.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.Razor.Language.Syntax; namespace Microsoft.AspNetCore.Razor.Language.Legacy { @@ -41,7 +42,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var diagnostics = context.ErrorSink.Errors; var root = markupParser.ParseDocument().CreateRed(); - return RazorSyntaxTree.Create(root, source, diagnostics, Options); + + var syntaxTree = RazorSyntaxTree.Create(root, source, diagnostics, Options); + + // Group markup elements + syntaxTree = MarkupElementRewriter.AddMarkupElements(syntaxTree); + return syntaxTree; } } } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs index 4c11269695..fefcf4aeee 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs @@ -10,13 +10,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { internal static class TagHelperBlockRewriter { - private static readonly string StringTypeName = typeof(string).FullName; - public static MarkupTagHelperStartTagSyntax Rewrite( string tagName, bool validStructure, RazorParserFeatureFlags featureFlags, - MarkupTagBlockSyntax tag, + MarkupStartTagSyntax tag, TagHelperBinding bindingResult, ErrorSink errorSink, RazorSourceDocument source) @@ -28,7 +26,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } public static TagMode GetTagMode( - MarkupTagBlockSyntax tagBlock, + MarkupStartTagSyntax tagBlock, TagHelperBinding bindingResult, ErrorSink errorSink) { @@ -57,7 +55,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy private static SyntaxList GetRewrittenChildren( string tagName, bool validStructure, - MarkupTagBlockSyntax tagBlock, + MarkupStartTagSyntax tagBlock, TagHelperBinding bindingResult, RazorParserFeatureFlags featureFlags, ErrorSink errorSink, diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs index 18b1cf5c4d..ca0bc08809 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs @@ -15,7 +15,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy public static RazorSyntaxTree Rewrite(RazorSyntaxTree syntaxTree, string tagHelperPrefix, IEnumerable descriptors) { var errorSink = new ErrorSink(); - syntaxTree = MarkupElementRewriter.AddMarkupElements(syntaxTree); var rewriter = new Rewriter( syntaxTree.Source, @@ -33,8 +32,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var diagnostics = CombineErrors(syntaxTree.Diagnostics, errorList).OrderBy(error => error.Span.AbsoluteIndex); var newSyntaxTree = RazorSyntaxTree.Create(rewritten, syntaxTree.Source, diagnostics, syntaxTree.Options); - newSyntaxTree = MarkupElementRewriter.RemoveMarkupElements(newSyntaxTree); - return newSyntaxTree; } @@ -103,7 +100,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy TagHelperInfo tagHelperInfo = null; // Visit the start tag. - var startTag = (MarkupTagBlockSyntax)Visit(node.StartTag); + var startTag = (MarkupStartTagSyntax)Visit(node.StartTag); if (startTag != null) { var tagName = startTag.GetTagName(); @@ -145,7 +142,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy else { // Non-TagHelper tag. - ValidateParentAllowsPlainTag(startTag); + ValidateParentAllowsPlainStartTag(startTag); if (!startTag.IsSelfClosing() && !startTag.IsVoidElement()) { @@ -159,7 +156,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var body = VisitList(node.Body); // Visit end tag. - var endTag = (MarkupTagBlockSyntax)Visit(node.EndTag); + var endTag = (MarkupEndTagSyntax)Visit(node.EndTag); if (endTag != null) { var tagName = endTag.GetTagName(); @@ -181,9 +178,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { // Standalone end tag. We may need to error if it is not supposed to be here. // If there was a corresponding start tag, we would have already added this error. - ValidateParentAllowsPlainTag(endTag); + ValidateParentAllowsPlainEndTag(endTag); } - else if (!endTag.IsVoidElement()) + else { // Since a start tag exists, we must already be tracking it. // Pop the stack as we're done with the end tag. @@ -205,7 +202,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy public override SyntaxNode VisitMarkupTextLiteral(MarkupTextLiteralSyntax node) { - var tagParent = node.FirstAncestorOrSelf(n => n is MarkupTagBlockSyntax); + var tagParent = node.FirstAncestorOrSelf(n => n is MarkupStartTagSyntax || n is MarkupEndTagSyntax); var isPartofTagBlock = tagParent != null; if (!isPartofTagBlock) { @@ -215,13 +212,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return base.VisitMarkupTextLiteral(node); } - private bool TryRewriteTagHelperStart(MarkupTagBlockSyntax tagBlock, out MarkupTagHelperStartTagSyntax rewritten, out TagHelperInfo tagHelperInfo) + private bool TryRewriteTagHelperStart(MarkupStartTagSyntax startTag, out MarkupTagHelperStartTagSyntax rewritten, out TagHelperInfo tagHelperInfo) { rewritten = null; tagHelperInfo = null; // Get tag name of the current block - var tagName = tagBlock.GetTagName(); + var tagName = startTag.GetTagName(); // Could not determine tag name, it can't be a TagHelper, continue on and track the element. if (tagName == null) @@ -231,7 +228,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy TagHelperBinding tagHelperBinding; - if (!IsPotentialTagHelper(tagName, tagBlock)) + if (!IsPotentialTagHelperStart(tagName, startTag)) { return false; } @@ -240,7 +237,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var tagNameScope = tracker?.TagName ?? string.Empty; // We're now in a start tag block, we first need to see if the tag block is a tag helper. - var elementAttributes = GetAttributeNameValuePairs(tagBlock); + var elementAttributes = GetAttributeNameValuePairs(startTag); tagHelperBinding = _tagHelperBinder.GetBinding( tagName, @@ -264,29 +261,29 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return false; } - ValidateParentAllowsTagHelper(tagName, tagBlock); - ValidateBinding(tagHelperBinding, tagName, tagBlock); + ValidateParentAllowsTagHelper(tagName, startTag); + ValidateBinding(tagHelperBinding, tagName, startTag); // We're in a start TagHelper block. - var validTagStructure = ValidateTagSyntax(tagName, tagBlock); + var validTagStructure = ValidateStartTagSyntax(tagName, startTag); - var startTag = TagHelperBlockRewriter.Rewrite( + var rewrittenStartTag = TagHelperBlockRewriter.Rewrite( tagName, validTagStructure, _featureFlags, - tagBlock, + startTag, tagHelperBinding, _errorSink, _source); - var tagMode = TagHelperBlockRewriter.GetTagMode(tagBlock, tagHelperBinding, _errorSink); + var tagMode = TagHelperBlockRewriter.GetTagMode(startTag, tagHelperBinding, _errorSink); tagHelperInfo = new TagHelperInfo(tagName, tagMode, tagHelperBinding); - rewritten = startTag; + rewritten = rewrittenStartTag; return true; } - private bool TryRewriteTagHelperEnd(MarkupTagBlockSyntax tagBlock, out MarkupTagHelperEndTagSyntax rewritten) + private bool TryRewriteTagHelperEnd(MarkupEndTagSyntax tagBlock, out MarkupTagHelperEndTagSyntax rewritten) { rewritten = null; var tagName = tagBlock.GetTagName(); @@ -298,7 +295,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var tracker = CurrentTagHelperTracker; var tagNameScope = tracker?.TagName ?? string.Empty; - if (!IsPotentialTagHelper(tagName, tagBlock)) + if (!IsPotentialTagHelperEnd(tagName, tagBlock)) { return false; } @@ -315,7 +312,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return false; } - ValidateTagSyntax(tagName, tagBlock); + ValidateEndTagSyntax(tagName, tagBlock); _trackerStack.Pop(); } @@ -360,10 +357,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } // Internal for testing - internal IReadOnlyList> GetAttributeNameValuePairs(MarkupTagBlockSyntax tagBlock) + internal IReadOnlyList> GetAttributeNameValuePairs(MarkupStartTagSyntax tagBlock) { // Need to calculate how many children we should take that represent the attributes. - var childrenOffset = IsPartialTag(tagBlock) ? 0 : 1; + var childrenOffset = IsPartialStartTag(tagBlock) ? 0 : 1; var childCount = tagBlock.Children.Count - childrenOffset; if (childCount <= 1) @@ -436,19 +433,19 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return attributes; } - private void ValidateParentAllowsTagHelper(string tagName, MarkupTagBlockSyntax tagBlock) + private void ValidateParentAllowsTagHelper(string tagName, MarkupStartTagSyntax tagBlock) { if (HasAllowedChildren() && !CurrentTagHelperTracker.PrefixedAllowedChildren.Contains(tagName, StringComparer.OrdinalIgnoreCase)) { - OnAllowedChildrenTagError(CurrentTagHelperTracker, tagName, tagBlock, _errorSink, _source); + OnAllowedChildrenStartTagError(CurrentTagHelperTracker, tagName, tagBlock, _errorSink, _source); } } private void ValidateBinding( TagHelperBinding bindingResult, string tagName, - MarkupTagBlockSyntax tagBlock) + MarkupStartTagSyntax tagBlock) { // Ensure that all descriptors associated with this tag have appropriate TagStructures. Cannot have // multiple descriptors that expect different TagStructures (other than TagStructure.Unspecified). @@ -479,12 +476,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } } - private bool ValidateTagSyntax(string tagName, MarkupTagBlockSyntax tag) + private bool ValidateStartTagSyntax(string tagName, MarkupStartTagSyntax tag) { // We assume an invalid syntax until we verify that the tag meets all of our "valid syntax" criteria. - if (IsPartialTag(tag)) + if (IsPartialStartTag(tag)) { - var errorStart = GetTagDeclarationErrorStart(tag); + var errorStart = GetStartTagDeclarationErrorStart(tag, _source); _errorSink.OnError( RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle( @@ -496,7 +493,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return true; } - private bool IsPotentialTagHelper(string tagName, MarkupTagBlockSyntax childBlock) + private bool ValidateEndTagSyntax(string tagName, MarkupEndTagSyntax tag) + { + // We assume an invalid syntax until we verify that the tag meets all of our "valid syntax" criteria. + if (IsPartialEndTag(tag)) + { + var errorStart = GetEndTagDeclarationErrorStart(tag, _source); + + _errorSink.OnError( + RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle( + new SourceSpan(errorStart, tagName.Length), tagName)); + + return false; + } + + return true; + } + + private bool IsPotentialTagHelperStart(string tagName, MarkupStartTagSyntax childBlock) { Debug.Assert(childBlock.Children.Count > 0); var child = childBlock.Children[0]; @@ -505,14 +519,37 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy child.Kind != SyntaxKind.MarkupTransition; } - private SourceLocation GetTagDeclarationErrorStart(MarkupTagBlockSyntax tagBlock) + private bool IsPotentialTagHelperEnd(string tagName, MarkupEndTagSyntax childBlock) { - var advanceBy = IsEndTag(tagBlock) ? " 0); + var child = childBlock.Children[0]; - return SourceLocationTracker.Advance(tagBlock.GetSourceLocation(_source), advanceBy); + return !string.Equals(tagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase) || + child.Kind != SyntaxKind.MarkupTransition; } - private static bool IsPartialTag(MarkupTagBlockSyntax tagBlock) + private static bool IsPartialStartTag(MarkupStartTagSyntax tagBlock) + { + // No need to validate the tag end because in order to be a tag block it must start with '<'. + var tagEnd = tagBlock.Children[tagBlock.Children.Count - 1]; + + // If our tag end is not a markup span it means it's some sort of code SyntaxTreeNode (not a valid format) + if (tagEnd != null && tagEnd is MarkupTextLiteralSyntax tagEndLiteral) + { + var endToken = tagEndLiteral.LiteralTokens.Count > 0 ? + tagEndLiteral.LiteralTokens[tagEndLiteral.LiteralTokens.Count - 1] : + null; + + if (endToken != null && endToken.Kind == SyntaxKind.CloseAngle) + { + return false; + } + } + + return true; + } + + private static bool IsPartialEndTag(MarkupEndTagSyntax tagBlock) { // No need to validate the tag end because in order to be a tag block it must start with '<'. var tagEnd = tagBlock.Children[tagBlock.Children.Count - 1]; @@ -566,7 +603,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } } - private void ValidateParentAllowsPlainTag(MarkupTagBlockSyntax tagBlock) + private void ValidateParentAllowsPlainStartTag(MarkupStartTagSyntax tagBlock) { var tagName = tagBlock.GetTagName(); @@ -595,7 +632,40 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var allowedChildren = tagHelperBinding != null ? CurrentTagHelperTracker.PrefixedAllowedChildren : CurrentTagHelperTracker.AllowedChildren; if (!allowedChildren.Contains(tagName, StringComparer.OrdinalIgnoreCase)) { - OnAllowedChildrenTagError(CurrentTagHelperTracker, tagName, tagBlock, _errorSink, _source); + OnAllowedChildrenStartTagError(CurrentTagHelperTracker, tagName, tagBlock, _errorSink, _source); + } + } + + private void ValidateParentAllowsPlainEndTag(MarkupEndTagSyntax tagBlock) + { + var tagName = tagBlock.GetTagName(); + + // Treat partial tags such as '>(), + parentTagName: CurrentParentTagName, + parentIsTagHelper: CurrentParentIsTagHelper); + + // If we found a binding for the current tag, then it is a tag helper. Use the prefixed allowed children to compare. + var allowedChildren = tagHelperBinding != null ? CurrentTagHelperTracker.PrefixedAllowedChildren : CurrentTagHelperTracker.AllowedChildren; + if (!allowedChildren.Contains(tagName, StringComparer.OrdinalIgnoreCase)) + { + OnAllowedChildrenEndTagError(CurrentTagHelperTracker, tagName, tagBlock, _errorSink, _source); } } @@ -632,15 +702,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return commentParent != null; } - private static void OnAllowedChildrenTagError( + private static void OnAllowedChildrenStartTagError( TagHelperTracker tracker, string tagName, - MarkupTagBlockSyntax tagBlock, + MarkupStartTagSyntax tagBlock, ErrorSink errorSink, RazorSourceDocument source) { var allowedChildrenString = string.Join(", ", tracker.AllowedChildren); - var errorStart = GetTagDeclarationErrorStart(tagBlock, source); + var errorStart = GetStartTagDeclarationErrorStart(tagBlock, source); errorSink.OnError( RazorDiagnosticFactory.CreateTagHelper_InvalidNestedTag( @@ -650,21 +720,32 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy allowedChildrenString)); } - private static SourceLocation GetTagDeclarationErrorStart(MarkupTagBlockSyntax tagBlock, RazorSourceDocument source) + private static void OnAllowedChildrenEndTagError( + TagHelperTracker tracker, + string tagName, + MarkupEndTagSyntax tagBlock, + ErrorSink errorSink, + RazorSourceDocument source) { - var advanceBy = IsEndTag(tagBlock) ? " Body { get { return new SyntaxList(_body); } } - public MarkupTagBlockSyntax EndTag { get { return _endTag; } } + public MarkupEndTagSyntax EndTag { get { return _endTag; } } internal override GreenNode GetSlot(int index) { @@ -1518,7 +1518,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax visitor.VisitMarkupElement(this); } - public MarkupElementSyntax Update(MarkupTagBlockSyntax startTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList body, MarkupTagBlockSyntax endTag) + public MarkupElementSyntax Update(MarkupStartTagSyntax startTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList body, MarkupEndTagSyntax endTag) { if (startTag != StartTag || body != Body || endTag != EndTag) { @@ -1546,6 +1546,168 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax } } + internal sealed partial class MarkupStartTagSyntax : RazorBlockSyntax + { + private readonly GreenNode _children; + + internal MarkupStartTagSyntax(SyntaxKind kind, GreenNode children, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations) + : base(kind, diagnostics, annotations) + { + SlotCount = 1; + if (children != null) + { + AdjustFlagsAndWidth(children); + _children = children; + } + } + + + internal MarkupStartTagSyntax(SyntaxKind kind, GreenNode children) + : base(kind) + { + SlotCount = 1; + if (children != null) + { + AdjustFlagsAndWidth(children); + _children = children; + } + } + + public override SyntaxList Children { get { return new SyntaxList(_children); } } + + internal override GreenNode GetSlot(int index) + { + switch (index) + { + case 0: return _children; + default: return null; + } + } + + internal override SyntaxNode CreateRed(SyntaxNode parent, int position) + { + return new Syntax.MarkupStartTagSyntax(this, parent, position); + } + + public override TResult Accept(SyntaxVisitor visitor) + { + return visitor.VisitMarkupStartTag(this); + } + + public override void Accept(SyntaxVisitor visitor) + { + visitor.VisitMarkupStartTag(this); + } + + public MarkupStartTagSyntax Update(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList children) + { + if (children != Children) + { + var newNode = SyntaxFactory.MarkupStartTag(children); + var diags = GetDiagnostics(); + if (diags != null && diags.Length > 0) + newNode = newNode.WithDiagnosticsGreen(diags); + var annotations = GetAnnotations(); + if (annotations != null && annotations.Length > 0) + newNode = newNode.WithAnnotationsGreen(annotations); + return newNode; + } + + return this; + } + + internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics) + { + return new MarkupStartTagSyntax(Kind, _children, diagnostics, GetAnnotations()); + } + + internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations) + { + return new MarkupStartTagSyntax(Kind, _children, GetDiagnostics(), annotations); + } + } + + internal sealed partial class MarkupEndTagSyntax : RazorBlockSyntax + { + private readonly GreenNode _children; + + internal MarkupEndTagSyntax(SyntaxKind kind, GreenNode children, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations) + : base(kind, diagnostics, annotations) + { + SlotCount = 1; + if (children != null) + { + AdjustFlagsAndWidth(children); + _children = children; + } + } + + + internal MarkupEndTagSyntax(SyntaxKind kind, GreenNode children) + : base(kind) + { + SlotCount = 1; + if (children != null) + { + AdjustFlagsAndWidth(children); + _children = children; + } + } + + public override SyntaxList Children { get { return new SyntaxList(_children); } } + + internal override GreenNode GetSlot(int index) + { + switch (index) + { + case 0: return _children; + default: return null; + } + } + + internal override SyntaxNode CreateRed(SyntaxNode parent, int position) + { + return new Syntax.MarkupEndTagSyntax(this, parent, position); + } + + public override TResult Accept(SyntaxVisitor visitor) + { + return visitor.VisitMarkupEndTag(this); + } + + public override void Accept(SyntaxVisitor visitor) + { + visitor.VisitMarkupEndTag(this); + } + + public MarkupEndTagSyntax Update(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList children) + { + if (children != Children) + { + var newNode = SyntaxFactory.MarkupEndTag(children); + var diags = GetDiagnostics(); + if (diags != null && diags.Length > 0) + newNode = newNode.WithDiagnosticsGreen(diags); + var annotations = GetAnnotations(); + if (annotations != null && annotations.Length > 0) + newNode = newNode.WithAnnotationsGreen(annotations); + return newNode; + } + + return this; + } + + internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics) + { + return new MarkupEndTagSyntax(Kind, _children, diagnostics, GetAnnotations()); + } + + internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations) + { + return new MarkupEndTagSyntax(Kind, _children, GetDiagnostics(), annotations); + } + } + internal sealed partial class MarkupTagHelperElementSyntax : MarkupSyntaxNode { private readonly MarkupTagHelperStartTagSyntax _startTag; @@ -3383,6 +3545,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax return DefaultVisit(node); } + public virtual TResult VisitMarkupStartTag(MarkupStartTagSyntax node) + { + return DefaultVisit(node); + } + + public virtual TResult VisitMarkupEndTag(MarkupEndTagSyntax node) + { + return DefaultVisit(node); + } + public virtual TResult VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node) { return DefaultVisit(node); @@ -3572,6 +3744,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax DefaultVisit(node); } + public virtual void VisitMarkupStartTag(MarkupStartTagSyntax node) + { + DefaultVisit(node); + } + + public virtual void VisitMarkupEndTag(MarkupEndTagSyntax node) + { + DefaultVisit(node); + } + public virtual void VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node) { DefaultVisit(node); @@ -3786,12 +3968,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax public override GreenNode VisitMarkupElement(MarkupElementSyntax node) { - var startTag = (MarkupTagBlockSyntax)Visit(node.StartTag); + var startTag = (MarkupStartTagSyntax)Visit(node.StartTag); var body = VisitList(node.Body); - var endTag = (MarkupTagBlockSyntax)Visit(node.EndTag); + var endTag = (MarkupEndTagSyntax)Visit(node.EndTag); return node.Update(startTag, body, endTag); } + public override GreenNode VisitMarkupStartTag(MarkupStartTagSyntax node) + { + var children = VisitList(node.Children); + return node.Update(children); + } + + public override GreenNode VisitMarkupEndTag(MarkupEndTagSyntax node) + { + var children = VisitList(node.Children); + return node.Update(children); + } + public override GreenNode VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node) { var startTag = (MarkupTagHelperStartTagSyntax)Visit(node.StartTag); @@ -4108,13 +4302,27 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax return result; } - public static MarkupElementSyntax MarkupElement(MarkupTagBlockSyntax startTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList body, MarkupTagBlockSyntax endTag) + public static MarkupElementSyntax MarkupElement(MarkupStartTagSyntax startTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList body, MarkupEndTagSyntax endTag) { var result = new MarkupElementSyntax(SyntaxKind.MarkupElement, startTag, body.Node, endTag); return result; } + public static MarkupStartTagSyntax MarkupStartTag(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList children) + { + var result = new MarkupStartTagSyntax(SyntaxKind.MarkupStartTag, children.Node); + + return result; + } + + public static MarkupEndTagSyntax MarkupEndTag(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList children) + { + var result = new MarkupEndTagSyntax(SyntaxKind.MarkupEndTag, children.Node); + + return result; + } + public static MarkupTagHelperElementSyntax MarkupTagHelperElement(MarkupTagHelperStartTagSyntax startTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList body, MarkupTagHelperEndTagSyntax endTag) { if (startTag == null) @@ -4343,6 +4551,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax typeof(MarkupLiteralAttributeValueSyntax), typeof(MarkupDynamicAttributeValueSyntax), typeof(MarkupElementSyntax), + typeof(MarkupStartTagSyntax), + typeof(MarkupEndTagSyntax), typeof(MarkupTagHelperElementSyntax), typeof(MarkupTagHelperStartTagSyntax), typeof(MarkupTagHelperEndTagSyntax), diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Main.Generated.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Main.Generated.cs index 019d64dc8d..a5f908438a 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Main.Generated.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Main.Generated.cs @@ -113,6 +113,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return DefaultVisit(node); } + /// Called when the visitor visits a MarkupStartTagSyntax node. + public virtual TResult VisitMarkupStartTag(MarkupStartTagSyntax node) + { + return DefaultVisit(node); + } + + /// Called when the visitor visits a MarkupEndTagSyntax node. + public virtual TResult VisitMarkupEndTag(MarkupEndTagSyntax node) + { + return DefaultVisit(node); + } + /// Called when the visitor visits a MarkupTagHelperElementSyntax node. public virtual TResult VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node) { @@ -338,6 +350,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax DefaultVisit(node); } + /// Called when the visitor visits a MarkupStartTagSyntax node. + public virtual void VisitMarkupStartTag(MarkupStartTagSyntax node) + { + DefaultVisit(node); + } + + /// Called when the visitor visits a MarkupEndTagSyntax node. + public virtual void VisitMarkupEndTag(MarkupEndTagSyntax node) + { + DefaultVisit(node); + } + /// Called when the visitor visits a MarkupTagHelperElementSyntax node. public virtual void VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node) { @@ -572,12 +596,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax public override SyntaxNode VisitMarkupElement(MarkupElementSyntax node) { - var startTag = (MarkupTagBlockSyntax)Visit(node.StartTag); + var startTag = (MarkupStartTagSyntax)Visit(node.StartTag); var body = VisitList(node.Body); - var endTag = (MarkupTagBlockSyntax)Visit(node.EndTag); + var endTag = (MarkupEndTagSyntax)Visit(node.EndTag); return node.Update(startTag, body, endTag); } + public override SyntaxNode VisitMarkupStartTag(MarkupStartTagSyntax node) + { + var children = VisitList(node.Children); + return node.Update(children); + } + + public override SyntaxNode VisitMarkupEndTag(MarkupEndTagSyntax node) + { + var children = VisitList(node.Children); + return node.Update(children); + } + public override SyntaxNode VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node) { var startTag = (MarkupTagHelperStartTagSyntax)Visit(node.StartTag); @@ -962,15 +998,39 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax } /// Creates a new MarkupElementSyntax instance. - public static MarkupElementSyntax MarkupElement(MarkupTagBlockSyntax startTag, SyntaxList body, MarkupTagBlockSyntax endTag) + public static MarkupElementSyntax MarkupElement(MarkupStartTagSyntax startTag, SyntaxList body, MarkupEndTagSyntax endTag) { - return (MarkupElementSyntax)InternalSyntax.SyntaxFactory.MarkupElement(startTag == null ? null : (InternalSyntax.MarkupTagBlockSyntax)startTag.Green, body.Node.ToGreenList(), endTag == null ? null : (InternalSyntax.MarkupTagBlockSyntax)endTag.Green).CreateRed(); + return (MarkupElementSyntax)InternalSyntax.SyntaxFactory.MarkupElement(startTag == null ? null : (InternalSyntax.MarkupStartTagSyntax)startTag.Green, body.Node.ToGreenList(), endTag == null ? null : (InternalSyntax.MarkupEndTagSyntax)endTag.Green).CreateRed(); } /// Creates a new MarkupElementSyntax instance. public static MarkupElementSyntax MarkupElement(SyntaxList body = default(SyntaxList)) { - return SyntaxFactory.MarkupElement(default(MarkupTagBlockSyntax), body, default(MarkupTagBlockSyntax)); + return SyntaxFactory.MarkupElement(default(MarkupStartTagSyntax), body, default(MarkupEndTagSyntax)); + } + + /// Creates a new MarkupStartTagSyntax instance. + public static MarkupStartTagSyntax MarkupStartTag(SyntaxList children) + { + return (MarkupStartTagSyntax)InternalSyntax.SyntaxFactory.MarkupStartTag(children.Node.ToGreenList()).CreateRed(); + } + + /// Creates a new MarkupStartTagSyntax instance. + public static MarkupStartTagSyntax MarkupStartTag() + { + return SyntaxFactory.MarkupStartTag(default(SyntaxList)); + } + + /// Creates a new MarkupEndTagSyntax instance. + public static MarkupEndTagSyntax MarkupEndTag(SyntaxList children) + { + return (MarkupEndTagSyntax)InternalSyntax.SyntaxFactory.MarkupEndTag(children.Node.ToGreenList()).CreateRed(); + } + + /// Creates a new MarkupEndTagSyntax instance. + public static MarkupEndTagSyntax MarkupEndTag() + { + return SyntaxFactory.MarkupEndTag(default(SyntaxList)); } /// Creates a new MarkupTagHelperElementSyntax instance. diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Syntax.Generated.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Syntax.Generated.cs index 4c0878d99f..92ba8867d0 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Syntax.Generated.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Syntax.Generated.cs @@ -1382,16 +1382,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax internal sealed partial class MarkupElementSyntax : MarkupSyntaxNode { - private MarkupTagBlockSyntax _startTag; + private MarkupStartTagSyntax _startTag; private SyntaxNode _body; - private MarkupTagBlockSyntax _endTag; + private MarkupEndTagSyntax _endTag; internal MarkupElementSyntax(GreenNode green, SyntaxNode parent, int position) : base(green, parent, position) { } - public MarkupTagBlockSyntax StartTag + public MarkupStartTagSyntax StartTag { get { @@ -1407,7 +1407,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax } } - public MarkupTagBlockSyntax EndTag + public MarkupEndTagSyntax EndTag { get { @@ -1446,7 +1446,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax visitor.VisitMarkupElement(this); } - public MarkupElementSyntax Update(MarkupTagBlockSyntax startTag, SyntaxList body, MarkupTagBlockSyntax endTag) + public MarkupElementSyntax Update(MarkupStartTagSyntax startTag, SyntaxList body, MarkupEndTagSyntax endTag) { if (startTag != StartTag || body != Body || endTag != EndTag) { @@ -1460,7 +1460,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return this; } - public MarkupElementSyntax WithStartTag(MarkupTagBlockSyntax startTag) + public MarkupElementSyntax WithStartTag(MarkupStartTagSyntax startTag) { return Update(startTag, Body, EndTag); } @@ -1470,14 +1470,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return Update(StartTag, body, EndTag); } - public MarkupElementSyntax WithEndTag(MarkupTagBlockSyntax endTag) + public MarkupElementSyntax WithEndTag(MarkupEndTagSyntax endTag) { return Update(StartTag, Body, endTag); } public MarkupElementSyntax AddStartTagChildren(params RazorSyntaxNode[] items) { - var _startTag = this.StartTag ?? SyntaxFactory.MarkupTagBlock(); + var _startTag = this.StartTag ?? SyntaxFactory.MarkupStartTag(); return this.WithStartTag(_startTag.WithChildren(_startTag.Children.AddRange(items))); } @@ -1488,11 +1488,153 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax public MarkupElementSyntax AddEndTagChildren(params RazorSyntaxNode[] items) { - var _endTag = this.EndTag ?? SyntaxFactory.MarkupTagBlock(); + var _endTag = this.EndTag ?? SyntaxFactory.MarkupEndTag(); return this.WithEndTag(_endTag.WithChildren(_endTag.Children.AddRange(items))); } } + internal sealed partial class MarkupStartTagSyntax : RazorBlockSyntax + { + private SyntaxNode _children; + + internal MarkupStartTagSyntax(GreenNode green, SyntaxNode parent, int position) + : base(green, parent, position) + { + } + + public override SyntaxList Children + { + get + { + return new SyntaxList(GetRed(ref _children, 0)); + } + } + + internal override SyntaxNode GetNodeSlot(int index) + { + switch (index) + { + case 0: return GetRedAtZero(ref _children); + default: return null; + } + } + internal override SyntaxNode GetCachedSlot(int index) + { + switch (index) + { + case 0: return _children; + default: return null; + } + } + + public override TResult Accept(SyntaxVisitor visitor) + { + return visitor.VisitMarkupStartTag(this); + } + + public override void Accept(SyntaxVisitor visitor) + { + visitor.VisitMarkupStartTag(this); + } + + public MarkupStartTagSyntax Update(SyntaxList children) + { + if (children != Children) + { + var newNode = SyntaxFactory.MarkupStartTag(children); + var annotations = GetAnnotations(); + if (annotations != null && annotations.Length > 0) + return newNode.WithAnnotations(annotations); + return newNode; + } + + return this; + } + + internal override RazorBlockSyntax WithChildrenCore(SyntaxList children) => WithChildren(children); + public new MarkupStartTagSyntax WithChildren(SyntaxList children) + { + return Update(children); + } + internal override RazorBlockSyntax AddChildrenCore(params RazorSyntaxNode[] items) => AddChildren(items); + + public new MarkupStartTagSyntax AddChildren(params RazorSyntaxNode[] items) + { + return WithChildren(this.Children.AddRange(items)); + } + } + + internal sealed partial class MarkupEndTagSyntax : RazorBlockSyntax + { + private SyntaxNode _children; + + internal MarkupEndTagSyntax(GreenNode green, SyntaxNode parent, int position) + : base(green, parent, position) + { + } + + public override SyntaxList Children + { + get + { + return new SyntaxList(GetRed(ref _children, 0)); + } + } + + internal override SyntaxNode GetNodeSlot(int index) + { + switch (index) + { + case 0: return GetRedAtZero(ref _children); + default: return null; + } + } + internal override SyntaxNode GetCachedSlot(int index) + { + switch (index) + { + case 0: return _children; + default: return null; + } + } + + public override TResult Accept(SyntaxVisitor visitor) + { + return visitor.VisitMarkupEndTag(this); + } + + public override void Accept(SyntaxVisitor visitor) + { + visitor.VisitMarkupEndTag(this); + } + + public MarkupEndTagSyntax Update(SyntaxList children) + { + if (children != Children) + { + var newNode = SyntaxFactory.MarkupEndTag(children); + var annotations = GetAnnotations(); + if (annotations != null && annotations.Length > 0) + return newNode.WithAnnotations(annotations); + return newNode; + } + + return this; + } + + internal override RazorBlockSyntax WithChildrenCore(SyntaxList children) => WithChildren(children); + public new MarkupEndTagSyntax WithChildren(SyntaxList children) + { + return Update(children); + } + internal override RazorBlockSyntax AddChildrenCore(params RazorSyntaxNode[] items) => AddChildren(items); + + public new MarkupEndTagSyntax AddChildren(params RazorSyntaxNode[] items) + { + return WithChildren(this.Children.AddRange(items)); + } + } + internal sealed partial class MarkupTagHelperElementSyntax : MarkupSyntaxNode { private MarkupTagHelperStartTagSyntax _startTag; diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/MarkupElementRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/MarkupElementRewriter.cs index 7aeda1c349..b0d9e82624 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/MarkupElementRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/MarkupElementRewriter.cs @@ -19,15 +19,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return newSyntaxTree; } - public static RazorSyntaxTree RemoveMarkupElements(RazorSyntaxTree syntaxTree) - { - var rewriter = new RemoveMarkupElementRewriter(); - var rewrittenRoot = rewriter.Visit(syntaxTree.Root); - - var newSyntaxTree = RazorSyntaxTree.Create(rewrittenRoot, syntaxTree.Source, syntaxTree.Diagnostics, syntaxTree.Options); - return newSyntaxTree; - } - private class AddMarkupElementRewriter : SyntaxRewriter { private readonly Stack _startTagTracker = new Stack(); @@ -38,10 +29,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax public override SyntaxNode Visit(SyntaxNode node) { - node = base.Visit(node); - if (node != null) { + var diagnostics = node.GetDiagnostics(); + node = base.Visit(node); + if (diagnostics.Length > 0) + { + // Persist node diagnostics. + node = node.WithDiagnostics(diagnostics); + } + node = RewriteNode(node); } @@ -71,7 +68,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax var tagName = tagBlock.GetTagName(); if (string.IsNullOrWhiteSpace(tagName) || tagBlock.IsSelfClosing()) { - // Don't want to track incomplete, invalid (Eg. , < >), void or self-closing tags. + // Don't want to track incomplete, invalid (Eg. , < >) or self-closing tags. // Simply wrap it in a block with no body or start/end tag. if (IsEndTag(tagBlock)) { @@ -102,7 +99,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax if (!TryRecoverStartTag(rewrittenChildren, tagName, tagBlock)) { // Could not recover. The end tag doesn't have a corresponding start tag. Wrap it in a block and move on. - var rewritten = SyntaxFactory.MarkupElement(startTag: null, body: new SyntaxList(), endTag: tagBlock); + var rewritten = SyntaxFactory.MarkupElement(startTag: null, body: new SyntaxList(), endTag: GetEndTagSyntax(tagBlock)); TrackChild(rewritten, rewrittenChildren); } } @@ -149,7 +146,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax // The call to SyntaxNode.ReplaceNodes() later will take care removing the nodes whose replacement is null. var body = tagChildren.Where(t => t != null).ToList(); - var rewritten = SyntaxFactory.MarkupElement(startTag, new SyntaxList(body), endTag); + var rewritten = SyntaxFactory.MarkupElement( + GetStartTagSyntax(startTag), + new SyntaxList(body), + GetEndTagSyntax(endTag)); + if (startTag != null) { // If there was a start tag, that is where we want to put our new element. @@ -232,6 +233,26 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return childContent.StartsWith(" - + - + + + + + + + + + diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxKind.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxKind.cs index d8c68ec77e..66be02fdfa 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxKind.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxKind.cs @@ -19,6 +19,8 @@ namespace Microsoft.AspNetCore.Razor.Language MarkupBlock, MarkupTransition, MarkupElement, + MarkupStartTag, + MarkupEndTag, MarkupTagBlock, MarkupTextLiteral, MarkupEphemeralTextLiteral, diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNodeExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNodeExtensions.cs index 4955f15294..521bb4ed79 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNodeExtensions.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNodeExtensions.cs @@ -223,55 +223,31 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax public static string GetTagName(this MarkupTagBlockSyntax tagBlock) { - if (tagBlock == null) - { - throw new ArgumentNullException(nameof(tagBlock)); - } - - var child = tagBlock.Children[0]; - - if (tagBlock.Children.Count == 0 || !(child is MarkupTextLiteralSyntax)) - { - return null; - } - - var childLiteral = (MarkupTextLiteralSyntax)child; - SyntaxToken textToken = null; - for (var i = 0; i < childLiteral.LiteralTokens.Count; i++) - { - var token = childLiteral.LiteralTokens[i]; - - if (token != null && - (token.Kind == SyntaxKind.Whitespace || token.Kind == SyntaxKind.Text)) - { - textToken = token; - break; - } - } - - if (textToken == null) - { - return null; - } - - return textToken.Kind == SyntaxKind.Whitespace ? null : textToken.Content; + return GetTagNameCore(tagBlock); } - public static string GetTagName(this MarkupTagHelperStartTagSyntax tagBlock) + public static string GetTagName(this MarkupStartTagSyntax startTag) + { + return GetTagNameCore(startTag); + } + + public static string GetTagName(this MarkupEndTagSyntax endTag) + { + return GetTagNameCore(endTag); + } + + private static string GetTagNameCore(RazorBlockSyntax tagBlock) { if (tagBlock == null) { throw new ArgumentNullException(nameof(tagBlock)); } - var child = tagBlock.Children[0]; - - if (tagBlock.Children.Count == 0 || !(child is MarkupTextLiteralSyntax)) + if (tagBlock.Children.Count == 0 || !(tagBlock.Children[0] is MarkupTextLiteralSyntax childLiteral)) { return null; } - var childLiteral = (MarkupTextLiteralSyntax)child; SyntaxToken textToken = null; for (var i = 0; i < childLiteral.LiteralTokens.Count; i++) { @@ -294,6 +270,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax } public static bool IsSelfClosing(this MarkupTagBlockSyntax tagBlock) + { + return IsSelfClosingCore(tagBlock); + } + + public static bool IsSelfClosing(this MarkupStartTagSyntax startTag) + { + return IsSelfClosingCore(startTag); + } + + private static bool IsSelfClosingCore(RazorBlockSyntax tagBlock) { if (tagBlock == null) { @@ -305,14 +291,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return lastChild?.GetContent().EndsWith("/>", StringComparison.Ordinal) ?? false; } - public static bool IsVoidElement(this MarkupTagBlockSyntax tagBlock) + public static bool IsVoidElement(this MarkupStartTagSyntax startTag) { - if (tagBlock == null) + if (startTag == null) { - throw new ArgumentNullException(nameof(tagBlock)); + throw new ArgumentNullException(nameof(startTag)); } - return ParserHelpers.VoidElements.Contains(tagBlock.GetTagName()); + return ParserHelpers.VoidElements.Contains(startTag.GetTagName()); } } } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxSerializer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxSerializer.cs index 5b167b510f..a811d79aa2 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxSerializer.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxSerializer.cs @@ -287,7 +287,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax { return node.Kind == SyntaxKind.MarkupTextLiteral || node.Kind == SyntaxKind.MarkupEphemeralTextLiteral || - node.Kind == SyntaxKind.MarkupTagBlock || + node.Kind == SyntaxKind.MarkupStartTag || + node.Kind == SyntaxKind.MarkupEndTag || node.Kind == SyntaxKind.MarkupAttributeBlock || node.Kind == SyntaxKind.MarkupMinimizedAttributeBlock || node.Kind == SyntaxKind.MarkupTagHelperAttribute || diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs index 1e88100c46..22d088d7d5 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs @@ -13,6 +13,7 @@ using System.Text; using Xunit; using Xunit.Sdk; using System.Text.RegularExpressions; +using Microsoft.AspNetCore.Razor.Language.Syntax; namespace Microsoft.AspNetCore.Razor.Language.Legacy { @@ -240,6 +241,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var syntaxTree = RazorSyntaxTree.Create(root, source, diagnostics, options); codeDocument.SetSyntaxTree(syntaxTree); + // Group markup elements + syntaxTree = MarkupElementRewriter.AddMarkupElements(syntaxTree); + var defaultDirectivePass = new DefaultDirectiveSyntaxTreePass(); syntaxTree = defaultDirectivePass.Execute(codeDocument, syntaxTree); @@ -267,6 +271,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var syntaxTree = RazorSyntaxTree.Create(root, source, diagnostics, options); + // Group markup elements + syntaxTree = MarkupElementRewriter.AddMarkupElements(syntaxTree); + return syntaxTree; } @@ -300,6 +307,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var syntaxTree = RazorSyntaxTree.Create(root, source, diagnostics, options); + // Group markup elements + syntaxTree = MarkupElementRewriter.AddMarkupElements(syntaxTree); + return syntaxTree; } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWriter.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWriter.cs index 3d1faba30e..0974b6a7b9 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWriter.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWriter.cs @@ -203,7 +203,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax { return node.Kind == SyntaxKind.MarkupTextLiteral || node.Kind == SyntaxKind.MarkupEphemeralTextLiteral || - node.Kind == SyntaxKind.MarkupTagBlock || + node.Kind == SyntaxKind.MarkupStartTag || + node.Kind == SyntaxKind.MarkupEndTag || node.Kind == SyntaxKind.MarkupAttributeBlock || node.Kind == SyntaxKind.MarkupMinimizedAttributeBlock || node.Kind == SyntaxKind.MarkupTagHelperAttribute || From 0c71f4f520f1915e405d113dd4774264c9f415fa Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Wed, 5 Dec 2018 11:48:33 -0800 Subject: [PATCH 013/337] Added test for razor comment between code block and markup (dotnet/aspnetcore-tooling#14) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/131003d0c33ea0f4cae0c5bb20ada98dbf54e272 --- .../src/Legacy/HtmlMarkupParser.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs index a30d5b2de1..9d7400dd11 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs @@ -798,6 +798,21 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy private void ParseRazorCommentWithLeadingAndTrailingWhitespace(in SyntaxListBuilder builder) { + if (Context.NullGenerateWhitespaceAndNewLine) + { + // Usually this is set to true when a Code block ends and there is whitespace left after it. + // We don't want to write it to output. + Context.NullGenerateWhitespaceAndNewLine = false; + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; + AcceptWhile(IsSpacingToken(includeNewLines: false)); + if (At(SyntaxKind.NewLine)) + { + AcceptAndMoveNext(); + } + + builder.Add(OutputAsMarkupEphemeralLiteral()); + } + var shouldRenderWhitespace = true; var lastWhitespace = AcceptWhitespaceInLines(); var startOfLine = Context.StartOfLine; From cf6b1d7135e1003f6839306ab214165ef1ea1154 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Thu, 6 Dec 2018 01:12:07 -0800 Subject: [PATCH 014/337] Correct logic for GetTagName \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/72a389149acd31b7e28546b004b6bb7186fbe3c6 --- .../src/Legacy/TagHelperParseTreeRewriter.cs | 4 +-- .../src/Syntax/SyntaxNodeExtensions.cs | 32 ++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs index ca0bc08809..c46a0b0bab 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs @@ -221,7 +221,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var tagName = startTag.GetTagName(); // Could not determine tag name, it can't be a TagHelper, continue on and track the element. - if (tagName == null) + if (tagName == null || tagName.StartsWith("!")) { return false; } @@ -288,7 +288,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy rewritten = null; var tagName = tagBlock.GetTagName(); // Could not determine tag name, it can't be a TagHelper, continue on and track the element. - if (tagName == null) + if (tagName == null || tagName.StartsWith("!")) { return false; } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNodeExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNodeExtensions.cs index 521bb4ed79..b696e221da 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNodeExtensions.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNodeExtensions.cs @@ -243,15 +243,33 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax throw new ArgumentNullException(nameof(tagBlock)); } - if (tagBlock.Children.Count == 0 || !(tagBlock.Children[0] is MarkupTextLiteralSyntax childLiteral)) + MarkupTextLiteralSyntax nameLiteral = null; + var isBangTag = false; + if (tagBlock.Children.Count > 0 && tagBlock.Children[0] is MarkupTextLiteralSyntax firstChild) + { + if (firstChild.GetContent().StartsWith("<") && + tagBlock.Children.Count >= 3 && + tagBlock.Children[1] is RazorMetaCodeSyntax && + tagBlock.Children[2] is MarkupTextLiteralSyntax potentialBangTagName) + { + isBangTag = true; + nameLiteral = potentialBangTagName; + } + else + { + nameLiteral = firstChild; + } + } + + if (nameLiteral == null) { return null; } SyntaxToken textToken = null; - for (var i = 0; i < childLiteral.LiteralTokens.Count; i++) + for (var i = 0; i < nameLiteral.LiteralTokens.Count; i++) { - var token = childLiteral.LiteralTokens[i]; + var token = nameLiteral.LiteralTokens[i]; if (token != null && (token.Kind == SyntaxKind.Whitespace || token.Kind == SyntaxKind.Text)) @@ -266,7 +284,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return null; } - return textToken.Kind == SyntaxKind.Whitespace ? null : textToken.Content; + var name = textToken.Kind == SyntaxKind.Whitespace ? null : textToken.Content; + if (name != null && isBangTag) + { + name = "!" + name; + } + + return name; } public static bool IsSelfClosing(this MarkupTagBlockSyntax tagBlock) From 9f93a212f0633e5ea5563a07c6adf08774617edb Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Thu, 6 Dec 2018 16:07:17 -0800 Subject: [PATCH 015/337] Partially moved tag grouping logic to the parser (dotnet/aspnetcore-tooling#20) * Partially moved tag grouping logic to the parser - Added StackGuard * Feedback * More feedback \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/0a37f5dafaaf16a61a3c032f439a7a09ed1e5afd --- .../src/Legacy/HtmlMarkupParser.cs | 183 +++++++++++++++--- .../InternalSyntax/SyntaxListBuilderOfT.cs | 7 + .../src/Syntax/StackGuard.cs | 30 +++ .../src/Syntax/SyntaxRewriter.cs | 20 ++ .../src/Syntax/SyntaxWalker.cs | 12 +- 5 files changed, 220 insertions(+), 32 deletions(-) create mode 100644 src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/StackGuard.cs diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs index 9d7400dd11..919c314d56 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs @@ -12,6 +12,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy internal partial class HtmlMarkupParser : TokenizerBackedParser { private const string ScriptTagName = "script"; + private static readonly SyntaxList EmptySyntaxList = new SyntaxListBuilder(0).ToList(); private static readonly char[] ValidAfterTypeAttributeNameCharacters = { ' ', '\t', '\r', '\n', '\f', '=' }; private static readonly SyntaxToken[] nonAllowedHtmlCommentEnding = new[] @@ -21,11 +22,19 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy SyntaxFactory.Token(SyntaxKind.OpenAngle, "<"), }; + private Stack _tagTracker = new Stack(); + public HtmlMarkupParser(ParserContext context) : base(context.ParseLeadingDirectives ? FirstDirectiveHtmlLanguageCharacteristics.Instance : HtmlLanguageCharacteristics.Instance, context) { } + private TagTracker CurrentTracker => _tagTracker.Count > 0 ? _tagTracker.Peek() : null; + + private string CurrentStartTagName => CurrentTracker?.TagName; + + private SourceLocation CurrentStartTagLocation => CurrentTracker?.TagLocation ?? SourceLocation.Undefined; + public CSharpCodeParser CodeParser { get; set; } public RazorDocumentSyntax ParseDocument() @@ -45,6 +54,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy AcceptMarkerTokenIfNecessary(); builder.Add(OutputAsMarkupLiteral()); + // If we are still tracking any unclosed start tags, we need to close them. + while (_tagTracker.Count > 0) + { + var tracker = _tagTracker.Pop(); + var element = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), endTag: null); + builder.AddRange(tracker.PreviousNodes); + builder.Add(element); + } + var markup = SyntaxFactory.MarkupBlock(builder.ToList()); return SyntaxFactory.RazorDocument(markup); @@ -71,7 +89,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy ParseMarkupText(builder); break; case ParserState.Tag: - ParseMarkupElement(builder); + ParseMarkupElement(builder, mode); break; case ParserState.SpecialTag: ParseSpecialTag(builder); @@ -111,7 +129,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy AcceptAndMoveNext(); } - private void ParseMarkupElement(in SyntaxListBuilder builder) + private void ParseMarkupElement(in SyntaxListBuilder builder, ParseMode mode) { Assert(SyntaxKind.OpenAngle); @@ -121,47 +139,101 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy if (!NextIs(SyntaxKind.ForwardSlash)) { // Parsing a start tag + var tagStart = CurrentStart; var startTag = ParseStartTag(out var tagName, out var tagMode); - builder.Add(startTag); - if (tagMode == MarkupTagMode.Script) { - ParseJavascriptAndEndScriptTag(builder); + ParseJavascriptAndEndScriptTag(builder, startTag); return; } - else if (tagMode != MarkupTagMode.Void && tagMode != MarkupTagMode.SelfClosing) + else if (tagMode == MarkupTagMode.SelfClosing || tagMode == MarkupTagMode.Invalid) { - var body = ParseTagBody(tagName, out var seenEndTag); - if (body != null) - { - builder.AddRange(body); - } - - if (seenEndTag) - { - var endTag = ParseEndTag(); - builder.Add(endTag); - } + // For cases like or invalid cases like |<|

+ var element = SyntaxFactory.MarkupElement(startTag, EmptySyntaxList, endTag: null); + builder.Add(element); + return; + } + else + { + // This is a normal start tag. We need to keep track of it. + var tracker = new TagTracker(tagName, startTag, tagStart, builder.Consume()); + _tagTracker.Push(tracker); + return; } } else { // Parsing an end tag. - var endTag = ParseEndTag(); - builder.Add(endTag); + var endTag = ParseEndTag(out var endTagName); + if (endTagName != null && string.Equals(CurrentStartTagName, endTagName, StringComparison.OrdinalIgnoreCase)) + { + // Happy path. Found a matching start tag. Create the element and reset the builder. + var tracker = _tagTracker.Pop(); + var element = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), endTag); + builder.AddRange(tracker.PreviousNodes); + builder.Add(element); + return; + } + else + { + // Current tag scope does not match the end tag. Attempt to recover the start tag + // by looking up the previous tag scopes for a matching start tag. + if (!TryRecoverStartTag(builder, endTagName, endTag)) + { + // Could not recover. + var element = SyntaxFactory.MarkupElement(startTag: null, body: EmptySyntaxList, endTag: endTag); + builder.Add(element); + } + } } } - private MarkupTagBlockSyntax ParseStartTag(out string tagName, out MarkupTagMode tagMode) + private bool TryRecoverStartTag(in SyntaxListBuilder builder, string endTagName, MarkupEndTagSyntax endTag) + { + var malformedTagCount = 0; + foreach (var tag in _tagTracker) + { + if (string.Equals(tag.TagName, endTagName, StringComparison.OrdinalIgnoreCase)) + { + break; + } + + malformedTagCount++; + } + + if (malformedTagCount != _tagTracker.Count) + { + // This means we found a matching tag. + for (var i = 0; i < malformedTagCount; i++) + { + var tracker = _tagTracker.Pop(); + var malformedElement = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), endTag: null); + builder.AddRange(tracker.PreviousNodes); + builder.Add(malformedElement); + } + + // Now complete our target tag which is not malformed. + var tagTracker = _tagTracker.Pop(); + var element = SyntaxFactory.MarkupElement(tagTracker.StartTag, builder.Consume(), endTag); + builder.AddRange(tagTracker.PreviousNodes); + builder.Add(element); + + return true; + } + + return false; + } + + private MarkupStartTagSyntax ParseStartTag(out string tagName, out MarkupTagMode tagMode) { tagName = null; - tagMode = MarkupTagMode.Normal; + tagMode = MarkupTagMode.Invalid; using (var pooledResult = Pool.Allocate()) { var tagBuilder = pooledResult.Builder; AcceptAndMoveNext(); // Accept '<' - TryParseBangEscape(tagBuilder); + var isBangEscape = TryParseBangEscape(tagBuilder); if (At(SyntaxKind.Text)) { @@ -171,6 +243,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // This is a void element. tagMode = MarkupTagMode.Void; } + else + { + tagMode = MarkupTagMode.Normal; + } + + if (isBangEscape) + { + // We don't want to group

and together. + tagName = "!" + tagName; + } } TryAccept(SyntaxKind.Text); @@ -189,7 +271,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // End tag block tagBuilder.Add(OutputAsMarkupLiteral()); - var tagBlock = SyntaxFactory.MarkupTagBlock(tagBuilder.ToList()); + var tagBlock = SyntaxFactory.MarkupStartTag(tagBuilder.ToList()); if (string.Equals(tagName, ScriptTagName, StringComparison.OrdinalIgnoreCase)) { // If the script tag expects javascript content then we should do minimal parsing until we reach @@ -204,11 +286,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } } - private MarkupTagBlockSyntax ParseEndTag() + private MarkupEndTagSyntax ParseEndTag(out string tagName) { // This section can accept things like: '

' or '

' etc. Assert(SyntaxKind.OpenAngle); + tagName = null; + using (var pooledResult = Pool.Allocate()) { var tagBuilder = pooledResult.Builder; @@ -217,14 +301,19 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy TryAccept(SyntaxKind.ForwardSlash); // Whitespace here is invalid (according to the spec) - TryParseBangEscape(tagBuilder); - TryAccept(SyntaxKind.Text); + var isBangEscape = TryParseBangEscape(tagBuilder); + if (At(SyntaxKind.Text)) + { + tagName = isBangEscape ? "!" : string.Empty; + tagName += CurrentToken.Content; + AcceptAndMoveNext(); + } TryAccept(SyntaxKind.Whitespace); TryAccept(SyntaxKind.CloseAngle); // End tag block tagBuilder.Add(OutputAsMarkupLiteral()); - var tagBlock = SyntaxFactory.MarkupTagBlock(tagBuilder.ToList()); + var tagBlock = SyntaxFactory.MarkupEndTag(tagBuilder.ToList()); return tagBlock; } } @@ -598,8 +687,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy token.Kind == SyntaxKind.NewLine; } - private void ParseJavascriptAndEndScriptTag(in SyntaxListBuilder builder, AcceptedCharactersInternal endTagAcceptedCharacters = AcceptedCharactersInternal.Any) + private void ParseJavascriptAndEndScriptTag(in SyntaxListBuilder builder, MarkupStartTagSyntax startTag, AcceptedCharactersInternal endTagAcceptedCharacters = AcceptedCharactersInternal.Any) { + var previousNodes = builder.Consume(); + // Special case for + + + + + + + + + + @RenderSection("Scripts", required: false) + + diff --git a/src/Razor/test/testassets/SimpleMvc22/Views/Shared/_ValidationScriptsPartial.cshtml b/src/Razor/test/testassets/SimpleMvc22/Views/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000000..a699aafa97 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc22/Views/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/src/Razor/test/testassets/SimpleMvc22/Views/_ViewImports.cshtml b/src/Razor/test/testassets/SimpleMvc22/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..477d4ba603 --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc22/Views/_ViewImports.cshtml @@ -0,0 +1,4 @@ +@using SimpleMvc +@using SimpleMvc.Models +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@namespace SimpleMvc21 diff --git a/src/Razor/test/testassets/SimpleMvc22/Views/_ViewStart.cshtml b/src/Razor/test/testassets/SimpleMvc22/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/src/Razor/test/testassets/SimpleMvc22/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj b/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj index c32a88baa1..c972b84e4b 100644 --- a/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj +++ b/src/Razor/test/testassets/SimpleMvcFSharp/SimpleMvcFSharp.fsproj @@ -2,6 +2,7 @@ $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ + true @@ -18,6 +19,10 @@ + + + + diff --git a/src/Razor/test/testassets/SimplePages/SimplePages.csproj b/src/Razor/test/testassets/SimplePages/SimplePages.csproj index 362406340c..afc2b469d0 100644 --- a/src/Razor/test/testassets/SimplePages/SimplePages.csproj +++ b/src/Razor/test/testassets/SimplePages/SimplePages.csproj @@ -2,6 +2,7 @@ $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ + true @@ -13,6 +14,10 @@ false + + + + From e6e8fba39c3124550eea1885cefd894075974d3e Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Fri, 4 Jan 2019 11:17:40 -0800 Subject: [PATCH 037/337] SDK updates for components tooling This is a bug fix for the RazorComponentWithTargetPath xaml rule. We need to have separate targets for components and views. The other fix here is a change to the set of workarounds we're using for components currently. We need this project capability for the correct project host to be used when loading the project. \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/78163f7e4f38937831cea526d682c30aad7bf80c --- .../Microsoft.NET.Sdk.Razor.DesignTime.targets | 10 ++++++++-- .../Rules/RazorComponentWithTargetPath.xaml | 4 ++-- .../IntegrationTests/DesignTimeBuildIntegrationTest.cs | 4 ++-- .../ComponentLibrary/ComponentLibrary.csproj | 4 ++++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets index bd66729778..2a9f95d7e4 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets @@ -59,8 +59,14 @@ Copyright (c) .NET Foundation. All rights reserved. + DependsOnTargets="ResolveRazorGenerateInputs;AssignRazorGenerateTargetPaths" + Returns="@(RazorGenerateWithTargetPath)"> + + + diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorComponentWithTargetPath.xaml b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorComponentWithTargetPath.xaml index 14a479afe3..668c85bd59 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorComponentWithTargetPath.xaml +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorComponentWithTargetPath.xaml @@ -2,14 +2,14 @@ diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/DesignTimeBuildIntegrationTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/DesignTimeBuildIntegrationTest.cs index 7d5f88d9fb..c6b33539ad 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/DesignTimeBuildIntegrationTest.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/DesignTimeBuildIntegrationTest.cs @@ -67,11 +67,11 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests [Fact] [InitializeTestProject("ComponentLibrary")] - public async Task RazorGenerateDesignTime_ReturnsRazorComponentWithTargetPath() + public async Task RazorGenerateComponentDesignTime_ReturnsRazorComponentWithTargetPath() { TargetFramework = "netstandard2.0"; - var result = await DotnetMSBuild("RazorGenerateDesignTime;_IntrospectRazorComponentWithTargetPath"); + var result = await DotnetMSBuild("RazorGenerateComponentDesignTime;_IntrospectRazorComponentWithTargetPath"); Assert.BuildPassed(result); diff --git a/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj b/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj index f3ad8532a3..631a4c0a46 100644 --- a/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj +++ b/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj @@ -42,6 +42,10 @@
+ + + + From b10374a368b7f590126019cd7c2844328f285cf2 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Fri, 4 Jan 2019 11:17:40 -0800 Subject: [PATCH 038/337] SDK updates for components tooling This is a bug fix for the RazorComponentWithTargetPath xaml rule. We need to have separate targets for components and views. The other fix here is a change to the set of workarounds we're using for components currently. We need this project capability for the correct project host to be used when loading the project. (cherry picked from commit dotnet/aspnetcore-tooling@78163f7e4f38937831cea526d682c30aad7bf80c) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/f8835ce7a88b188ff397b1be1b06e8e3e75dc1d1 --- .../Microsoft.NET.Sdk.Razor.DesignTime.targets | 10 ++++++++-- .../Rules/RazorComponentWithTargetPath.xaml | 4 ++-- .../IntegrationTests/DesignTimeBuildIntegrationTest.cs | 4 ++-- .../ComponentLibrary/ComponentLibrary.csproj | 4 ++++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets index bd66729778..2a9f95d7e4 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets @@ -59,8 +59,14 @@ Copyright (c) .NET Foundation. All rights reserved. + DependsOnTargets="ResolveRazorGenerateInputs;AssignRazorGenerateTargetPaths" + Returns="@(RazorGenerateWithTargetPath)"> + + + diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorComponentWithTargetPath.xaml b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorComponentWithTargetPath.xaml index 14a479afe3..668c85bd59 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorComponentWithTargetPath.xaml +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Rules/RazorComponentWithTargetPath.xaml @@ -2,14 +2,14 @@ diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/DesignTimeBuildIntegrationTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/DesignTimeBuildIntegrationTest.cs index 7d5f88d9fb..c6b33539ad 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/DesignTimeBuildIntegrationTest.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/DesignTimeBuildIntegrationTest.cs @@ -67,11 +67,11 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests [Fact] [InitializeTestProject("ComponentLibrary")] - public async Task RazorGenerateDesignTime_ReturnsRazorComponentWithTargetPath() + public async Task RazorGenerateComponentDesignTime_ReturnsRazorComponentWithTargetPath() { TargetFramework = "netstandard2.0"; - var result = await DotnetMSBuild("RazorGenerateDesignTime;_IntrospectRazorComponentWithTargetPath"); + var result = await DotnetMSBuild("RazorGenerateComponentDesignTime;_IntrospectRazorComponentWithTargetPath"); Assert.BuildPassed(result); diff --git a/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj b/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj index f3ad8532a3..631a4c0a46 100644 --- a/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj +++ b/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj @@ -42,6 +42,10 @@
+ + + + From 500bdc1fd42ba0bdd3058006a6275db1be8166b4 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 7 Jan 2019 15:09:56 -0800 Subject: [PATCH 039/337] Exclude RazorComponent items from RazorGenerate item group Interim solution to allow components to share the .cshtml extension. When declared in the project file, the SDK will prevent RazorComponent items from being included in the RazorGenerate itemgroup. \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/92e2c70b699a35b1410b80863aa0c3415aa0bbc6 --- .../Sdk.Razor.CurrentVersion.targets | 5 +++- .../test/IntegrationTests/Assert.cs | 26 ++++++++++++++++--- .../BuildWithComponentsIntegrationTest.cs | 2 ++ .../ComponentLibrary/ComponentLibrary.csproj | 15 ----------- .../Components/Counter.cshtml | 1 + .../MvcWithComponents.csproj | 4 +++ 6 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 src/Razor/test/testassets/MvcWithComponents/Components/Counter.cshtml diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets index 704b14d22a..a4cb71a514 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets @@ -367,7 +367,10 @@ Copyright (c) .NET Foundation. All rights reserved. - + - - - - - - - diff --git a/src/Razor/test/testassets/MvcWithComponents/Components/Counter.cshtml b/src/Razor/test/testassets/MvcWithComponents/Components/Counter.cshtml new file mode 100644 index 0000000000..f8b81d88c7 --- /dev/null +++ b/src/Razor/test/testassets/MvcWithComponents/Components/Counter.cshtml @@ -0,0 +1 @@ +This file should produce a component diff --git a/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj b/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj index c50aefcff5..1d3cf1b9ed 100644 --- a/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj +++ b/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj @@ -29,6 +29,10 @@ + + + + From 4e909515a7e75d95a850fee59cd3bc97472249f3 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 7 Jan 2019 15:43:28 -0800 Subject: [PATCH 040/337] PR changes \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/ef1a7507c9ecc6db6dc4148e8bb9338729524456 --- .../test/IntegrationTests/Assert.cs | 9 ++++----- .../BuildWithComponentsIntegrationTest.cs | 10 +++++++++- .../ComponentLibrary/ComponentLibrary.csproj | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/Assert.cs b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/Assert.cs index d94289e180..f2ee9393f6 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/Assert.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/Assert.cs @@ -397,25 +397,24 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests throw new ArgumentNullException(nameof(result)); } + assemblyPath = Path.Combine(result.Project.DirectoryPath, Path.Combine(assemblyPath)); + var typeNames = GetDeclaredTypeNames(assemblyPath); Assert.DoesNotContain(fullTypeName, typeNames); } private static IEnumerable GetDeclaredTypeNames(string assemblyPath) { - IEnumerable typeNames; using (var file = File.OpenRead(assemblyPath)) { var peReader = new PEReader(file); var metadataReader = peReader.GetMetadataReader(); - typeNames = metadataReader.TypeDefinitions.Where(t => !t.IsNil).Select(t => + return metadataReader.TypeDefinitions.Where(t => !t.IsNil).Select(t => { var type = metadataReader.GetTypeDefinition(t); return metadataReader.GetString(type.Namespace) + "." + metadataReader.GetString(type.Name); - }); + }).ToArray(); } - - return typeNames; } private abstract class MSBuildXunitException : Xunit.Sdk.XunitException diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildWithComponentsIntegrationTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildWithComponentsIntegrationTest.cs index 4ce8344550..847fccafc3 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildWithComponentsIntegrationTest.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildWithComponentsIntegrationTest.cs @@ -36,8 +36,16 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests Assert.AssemblyContainsType(result, Path.Combine(OutputPath, "MvcWithComponents.dll"), "MvcWithComponents.TestComponent"); Assert.AssemblyContainsType(result, Path.Combine(OutputPath, "MvcWithComponents.dll"), "MvcWithComponents.Views.Shared.NavMenu"); + + // This is a component file with a .cshtml extension. It should appear in the main assembly, but not in the views dll. Assert.AssemblyContainsType(result, Path.Combine(OutputPath, "MvcWithComponents.dll"), "MvcWithComponents.Components.Counter"); - Assert.AssemblyDoesNotContainType(result, Path.Combine(OutputPath, "MvcWithComponents.dll"), "MvcWithComponents.Views.Home.Index"); + Assert.AssemblyDoesNotContainType(result, Path.Combine(OutputPath, "MvcWithComponents.Views.dll"), "MvcWithComponents.Components.Counter"); + Assert.AssemblyDoesNotContainType(result, Path.Combine(OutputPath, "MvcWithComponents.Views.dll"), "AspNetCore.Components_Counter"); + + // Verify a regular View appears in the views dll, but not in the main assembly. + Assert.AssemblyDoesNotContainType(result, Path.Combine(OutputPath, "MvcWithComponents.dll"), "AspNetCore.Views.Home.Index"); + Assert.AssemblyDoesNotContainType(result, Path.Combine(OutputPath, "MvcWithComponents.dll"), "AspNetCore.Views_Home_Index"); + Assert.AssemblyContainsType(result, Path.Combine(OutputPath, "MvcWithComponents.Views.dll"), "AspNetCore.Views_Home_Index"); } } } diff --git a/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj b/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj index f4cf248c2b..077e7ae96b 100644 --- a/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj +++ b/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj @@ -28,7 +28,7 @@ - + From d46aa2e2bd96b5b8455f629e2f0e47498f40cb5d Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Wed, 2 Jan 2019 18:21:34 -0800 Subject: [PATCH 041/337] Enabling features for Components in VS This is the final set of enabling features for VS.. including: - Adding component types to IDE project engine - Using file kind in the editor - Enabling component documents in the project system - Fixing some bugs in the xaml/msbuild authoring - Adding a missing capability for component projects The only thing here that probably bears explaining is the class name mangling. This is a carry over from Blazor, basically because the generated code is part of the workspace, we have to mangle the class name to avoid collisions. The work to resolve this is tracked separately, and will require coordination from a few teams to resolve. \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/d0a8aa3f9717994f2567e4caf7c0061dd89d3459 --- .../BasicComponent_DesignTime.codegen.cs | 4 +- .../BasicComponent_DesignTime.ir.txt | 4 +- .../BasicComponent_DesignTime.mappings.txt | 8 +- .../BasicComponent_Runtime.codegen.cs | 4 +- .../BasicComponent_Runtime.ir.txt | 4 +- .../ComponentDocumentClassifierPass.cs | 73 ++++++++++++------- .../src/BindTagHelperDescriptorProvider.cs | 6 +- .../Microsoft.NET.Sdk.Razor.Component.targets | 4 +- ...Microsoft.NET.Sdk.Razor.DesignTime.targets | 17 +++++ 9 files changed, 82 insertions(+), 42 deletions(-) diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.codegen.cs index 5fe69361a5..a440afb781 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.codegen.cs +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.codegen.cs @@ -1,6 +1,6 @@ // #pragma warning disable 1591 -namespace AspNetCore +namespace __BlazorGenerated { #line hidden using TModel = global::System.Object; @@ -9,7 +9,7 @@ namespace AspNetCore using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; - public class BasicComponent : Microsoft.AspNetCore.Components.ComponentBase, IDisposable + public class AspNetCore_d3c3d6059615673cb46fc4974164d61eabadb890 : Microsoft.AspNetCore.Components.ComponentBase, IDisposable { #pragma warning disable 219 private void __RazorDirectiveTokenHelpers__() { diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.ir.txt index 73d65846a2..2f6aa48182 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.ir.txt +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.ir.txt @@ -1,12 +1,12 @@ Document - - NamespaceDeclaration - - AspNetCore + NamespaceDeclaration - - __BlazorGenerated UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System UsingDirective - (16:1,1 [32] ) - System.Collections.Generic UsingDirective - (51:2,1 [17] ) - System.Linq UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks UsingDirective - (102:4,1 [37] ) - Microsoft.AspNetCore.Components - ClassDeclaration - - public - BasicComponent - Microsoft.AspNetCore.Components.ComponentBase - IDisposable + ClassDeclaration - - public - AspNetCore_d3c3d6059615673cb46fc4974164d61eabadb890 - Microsoft.AspNetCore.Components.ComponentBase - IDisposable DesignTimeDirective - DirectiveToken - (14:0,14 [36] ) - "*, Microsoft.AspNetCore.Components" DirectiveToken - (12:0,12 [11] BasicComponent.cshtml) - IDisposable diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.mappings.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.mappings.txt index abc4f51e55..0baa77e8ca 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.mappings.txt +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_DesignTime.mappings.txt @@ -1,23 +1,23 @@ Source Location: (12:0,12 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml) |IDisposable| -Generated Location: (618:17,0 [11] ) +Generated Location: (662:17,0 [11] ) |IDisposable| Source Location: (38:1,13 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml) |this.ToString()| -Generated Location: (1214:33,13 [15] ) +Generated Location: (1258:33,13 [15] ) |this.ToString()| Source Location: (79:3,5 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml) |string.Format("{0}", "Hello")| -Generated Location: (1359:38,6 [29] ) +Generated Location: (1403:38,6 [29] ) |string.Format("{0}", "Hello")| Source Location: (132:6,12 [37] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml) | void IDisposable.Dispose(){ } | -Generated Location: (1573:45,12 [37] ) +Generated Location: (1617:45,12 [37] ) | void IDisposable.Dispose(){ } | diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_Runtime.codegen.cs index 65fa29f408..c376721682 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_Runtime.codegen.cs +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_Runtime.codegen.cs @@ -1,7 +1,7 @@ #pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d3c3d6059615673cb46fc4974164d61eabadb890" // #pragma warning disable 1591 -namespace AspNetCore +namespace __BlazorGenerated { #line hidden using System; @@ -9,7 +9,7 @@ namespace AspNetCore using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; - public class BasicComponent : Microsoft.AspNetCore.Components.ComponentBase, IDisposable + public class AspNetCore_d3c3d6059615673cb46fc4974164d61eabadb890 : Microsoft.AspNetCore.Components.ComponentBase, IDisposable { #pragma warning disable 1998 protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder) diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_Runtime.ir.txt index 58d2bd23dd..65c88c6ce0 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_Runtime.ir.txt +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent_Runtime.ir.txt @@ -1,11 +1,11 @@ Document - - NamespaceDeclaration - - AspNetCore + NamespaceDeclaration - - __BlazorGenerated UsingDirective - (1:0,1 [14] ) - System UsingDirective - (16:1,1 [34] ) - System.Collections.Generic UsingDirective - (51:2,1 [19] ) - System.Linq UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks UsingDirective - (102:4,1 [37] ) - Microsoft.AspNetCore.Components - ClassDeclaration - - public - BasicComponent - Microsoft.AspNetCore.Components.ComponentBase - IDisposable + ClassDeclaration - - public - AspNetCore_d3c3d6059615673cb46fc4974164d61eabadb890 - Microsoft.AspNetCore.Components.ComponentBase - IDisposable MethodDeclaration - - protected override - void - BuildRenderTree CSharpCode - IntermediateToken - - CSharp - base.BuildRenderTree(builder); diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDocumentClassifierPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDocumentClassifierPass.cs index 09197b56b5..4a992de20a 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDocumentClassifierPass.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDocumentClassifierPass.cs @@ -17,6 +17,25 @@ namespace Microsoft.AspNetCore.Razor.Language.Components private static readonly char[] PathSeparators = new char[] { '/', '\\' }; private static readonly char[] NamespaceSeparators = new char[] { '.' }; + /// + /// The base namespace. + /// + // This is a fallback value and will only be used if we can't compute + // a reasonable namespace. + public string BaseNamespace { get; set; } = "__BlazorGenerated"; + + /// + /// Gets or sets whether to mangle class names. + /// + /// Set to true in the IDE so we can generated mangled class names. This is needed + /// to avoid conflicts between generated design-time code and the code in the editor. + /// + /// A better workaround for this would be to create a singlefilegenerator that overrides + /// the codegen process when a document is open, but this is more involved, so hacking + /// it for now. + /// + public bool MangleClassNames { get; set; } = false; + protected override string DocumentKind => ComponentDocumentKind; // Ensure this runs before the MVC classifiers which have Order = 0 @@ -32,40 +51,35 @@ namespace Microsoft.AspNetCore.Razor.Language.Components return new ComponentCodeTarget(options, TargetExtensions); } - protected override void OnDocumentStructureCreated(RazorCodeDocument codeDocument, NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class, MethodDeclarationIntermediateNode method) + /// + protected override void OnDocumentStructureCreated( + RazorCodeDocument codeDocument, + NamespaceDeclarationIntermediateNode @namespace, + ClassDeclarationIntermediateNode @class, + MethodDeclarationIntermediateNode method) { - base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method); - if (!TryComputeNamespaceAndClass( - codeDocument.Source.FilePath, - codeDocument.Source.RelativePath, - out var computedNamespace, - out var computedClass)) + codeDocument.Source.FilePath, + codeDocument.Source.RelativePath, + out var computedNamespace, + out var computedClass)) { // If we can't compute a nice namespace (no relative path) then just generate something // mangled. - computedNamespace = "AspNetCore"; + computedNamespace = BaseNamespace; var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum()); computedClass = $"AspNetCore_{checksum}"; } + if (MangleClassNames) + { + computedClass = "__" + computedClass; + } + @namespace.Content = computedNamespace; + @class.BaseType = ComponentsApi.ComponentBase.FullTypeName; @class.ClassName = computedClass; - @class.BaseType = $"{CodeGenerationConstants.ComponentBase.FullTypeName}"; - var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath; - if (string.IsNullOrEmpty(filePath)) - { - // It's possible for a Razor document to not have a file path. - // Eg. When we try to generate code for an in memory document like default imports. - var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum()); - @class.ClassName = $"AspNetCore_{checksum}"; - } - else - { - @class.ClassName = CSharpIdentifier.SanitizeIdentifier(Path.GetFileNameWithoutExtension(filePath)); - } - @class.Modifiers.Clear(); @class.Modifiers.Add("public"); @@ -82,8 +96,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Components @class.TypeParameters.Add(new TypeParameter() { ParameterName = typeParamNode.Tokens.First().Content, }); } - method.MethodName = CodeGenerationConstants.ComponentBase.BuildRenderTree; method.ReturnType = "void"; + method.MethodName = ComponentsApi.ComponentBase.BuildRenderTree; method.Modifiers.Clear(); method.Modifiers.Add("protected"); method.Modifiers.Add("override"); @@ -91,8 +105,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Components method.Parameters.Clear(); method.Parameters.Add(new MethodParameter() { - TypeName = CodeGenerationConstants.RenderTreeBuilder.FullTypeName, - ParameterName = CodeGenerationConstants.ComponentBase.BuildRenderTreeParameter, + ParameterName = "builder", + TypeName = ComponentsApi.RenderTreeBuilder.FullTypeName, }); // We need to call the 'base' method as the first statement. @@ -101,11 +115,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Components callBase.Children.Add(new IntermediateToken { Kind = TokenKind.CSharp, - Content = $"base.{CodeGenerationConstants.ComponentBase.BuildRenderTree}({CodeGenerationConstants.ComponentBase.BuildRenderTreeParameter});" + Content = $"base.{ComponentsApi.ComponentBase.BuildRenderTree}(builder);" }); method.Children.Insert(0, callBase); } + // In general documents will have a relative path (relative to the project root). + // We can only really compute a nice class/namespace when we know a relative path. + // + // However all kinds of thing are possible in tools. We shouldn't barf here if the document isn't + // set up correctly. private bool TryComputeNamespaceAndClass(string filePath, string relativePath, out string @namespace, out string @class) { if (filePath == null || relativePath == null || filePath.Length <= relativePath.Length) @@ -158,4 +177,4 @@ namespace Microsoft.AspNetCore.Razor.Language.Components internal static bool IsBuildRenderTreeBaseCall(CSharpCodeIntermediateNode node) => node.Annotations[BuildRenderTreeBaseCallAnnotation] != null; } -} \ No newline at end of file +} diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs index 91aa32f4f3..02bf8e3fcf 100644 --- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs +++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs @@ -207,7 +207,9 @@ namespace Microsoft.CodeAnalysis.Razor { var attribute = attributes[j]; - if (attribute.AttributeClass == bindElement) + // We need to check the constructor argument length here, because this can show up as 0 + // if the language service fails to initialize. This is an invalid case, so skip it. + if (attribute.AttributeClass == bindElement && attribute.ConstructorArguments.Length == 4) { results.Add(new ElementBindData( type.ContainingAssembly.Name, @@ -218,7 +220,7 @@ namespace Microsoft.CodeAnalysis.Razor (string)attribute.ConstructorArguments[2].Value, (string)attribute.ConstructorArguments[3].Value)); } - else if (attribute.AttributeClass == bindInputElement) + else if (attribute.AttributeClass == bindInputElement && attribute.ConstructorArguments.Length == 4) { results.Add(new ElementBindData( type.ContainingAssembly.Name, diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets index 15593fa737..af7427334c 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets @@ -49,7 +49,9 @@ Copyright (c) .NET Foundation. All rights reserved. Condition="'%(RazorComponentWithTargetPath.GeneratedDeclaration)' == ''" /> - <_RazorComponentDeclaration Include="%(RazorComponentWithTargetPath.GeneratedDeclaration)" /> + <_RazorComponentDeclaration Include="@(RazorComponentWithTargetPath->'%(GeneratedDeclaration)')"> + %(Identity) + <_RazorComponentDefinition Include="%(RazorComponentWithTargetPath.GeneratedOutput)" /> diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets index 2a9f95d7e4..a1b33cf7cc 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets @@ -29,6 +29,17 @@ Copyright (c) .NET Foundation. All rights reserved. + + + + MSBuild:RazorGenerateComponentDeclarationDesignTime + Never + + + + + + From 32a8a7485eb49828ebddeb2ef4be6a6b2230832d Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 7 Jan 2019 16:33:11 -0800 Subject: [PATCH 042/337] Remove workarounds for missing 3.0 support Leading up the release of VS 16.0p1 we added workarounds to the SDK to make Razor fall back to the 2.1 configuration for design-time. Since we're adding the 3.0 language support to preview2 we can remove these workarounds. These features have been available in internal builds for some time. \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/e6be8a7a3e092cd79c3243fb42521e85b8245573 --- ...rosoft.NET.Sdk.Razor.Configuration.targets | 33 ++----------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Configuration.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Configuration.targets index 7b27791129..f904665aee 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Configuration.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Configuration.targets @@ -54,12 +54,6 @@ Copyright (c) .NET Foundation. All rights reserved. 3.0 - - - 2.1 MVC-3.0 - - - MVC-2.1 @@ -81,33 +69,16 @@ Copyright (c) .NET Foundation. All rights reserved. it here. The IDE is hardcoded to inject 2.0 support when needed. The settings flowing through MSBuild should reflect the project's runtime. --> - + MVC-3.0;$(CustomRazorExtension) - - - - MVC-2.1;$(CustomRazorExtension) - - + Microsoft.AspNetCore.Mvc.Razor.Extensions $(RazorSdkDirectoryRoot)extensions\mvc-3-0\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll - - - - Microsoft.AspNetCore.Mvc.Razor.Extensions - $(RazorSdkDirectoryRoot)extensions\mvc-2-1\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll - From f87d9b533576352e80ec4c6c41dd7f76e6f4dec5 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Mon, 7 Jan 2019 20:18:39 -0800 Subject: [PATCH 043/337] Fix null ref in the parser (dotnet/aspnetcore-tooling#103) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/8e1629b60b26c438b7bfbbf0e654a4bf15141788 --- .../src/Legacy/HtmlMarkupParser.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs index ed20cc9617..60bca288c6 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs @@ -1591,6 +1591,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var node = tagBlock.Attributes[i]; if (node is MarkupAttributeBlockSyntax attributeBlock && + attributeBlock.Value != null && attributeBlock.Value.Children.Count > 0 && IsTypeAttribute(attributeBlock)) { From 77bd9d343cae6329c1980e0faf3b9855e4dd1602 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Mon, 7 Jan 2019 19:37:08 -0800 Subject: [PATCH 044/337] Fixed exception with non taghelper start/end void tags \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/ee8fdae75612e9d5c20b6947c1e3945d5c917cbd --- .../src/Legacy/TagHelperParseTreeRewriter.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs index 13a6a89cdc..3ad6edcff9 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs @@ -144,8 +144,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Non-TagHelper tag. ValidateParentAllowsPlainStartTag(startTag); - if (!startTag.IsSelfClosing() && !startTag.IsVoidElement()) + if (node.EndTag != null || (!startTag.IsSelfClosing() && !startTag.IsVoidElement())) { + // Ideally we don't want to keep track of self-closing or void tags. + // But if a matching end tag exists, keep track of the start tag no matter what. + // We will just assume the parser had a good reason to do this. var tracker = new TagTracker(tagName, isTagHelper: false); _trackerStack.Push(tracker); } From 5b5aa6837fd0c3d23e40c32129a6eb2cb62f0fa8 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Tue, 8 Jan 2019 09:42:01 -0800 Subject: [PATCH 045/337] Properly handle attr-value prefix in markup pass Fixes aspnet/AspNetCoredotnet/aspnetcore-tooling#6480 We were missing handling for the attribute value prefix of a markup attribute during the markup block rewrite pass. This is properly handled inside the runtime code writer so you wouldn't see this bug if the contents of the element were dynamic (and thus could not be rewritten). Most of the churn here is due to renaming classes. We generally prefer the term *markup* over *html* in code artifacts, and this was one piece of new code that refers to html. \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/d16eafd667a04e40944158dd92d786cebadc1a2b --- ...{ComponentHtmlBlockPass.cs => ComponentMarkupBlockPass.cs} | 4 +++- .../src/RazorProjectEngine.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) rename src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/{ComponentHtmlBlockPass.cs => ComponentMarkupBlockPass.cs} (98%) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentHtmlBlockPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentMarkupBlockPass.cs similarity index 98% rename from src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentHtmlBlockPass.cs rename to src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentMarkupBlockPass.cs index 8327b33318..4d467d6203 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentHtmlBlockPass.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentMarkupBlockPass.cs @@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components // // Does not preserve insignificant details of the HTML, like tag closing style // or quote style. - internal class ComponentHtmlBlockPass : ComponentIntermediateNodePassBase, IRazorOptimizationPass + internal class ComponentMarkupBlockPass : ComponentIntermediateNodePassBase, IRazorOptimizationPass { // Runs LATE because we want to destroy structure. public override int Order => 10000; @@ -322,6 +322,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Components { for (var i = 0; i < node.Children.Count; i++) { + Builder.Append(node.Prefix); + if (node.Children[i] is IntermediateToken token) { Builder.Append(token.Content); diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngine.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngine.cs index d29ba2e775..39afa6b0ae 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngine.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngine.cs @@ -231,7 +231,7 @@ namespace Microsoft.AspNetCore.Razor.Language builder.Features.Add(new ComponentTemplateDiagnosticPass()); builder.Features.Add(new ComponentGenericTypePass()); builder.Features.Add(new ComponentChildContentDiagnosticPass()); - builder.Features.Add(new ComponentHtmlBlockPass()); + builder.Features.Add(new ComponentMarkupBlockPass()); } private static void LoadExtensions(RazorProjectEngineBuilder builder, IReadOnlyList extensions) From e1245d874f695ac5f65cf9412b0cbbfc9be53c5b Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Tue, 8 Jan 2019 16:11:18 -0800 Subject: [PATCH 046/337] Fix: Missing void end tag when targeted by TH with WithoutEndTag structure (dotnet/aspnetcore-tooling#105) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/33bf2691d5a58e9a071b9774c3867d8c5120cf4a --- .../src/Legacy/TagHelperParseTreeRewriter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs index 3ad6edcff9..47f96d7d3b 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs @@ -111,18 +111,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { var tagHelperElement = SyntaxFactory.MarkupTagHelperElement(tagHelperStart, body: new SyntaxList(), endTag: null); var rewrittenTagHelper = tagHelperElement.WithTagHelperInfo(tagHelperInfo); - if (node.Body.Count == 0) + if (node.Body.Count == 0 && node.EndTag == null) { return rewrittenTagHelper; } - // This tag contains a body which needs to be moved to the parent. + // This tag contains a body and/or an end tag which needs to be moved to the parent. var rewrittenNodes = SyntaxListBuilder.Create(); rewrittenNodes.Add(rewrittenTagHelper); var rewrittenBody = VisitList(node.Body); rewrittenNodes.AddRange(rewrittenBody); - return SyntaxFactory.MarkupElement(startTag: null, body: rewrittenNodes.ToList(), endTag: null); + return SyntaxFactory.MarkupElement(startTag: null, body: rewrittenNodes.ToList(), endTag: node.EndTag); } else if (node.EndTag == null) { From 14afcc3eafacad0afa81ba6089b6b1b8ed67f359 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Wed, 9 Jan 2019 11:39:02 -0800 Subject: [PATCH 047/337] Reenable skipped test (dotnet/aspnetcore-tooling#99) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/2ad0641b1e8e0cebb17115e3b8a7eb878f460d5c --- .../test/IntegrationTests/BuildServerIntegrationTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerIntegrationTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerIntegrationTest.cs index cad1a57355..bb144b162e 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerIntegrationTest.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/test/IntegrationTests/BuildServerIntegrationTest.cs @@ -141,9 +141,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests } // Skipping on MacOS because of https://github.com/dotnet/corefx/issues/33141. - // Skipping on Linux because of https://github.com/aspnet/Razor/issues/2525. [ConditionalFact] - [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] + [OSSkipCondition(OperatingSystems.MacOSX)] [InitializeTestProject("SimpleMvc")] public async Task ManualServerShutdown_NoPipeName_ShutsDownServer() { From b449a444408dda116d0716f74d5c2d6b9445c12a Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Wed, 9 Jan 2019 11:41:10 -0800 Subject: [PATCH 048/337] Fix void tags grouping logic (dotnet/aspnetcore-tooling#110) * Fix void tags grouping logic * Handle bang in tag name \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/2c41ae95503b6fcc0b2f067130b8113de5ccb674 --- .../src/Legacy/HtmlMarkupParser.cs | 49 +++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs index 60bca288c6..85f7540dd9 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/HtmlMarkupParser.cs @@ -71,9 +71,22 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy while (_tagTracker.Count > 0) { var tracker = _tagTracker.Pop(); - var element = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), endTag: null); - builder.AddRange(tracker.PreviousNodes); - builder.Add(element); + if (IsVoidElement(tracker.TagName)) + { + // We were tracking a void element but we reached the end of the document without finding a matching end tag. + // So, close that element and move its content to its parent. + var children = builder.Consume(); + var voidElement = SyntaxFactory.MarkupElement(tracker.StartTag, EmptySyntaxList, endTag: null); + builder.AddRange(tracker.PreviousNodes); + builder.Add(voidElement); + builder.AddRange(children); + } + else + { + var element = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), endTag: null); + builder.AddRange(tracker.PreviousNodes); + builder.Add(element); + } } var markup = SyntaxFactory.MarkupBlock(builder.ToList()); @@ -533,6 +546,19 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy private bool TryRecoverStartTag(in SyntaxListBuilder builder, string endTagName, MarkupEndTagSyntax endTag) { + // First check if the tag we're tracking is a void tag. If so, we need to close it out before moving on. + while (_tagTracker.Count > 0 && + !string.Equals(CurrentStartTagName, endTagName, StringComparison.OrdinalIgnoreCase) && + IsVoidElement(CurrentStartTagName)) + { + var tracker = _tagTracker.Pop(); + var children = builder.Consume(); + var voidElement = SyntaxFactory.MarkupElement(tracker.StartTag, EmptySyntaxList, endTag: null); + builder.AddRange(tracker.PreviousNodes); + builder.Add(voidElement); + builder.AddRange(children); + } + var malformedTagCount = 0; foreach (var tag in _tagTracker) { @@ -647,7 +673,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Completed tags in code blocks have no accepted characters. SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None; - if (tagMode != MarkupTagMode.SelfClosing && ParserHelpers.VoidElements.Contains(tagName)) + if (tagMode != MarkupTagMode.SelfClosing && IsVoidElement(tagName)) { // This is a void element. // Technically, void elements like "meta" are not allowed to have end tags. Just in case they do, @@ -2114,6 +2140,21 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return last.Green; } + private static bool IsVoidElement(string tagName) + { + if (string.IsNullOrEmpty(tagName)) + { + return false; + } + + if (tagName.StartsWith("!")) + { + tagName = tagName.Substring(1); + } + + return ParserHelpers.VoidElements.Contains(tagName); + } + private enum ParseMode { Markup, From b0e2dc2addb46661ac39fdce3253193eab40c33d Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Thu, 10 Jan 2019 13:55:28 -0800 Subject: [PATCH 049/337] Added check to ensure we generate syntax tree with full fidelity (dotnet/aspnetcore-tooling#111) * Added check to ensure we generate syntax tree with full fidelity * Better check * Feedback \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/88653fc34823633fbad1e7e9b7dffbbce8e27a36 --- .../Language/Legacy/ParserTestBase.cs | 130 +++--------------- .../Language/SyntaxTreeVerifier.cs | 29 +++- 2 files changed, 44 insertions(+), 115 deletions(-) diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs index 80287a2f9e..522fa00289 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs @@ -4,16 +4,13 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Text.RegularExpressions; using System.Threading; -using System.Text; using Xunit; using Xunit.Sdk; -using System.Text.RegularExpressions; -using Microsoft.AspNetCore.Razor.Language.Syntax; namespace Microsoft.AspNetCore.Razor.Language.Legacy { @@ -175,44 +172,19 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return Regex.Replace(content, "(? directives, bool designTime) - { - return ParseBlock(RazorLanguageVersion.Latest, document, directives, designTime); - } - internal abstract RazorSyntaxTree ParseBlock(RazorLanguageVersion version, string document, IEnumerable directives, bool designTime); - internal RazorSyntaxTree ParseDocument(string document, bool designTime = false, RazorParserFeatureFlags featureFlags = null) - { - return ParseDocument(RazorLanguageVersion.Latest, document, designTime, featureFlags); - } - - internal RazorSyntaxTree ParseDocument(RazorLanguageVersion version, string document, bool designTime = false, RazorParserFeatureFlags featureFlags = null) - { - return ParseDocument(version, document, null, designTime, featureFlags); - } - - internal RazorSyntaxTree ParseDocument(string document, IEnumerable directives, bool designTime = false, RazorParserFeatureFlags featureFlags = null) + internal RazorSyntaxTree ParseDocument(string document, bool designTime = false, IEnumerable directives = null, RazorParserFeatureFlags featureFlags = null) { return ParseDocument(RazorLanguageVersion.Latest, document, directives, designTime, featureFlags); } @@ -271,11 +243,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return syntaxTree; } - internal RazorSyntaxTree ParseCodeBlock(string document, bool designTime = false) - { - return ParseCodeBlock(RazorLanguageVersion.Latest, document, Enumerable.Empty(), designTime); - } - internal virtual RazorSyntaxTree ParseCodeBlock( RazorLanguageVersion version, string document, @@ -306,86 +273,39 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy internal virtual void ParseBlockTest(string document) { - ParseBlockTest(document, null, false, new RazorDiagnostic[0]); + ParseBlockTest(document, null, false); } - internal virtual void ParseBlockTest(string document, IEnumerable directives) + internal virtual void ParseBlockTest(string document, bool designTime) { - ParseBlockTest(document, directives, null); - } - - internal virtual void ParseBlockTest(string document, params RazorDiagnostic[] expectedErrors) - { - ParseBlockTest(document, false, expectedErrors); - } - - internal virtual void ParseBlockTest(string document, bool designTime, params RazorDiagnostic[] expectedErrors) - { - ParseBlockTest(document, null, designTime, expectedErrors); + ParseBlockTest(document, null, designTime); } internal virtual void ParseBlockTest(RazorLanguageVersion version, string document) { - ParseBlockTest(version, document, false, null); + ParseBlockTest(version, document, false); } - internal virtual void ParseBlockTest(string document, IEnumerable directives, params RazorDiagnostic[] expectedErrors) + internal virtual void ParseBlockTest(string document, IEnumerable directives) { - ParseBlockTest(document, directives, false, expectedErrors); + ParseBlockTest(document, directives, false); } - internal virtual void ParseBlockTest(RazorLanguageVersion version, string document, bool designTime, params RazorDiagnostic[] expectedErrors) + internal virtual void ParseBlockTest(RazorLanguageVersion version, string document, bool designTime) { - ParseBlockTest(version, document, null, designTime, expectedErrors); + ParseBlockTest(version, document, null, designTime); } - internal virtual void ParseBlockTest(string document, IEnumerable directives, bool designTime, params RazorDiagnostic[] expectedErrors) + internal virtual void ParseBlockTest(string document, IEnumerable directives, bool designTime) { - ParseBlockTest(RazorLanguageVersion.Latest, document, directives, designTime, expectedErrors); + ParseBlockTest(RazorLanguageVersion.Latest, document, directives, designTime); } - internal virtual void ParseBlockTest(RazorLanguageVersion version, string document, IEnumerable directives, bool designTime, params RazorDiagnostic[] expectedErrors) + internal virtual void ParseBlockTest(RazorLanguageVersion version, string document, IEnumerable directives, bool designTime) { var result = ParseBlock(version, document, directives, designTime); - BaselineTest(result); - } - - internal virtual void SingleSpanBlockTest(string document) - { - SingleSpanBlockTest(document, default, default); - } - - internal virtual void SingleSpanBlockTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters = AcceptedCharactersInternal.Any) - { - SingleSpanBlockTest(document, blockKind, spanType, acceptedCharacters, expectedError: null); - } - - internal virtual void SingleSpanBlockTest(string document, string spanContent, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters = AcceptedCharactersInternal.Any) - { - SingleSpanBlockTest(document, spanContent, blockKind, spanType, acceptedCharacters, expectedErrors: null); - } - - internal virtual void SingleSpanBlockTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType, params RazorDiagnostic[] expectedError) - { - SingleSpanBlockTest(document, document, blockKind, spanType, expectedError); - } - - internal virtual 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 virtual void SingleSpanBlockTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters, params RazorDiagnostic[] expectedError) - { - SingleSpanBlockTest(document, document, blockKind, spanType, acceptedCharacters, expectedError); - } - - internal virtual void SingleSpanBlockTest(string document, string spanContent, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters, params RazorDiagnostic[] expectedErrors) - { - var result = ParseBlock(document, designTime: false); - - BaselineTest(result); + BaselineTest(result, ensureFullFidelity: false); } internal virtual void ParseDocumentTest(string document) @@ -393,14 +313,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy ParseDocumentTest(document, null, false); } - internal virtual void ParseDocumentTest(string document, params RazorDiagnostic[] expectedErrors) + internal virtual void ParseDocumentTest(string document, IEnumerable directives) { - ParseDocumentTest(document, false, expectedErrors); - } - - internal virtual void ParseDocumentTest(string document, IEnumerable directives, params RazorDiagnostic[] expectedErrors) - { - ParseDocumentTest(document, directives, false, expectedErrors); + ParseDocumentTest(document, directives, false); } internal virtual void ParseDocumentTest(string document, bool designTime) @@ -408,14 +323,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy ParseDocumentTest(document, null, designTime); } - internal virtual void ParseDocumentTest(string document, bool designTime, params RazorDiagnostic[] expectedErrors) + internal virtual void ParseDocumentTest(string document, IEnumerable directives, bool designTime) { - ParseDocumentTest(document, null, designTime, expectedErrors); - } - - internal virtual void ParseDocumentTest(string document, IEnumerable directives, bool designTime, params RazorDiagnostic[] expectedErrors) - { - var result = ParseDocument(document, directives, designTime); + var result = ParseDocument(document, designTime, directives); BaselineTest(result); } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/SyntaxTreeVerifier.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/SyntaxTreeVerifier.cs index fee17d1368..f4f416616c 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/SyntaxTreeVerifier.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/SyntaxTreeVerifier.cs @@ -2,20 +2,37 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Text; using Microsoft.AspNetCore.Razor.Language.Legacy; using Microsoft.AspNetCore.Razor.Language.Syntax; +using Xunit; namespace Microsoft.AspNetCore.Razor.Language { // Verifies recursively that a syntax tree has no gaps in terms of position/location. internal class SyntaxTreeVerifier { - public static void Verify(RazorSyntaxTree syntaxTree) + public static void Verify(RazorSyntaxTree syntaxTree, bool ensureFullFidelity = true) { - new Verifier(syntaxTree.Source).Visit(syntaxTree.Root); + var verifier = new Verifier(syntaxTree.Source); + verifier.Visit(syntaxTree.Root); + + if (ensureFullFidelity) + { + var syntaxTreeString = syntaxTree.Root.ToFullString(); + var builder = new StringBuilder(syntaxTree.Source.Length); + for (var i = 0; i < syntaxTree.Source.Length; i++) + { + builder.Append(syntaxTree.Source[i]); + } + var sourceString = builder.ToString(); + + // Make sure the syntax tree contains all of the text in the document. + Assert.Equal(sourceString, syntaxTreeString); + } } - private class Verifier : SyntaxRewriter + private class Verifier : SyntaxWalker { private readonly SourceLocationTracker _tracker; private readonly RazorSourceDocument _source; @@ -26,7 +43,9 @@ namespace Microsoft.AspNetCore.Razor.Language _source = source; } - public override SyntaxNode VisitToken(SyntaxToken token) + public SourceLocationTracker SourceLocationTracker => _tracker; + + public override void VisitToken(SyntaxToken token) { if (token != null && !token.IsMissing && token.Kind != SyntaxKind.Marker) { @@ -39,7 +58,7 @@ namespace Microsoft.AspNetCore.Razor.Language _tracker.UpdateLocation(token.Content); } - return base.VisitToken(token); + base.VisitToken(token); } } } From 95419383271d581e2de102025c7cfe0a8910ac8d Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Fri, 11 Jan 2019 12:39:35 -0800 Subject: [PATCH 050/337] Fix A VS issue The issue here is that the downlevel SDK (2.1/2.2) don't define the component-related targets needed for the component design time build. Depending on the ordering of targets, this can break all features in VS that depend on the design-time build. Since we want this to noop in those cases, the best fix is to make our targets depend on a target property that will be empty in the downlevel SDKS, but will contain our targets in the 3.0 SDK. (cherry picked from commit dotnet/aspnetcore-tooling@b88b32c73ac823febf2319690e5b7ff9f23e9e28) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/1c4b19ae88c4a4f53671b85f8afb0a6c32c0efbf --- .../Microsoft.NET.Sdk.Razor.DesignTime.targets | 16 +++++++++++++--- .../Sdk.Razor.CurrentVersion.props | 9 +++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets index a1b33cf7cc..29d5e8ea4c 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets @@ -74,16 +74,26 @@ Copyright (c) .NET Foundation. All rights reserved. Returns="@(RazorGenerateWithTargetPath)"> + - + + + DependsOnTargets="$(_RazorGenerateComponentDeclarationDesignTimeDependsOn)"> diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.props b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.props index 71100e6541..aa0a8da485 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.props +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.props @@ -78,4 +78,13 @@ Copyright (c) .NET Foundation. All rights reserved. + + + <_RazorGenerateComponentDeclarationDesignTimeDependsOn>ResolveRazorConfiguration;ResolveRazorComponentInputs;AssignRazorComponentTargetPaths;RazorGenerateComponentDeclaration + <_RazorGenerateComponentDesignTimeDependsOn>ResolveRazorComponentInputs;AssignRazorComponentTargetPaths + + From d5e9a153c736816c954b74d90147819a80b3de60 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Mon, 14 Jan 2019 11:59:37 -0800 Subject: [PATCH 051/337] Correctly handle whitespace that precedes a Razor directive (dotnet/aspnetcore-tooling#117) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/15556c8ff3a15c41794c45a2d8fe31adf8bbd94d --- .../src/Components/ComponentWhitespacePass.cs | 18 +------ .../src/Legacy/CSharpCodeParser.cs | 51 +++++++++++++++---- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentWhitespacePass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentWhitespacePass.cs index 0cc0e117e9..2713f96de8 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentWhitespacePass.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentWhitespacePass.cs @@ -77,11 +77,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Components break; case CSharpCodeIntermediateNode codeIntermediateNode: - // A C# code node could be empty. We can't remove them, but we can skip them. shouldRemoveNode = false; - shouldContinueIteration = - IsEmpty(codeIntermediateNode) || - ComponentDocumentClassifierPass.IsBuildRenderTreeBaseCall(codeIntermediateNode); + shouldContinueIteration = ComponentDocumentClassifierPass.IsBuildRenderTreeBaseCall(codeIntermediateNode); break; default: @@ -113,18 +110,5 @@ namespace Microsoft.AspNetCore.Razor.Language.Components Forwards, Backwards } - - private static bool IsEmpty(CSharpCodeIntermediateNode node) - { - for (var i = 0; i < node.Children.Count; i++) - { - if (!(node.Children[i] is IntermediateToken token && string.IsNullOrWhiteSpace(token.Content))) - { - return false; - } - } - - return true; - } } } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpCodeParser.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpCodeParser.cs index e63c1dbe90..bfdcbad2aa 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpCodeParser.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpCodeParser.cs @@ -124,9 +124,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { NextToken(); - // Unless changed, the block is a statement block - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - builder.Add(OutputTokensAsStatementLiteral()); + var precedingWhitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); // We are usually called when the other parser sees a transition '@'. Look for it. SyntaxToken transitionToken = null; @@ -157,20 +155,33 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy if (At(SyntaxKind.LeftBrace)) { + // This is a statement. We want to preserve preceding whitespace in the output. + Accept(precedingWhitespace); + builder.Add(OutputTokensAsStatementLiteral()); + var statementBody = ParseStatementBody(); var statement = SyntaxFactory.CSharpStatement(transition, statementBody); builder.Add(statement); } else if (At(SyntaxKind.LeftParenthesis)) { + // This is an explicit expression. We want to preserve preceding whitespace in the output. + Accept(precedingWhitespace); + builder.Add(OutputTokensAsStatementLiteral()); + var expressionBody = ParseExplicitExpressionBody(); var expression = SyntaxFactory.CSharpExplicitExpression(transition, expressionBody); builder.Add(expression); } else if (At(SyntaxKind.Identifier)) { - if (!TryParseDirective(builder, transition, CurrentToken.Content)) + if (!TryParseDirective(builder, precedingWhitespace, transition, CurrentToken.Content)) { + // Not a directive. + // This is an implicit expression. We want to preserve preceding whitespace in the output. + Accept(precedingWhitespace); + builder.Add(OutputTokensAsStatementLiteral()); + if (string.Equals( CurrentToken.Content, SyntaxConstants.CSharp.HelperKeyword, @@ -189,9 +200,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } else if (At(SyntaxKind.Keyword)) { - if (!TryParseDirective(builder, transition, CurrentToken.Content) && - !TryParseKeyword(builder, transition)) + if (!TryParseDirective(builder, precedingWhitespace, transition, CurrentToken.Content) && + !TryParseKeyword(builder, precedingWhitespace, transition)) { + // Not a directive or keyword. + // This is an implicit expression. We want to preserve preceding whitespace in the output. + Accept(precedingWhitespace); + builder.Add(OutputTokensAsStatementLiteral()); + // Not a directive or a special keyword. Just parse as an implicit expression. var implicitExpressionBody = ParseImplicitExpressionBody(); var implicitExpression = SyntaxFactory.CSharpImplicitExpression(transition, implicitExpressionBody); @@ -202,7 +218,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } else { - // Invalid character + // Invalid character after transition. + // Preserve the preceding whitespace in the output + Accept(precedingWhitespace); + builder.Add(OutputTokensAsStatementLiteral()); + SpanContext.ChunkGenerator = new ExpressionChunkGenerator(); SpanContext.EditHandler = new ImplicitExpressionEditHandler( Language.TokenizeString, @@ -616,7 +636,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy ParseCodeBlock(builder, block); break; case SyntaxKind.Keyword: - if (!TryParseKeyword(builder, transition: null)) + if (!TryParseKeyword(builder, whitespace: null, transition: null)) { ParseStandardStatement(builder); } @@ -797,10 +817,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } } - protected bool TryParseDirective(in SyntaxListBuilder builder, CSharpTransitionSyntax transition, string directive) + protected bool TryParseDirective(in SyntaxListBuilder builder, IEnumerable whitespace, CSharpTransitionSyntax transition, string directive) { if (_directiveParserMap.TryGetValue(directive, out var handler)) { + // This is a directive. We don't want to generate the preceding whitespace in the output. + Accept(whitespace); + builder.Add(OutputTokensAsEphemeralLiteral()); + SpanContext.ChunkGenerator = SpanChunkGenerator.Null; handler(builder, transition); return true; @@ -1544,12 +1568,19 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } } - private bool TryParseKeyword(in SyntaxListBuilder builder, CSharpTransitionSyntax transition) + private bool TryParseKeyword(in SyntaxListBuilder builder, IEnumerable whitespace, CSharpTransitionSyntax transition) { var result = CSharpTokenizer.GetTokenKeyword(CurrentToken); Debug.Assert(CurrentToken.Kind == SyntaxKind.Keyword && result.HasValue); if (_keywordParserMap.TryGetValue(result.Value, out var handler)) { + if (whitespace != null) + { + // This is a keyword. We want to preserve preceding whitespace in the output. + Accept(whitespace); + builder.Add(OutputTokensAsStatementLiteral()); + } + handler(builder, transition); return true; } From 56695d17c98acfd3356dac358aeef4b1aceb6a5d Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Mon, 14 Jan 2019 14:17:22 -0800 Subject: [PATCH 052/337] Set ParserContext.StartOfLine to true when parsing starts (dotnet/aspnetcore-tooling#116) * Set ParserContext.StartOfLine to true when parsing starts * Missed baselines \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/a80c3a981aa332bb9b1ed77e09214c04cc1abf8b --- .../IncompleteDirectives_DesignTime.ir.txt | 4 ++-- .../IncompleteDirectives_DesignTime.ir.txt | 4 ++-- .../IncompleteDirectives_Runtime.codegen.cs | 4 ++-- .../IncompleteDirectives_Runtime.ir.txt | 6 +++--- .../IncompleteDirectives_DesignTime.ir.txt | 4 ++-- .../IncompleteDirectives_Runtime.codegen.cs | 2 +- .../IncompleteDirectives_Runtime.ir.txt | 4 ++-- .../src/Legacy/ParserContext.cs | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt index 3a6d24fc1e..b39482f802 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt @@ -34,8 +34,8 @@ Document - CSharpCode - IntermediateToken - - CSharp - #pragma warning restore 0414 MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync - HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) - IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + HtmlContent - (85:1,0 [2] IncompleteDirectives.cshtml) + IntermediateToken - (85:1,0 [2] IncompleteDirectives.cshtml) - Html - \n MalformedDirective - (87:2,0 [6] IncompleteDirectives.cshtml) - model DirectiveToken - (93:2,6 [0] IncompleteDirectives.cshtml) - HtmlContent - (93:2,6 [2] IncompleteDirectives.cshtml) diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt index 2aeddc2fa2..bafb3e68a3 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt @@ -38,8 +38,8 @@ Document - CSharpCode - IntermediateToken - - CSharp - #pragma warning restore 0414 MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync - HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) - IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + HtmlContent - (85:1,0 [2] IncompleteDirectives.cshtml) + IntermediateToken - (85:1,0 [2] IncompleteDirectives.cshtml) - Html - \n MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page MalformedDirective - (102:4,0 [6] IncompleteDirectives.cshtml) - page HtmlContent - (108:4,6 [5] IncompleteDirectives.cshtml) diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs index 743eed291e..25d746e332 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs @@ -19,8 +19,8 @@ namespace AspNetCore #pragma warning disable 1998 public async override global::System.Threading.Tasks.Task ExecuteAsync() { - BeginContext(83, 4, true); - WriteLiteral("\r\n\r\n"); + BeginContext(85, 2, true); + WriteLiteral("\r\n"); EndContext(); BeginContext(108, 5, true); WriteLiteral("\"\r\n\r\n"); diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt index bd3bdd87e2..1b5f45c4bf 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt @@ -14,9 +14,9 @@ Document - ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync CSharpCode - - IntermediateToken - - CSharp - BeginContext(83, 4, true); - HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) - IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + IntermediateToken - - CSharp - BeginContext(85, 2, true); + HtmlContent - (85:1,0 [2] IncompleteDirectives.cshtml) + IntermediateToken - (85:1,0 [2] IncompleteDirectives.cshtml) - Html - \n CSharpCode - IntermediateToken - - CSharp - EndContext(); MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt index 2aeddc2fa2..bafb3e68a3 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt @@ -38,8 +38,8 @@ Document - CSharpCode - IntermediateToken - - CSharp - #pragma warning restore 0414 MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync - HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) - IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + HtmlContent - (85:1,0 [2] IncompleteDirectives.cshtml) + IntermediateToken - (85:1,0 [2] IncompleteDirectives.cshtml) - Html - \n MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page MalformedDirective - (102:4,0 [6] IncompleteDirectives.cshtml) - page HtmlContent - (108:4,6 [5] IncompleteDirectives.cshtml) diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs index 890a758536..fa72740aa3 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs @@ -18,7 +18,7 @@ namespace AspNetCore #pragma warning disable 1998 public async override global::System.Threading.Tasks.Task ExecuteAsync() { - WriteLiteral("\r\n\r\n"); + WriteLiteral("\r\n"); WriteLiteral("\"\r\n\r\n"); WriteLiteral("\r\n"); WriteLiteral("\r\n\r\n"); diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt index ee2a61fcb4..54ba239858 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt @@ -11,8 +11,8 @@ Document - RazorSourceChecksumAttribute - ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives - global::Microsoft.AspNetCore.Mvc.RazorPages.Page - MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync - HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml) - IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n + HtmlContent - (85:1,0 [2] IncompleteDirectives.cshtml) + IntermediateToken - (85:1,0 [2] IncompleteDirectives.cshtml) - Html - \n MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page MalformedDirective - (102:4,0 [6] IncompleteDirectives.cshtml) - page HtmlContent - (108:4,6 [5] IncompleteDirectives.cshtml) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ParserContext.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ParserContext.cs index 47799e94e9..e976191f92 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ParserContext.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/ParserContext.cs @@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy public bool InTemplateContext { get; set; } - public bool StartOfLine { get; set; } + public bool StartOfLine { get; set; } = true; public AcceptedCharactersInternal LastAcceptedCharacters { get; set; } = AcceptedCharactersInternal.None; From 148bc99cce07b26f3516882515849c5430103857 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 14 Jan 2019 10:07:08 -0800 Subject: [PATCH 053/337] Use a property to allow specifying component globbing pattern Workaround for https://github.com/aspnet/AspNetCore/issues/6500 \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/cee02237329f71823d54572c8fe79f2a9ea0d3c1 --- .../build/netstandard2.0/Sdk.Razor.CurrentVersion.targets | 3 ++- .../test/testassets/ComponentLibrary/ComponentLibrary.csproj | 5 +---- .../testassets/MvcWithComponents/MvcWithComponents.csproj | 5 +---- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets index a4cb71a514..245a4e0143 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets @@ -369,7 +369,7 @@ Copyright (c) .NET Foundation. All rights reserved. @@ -406,6 +406,7 @@ Copyright (c) .NET Foundation. All rights reserved. + diff --git a/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj b/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj index 077e7ae96b..0aca4f7bc1 100644 --- a/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj +++ b/src/Razor/test/testassets/ComponentLibrary/ComponentLibrary.csproj @@ -2,6 +2,7 @@ $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ + <_RazorComponentInclude>**\*.cshtml @@ -27,10 +28,6 @@ - - - - diff --git a/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj b/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj index 1d3cf1b9ed..9de30c05d9 100644 --- a/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj +++ b/src/Razor/test/testassets/MvcWithComponents/MvcWithComponents.csproj @@ -3,6 +3,7 @@ $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\ true + <_RazorComponentInclude>Components\**\*.cshtml @@ -29,10 +30,6 @@ - - - - From 40633dde21a1ce42bb56f762ca8f74ca0c1cd512 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 14 Jan 2019 08:24:20 -0800 Subject: [PATCH 054/337] Add attribute only bindings and fix dotnet/aspnetcore-tooling#6373 Adds a new API for WTE to call given a TagHelperBinding to determine if the binding should colorize/classify only the attributes of the HTML element in source code. This is driven by a new metadata item that the Components 'directive attributes' all set. There's no way for a user to access this feature via tag helpers currently, but it could be added easily in the future. Also fixing dotnet/aspnetcore-tooling#6376 while I'm in there. :+1: \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/df449beea9085221a1ba75ee61dcfbd2beb3aa34 --- .../src/Legacy/TagHelperBlockRewriter.cs | 2 +- .../src/Legacy/TagHelperParseTreeRewriter.cs | 4 +- .../src/TagHelperBinding.cs | 46 +++++++++++++++++-- .../src/TagHelperMetadata.cs | 2 + .../src/BindTagHelperDescriptorProvider.cs | 2 + ...EventHandlerTagHelperDescriptorProvider.cs | 2 +- .../src/RefTagHelperDescriptorProvider.cs | 15 ++++++ .../BindTagHelperDescriptorProviderTest.cs | 2 + ...tHandlerTagHelperDescriptorProviderTest.cs | 5 +- .../RefTagHelperDescriptorProviderTest.cs | 3 ++ 10 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs index fefcf4aeee..23a0a488a1 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy foreach (var descriptor in bindingResult.Descriptors) { - var boundRules = bindingResult.GetBoundRules(descriptor); + var boundRules = bindingResult.Mappings[descriptor]; var nonDefaultRule = boundRules.FirstOrDefault(rule => rule.TagStructure != TagStructure.Unspecified); if (nonDefaultRule?.TagStructure == TagStructure.WithoutEndTag) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs index 47f96d7d3b..1619f42240 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs @@ -336,7 +336,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy foreach (var descriptor in tagHelperBinding.Descriptors) { - var boundRules = tagHelperBinding.GetBoundRules(descriptor); + var boundRules = tagHelperBinding.Mappings[descriptor]; var invalidRule = boundRules.FirstOrDefault(rule => rule.TagStructure == TagStructure.WithoutEndTag); if (invalidRule != null) @@ -456,7 +456,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy TagStructure? baseStructure = null; foreach (var descriptor in bindingResult.Descriptors) { - var boundRules = bindingResult.GetBoundRules(descriptor); + var boundRules = bindingResult.Mappings[descriptor]; foreach (var rule in boundRules) { if (rule.TagStructure != TagStructure.Unspecified) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperBinding.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperBinding.cs index a5590c536e..4b88cf5b12 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperBinding.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperBinding.cs @@ -1,14 +1,13 @@ // 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; namespace Microsoft.AspNetCore.Razor.Language { public sealed class TagHelperBinding { - private IReadOnlyDictionary> _mappings; - internal TagHelperBinding( string tagName, IReadOnlyList> attributes, @@ -19,12 +18,42 @@ namespace Microsoft.AspNetCore.Razor.Language TagName = tagName; Attributes = attributes; ParentTagName = parentTagName; + Mappings = mappings; TagHelperPrefix = tagHelperPrefix; - _mappings = mappings; } - public IEnumerable Descriptors => _mappings.Keys; + public IEnumerable Descriptors => Mappings.Keys; + + /// + /// Gets a value that indicates whether the the binding matched on attributes only. + /// + /// false if the entire element should be classified as a tag helper. + /// + /// If this returns true, use TagHelperFactsService.GetBoundTagHelperAttributes to find the + /// set of attributes that should be considered part of the match. + /// + public bool IsAttributeMatch + { + get + { + foreach (var descriptor in Mappings.Keys) + { + if (!descriptor.Metadata.TryGetValue(TagHelperMetadata.Common.ClassifyAttributesOnly, out var value) || + !string.Equals(value, bool.TrueString, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + } + + // All the matching tag helpers want to be classified with **attributes only**. + // + // Ex: (components) + // + //