Merge remote-tracking branch 'Razor/rybrande/masterToSrc' into rybrande/MondoMaster
This commit is contained in:
commit
77001e40f2
|
|
@ -1,8 +1,8 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">$(MicrosoftNETCoreApp20PackageVersion)</RuntimeFrameworkVersion>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">$(MicrosoftNETCoreApp21PackageVersion)</RuntimeFrameworkVersion>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.2' ">$(MicrosoftNETCoreApp22PackageVersion)</RuntimeFrameworkVersion>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">$(MicrosoftNETCoreApp30PackageVersion)</RuntimeFrameworkVersion>
|
||||
<NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion>
|
||||
<!-- aspnet/BuildTools#662 Don't police what version of NetCoreApp we use -->
|
||||
<NETCoreAppMaximumVersion>99.9</NETCoreAppMaximumVersion>
|
||||
|
|
|
|||
|
|
@ -18,54 +18,53 @@
|
|||
"DefaultCompositeRule"
|
||||
],
|
||||
"packages": {
|
||||
"Microsoft.AspNetCore.Razor.Design": {
|
||||
"exclusions": {
|
||||
"Microsoft.NET.Sdk.Razor": {
|
||||
"Exclusions": {
|
||||
"ASSEMBLY_DESCRIPTION": {
|
||||
"tools/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"NEUTRAL_RESOURCES_LANGUAGE": {
|
||||
"tools/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"ASSEMBLY_PRODUCT": {
|
||||
"tools/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"NEUTRAL_RESOURCES_LANGUAGE": {
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"SERVICING_ATTRIBUTE": {
|
||||
"tools/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"VERSION_INFORMATIONALVERSION": {
|
||||
"tools/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
"tools/netcoreapp3.0/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"WRONG_PUBLICKEYTOKEN": {
|
||||
"tools/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"ASSEMBLY_INFORMATIONAL_VERSION_MISMATCH": {
|
||||
"tools/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"ASSEMBLY_FILE_VERSION_MISMATCH": {
|
||||
"tools/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"ASSEMBLY_VERSION_MISMATCH": {
|
||||
"tools/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.CSharp.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Microsoft.CodeAnalysis.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/Newtonsoft.Json.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions.",
|
||||
"tools/netcoreapp3.0/runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": "This assembly is not owned by us and does not follow our conventions."
|
||||
},
|
||||
"BUILD_ITEMS_FRAMEWORK": {
|
||||
"*": "Razor SDK does not contain any dependencies or binaries and consequently does not have a dependency group."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
build\dependencies.props = build\dependencies.props
|
||||
Directory.Build.props = Directory.Build.props
|
||||
Directory.Build.targets = Directory.Build.targets
|
||||
build\repo.props = build\repo.props
|
||||
build\repo.targets = build\repo.targets
|
||||
build\sources.props = build\sources.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
|
@ -77,9 +79,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.Mac.
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.Mac.LanguageServices.Razor.Test", "test\Microsoft.VisualStudio.Mac.LanguageServices.Razor.Test\Microsoft.VisualStudio.Mac.LanguageServices.Razor.Test.csproj", "{B8A3E4CA-D54A-441F-A3BF-E00F060CA042}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Design", "src\Microsoft.AspNetCore.Razor.Design\Microsoft.AspNetCore.Razor.Design.csproj", "{5257B25D-330A-4DCF-ACED-B4709CFBF916}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Design.Test", "test\Microsoft.AspNetCore.Razor.Design.Test\Microsoft.AspNetCore.Razor.Design.Test.csproj", "{1D90F276-E1CA-4FDF-A173-EB889E7D3150}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.Razor.Test", "test\Microsoft.NET.Sdk.Razor.Test\Microsoft.NET.Sdk.Razor.Test.csproj", "{1D90F276-E1CA-4FDF-A173-EB889E7D3150}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test", "test\Microsoft.AspNetCore.Razor.Test\Microsoft.AspNetCore.Razor.Test.csproj", "{323553F0-14AB-4FBD-9CF0-1CC0BE8056F8}"
|
||||
EndProject
|
||||
|
|
@ -97,6 +97,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib", "test\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj", "{72E89155-86C7-454E-BDD9-39F497F2F61B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X", "src\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj", "{0693CA32-BB75-401E-BC08-72D6DEEB4C99}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test", "test\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj", "{495A006C-D2B9-4AD0-9D33-60820BA501D8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X", "test\Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X\Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X.csproj", "{D87E5501-B832-46B6-ACD3-EC989E3D14ED}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -327,14 +333,6 @@ Global
|
|||
{B8A3E4CA-D54A-441F-A3BF-E00F060CA042}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B8A3E4CA-D54A-441F-A3BF-E00F060CA042}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B8A3E4CA-D54A-441F-A3BF-E00F060CA042}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{5257B25D-330A-4DCF-ACED-B4709CFBF916}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5257B25D-330A-4DCF-ACED-B4709CFBF916}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5257B25D-330A-4DCF-ACED-B4709CFBF916}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5257B25D-330A-4DCF-ACED-B4709CFBF916}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5257B25D-330A-4DCF-ACED-B4709CFBF916}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5257B25D-330A-4DCF-ACED-B4709CFBF916}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5257B25D-330A-4DCF-ACED-B4709CFBF916}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5257B25D-330A-4DCF-ACED-B4709CFBF916}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{1D90F276-E1CA-4FDF-A173-EB889E7D3150}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1D90F276-E1CA-4FDF-A173-EB889E7D3150}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1D90F276-E1CA-4FDF-A173-EB889E7D3150}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -399,6 +397,30 @@ Global
|
|||
{72E89155-86C7-454E-BDD9-39F497F2F61B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{72E89155-86C7-454E-BDD9-39F497F2F61B}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{72E89155-86C7-454E-BDD9-39F497F2F61B}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -432,7 +454,6 @@ Global
|
|||
{FAF9986F-E086-4513-9D52-F7BF5FFCF31D} = {C0CC1E1F-1559-44DE-93A8-63259CEA2AAB}
|
||||
{95B18DEE-8B45-4CF0-B9F8-CCBAF3B5251A} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
||||
{B8A3E4CA-D54A-441F-A3BF-E00F060CA042} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
{5257B25D-330A-4DCF-ACED-B4709CFBF916} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
||||
{1D90F276-E1CA-4FDF-A173-EB889E7D3150} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
{323553F0-14AB-4FBD-9CF0-1CC0BE8056F8} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
{6205467F-E381-4C42-AEEC-763BD62B3D5E} = {C2C98051-0F39-47F2-80B6-E72B29159F2C}
|
||||
|
|
@ -441,6 +462,9 @@ Global
|
|||
{7D9ECCEE-71D1-4A42-ABEE-876AFA1B4FC9} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
||||
{6EA56B2B-89EC-4C38-A384-97D203375B06} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
{72E89155-86C7-454E-BDD9-39F497F2F61B} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
{0693CA32-BB75-401E-BC08-72D6DEEB4C99} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
||||
{495A006C-D2B9-4AD0-9D33-60820BA501D8} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
{D87E5501-B832-46B6-ACD3-EC989E3D14ED} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0035341D-175A-4D05-95E6-F1C2785A1E26}
|
||||
|
|
|
|||
|
|
@ -132,14 +132,6 @@ namespace Microsoft.AspNetCore.Razor.Performance
|
|||
|
||||
private class StaticProjectSnapshotProjectEngineFactory : ProjectSnapshotProjectEngineFactory
|
||||
{
|
||||
public override RazorProjectEngine Create(ProjectSnapshot project, RazorProjectFileSystem fileSystem, Action<RazorProjectEngineBuilder> configure)
|
||||
{
|
||||
return RazorProjectEngine.Create(project.Configuration, fileSystem, b =>
|
||||
{
|
||||
RazorExtensions.Register(b);
|
||||
});
|
||||
}
|
||||
|
||||
public override IProjectEngineFactory FindFactory(ProjectSnapshot project)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
|
@ -149,6 +141,14 @@ namespace Microsoft.AspNetCore.Razor.Performance
|
|||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action<RazorProjectEngineBuilder> configure)
|
||||
{
|
||||
return RazorProjectEngine.Create(configuration, fileSystem, b =>
|
||||
{
|
||||
RazorExtensions.Register(b);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
<MPackArtifactCategory>shipoob</MPackArtifactCategory>
|
||||
|
||||
<MPackIntermediateOutputPath>$(IntermediateDir)mpack\</MPackIntermediateOutputPath>
|
||||
<AddinOutputPath>$(AddinDirectory)bin\$(Configuration)\net461\</AddinOutputPath>
|
||||
<AddinOutputPath>$(AddinDirectory)bin\$(Configuration)\net472\</AddinOutputPath>
|
||||
<LanguageServiceName>Microsoft.VisualStudio.Mac.LanguageServices.Razor</LanguageServiceName>
|
||||
<LanguageServiceOutputPath>$(RepositoryRoot)src\$(LanguageServiceName)\bin\$(Configuration)\net461\</LanguageServiceOutputPath>
|
||||
<LanguageServiceOutputPath>$(RepositoryRoot)src\$(LanguageServiceName)\bin\$(Configuration)\net472\</LanguageServiceOutputPath>
|
||||
<MPackName>$(AddinName)_$(AddinVersion)</MPackName>
|
||||
<MPackFileName>$(MPackName).mpack</MPackFileName>
|
||||
<MPackOutputPath>$(BuildDir)$(MPackFileName)</MPackOutputPath>
|
||||
|
|
@ -72,8 +72,9 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<LanguageServiceExtensionAssembly Include="$(RepositoryRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X\bin\$(Configuration)\net46\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.dll" />
|
||||
<LanguageServiceExtensionAssembly Include="$(RepositoryRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\bin\$(Configuration)\net46\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll" />
|
||||
<LanguageServiceExtensionAssembly Include="$(RepositoryRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X\bin\$(Configuration)\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.dll" />
|
||||
<LanguageServiceExtensionAssembly Include="$(RepositoryRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X\bin\$(Configuration)\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.dll" />
|
||||
<LanguageServiceExtensionAssembly Include="$(RepositoryRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\bin\$(Configuration)\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll" />
|
||||
<LanguageServiceAssembly Include="$(LanguageServiceOutputPath)%(LanguageServiceAssemblyNames.Identity)" Condition="Exists('$(LanguageServiceOutputPath)%(LanguageServiceAssemblyNames.Identity)')" />
|
||||
<LanguageServiceAssembly Include="%(LanguageServiceExtensionAssembly.Identity)" />
|
||||
<LanguageServicePDB Include="%(LanguageServiceAssembly.RootDir)%(Directory)%(FileName).pdb" Condition="Exists('%(LanguageServiceAssembly.RootDir)%(Directory)%(FileName).pdb')" />
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@
|
|||
/p:Configuration=$(Configuration);
|
||||
/p:FeatureBranchVersionSuffix=$(FeatureBranchVersionSuffix);
|
||||
/p:BuildNumber=$(BuildNumber);
|
||||
/p:LangVersion=7.1" />
|
||||
/p:LangVersion=7.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<MakeDir Directories="$(LogOutputDir)" />
|
||||
|
|
|
|||
|
|
@ -4,60 +4,63 @@
|
|||
</PropertyGroup>
|
||||
<PropertyGroup Label="Package Versions">
|
||||
<BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion>
|
||||
<InternalAspNetCoreSdkPackageVersion>2.2.0-preview2-20181108.4</InternalAspNetCoreSdkPackageVersion>
|
||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.2.0-rtm-181106-13</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>2.2.0-rtm-35661</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-rtm-181106-13</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftBuildFrameworkPackageVersion>15.6.82</MicrosoftBuildFrameworkPackageVersion>
|
||||
<MicrosoftBuildPackageVersion>15.6.82</MicrosoftBuildPackageVersion>
|
||||
<MicrosoftBuildUtilitiesCorePackageVersion>15.6.82</MicrosoftBuildUtilitiesCorePackageVersion>
|
||||
<InternalAspNetCoreSdkPackageVersion>3.0.0-alpha1-20181108.5</InternalAspNetCoreSdkPackageVersion>
|
||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-preview-181106-14</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-preview-181106-14</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftBuildFrameworkPackageVersion>15.8.166</MicrosoftBuildFrameworkPackageVersion>
|
||||
<MicrosoftBuildPackageVersion>15.8.166</MicrosoftBuildPackageVersion>
|
||||
<MicrosoftBuildUtilitiesCorePackageVersion>15.8.166</MicrosoftBuildUtilitiesCorePackageVersion>
|
||||
<MicrosoftCodeAnalysisCommonPackageVersion>2.8.0</MicrosoftCodeAnalysisCommonPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpPackageVersion>
|
||||
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>2.2.0-rtm-181106-13</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
|
||||
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>2.2.0-rtm-181106-13</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
|
||||
<MicrosoftExtensionsDependencyModelPackageVersion>2.1.0</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>2.2.0-rtm-181106-13</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion>2.2.0-rtm-181106-13</MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersPackageVersion>2.2.0-rtm-35661</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
|
||||
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>3.0.0-preview-181106-14</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
|
||||
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>3.0.0-preview-181106-14</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
|
||||
<MicrosoftExtensionsDependencyModelPackageVersion>3.0.0-preview1-26907-05</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-preview-181106-14</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion>3.0.0-preview-181106-14</MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersPackageVersion>3.0.0-alpha1-10717</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||
<MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion>
|
||||
<MicrosoftNETCoreApp22PackageVersion>2.2.0-rtm-27105-02</MicrosoftNETCoreApp22PackageVersion>
|
||||
<MicrosoftNETCoreApp30PackageVersion>3.0.0-preview1-26907-05</MicrosoftNETCoreApp30PackageVersion>
|
||||
<MicrosoftNETFrameworkReferenceAssemblies>1.0.0-alpha-004</MicrosoftNETFrameworkReferenceAssemblies>
|
||||
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
|
||||
<MicrosoftVisualStudioComponentModelHostPackageVersion>15.0.26606</MicrosoftVisualStudioComponentModelHostPackageVersion>
|
||||
<MicrosoftVisualStudioEditorPackageVersion>15.6.161-preview</MicrosoftVisualStudioEditorPackageVersion>
|
||||
<MicrosoftVisualStudioLanguageIntellisensePackageVersion>15.6.161-preview</MicrosoftVisualStudioLanguageIntellisensePackageVersion>
|
||||
<MicrosoftVisualStudioOLEInteropPackageVersion>7.10.6070</MicrosoftVisualStudioOLEInteropPackageVersion>
|
||||
<MicrosoftVisualStudioProjectSystemAnalyzersPackageVersion>15.3.224</MicrosoftVisualStudioProjectSystemAnalyzersPackageVersion>
|
||||
<MicrosoftVisualStudioComponentModelHostPackageVersion>15.8.525</MicrosoftVisualStudioComponentModelHostPackageVersion>
|
||||
<MicrosoftVisualStudioImageCatalogPackageVersion>15.8.28010</MicrosoftVisualStudioImageCatalogPackageVersion>
|
||||
<MicrosoftVisualStudioEditorPackageVersion>16.0.142-g25b7188c54</MicrosoftVisualStudioEditorPackageVersion>
|
||||
<MicrosoftVisualStudioLanguagePackageVersion>16.0.142-g25b7188c54</MicrosoftVisualStudioLanguagePackageVersion>
|
||||
<MicrosoftVisualStudioLanguageIntellisensePackageVersion>16.0.142-g25b7188c54</MicrosoftVisualStudioLanguageIntellisensePackageVersion>
|
||||
<MicrosoftVisualStudioOLEInteropPackageVersion>7.10.6071</MicrosoftVisualStudioOLEInteropPackageVersion>
|
||||
<MicrosoftVisualStudioProjectSystemAnalyzersPackageVersion>16.0.201-pre-g7d366164d0</MicrosoftVisualStudioProjectSystemAnalyzersPackageVersion>
|
||||
<MicrosoftVisualStudioProjectSystemManagedVSPackageVersion>2.0.6142705</MicrosoftVisualStudioProjectSystemManagedVSPackageVersion>
|
||||
<MicrosoftVisualStudioProjectSystemSDKPackageVersion>15.3.224</MicrosoftVisualStudioProjectSystemSDKPackageVersion>
|
||||
<MicrosoftVisualStudioShell150PackageVersion>15.0.26606</MicrosoftVisualStudioShell150PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop100PackageVersion>10.0.30319</MicrosoftVisualStudioShellInterop100PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop110PackageVersion>11.0.61030</MicrosoftVisualStudioShellInterop110PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop120PackageVersion>12.0.30110</MicrosoftVisualStudioShellInterop120PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop80PackageVersion>8.0.50727</MicrosoftVisualStudioShellInterop80PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop90PackageVersion>9.0.30729</MicrosoftVisualStudioShellInterop90PackageVersion>
|
||||
<MicrosoftVisualStudioShellInteropPackageVersion>7.10.6071</MicrosoftVisualStudioShellInteropPackageVersion>
|
||||
<MicrosoftVisualStudioTextUIPackageVersion>15.6.161-preview</MicrosoftVisualStudioTextUIPackageVersion>
|
||||
<MicrosoftVisualStudioProjectSystemSDKPackageVersion>16.0.201-pre-g7d366164d0</MicrosoftVisualStudioProjectSystemSDKPackageVersion>
|
||||
<MicrosoftVisualStudioShell150PackageVersion>15.8.28010</MicrosoftVisualStudioShell150PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop100PackageVersion>10.0.30320</MicrosoftVisualStudioShellInterop100PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop110PackageVersion>11.0.61031</MicrosoftVisualStudioShellInterop110PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop120PackageVersion>12.0.30111</MicrosoftVisualStudioShellInterop120PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop80PackageVersion>8.0.50728</MicrosoftVisualStudioShellInterop80PackageVersion>
|
||||
<MicrosoftVisualStudioShellInterop90PackageVersion>9.0.30730</MicrosoftVisualStudioShellInterop90PackageVersion>
|
||||
<MicrosoftVisualStudioShellInteropPackageVersion>7.10.6072</MicrosoftVisualStudioShellInteropPackageVersion>
|
||||
<MicrosoftVisualStudioTextUIPackageVersion>16.0.142-g25b7188c54</MicrosoftVisualStudioTextUIPackageVersion>
|
||||
<MicrosoftVisualStudioThreadingPackageVersion>15.8.168</MicrosoftVisualStudioThreadingPackageVersion>
|
||||
<MonoAddinsPackageVersion>1.3.8</MonoAddinsPackageVersion>
|
||||
<MonoDevelopSdkPackageVersion>1.0.1</MonoDevelopSdkPackageVersion>
|
||||
<MoqPackageVersion>4.10.0</MoqPackageVersion>
|
||||
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
|
||||
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
|
||||
<StreamJsonRpcPackageVersion>1.1.92</StreamJsonRpcPackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.5.0</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<StreamJsonRpcPackageVersion>1.3.23</StreamJsonRpcPackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.6.0-preview1-26907-04</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<SystemRuntimeInteropServicesRuntimeInformationPackageVersion>4.3.0</SystemRuntimeInteropServicesRuntimeInformationPackageVersion>
|
||||
<SystemValueTuplePackageVersion>4.5.0</SystemValueTuplePackageVersion>
|
||||
<SystemValueTuplePackageVersion>4.6.0-preview1-26829-04</SystemValueTuplePackageVersion>
|
||||
<VisualStudio_NewtonsoftJsonPackageVersion>9.0.1</VisualStudio_NewtonsoftJsonPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisCommonPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftCodeAnalysisCommonPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisCSharpPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftCodeAnalysisCSharpPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisRemoteRazorServiceHubPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftCodeAnalysisRemoteRazorServiceHubPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisVisualBasicWorkspacesPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftCodeAnalysisVisualBasicWorkspacesPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisWorkspacesCommonPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftCodeAnalysisWorkspacesCommonPackageVersion>
|
||||
<VSIX_MicrosoftVisualStudioLanguageServicesPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftVisualStudioLanguageServicesPackageVersion>
|
||||
<VSIX_MicrosoftVisualStudioLanguageServicesRazorRemoteClientPackageVersion>2.9.0-beta4-62911-02</VSIX_MicrosoftVisualStudioLanguageServicesRazorRemoteClientPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisCommonPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftCodeAnalysisCommonPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisCSharpPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftCodeAnalysisCSharpPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisRemoteRazorServiceHubPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftCodeAnalysisRemoteRazorServiceHubPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisVisualBasicWorkspacesPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftCodeAnalysisVisualBasicWorkspacesPackageVersion>
|
||||
<VSIX_MicrosoftCodeAnalysisWorkspacesCommonPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftCodeAnalysisWorkspacesCommonPackageVersion>
|
||||
<VSIX_MicrosoftVisualStudioLanguageServicesPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftVisualStudioLanguageServicesPackageVersion>
|
||||
<VSIX_MicrosoftVisualStudioLanguageServicesRazorRemoteClientPackageVersion>2.11.0-beta3-63519-01</VSIX_MicrosoftVisualStudioLanguageServicesRazorRemoteClientPackageVersion>
|
||||
<XunitAnalyzersPackageVersion>0.10.0</XunitAnalyzersPackageVersion>
|
||||
<XunitPackageVersion>2.3.1</XunitPackageVersion>
|
||||
<XunitRunnerVisualStudioPackageVersion>2.4.0</XunitRunnerVisualStudioPackageVersion>
|
||||
|
|
|
|||
|
|
@ -21,13 +21,11 @@
|
|||
<PropertyGroup>
|
||||
<!-- These properties are use by the automation that updates dependencies.props -->
|
||||
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
|
||||
<LineupPackageVersion>2.2.0-*</LineupPackageVersion>
|
||||
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp20PackageVersion)" />
|
||||
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp21PackageVersion)" />
|
||||
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp22PackageVersion)" />
|
||||
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp30PackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<PrepareDependsOn>$(PrepareDependsOn);GenerateMSBuildLocationFile</PrepareDependsOn>
|
||||
<RazorDesignTestProject>$(RepositoryRoot)test\Microsoft.AspNetCore.Razor.Design.Test\</RazorDesignTestProject>
|
||||
<MSBuildLocationFileTemplate>$(RazorDesignTestProject)BuildVariables.cs.template</MSBuildLocationFileTemplate>
|
||||
<MSBuildLocationFileOutput>$(RazorDesignTestProject)obj\BuildVariables.generated.cs</MSBuildLocationFileOutput>
|
||||
<RazorSdkTestProject>$(RepositoryRoot)test\Microsoft.NET.Sdk.Razor.Test\</RazorSdkTestProject>
|
||||
<MSBuildLocationFileTemplate>$(RazorSdkTestProject)BuildVariables.cs.template</MSBuildLocationFileTemplate>
|
||||
<MSBuildLocationFileOutput>$(RazorSdkTestProject)obj\BuildVariables.generated.cs</MSBuildLocationFileOutput>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="GenerateMSBuildLocationFile"
|
||||
|
|
@ -24,8 +24,8 @@
|
|||
<PropertyGroup>
|
||||
<TemplateProperties>
|
||||
MSBuildLocation=$(VisualStudioMSBuildx86Path);
|
||||
MicrosoftNETCoreAppPackageVersion=$(MicrosoftNETCoreApp22PackageVersion);
|
||||
NETStandardLibraryPackageVersion=$(NETStandardLibrary20PackageVersion)
|
||||
MicrosoftNETCoreApp30PackageVersion=$(MicrosoftNETCoreApp30PackageVersion);
|
||||
NETStandardLibrary20PackageVersion=$(NETStandardLibrary20PackageVersion)
|
||||
</TemplateProperties>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@
|
|||
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/msbuild/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/roslyn/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json;
|
||||
https://vside.myget.org/F/vssdk/api/v3/index.json;
|
||||
https://vside.myget.org/F/vsmac/api/v3/index.json
|
||||
https://vside.myget.org/F/vsmac/api/v3/index.json;
|
||||
https://vside.myget.org/F/devcore/api/v3/index.json;
|
||||
</RestoreSources>
|
||||
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
|
||||
$(RestoreSources);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core design time hosting infrastructure for the Razor view engine.</Description>
|
||||
<TargetFrameworks>net46;netstandard2.0</TargetFrameworks>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<PackageTags>$(PackageTags);aspnetcoremvc</PackageTags>
|
||||
<EnableApiCheck>false</EnableApiCheck>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
InjectDirective.Register(builder);
|
||||
ModelDirective.Register(builder);
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
|
||||
builder.Features.Add(new DefaultTagHelperDescriptorProvider());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ using System;
|
|||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
|
||||
{
|
||||
internal static class CSharpIdentifier
|
||||
{
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<string>(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("<TModel>", "<" + 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<DirectiveIntermediateNode> Directives { get; } = new List<DirectiveIntermediateNode>();
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -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<InjectIntermediateNode>(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<IInjectTargetExtension>();
|
||||
if (extension == null)
|
||||
{
|
||||
ReportMissingCodeTargetExtension<IInjectTargetExtension>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Razor.Language;
|
|||
using Microsoft.AspNetCore.Razor.Language.Extensions;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
|
||||
{
|
||||
public class InstrumentationPass : IntermediateNodePassBase, IRazorOptimizationPass
|
||||
{
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core design time hosting infrastructure for the Razor view engine.</Description>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<PackageTags>$(PackageTags);aspnetcoremvc</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\CodeGeneration\CodeWriterExtensions.cs">
|
||||
<Link>Shared\CodeWriterExtensions.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Microsoft.AspNetCore.Razor.Language/Microsoft.AspNetCore.Razor.Language.csproj" />
|
||||
<ProjectReference Include="../Microsoft.CodeAnalysis.Razor/Microsoft.CodeAnalysis.Razor.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -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("<TModel>", "<" + modelType + ">");
|
||||
visitor.Class.BaseType = baseType;
|
||||
}
|
||||
}
|
||||
|
||||
private class Visitor : IntermediateNodeWalker
|
||||
{
|
||||
public NamespaceDeclarationIntermediateNode Namespace { get; private set; }
|
||||
|
||||
public ClassDeclarationIntermediateNode Class { get; private set; }
|
||||
|
||||
public IList<DirectiveIntermediateNode> ModelDirectives { get; } = new List<DirectiveIntermediateNode>();
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -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<TagHelperIntermediateNode> TagHelpers { get; } = new List<TagHelperIntermediateNode>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<RazorProjectItem> GetImports(RazorProjectItem projectItem)
|
||||
{
|
||||
if (projectItem == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectItem));
|
||||
}
|
||||
|
||||
var imports = new List<RazorProjectItem>();
|
||||
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<RazorProjectItem> imports)
|
||||
{
|
||||
imports.Add(DefaultDirectivesProjectItem.Instance);
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
internal void AddHierarchicalImports(RazorProjectItem projectItem, List<RazorProjectItem> 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<TModel> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<TModel>";
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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<DirectiveTokenIntermediateNode> 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
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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")]
|
||||
338
src/Razor/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/Properties/Resources.Designer.cs
generated
Normal file
338
src/Razor/src/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/Properties/Resources.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
// <auto-generated />
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Value cannot be null or empty.
|
||||
/// </summary>
|
||||
internal static string ArgumentCannotBeNullOrEmpty
|
||||
{
|
||||
get => GetString("ArgumentCannotBeNullOrEmpty");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Value cannot be null or empty.
|
||||
/// </summary>
|
||||
internal static string FormatArgumentCannotBeNullOrEmpty()
|
||||
=> GetString("ArgumentCannotBeNullOrEmpty");
|
||||
|
||||
/// <summary>
|
||||
/// Inject a service from the application's service container into a property.
|
||||
/// </summary>
|
||||
internal static string InjectDirective_Description
|
||||
{
|
||||
get => GetString("InjectDirective_Description");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inject a service from the application's service container into a property.
|
||||
/// </summary>
|
||||
internal static string FormatInjectDirective_Description()
|
||||
=> GetString("InjectDirective_Description");
|
||||
|
||||
/// <summary>
|
||||
/// The name of the property.
|
||||
/// </summary>
|
||||
internal static string InjectDirective_MemberToken_Description
|
||||
{
|
||||
get => GetString("InjectDirective_MemberToken_Description");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the property.
|
||||
/// </summary>
|
||||
internal static string FormatInjectDirective_MemberToken_Description()
|
||||
=> GetString("InjectDirective_MemberToken_Description");
|
||||
|
||||
/// <summary>
|
||||
/// PropertyName
|
||||
/// </summary>
|
||||
internal static string InjectDirective_MemberToken_Name
|
||||
{
|
||||
get => GetString("InjectDirective_MemberToken_Name");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PropertyName
|
||||
/// </summary>
|
||||
internal static string FormatInjectDirective_MemberToken_Name()
|
||||
=> GetString("InjectDirective_MemberToken_Name");
|
||||
|
||||
/// <summary>
|
||||
/// The type of the service to inject.
|
||||
/// </summary>
|
||||
internal static string InjectDirective_TypeToken_Description
|
||||
{
|
||||
get => GetString("InjectDirective_TypeToken_Description");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type of the service to inject.
|
||||
/// </summary>
|
||||
internal static string FormatInjectDirective_TypeToken_Description()
|
||||
=> GetString("InjectDirective_TypeToken_Description");
|
||||
|
||||
/// <summary>
|
||||
/// TypeName
|
||||
/// </summary>
|
||||
internal static string InjectDirective_TypeToken_Name
|
||||
{
|
||||
get => GetString("InjectDirective_TypeToken_Name");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TypeName
|
||||
/// </summary>
|
||||
internal static string FormatInjectDirective_TypeToken_Name()
|
||||
=> GetString("InjectDirective_TypeToken_Name");
|
||||
|
||||
/// <summary>
|
||||
/// Specify the view or page model for the page.
|
||||
/// </summary>
|
||||
internal static string ModelDirective_Description
|
||||
{
|
||||
get => GetString("ModelDirective_Description");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify the view or page model for the page.
|
||||
/// </summary>
|
||||
internal static string FormatModelDirective_Description()
|
||||
=> GetString("ModelDirective_Description");
|
||||
|
||||
/// <summary>
|
||||
/// The model type.
|
||||
/// </summary>
|
||||
internal static string ModelDirective_TypeToken_Description
|
||||
{
|
||||
get => GetString("ModelDirective_TypeToken_Description");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The model type.
|
||||
/// </summary>
|
||||
internal static string FormatModelDirective_TypeToken_Description()
|
||||
=> GetString("ModelDirective_TypeToken_Description");
|
||||
|
||||
/// <summary>
|
||||
/// TypeName
|
||||
/// </summary>
|
||||
internal static string ModelDirective_TypeToken_Name
|
||||
{
|
||||
get => GetString("ModelDirective_TypeToken_Name");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TypeName
|
||||
/// </summary>
|
||||
internal static string FormatModelDirective_TypeToken_Name()
|
||||
=> GetString("ModelDirective_TypeToken_Name");
|
||||
|
||||
/// <summary>
|
||||
/// The 'inherits' keyword is not allowed when a '{0}' keyword is used.
|
||||
/// </summary>
|
||||
internal static string MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword
|
||||
{
|
||||
get => GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The 'inherits' keyword is not allowed when a '{0}' keyword is used.
|
||||
/// </summary>
|
||||
internal static string FormatMvcRazorCodeParser_CannotHaveModelAndInheritsKeyword(object p0)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword"), p0);
|
||||
|
||||
/// <summary>
|
||||
/// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'.
|
||||
/// </summary>
|
||||
internal static string MvcRazorCodeParser_InjectDirectivePropertyNameRequired
|
||||
{
|
||||
get => GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'.
|
||||
/// </summary>
|
||||
internal static string FormatMvcRazorCodeParser_InjectDirectivePropertyNameRequired(object p0)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired"), p0);
|
||||
|
||||
/// <summary>
|
||||
/// The '{0}' keyword must be followed by a type name on the same line.
|
||||
/// </summary>
|
||||
internal static string MvcRazorCodeParser_KeywordMustBeFollowedByTypeName
|
||||
{
|
||||
get => GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The '{0}' keyword must be followed by a type name on the same line.
|
||||
/// </summary>
|
||||
internal static string FormatMvcRazorCodeParser_KeywordMustBeFollowedByTypeName(object p0)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName"), p0);
|
||||
|
||||
/// <summary>
|
||||
/// Only one '{0}' statement is allowed in a file.
|
||||
/// </summary>
|
||||
internal static string MvcRazorCodeParser_OnlyOneModelStatementIsAllowed
|
||||
{
|
||||
get => GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only one '{0}' statement is allowed in a file.
|
||||
/// </summary>
|
||||
internal static string FormatMvcRazorCodeParser_OnlyOneModelStatementIsAllowed(object p0)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed"), p0);
|
||||
|
||||
/// <summary>
|
||||
/// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'.
|
||||
/// </summary>
|
||||
internal static string MvcRazorParser_InvalidPropertyType
|
||||
{
|
||||
get => GetString("MvcRazorParser_InvalidPropertyType");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'.
|
||||
/// </summary>
|
||||
internal static string FormatMvcRazorParser_InvalidPropertyType(object p0, object p1, object p2)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorParser_InvalidPropertyType"), p0, p1, p2);
|
||||
|
||||
/// <summary>
|
||||
/// Specify the base namespace for the page.
|
||||
/// </summary>
|
||||
internal static string NamespaceDirective_Description
|
||||
{
|
||||
get => GetString("NamespaceDirective_Description");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify the base namespace for the page.
|
||||
/// </summary>
|
||||
internal static string FormatNamespaceDirective_Description()
|
||||
=> GetString("NamespaceDirective_Description");
|
||||
|
||||
/// <summary>
|
||||
/// The namespace for the page.
|
||||
/// </summary>
|
||||
internal static string NamespaceDirective_NamespaceToken_Description
|
||||
{
|
||||
get => GetString("NamespaceDirective_NamespaceToken_Description");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The namespace for the page.
|
||||
/// </summary>
|
||||
internal static string FormatNamespaceDirective_NamespaceToken_Description()
|
||||
=> GetString("NamespaceDirective_NamespaceToken_Description");
|
||||
|
||||
/// <summary>
|
||||
/// Namespace
|
||||
/// </summary>
|
||||
internal static string NamespaceDirective_NamespaceToken_Name
|
||||
{
|
||||
get => GetString("NamespaceDirective_NamespaceToken_Name");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Namespace
|
||||
/// </summary>
|
||||
internal static string FormatNamespaceDirective_NamespaceToken_Name()
|
||||
=> GetString("NamespaceDirective_NamespaceToken_Name");
|
||||
|
||||
/// <summary>
|
||||
/// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file.
|
||||
/// </summary>
|
||||
internal static string PageDirectiveCannotBeImported
|
||||
{
|
||||
get => GetString("PageDirectiveCannotBeImported");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file.
|
||||
/// </summary>
|
||||
internal static string FormatPageDirectiveCannotBeImported(object p0, object p1)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveCannotBeImported"), p0, p1);
|
||||
|
||||
/// <summary>
|
||||
/// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive.
|
||||
/// </summary>
|
||||
internal static string PageDirectiveMustExistAtTheTopOfFile
|
||||
{
|
||||
get => GetString("PageDirectiveMustExistAtTheTopOfFile");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive.
|
||||
/// </summary>
|
||||
internal static string FormatPageDirectiveMustExistAtTheTopOfFile(object p0)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveMustExistAtTheTopOfFile"), p0);
|
||||
|
||||
/// <summary>
|
||||
/// Mark the page as a Razor Page.
|
||||
/// </summary>
|
||||
internal static string PageDirective_Description
|
||||
{
|
||||
get => GetString("PageDirective_Description");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mark the page as a Razor Page.
|
||||
/// </summary>
|
||||
internal static string FormatPageDirective_Description()
|
||||
=> GetString("PageDirective_Description");
|
||||
|
||||
/// <summary>
|
||||
/// An optional route template for the page.
|
||||
/// </summary>
|
||||
internal static string PageDirective_RouteToken_Description
|
||||
{
|
||||
get => GetString("PageDirective_RouteToken_Description");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional route template for the page.
|
||||
/// </summary>
|
||||
internal static string FormatPageDirective_RouteToken_Description()
|
||||
=> GetString("PageDirective_RouteToken_Description");
|
||||
|
||||
/// <summary>
|
||||
/// RouteTemplate
|
||||
/// </summary>
|
||||
internal static string PageDirective_RouteToken_Name
|
||||
{
|
||||
get => GetString("PageDirective_RouteToken_Name");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RouteTemplate
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
// <auto-generated />
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// View component '{0}' must have exactly one public method named '{1}' or '{2}'.
|
||||
/// </summary>
|
||||
internal static string ViewComponent_AmbiguousMethods
|
||||
{
|
||||
get => GetString("ViewComponent_AmbiguousMethods");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// View component '{0}' must have exactly one public method named '{1}' or '{2}'.
|
||||
/// </summary>
|
||||
internal static string FormatViewComponent_AmbiguousMethods(object p0, object p1, object p2)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AmbiguousMethods"), p0, p1, p2);
|
||||
|
||||
/// <summary>
|
||||
/// Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;.
|
||||
/// </summary>
|
||||
internal static string ViewComponent_AsyncMethod_ShouldReturnTask
|
||||
{
|
||||
get => GetString("ViewComponent_AsyncMethod_ShouldReturnTask");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;.
|
||||
/// </summary>
|
||||
internal static string FormatViewComponent_AsyncMethod_ShouldReturnTask(object p0, object p1, object p2)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AsyncMethod_ShouldReturnTask"), p0, p1, p2);
|
||||
|
||||
/// <summary>
|
||||
/// Could not find an '{0}' or '{1}' method for the view component '{2}'.
|
||||
/// </summary>
|
||||
internal static string ViewComponent_CannotFindMethod
|
||||
{
|
||||
get => GetString("ViewComponent_CannotFindMethod");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Could not find an '{0}' or '{1}' method for the view component '{2}'.
|
||||
/// </summary>
|
||||
internal static string FormatViewComponent_CannotFindMethod(object p0, object p1, object p2)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_CannotFindMethod"), p0, p1, p2);
|
||||
|
||||
/// <summary>
|
||||
/// Method '{0}' of view component '{1}' cannot return a {2}.
|
||||
/// </summary>
|
||||
internal static string ViewComponent_SyncMethod_CannotReturnTask
|
||||
{
|
||||
get => GetString("ViewComponent_SyncMethod_CannotReturnTask");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method '{0}' of view component '{1}' cannot return a {2}.
|
||||
/// </summary>
|
||||
internal static string FormatViewComponent_SyncMethod_CannotReturnTask(object p0, object p1, object p2)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_CannotReturnTask"), p0, p1, p2);
|
||||
|
||||
/// <summary>
|
||||
/// Method '{0}' of view component '{1}' should be declared to return a value.
|
||||
/// </summary>
|
||||
internal static string ViewComponent_SyncMethod_ShouldReturnValue
|
||||
{
|
||||
get => GetString("ViewComponent_SyncMethod_ShouldReturnValue");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method '{0}' of view component '{1}' should be declared to return a value.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
|
||||
<value>Value cannot be null or empty.</value>
|
||||
</data>
|
||||
<data name="InjectDirective_Description" xml:space="preserve">
|
||||
<value>Inject a service from the application's service container into a property.</value>
|
||||
</data>
|
||||
<data name="InjectDirective_MemberToken_Description" xml:space="preserve">
|
||||
<value>The name of the property.</value>
|
||||
</data>
|
||||
<data name="InjectDirective_MemberToken_Name" xml:space="preserve">
|
||||
<value>PropertyName</value>
|
||||
</data>
|
||||
<data name="InjectDirective_TypeToken_Description" xml:space="preserve">
|
||||
<value>The type of the service to inject.</value>
|
||||
</data>
|
||||
<data name="InjectDirective_TypeToken_Name" xml:space="preserve">
|
||||
<value>TypeName</value>
|
||||
</data>
|
||||
<data name="ModelDirective_Description" xml:space="preserve">
|
||||
<value>Specify the view or page model for the page.</value>
|
||||
</data>
|
||||
<data name="ModelDirective_TypeToken_Description" xml:space="preserve">
|
||||
<value>The model type.</value>
|
||||
</data>
|
||||
<data name="ModelDirective_TypeToken_Name" xml:space="preserve">
|
||||
<value>TypeName</value>
|
||||
</data>
|
||||
<data name="MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword" xml:space="preserve">
|
||||
<value>The 'inherits' keyword is not allowed when a '{0}' keyword is used.</value>
|
||||
</data>
|
||||
<data name="MvcRazorCodeParser_InjectDirectivePropertyNameRequired" xml:space="preserve">
|
||||
<value>A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} <Type Name> <Property Name>'.</value>
|
||||
</data>
|
||||
<data name="MvcRazorCodeParser_KeywordMustBeFollowedByTypeName" xml:space="preserve">
|
||||
<value>The '{0}' keyword must be followed by a type name on the same line.</value>
|
||||
</data>
|
||||
<data name="MvcRazorCodeParser_OnlyOneModelStatementIsAllowed" xml:space="preserve">
|
||||
<value>Only one '{0}' statement is allowed in a file.</value>
|
||||
</data>
|
||||
<data name="MvcRazorParser_InvalidPropertyType" xml:space="preserve">
|
||||
<value>Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'.</value>
|
||||
</data>
|
||||
<data name="NamespaceDirective_Description" xml:space="preserve">
|
||||
<value>Specify the base namespace for the page.</value>
|
||||
</data>
|
||||
<data name="NamespaceDirective_NamespaceToken_Description" xml:space="preserve">
|
||||
<value>The namespace for the page.</value>
|
||||
</data>
|
||||
<data name="NamespaceDirective_NamespaceToken_Name" xml:space="preserve">
|
||||
<value>Namespace</value>
|
||||
</data>
|
||||
<data name="PageDirectiveCannotBeImported" xml:space="preserve">
|
||||
<value>The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file.</value>
|
||||
</data>
|
||||
<data name="PageDirectiveMustExistAtTheTopOfFile" xml:space="preserve">
|
||||
<value>The '@{0}' directive must precede all other elements defined in a Razor file.</value>
|
||||
</data>
|
||||
<data name="PageDirective_Description" xml:space="preserve">
|
||||
<value>Mark the page as a Razor Page.</value>
|
||||
</data>
|
||||
<data name="PageDirective_RouteToken_Description" xml:space="preserve">
|
||||
<value>An optional route template for the page.</value>
|
||||
</data>
|
||||
<data name="PageDirective_RouteToken_Name" xml:space="preserve">
|
||||
<value>RouteTemplate</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether a <see cref="TagHelperDescriptor"/> represents a view component.
|
||||
/// </summary>
|
||||
/// <param name="tagHelper">The <see cref="TagHelperDescriptor"/> to check.</param>
|
||||
/// <returns>Whether a <see cref="TagHelperDescriptor"/> represents a view component.</returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ViewComponent_AmbiguousMethods" xml:space="preserve">
|
||||
<value>View component '{0}' must have exactly one public method named '{1}' or '{2}'.</value>
|
||||
</data>
|
||||
<data name="ViewComponent_AsyncMethod_ShouldReturnTask" xml:space="preserve">
|
||||
<value>Method '{0}' of view component '{1}' should be declared to return {2}&lt;T&gt;.</value>
|
||||
</data>
|
||||
<data name="ViewComponent_CannotFindMethod" xml:space="preserve">
|
||||
<value>Could not find an '{0}' or '{1}' method for the view component '{2}'.</value>
|
||||
</data>
|
||||
<data name="ViewComponent_SyncMethod_CannotReturnTask" xml:space="preserve">
|
||||
<value>Method '{0}' of view component '{1}' cannot return a {2}.</value>
|
||||
</data>
|
||||
<data name="ViewComponent_SyncMethod_ShouldReturnValue" xml:space="preserve">
|
||||
<value>Method '{0}' of view component '{1}' should be declared to return a value.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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<string, string> PrimitiveDisplayTypeNameLookups = new Dictionary<string, string>(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<T>.
|
||||
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<T>.
|
||||
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<IMethodSymbol> GetInvokeMethods(INamedTypeSymbol type)
|
||||
{
|
||||
var methods = new List<IMethodSymbol>();
|
||||
while (type != null)
|
||||
{
|
||||
var currentTypeMethods = type.GetMembers()
|
||||
.OfType<IMethodSymbol>()
|
||||
.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<IParameterSymbol> 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<IParameterSymbol> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<INamedTypeSymbol>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<ViewComponentTagHelperIntermediateNode>(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<IViewComponentTagHelperTargetExtension>();
|
||||
if (extension == null)
|
||||
{
|
||||
ReportMissingCodeTargetExtension<IViewComponentTagHelperTargetExtension>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// The key in a <see cref="Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor.Metadata"/> containing
|
||||
/// the short name of a view component.
|
||||
/// </summary>
|
||||
public static readonly string Name = "MVC.ViewComponent.Name";
|
||||
}
|
||||
}
|
||||
|
|
@ -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<TagHelperIntermediateNode>();
|
||||
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<TagHelperDescriptor, (string className, string fullyQualifiedName, string fieldName)> _tagHelpers;
|
||||
|
||||
public Context(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class)
|
||||
{
|
||||
Namespace = @namespace;
|
||||
Class = @class;
|
||||
|
||||
_tagHelpers = new Dictionary<TagHelperDescriptor, (string, string, string)>();
|
||||
}
|
||||
|
||||
public ClassDeclarationIntermediateNode Class { get; }
|
||||
|
||||
public NamespaceDeclarationIntermediateNode Namespace { get; }
|
||||
|
||||
|
||||
public IEnumerable<TagHelperDescriptor> 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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<string, string>()
|
||||
{
|
||||
{ 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(")]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<INamedTypeSymbol> _results;
|
||||
|
||||
public ViewComponentTypeVisitor(
|
||||
INamedTypeSymbol viewComponentAttribute,
|
||||
INamedTypeSymbol nonViewComponentAttribute,
|
||||
List<INamedTypeSymbol> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
// 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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,6 +44,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -2,19 +2,14 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core design time hosting infrastructure for the Razor view engine.</Description>
|
||||
<TargetFrameworks>net46;netstandard2.0</TargetFrameworks>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<PackageTags>$(PackageTags);aspnetcoremvc</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\CodeGeneration\CodeWriterExtensions.cs">
|
||||
<Link>Shared\CodeWriterExtensions.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="build\**\*.props" PackagePath="build\" />
|
||||
<Content Include="build\**\*.targets" PackagePath="build\" />
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\CodeGeneration\CodeWriterExtensions.cs" Link="Shared\CodeWriterExtensions.cs" />
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\CSharpIdentifier.cs" Link="Shared\CSharpIdentifier.cs" />
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\Checksum.cs" Link="Shared\Checksum.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// 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;
|
||||
|
||||
|
|
@ -31,12 +30,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
{
|
||||
// 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());
|
||||
var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum());
|
||||
@class.ClassName = $"AspNetCore_{checksum}";
|
||||
}
|
||||
else
|
||||
{
|
||||
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
|
||||
@class.ClassName = GetClassNameFromPath(filePath);
|
||||
}
|
||||
|
||||
@class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>";
|
||||
|
|
@ -51,21 +50,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}";
|
||||
}
|
||||
|
||||
private static string BytesToString(byte[] bytes)
|
||||
private static string GetClassNameFromPath(string path)
|
||||
{
|
||||
if (bytes == null)
|
||||
const string cshtmlExtension = ".cshtml";
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(bytes));
|
||||
return path;
|
||||
}
|
||||
|
||||
var result = new StringBuilder(bytes.Length);
|
||||
for (var i = 0; i < bytes.Length; i++)
|
||||
if (path.EndsWith(cshtmlExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// The x2 format means lowercase hex, where each byte is a 2-character string.
|
||||
result.Append(bytes[i].ToString("x2"));
|
||||
path = path.Substring(0, path.Length - cshtmlExtension.Length);
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
return CSharpIdentifier.SanitizeIdentifier(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
for (var i = 0; i < segments.Length - 1; i++)
|
||||
{
|
||||
builder.Append('.');
|
||||
builder.Append(CSharpIdentifier.SanitizeClassName(segments[i]));
|
||||
builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[i]));
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@ using System.Runtime.CompilerServices;
|
|||
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
|
||||
[assembly: ProvideRazorExtensionInitializer("MVC-2.0", typeof(ExtensionInitializer))]
|
||||
[assembly: ProvideRazorExtensionInitializer("MVC-2.1", typeof(ExtensionInitializer))]
|
||||
[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")]
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
NamespaceDirective.Register(builder);
|
||||
PageDirective.Register(builder);
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
SectionDirective.Register(builder);
|
||||
|
||||
|
|
@ -41,50 +40,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
builder.Features.Add(new RazorPageDocumentClassifierPass());
|
||||
builder.Features.Add(new MvcViewDocumentClassifierPass());
|
||||
builder.Features.Add(new AssemblyAttributeInjectionPass());
|
||||
builder.Features.Add(new InstrumentationPass());
|
||||
|
||||
builder.SetImportFeature(new MvcImportProjectFeature());
|
||||
}
|
||||
|
||||
#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));
|
||||
}
|
||||
|
||||
InjectDirective.Register(builder);
|
||||
ModelDirective.Register(builder);
|
||||
NamespaceDirective.Register(builder);
|
||||
PageDirective.Register(builder);
|
||||
|
||||
FunctionsDirective.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());
|
||||
|
||||
if (!builder.DesignTime)
|
||||
{
|
||||
builder.Features.Add(new AssemblyAttributeInjectionPass());
|
||||
builder.Features.Add(new InstrumentationPass());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
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;
|
||||
|
|
@ -58,12 +57,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
{
|
||||
// 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());
|
||||
var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum());
|
||||
@class.ClassName = $"AspNetCore_{checksum}";
|
||||
}
|
||||
else
|
||||
{
|
||||
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
|
||||
@class.ClassName = GetClassNameFromPath(filePath);
|
||||
}
|
||||
|
||||
@class.Modifiers.Clear();
|
||||
|
|
@ -144,21 +143,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
}
|
||||
}
|
||||
|
||||
private static string BytesToString(byte[] bytes)
|
||||
private static string GetClassNameFromPath(string path)
|
||||
{
|
||||
if (bytes == null)
|
||||
const string cshtmlExtension = ".cshtml";
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(bytes));
|
||||
return path;
|
||||
}
|
||||
|
||||
var result = new StringBuilder(bytes.Length);
|
||||
for (var i = 0; i < bytes.Length; i++)
|
||||
if (path.EndsWith(cshtmlExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// The x2 format means lowercase hex, where each byte is a 2-character string.
|
||||
result.Append(bytes[i].ToString("x2"));
|
||||
path = path.Substring(0, path.Length - cshtmlExtension.Length);
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
return CSharpIdentifier.SanitizeIdentifier(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<Project>
|
||||
<!--
|
||||
MSBuild support for Razor code generation that targets ASP.NET Core MVC 2.X
|
||||
|
||||
The properties and items here are designed to be read by CPS so they should be just simple evaluation-time values
|
||||
and should not require targets to initialize.
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
Set the primary configuration supported by this pacakge as the default configuration for Razor.
|
||||
-->
|
||||
<RazorDefaultConfiguration Condition="'$(RazorDefaultConfiguration)'==''">MVC-2.1</RazorDefaultConfiguration>
|
||||
|
||||
<!--
|
||||
MVC uses a ProvideApplicationPartFactoryAttribute on the generated assembly to load compiled views from assembly. Set this to false, to prevent generating this attribute.
|
||||
-->
|
||||
<GenerateProvideApplicationPartFactoryAttribute>true</GenerateProvideApplicationPartFactoryAttribute>
|
||||
|
||||
<!-- Override for testing. This path is only correct inside a nuget package. -->
|
||||
<_MvcExtensionAssemblyPath Condition="'$(_MvcExtensionAssemblyPath)'==''">$(MSBuildThisFileDirectory)..\..\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll</_MvcExtensionAssemblyPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!--
|
||||
While technically the assembly in this package can provide support for the MVC-2.0 configuration, don't declare
|
||||
it here. The IDE is hardcoded to inject 2.0 support when needed. The settings flowing through MSBuild should reflect
|
||||
the project's runtime.
|
||||
-->
|
||||
<RazorConfiguration Include="MVC-2.1">
|
||||
<Extensions>MVC-2.1;$(CustomRazorExtension)</Extensions>
|
||||
</RazorConfiguration>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<RazorExtension Include="MVC-2.1">
|
||||
<AssemblyName>Microsoft.AspNetCore.Mvc.Razor.Extensions</AssemblyName>
|
||||
<AssemblyFilePath>$(_MvcExtensionAssemblyPath)</AssemblyFilePath>
|
||||
</RazorExtension>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
Determines if the Sdk is allowed to add additional attributes to the project assembly.
|
||||
For instance, MVC will generally want to add attributes to support view discovery and runtime compilation.
|
||||
-->
|
||||
<GenerateRazorAssemblyInfo Condition="'$(GenerateRazorAssemblyInfo)'==''">true</GenerateRazorAssemblyInfo>
|
||||
|
||||
<!--
|
||||
MVC will generally want to add support for runtime compilation, but only for applications.
|
||||
-->
|
||||
<GenerateRazorHostingAssemblyInfo Condition="'$(GenerateRazorHostingAssemblyInfo)'=='' AND '$(OutputType)'=='exe'">$(GenerateRazorAssemblyInfo)</GenerateRazorHostingAssemblyInfo>
|
||||
|
||||
<!--
|
||||
Use the suffix .Views when producing compiled view assemblies. This matches the requirements for Mvc's ViewsFeatureProvider.
|
||||
-->
|
||||
<RazorTargetNameSuffix Condition="'$(RazorTargetNameSuffix)'==''">.Views</RazorTargetNameSuffix>
|
||||
|
||||
<!--
|
||||
The type name of the ApplicationPartFactory applied to the generated Razor file.
|
||||
-->
|
||||
<ProvideApplicationPartFactoryAttributeTypeName Condition="'$(ProvideApplicationPartFactoryAttributeTypeName)' == ''">Microsoft.AspNetCore.Mvc.ApplicationParts.CompiledRazorAssemblyApplicationPartFactory, Microsoft.AspNetCore.Mvc.Razor</ProvideApplicationPartFactoryAttributeTypeName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(GenerateRazorAssemblyInfo)'=='true' AND '$(ResolvedRazorCompileToolset)'=='RazorSdk' AND ('$(RazorCompileOnBuild)' == 'true' OR '$(RazorCompileOnPublish)' == 'true')">
|
||||
<_RazorAssemblyAttribute Include="Microsoft.AspNetCore.Mvc.ApplicationParts.RelatedAssemblyAttribute">
|
||||
<_Parameter1>$(RazorTargetName)</_Parameter1>
|
||||
</_RazorAssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(GenerateProvideApplicationPartFactoryAttribute)' == 'true' AND '$(ProvideApplicationPartFactoryAttributeTypeName)'!=''">
|
||||
<RazorTargetAssemblyAttribute Include="Microsoft.AspNetCore.Mvc.ApplicationParts.ProvideApplicationPartFactoryAttribute">
|
||||
<_Parameter1>$(ProvideApplicationPartFactoryAttributeTypeName)</_Parameter1>
|
||||
</RazorTargetAssemblyAttribute>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Description>Razor is a markup syntax for adding server-side logic to web pages. This package contains MSBuild support for Razor.</Description>
|
||||
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
|
||||
|
||||
<!-- This project doesn't have any code, so don't include it in the .nupkg -->
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
|
||||
<NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--
|
||||
Building this package is somewhat complicated because we need to Publish some other projects
|
||||
that have different TFM's including one with multiple TFMs.
|
||||
|
||||
We then need to include the output of those projects in our output directory (where it will be used
|
||||
by tests) and in the nukpg.
|
||||
-->
|
||||
<!-- These are tools that need to be included in the package. -->
|
||||
|
||||
<PropertyGroup>
|
||||
<ToolProject>..\Microsoft.AspNetCore.Razor.Tools\Microsoft.AspNetCore.Razor.Tools.csproj</ToolProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(ToolProject)" ReferenceOutputAssembly="false" Condition="'$(TargetFramework)' == 'netcoreapp2.0'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'==''">
|
||||
<!-- Binaries produced in this project -->
|
||||
<SignedPackageFile Include="$(MSBuildProjectDirectory)\$(OutputPath)\tools/rzc.dll" Certificate="$(AssemblySigningCertName)" />
|
||||
|
||||
<!-- Third-party assemblies -->
|
||||
<SignedPackageFile Include="$(MSBuildProjectDirectory)\$(OutputPath)\tools/Newtonsoft.Json.dll" Certificate="$(AssemblySigning3rdPartyCertName)" />
|
||||
|
||||
<!-- Binaries that should be signed by corefx/roslyn -->
|
||||
<ExcludePackageFileFromSigning Include="$(MSBuildProjectDirectory)\$(OutputPath)\tools/Microsoft.CodeAnalysis.CSharp.dll" />
|
||||
<ExcludePackageFileFromSigning Include="$(MSBuildProjectDirectory)\$(OutputPath)\tools/Microsoft.CodeAnalysis.dll" />
|
||||
<ExcludePackageFileFromSigning Include="$(MSBuildProjectDirectory)\$(OutputPath)\tools/runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll" />
|
||||
<ExcludePackageFileFromSigning Include="$(MSBuildProjectDirectory)\$(OutputPath)\tools/runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PopulateNuspec" BeforeTargets="GenerateNuspec">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Make sure we create a symbols.nupkg. -->
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
|
||||
<!-- RepositoryCommit is only available when "build" runs, but not during dotnet pack -->
|
||||
<RepositoryCommit Condition="'$(RepositoryCommit)' == ''">unknown</RepositoryCommit>
|
||||
|
||||
<NuspecProperties>
|
||||
id=$(PackageId);
|
||||
version=$(PackageVersion);
|
||||
authors=$(Authors);
|
||||
description=$(Description);
|
||||
tags=$(PackageTags.Replace(';', ' '));
|
||||
licenseUrl=$(PackageLicenseUrl);
|
||||
projectUrl=$(PackageProjectUrl);
|
||||
iconUrl=$(PackageIconUrl);
|
||||
repositoryUrl=$(RepositoryUrl);
|
||||
repositoryCommit=$(RepositoryCommit);
|
||||
copyright=$(Copyright);
|
||||
|
||||
<!-- Include the assembly and symbols from the tools project -->
|
||||
ToolFiles=$(OutputPath)tools\**\*;
|
||||
</NuspecProperties>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="LayoutDependencies" AfterTargets="Build" BeforeTargets="PopulateNuspec">
|
||||
<RemoveDir Directories="$(OutputPath)tools\" />
|
||||
<MSBuild Projects="$(ToolProject)" Properties="PublishDir=$(MSBuildProjectDirectory)\$(OutputPath)tools\;TargetFramework=netcoreapp2.0" Targets="Publish" />
|
||||
|
||||
<ItemGroup>
|
||||
<_RazorTool Include="$(OutputPath)tools\**\*" />
|
||||
</ItemGroup>
|
||||
|
||||
<Error Text="_RazorTool is empty. This is a bug" Condition="'@(_RazorTool)'==''" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>$id$</id>
|
||||
<version>$version$</version>
|
||||
<authors>$authors$</authors>
|
||||
<description>$description$</description>
|
||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||
<tags>$tags$</tags>
|
||||
<licenseUrl>$licenseUrl$</licenseUrl>
|
||||
<projectUrl>$projectUrl$</projectUrl>
|
||||
<iconUrl>$iconUrl$</iconUrl>
|
||||
<repository type="git" url="$repositoryUrl$" commit="$repositoryCommit$" />
|
||||
<copyright>$copyright$</copyright>
|
||||
<dependencies>
|
||||
<group targetFramework=".NETStandard2.0" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
|
||||
<files>
|
||||
<file src="build\**\*.props" target="build\" />
|
||||
<file src="build\**\*.targets" target="build\" />
|
||||
<file src="buildMultiTargeting\**\*.props" target="buildMultiTargeting\" />
|
||||
<file src="buildMultiTargeting\**\*.targets" target="buildMultiTargeting\" />
|
||||
<file src="$TaskAssemblyNet46$" target="tasks\net46\" />
|
||||
<file src="$TaskSymbolNet46$" target="tasks\net46\" />
|
||||
<file src="$TaskAssemblyNetStandard$" target="tasks\netstandard2.0\" />
|
||||
<file src="$TaskSymbolNetStandard$" target="tasks\netstandard2.0\" />
|
||||
<file src="$ToolFiles$" target="tools\" exclude="**\*.xml" />
|
||||
</files>
|
||||
</package>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"AssemblyIdentity": "Microsoft.AspNetCore.Razor.Design, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
|
||||
"Types": []
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
{
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
<Project ToolsVersion="14.0" TreatAsLocalProperty="_RazorTaskFolder;_RazorTaskAssembly">
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
Used by the Web SDK if the Razor SDK can be used for compilation. This needs to live in a nuget package (not in the SDK)
|
||||
so that it only shows up in supported versions.
|
||||
-->
|
||||
<IsRazorCompilerReferenced>true</IsRazorCompilerReferenced>
|
||||
|
||||
<!--
|
||||
Location of the CodeGeneration targets. The SDK uses this to import the file ensuring deterministic import order.
|
||||
-->
|
||||
<RazorCodeGenerationTargetsPath>$(MSBuildThisFileDirectory)Microsoft.AspNetCore.Razor.Design.CodeGeneration.targets</RazorCodeGenerationTargetsPath>
|
||||
|
||||
<!--
|
||||
Configures the language version of Razor. Supported and default values differ depending on the version of
|
||||
the packages in use.
|
||||
|
||||
Supported:
|
||||
2.0
|
||||
2.1
|
||||
Latest = 2.1
|
||||
|
||||
Default:
|
||||
2.1
|
||||
-->
|
||||
<RazorLangVersion Condition="'$(RazorLangVersion)'==''">2.1</RazorLangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Override this to hijack the tasks and targets. Used by tests. -->
|
||||
<_RazorMSBuildRoot Condition="'$(_RazorMSBuildRoot)'==''">$(MSBuildThisFileDirectory)..\..\</_RazorMSBuildRoot>
|
||||
|
||||
<!-- Used to locate our tools -->
|
||||
<_RazorToolAssembly Condition="'$(_RazorToolAssembly)'==''">$(_RazorMSBuildRoot)tools\rzc.dll</_RazorToolAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!--
|
||||
Defines the ability to understand the configuration for the Razor language service provided by
|
||||
the runtime/toolset packages. Introduced in 2.1
|
||||
-->
|
||||
<ProjectCapability Include="DotNetCoreRazorConfiguration"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<Project ToolsVersion="14.0">
|
||||
<Import Project="..\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props" />
|
||||
</Project>
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<ClassifiedSpanInternal> _spans;
|
||||
private BlockKindInternal _currentBlockKind;
|
||||
private SyntaxNode _currentBlock;
|
||||
|
||||
public ClassifiedSpanVisitor(RazorSourceDocument source)
|
||||
{
|
||||
_source = source;
|
||||
_spans = new List<ClassifiedSpanInternal>();
|
||||
_currentBlockKind = BlockKindInternal.Markup;
|
||||
}
|
||||
|
||||
public IReadOnlyList<ClassifiedSpanInternal> 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<SyntaxToken>(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>(TNode node, BlockKindInternal kind, Action<TNode> 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<Syntax.InternalSyntax.SyntaxToken>());
|
||||
|
||||
return (MarkupTextLiteralSyntax)mergedLiteralSyntax.CreateRed(parent, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ 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
|
||||
{
|
||||
|
|
@ -23,37 +24,42 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
{
|
||||
throw new ArgumentNullException(nameof(syntaxTree));
|
||||
}
|
||||
|
||||
var sectionVerifier = new NestedSectionVerifier();
|
||||
sectionVerifier.Verify(syntaxTree);
|
||||
|
||||
return syntaxTree;
|
||||
|
||||
var sectionVerifier = new NestedSectionVerifier(syntaxTree);
|
||||
return sectionVerifier.Verify();
|
||||
}
|
||||
|
||||
private class NestedSectionVerifier : ParserVisitor
|
||||
private class NestedSectionVerifier : SyntaxRewriter
|
||||
{
|
||||
private int _nestedLevel;
|
||||
private RazorSyntaxTree _syntaxTree;
|
||||
|
||||
public void Verify(RazorSyntaxTree tree)
|
||||
public NestedSectionVerifier(RazorSyntaxTree syntaxTree)
|
||||
{
|
||||
tree.Root.Accept(this);
|
||||
_syntaxTree = syntaxTree;
|
||||
}
|
||||
|
||||
public override void VisitDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
|
||||
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 = block.Children.First(child => !child.IsBlock && ((Span)child).Kind == SpanKindInternal.Transition).Start;
|
||||
var directiveStart = node.Transition.GetSourceLocation(_syntaxTree.Source);
|
||||
var errorLength = /* @ */ 1 + SectionDirective.Directive.Directive.Length;
|
||||
var error = RazorDiagnosticFactory.CreateParsing_SectionsCannotBeNested(new SourceSpan(directiveStart, errorLength));
|
||||
chunkGenerator.Diagnostics.Add(error);
|
||||
node = node.AppendDiagnostic(error);
|
||||
}
|
||||
|
||||
_nestedLevel++;
|
||||
|
||||
VisitDefault(block);
|
||||
|
||||
var result = base.VisitRazorDirective(node);
|
||||
_nestedLevel--;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
int indentSize,
|
||||
bool designTime,
|
||||
bool suppressChecksum,
|
||||
bool supressMetadataAttributes)
|
||||
bool supressMetadataAttributes,
|
||||
bool suppressPrimaryMethodBody)
|
||||
{
|
||||
IndentWithTabs = indentWithTabs;
|
||||
IndentSize = indentSize;
|
||||
DesignTime = designTime;
|
||||
SuppressChecksum = suppressChecksum;
|
||||
SuppressMetadataAttributes = supressMetadataAttributes;
|
||||
SuppressPrimaryMethodBody = suppressPrimaryMethodBody;
|
||||
}
|
||||
|
||||
public override bool DesignTime { get; }
|
||||
|
|
|
|||
|
|
@ -31,10 +31,16 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
public override bool IndentWithTabs { get; set; }
|
||||
|
||||
public override bool SuppressChecksum { get; set; }
|
||||
|
||||
|
||||
public override RazorCodeGenerationOptions Build()
|
||||
{
|
||||
return new DefaultRazorCodeGenerationOptions(IndentWithTabs, IndentSize, DesignTime, SuppressChecksum, SuppressMetadataAttributes);
|
||||
return new DefaultRazorCodeGenerationOptions(
|
||||
IndentWithTabs,
|
||||
IndentSize,
|
||||
DesignTime,
|
||||
SuppressChecksum,
|
||||
SuppressMetadataAttributes,
|
||||
SuppressPrimaryMethodBody);
|
||||
}
|
||||
|
||||
public override void SetDesignTime(bool designTime)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -49,6 +49,10 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
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, '/');
|
||||
|
|
|
|||
|
|
@ -1,15 +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;
|
||||
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(
|
||||
Block root,
|
||||
SyntaxNode root,
|
||||
RazorSourceDocument source,
|
||||
IReadOnlyList<RazorDiagnostic> diagnostics,
|
||||
RazorParserOptions options)
|
||||
|
|
@ -24,7 +26,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
|
||||
public override RazorParserOptions Options { get; }
|
||||
|
||||
internal override Block Root { get; }
|
||||
internal override SyntaxNode Root { get; }
|
||||
|
||||
public override RazorSourceDocument Source { get; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ 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
|
||||
{
|
||||
|
|
@ -39,11 +40,11 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
for (var i = 0; i < imports.Count; i++)
|
||||
{
|
||||
var import = imports[i];
|
||||
visitor.VisitBlock(import.Root);
|
||||
visitor.Visit(import.Root);
|
||||
}
|
||||
}
|
||||
|
||||
visitor.VisitBlock(syntaxTree.Root);
|
||||
visitor.Visit(syntaxTree.Root);
|
||||
|
||||
var tagHelperPrefix = visitor.TagHelperPrefix;
|
||||
descriptors = visitor.Matches.ToArray();
|
||||
|
|
@ -57,21 +58,9 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return;
|
||||
}
|
||||
|
||||
var errorSink = new ErrorSink();
|
||||
var rewriter = new TagHelperParseTreeRewriter(tagHelperPrefix, descriptors, syntaxTree.Options.FeatureFlags);
|
||||
|
||||
var root = syntaxTree.Root;
|
||||
root = rewriter.Rewrite(root, errorSink);
|
||||
|
||||
var errorList = new List<RazorDiagnostic>();
|
||||
errorList.AddRange(errorSink.Errors);
|
||||
|
||||
errorList.AddRange(descriptors.SelectMany(d => d.GetAllDiagnostics()));
|
||||
|
||||
var diagnostics = CombineErrors(syntaxTree.Diagnostics, errorList);
|
||||
|
||||
var newSyntaxTree = RazorSyntaxTree.Create(root, syntaxTree.Source, diagnostics, syntaxTree.Options);
|
||||
codeDocument.SetSyntaxTree(newSyntaxTree);
|
||||
var rewrittenSyntaxTree = TagHelperParseTreeRewriter.Rewrite(syntaxTree, tagHelperPrefix, descriptors);
|
||||
|
||||
codeDocument.SetSyntaxTree(rewrittenSyntaxTree);
|
||||
}
|
||||
|
||||
private static bool MatchesDirective(TagHelperDescriptor descriptor, string typePattern, string assemblyName)
|
||||
|
|
@ -97,25 +86,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return string.Equals(descriptor.Name, typePattern, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static int GetErrorLength(string directiveText)
|
||||
{
|
||||
var nonNullLength = directiveText == null ? 1 : directiveText.Length;
|
||||
var normalizeEmptyStringLength = Math.Max(nonNullLength, 1);
|
||||
|
||||
return normalizeEmptyStringLength;
|
||||
}
|
||||
|
||||
private IReadOnlyList<RazorDiagnostic> CombineErrors(IReadOnlyList<RazorDiagnostic> errors1, IReadOnlyList<RazorDiagnostic> errors2)
|
||||
{
|
||||
var combinedErrors = new List<RazorDiagnostic>(errors1.Count + errors2.Count);
|
||||
combinedErrors.AddRange(errors1);
|
||||
combinedErrors.AddRange(errors2);
|
||||
|
||||
return combinedErrors;
|
||||
}
|
||||
|
||||
// Internal for testing.
|
||||
internal class DirectiveVisitor : ParserVisitor
|
||||
internal class DirectiveVisitor : SyntaxRewriter
|
||||
{
|
||||
private IReadOnlyList<TagHelperDescriptor> _tagHelpers;
|
||||
|
||||
|
|
@ -128,62 +99,80 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
|
||||
public HashSet<TagHelperDescriptor> Matches { get; } = new HashSet<TagHelperDescriptor>();
|
||||
|
||||
public override void VisitAddTagHelperSpan(AddTagHelperChunkGenerator chunkGenerator, Span span)
|
||||
public override SyntaxNode VisitRazorDirective(RazorDirectiveSyntax node)
|
||||
{
|
||||
if (chunkGenerator.AssemblyName == null)
|
||||
var descendantLiterals = node.DescendantNodes();
|
||||
foreach (var child in descendantLiterals)
|
||||
{
|
||||
// Skip this one, it's an error
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AssemblyContainsTagHelpers(chunkGenerator.AssemblyName, _tagHelpers))
|
||||
{
|
||||
// No tag helpers in the assembly.
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < _tagHelpers.Count; i++)
|
||||
{
|
||||
var tagHelper = _tagHelpers[i];
|
||||
if (MatchesDirective(tagHelper, chunkGenerator.TypePattern, chunkGenerator.AssemblyName))
|
||||
if (!(child is CSharpStatementLiteralSyntax literal))
|
||||
{
|
||||
Matches.Add(tagHelper);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitRemoveTagHelperSpan(RemoveTagHelperChunkGenerator chunkGenerator, Span span)
|
||||
{
|
||||
if (chunkGenerator.AssemblyName == null)
|
||||
{
|
||||
// Skip this one, it's an error
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!AssemblyContainsTagHelpers(chunkGenerator.AssemblyName, _tagHelpers))
|
||||
{
|
||||
// No tag helpers in the assembly.
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < _tagHelpers.Count; i++)
|
||||
{
|
||||
var tagHelper = _tagHelpers[i];
|
||||
if (MatchesDirective(tagHelper, chunkGenerator.TypePattern, chunkGenerator.AssemblyName))
|
||||
{
|
||||
Matches.Remove(tagHelper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitTagHelperPrefixDirectiveSpan(TagHelperPrefixDirectiveChunkGenerator chunkGenerator, Span span)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(chunkGenerator.DirectiveText))
|
||||
{
|
||||
// We only expect to see a single one of these per file, but that's enforced at another level.
|
||||
TagHelperPrefix = chunkGenerator.DirectiveText;
|
||||
}
|
||||
return base.VisitRazorDirective(node);
|
||||
}
|
||||
|
||||
private bool AssemblyContainsTagHelpers(string assemblyName, IReadOnlyList<TagHelperDescriptor> tagHelpers)
|
||||
|
|
|
|||
|
|
@ -4,18 +4,19 @@
|
|||
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<string, IEnumerable<IToken>> tokenizer) : base(tokenizer)
|
||||
public DirectiveTokenEditHandler(Func<string, IEnumerable<Syntax.InternalSyntax.SyntaxToken>> tokenizer) : base(tokenizer)
|
||||
{
|
||||
}
|
||||
|
||||
protected override PartialParseResultInternal CanAcceptChange(Span target, SourceChange change)
|
||||
protected override PartialParseResultInternal CanAcceptChange(SyntaxNode target, SourceChange change)
|
||||
{
|
||||
if (AcceptedCharacters == AcceptedCharactersInternal.NonWhiteSpace)
|
||||
if (AcceptedCharacters == AcceptedCharactersInternal.NonWhitespace)
|
||||
{
|
||||
var originalText = change.GetOriginalText(target);
|
||||
var editedContent = change.GetEditedContent(target);
|
||||
|
|
@ -30,7 +31,6 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
}
|
||||
|
||||
return PartialParseResultInternal.Rejected;
|
||||
|
||||
}
|
||||
|
||||
private static bool ContainsWhitespace(string content)
|
||||
|
|
|
|||
|
|
@ -65,15 +65,17 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
}
|
||||
|
||||
// {node.Content} __typeHelper = default({node.Content});
|
||||
|
||||
context.AddSourceMappingFor(node);
|
||||
context.CodeWriter
|
||||
.Write(node.Content)
|
||||
.Write(" ")
|
||||
.WriteStartAssignment(TypeHelper)
|
||||
.Write("default(")
|
||||
.Write(node.Content)
|
||||
.WriteLine(");");
|
||||
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:
|
||||
|
|
@ -86,16 +88,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
}
|
||||
|
||||
// global::System.Object {node.content} = null;
|
||||
|
||||
context.CodeWriter
|
||||
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;");
|
||||
context.AddSourceMappingFor(node);
|
||||
context.CodeWriter
|
||||
.Write(node.Content)
|
||||
.WriteLine(" = null;");
|
||||
}
|
||||
break;
|
||||
|
||||
case DirectiveTokenKind.Namespace:
|
||||
|
|
@ -108,46 +112,50 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
}
|
||||
|
||||
// global::System.Object __typeHelper = nameof({node.Content});
|
||||
|
||||
context.CodeWriter
|
||||
using (context.CodeWriter.BuildLinePragma(node.Source))
|
||||
{
|
||||
context.CodeWriter
|
||||
.Write("global::")
|
||||
.Write(typeof(object).FullName)
|
||||
.Write(" ")
|
||||
.WriteStartAssignment(TypeHelper);
|
||||
|
||||
context.CodeWriter.Write("nameof(");
|
||||
context.CodeWriter.Write("nameof(");
|
||||
|
||||
context.AddSourceMappingFor(node);
|
||||
context.CodeWriter
|
||||
.Write(node.Content)
|
||||
.WriteLine(");");
|
||||
context.AddSourceMappingFor(node);
|
||||
context.CodeWriter
|
||||
.Write(node.Content)
|
||||
.WriteLine(");");
|
||||
}
|
||||
break;
|
||||
|
||||
case DirectiveTokenKind.String:
|
||||
|
||||
// global::System.Object __typeHelper = "{node.Content}";
|
||||
|
||||
context.CodeWriter
|
||||
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("\"");
|
||||
}
|
||||
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(";");
|
||||
context.CodeWriter.WriteLine(";");
|
||||
}
|
||||
break;
|
||||
}
|
||||
context.CodeWriter.CurrentIndent = originalIndent;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,14 +22,11 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
throw new ArgumentNullException(nameof(syntaxTree));
|
||||
}
|
||||
|
||||
var conditionalAttributeCollapser = new ConditionalAttributeCollapser();
|
||||
var rewritten = conditionalAttributeCollapser.Rewrite(syntaxTree.Root);
|
||||
|
||||
var whitespaceRewriter = new WhiteSpaceRewriter();
|
||||
rewritten = whitespaceRewriter.Rewrite(rewritten);
|
||||
var whitespaceRewriter = new WhitespaceRewriter();
|
||||
var rewritten = whitespaceRewriter.Visit(syntaxTree.Root);
|
||||
|
||||
var rewrittenSyntaxTree = RazorSyntaxTree.Create(rewritten, syntaxTree.Source, syntaxTree.Diagnostics, syntaxTree.Options);
|
||||
return rewrittenSyntaxTree;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -10,13 +10,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
None = 0,
|
||||
NewLine = 1,
|
||||
WhiteSpace = 2,
|
||||
Whitespace = 2,
|
||||
|
||||
NonWhiteSpace = 4,
|
||||
NonWhitespace = 4,
|
||||
|
||||
AllWhiteSpace = NewLine | WhiteSpace,
|
||||
Any = AllWhiteSpace | NonWhiteSpace,
|
||||
AllWhitespace = NewLine | Whitespace,
|
||||
Any = AllWhitespace | NonWhitespace,
|
||||
|
||||
AnyExceptNewline = NonWhiteSpace | WhiteSpace
|
||||
AnyExceptNewline = NonWhitespace | Whitespace
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,23 +14,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
public string Namespace { get; }
|
||||
|
||||
public override void Accept(ParserVisitor visitor, Span span)
|
||||
{
|
||||
visitor.VisitImportSpan(this, span);
|
||||
}
|
||||
|
||||
public override void GenerateChunk(Span target, ChunkGeneratorContext context)
|
||||
{
|
||||
var ns = Namespace;
|
||||
|
||||
if (!string.IsNullOrEmpty(ns) && char.IsWhiteSpace(ns[0]))
|
||||
{
|
||||
ns = ns.Substring(1);
|
||||
}
|
||||
|
||||
//context.ChunkTreeBuilder.AddUsingChunk(ns, target);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Import:" + Namespace + ";";
|
||||
|
|
|
|||
|
|
@ -35,11 +35,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
public List<RazorDiagnostic> Diagnostics { get; }
|
||||
|
||||
public override void Accept(ParserVisitor visitor, Span span)
|
||||
{
|
||||
visitor.VisitAddTagHelperSpan(this, span);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,68 +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.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
internal class AttributeBlockChunkGenerator : ParentChunkGenerator
|
||||
{
|
||||
public AttributeBlockChunkGenerator(string name, LocationTagged<string> prefix, LocationTagged<string> suffix)
|
||||
{
|
||||
Name = name;
|
||||
Prefix = prefix;
|
||||
Suffix = suffix;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public LocationTagged<string> Prefix { get; }
|
||||
|
||||
public LocationTagged<string> Suffix { get; }
|
||||
|
||||
public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)
|
||||
{
|
||||
//var chunk = context.ChunkTreeBuilder.StartParentChunk<CodeAttributeChunk>(target);
|
||||
|
||||
//chunk.Attribute = Name;
|
||||
//chunk.Prefix = Prefix;
|
||||
//chunk.Suffix = Suffix;
|
||||
}
|
||||
|
||||
public override void GenerateEndParentChunk(Block target, ChunkGeneratorContext context)
|
||||
{
|
||||
//context.ChunkTreeBuilder.EndParentChunk();
|
||||
}
|
||||
|
||||
public override void Accept(ParserVisitor visitor, Block block)
|
||||
{
|
||||
visitor.VisitAttributeBlock(this, block);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "Attr:{0},{1:F},{2:F}", Name, Prefix, Suffix);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as AttributeBlockChunkGenerator;
|
||||
return other != null &&
|
||||
string.Equals(other.Name, Name, StringComparison.Ordinal) &&
|
||||
Equals(other.Prefix, Prefix) &&
|
||||
Equals(other.Suffix, Suffix);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(Name, StringComparer.Ordinal);
|
||||
hashCodeCombiner.Add(Prefix);
|
||||
hashCodeCombiner.Add(Suffix);
|
||||
|
||||
return hashCodeCombiner;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
|
|
@ -11,18 +12,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
private static readonly int TypeHashCode = typeof(AutoCompleteEditHandler).GetHashCode();
|
||||
|
||||
public AutoCompleteEditHandler(Func<string, IEnumerable<IToken>> tokenizer)
|
||||
public AutoCompleteEditHandler(Func<string, IEnumerable<Syntax.InternalSyntax.SyntaxToken>> tokenizer)
|
||||
: base(tokenizer)
|
||||
{
|
||||
}
|
||||
|
||||
public AutoCompleteEditHandler(Func<string, IEnumerable<IToken>> tokenizer, bool autoCompleteAtEndOfSpan)
|
||||
public AutoCompleteEditHandler(Func<string, IEnumerable<Syntax.InternalSyntax.SyntaxToken>> tokenizer, bool autoCompleteAtEndOfSpan)
|
||||
: this(tokenizer)
|
||||
{
|
||||
AutoCompleteAtEndOfSpan = autoCompleteAtEndOfSpan;
|
||||
}
|
||||
|
||||
public AutoCompleteEditHandler(Func<string, IEnumerable<IToken>> tokenizer, AcceptedCharactersInternal accepted)
|
||||
public AutoCompleteEditHandler(Func<string, IEnumerable<Syntax.InternalSyntax.SyntaxToken>> tokenizer, AcceptedCharactersInternal accepted)
|
||||
: base(tokenizer, accepted)
|
||||
{
|
||||
}
|
||||
|
|
@ -31,7 +32,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
public string AutoCompleteString { get; set; }
|
||||
|
||||
protected override PartialParseResultInternal CanAcceptChange(Span target, SourceChange change)
|
||||
protected override PartialParseResultInternal CanAcceptChange(SyntaxNode target, SourceChange change)
|
||||
{
|
||||
if (((AutoCompleteAtEndOfSpan && IsAtEndOfSpan(target, change)) || IsAtEndOfFirstLine(target, change)) &&
|
||||
change.IsInsert &&
|
||||
|
|
|
|||
|
|
@ -1,288 +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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
internal class Block : SyntaxTreeNode
|
||||
{
|
||||
private int? _length;
|
||||
|
||||
public Block(BlockBuilder source)
|
||||
: this(source.Type, source.Children, source.ChunkGenerator)
|
||||
{
|
||||
source.Reset();
|
||||
}
|
||||
|
||||
protected Block(BlockKindInternal? type, IReadOnlyList<SyntaxTreeNode> children, IParentChunkGenerator generator)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new InvalidOperationException(Resources.Block_Type_Not_Specified);
|
||||
}
|
||||
|
||||
Type = type.Value;
|
||||
Children = children;
|
||||
ChunkGenerator = generator;
|
||||
|
||||
// Perf: Avoid allocating an enumerator.
|
||||
for (var i = 0; i < Children.Count; i++)
|
||||
{
|
||||
Children[i].Parent = this;
|
||||
}
|
||||
}
|
||||
public IParentChunkGenerator ChunkGenerator { get; }
|
||||
|
||||
public BlockKindInternal Type { get; }
|
||||
|
||||
public IReadOnlyList<SyntaxTreeNode> Children { get; }
|
||||
|
||||
public override bool IsBlock => true;
|
||||
|
||||
public override SourceLocation Start
|
||||
{
|
||||
get
|
||||
{
|
||||
var child = Children.FirstOrDefault();
|
||||
if (child == null)
|
||||
{
|
||||
return SourceLocation.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
return child.Start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_length == null)
|
||||
{
|
||||
var length = 0;
|
||||
for (var i = 0; i < Children.Count; i++)
|
||||
{
|
||||
length += Children[i].Length;
|
||||
}
|
||||
|
||||
_length = length;
|
||||
}
|
||||
|
||||
return _length.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual IEnumerable<Span> Flatten()
|
||||
{
|
||||
// Perf: Avoid allocating an enumerator.
|
||||
for (var i = 0; i < Children.Count; i++)
|
||||
{
|
||||
var element = Children[i];
|
||||
var span = element as Span;
|
||||
if (span != null)
|
||||
{
|
||||
yield return span;
|
||||
}
|
||||
else
|
||||
{
|
||||
var block = element as Block;
|
||||
foreach (Span childSpan in block.Flatten())
|
||||
{
|
||||
yield return childSpan;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Span FindFirstDescendentSpan()
|
||||
{
|
||||
SyntaxTreeNode current = this;
|
||||
while (current != null && current.IsBlock)
|
||||
{
|
||||
current = ((Block)current).Children.FirstOrDefault();
|
||||
}
|
||||
return current as Span;
|
||||
}
|
||||
|
||||
public Span FindLastDescendentSpan()
|
||||
{
|
||||
SyntaxTreeNode current = this;
|
||||
while (current != null && current.IsBlock)
|
||||
{
|
||||
current = ((Block)current).Children.LastOrDefault();
|
||||
}
|
||||
return current as Span;
|
||||
}
|
||||
|
||||
public virtual Span LocateOwner(SourceChange change) => LocateOwner(change, Children);
|
||||
|
||||
protected static Span LocateOwner(SourceChange change, IEnumerable<SyntaxTreeNode> elements)
|
||||
{
|
||||
// Ask each child recursively
|
||||
Span owner = null;
|
||||
foreach (var element in elements)
|
||||
{
|
||||
var span = element as Span;
|
||||
if (span == null)
|
||||
{
|
||||
owner = ((Block)element).LocateOwner(change);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (change.Span.AbsoluteIndex < span.Start.AbsoluteIndex)
|
||||
{
|
||||
// Early escape for cases where changes overlap multiple spans
|
||||
// In those cases, the span will return false, and we don't want to search the whole tree
|
||||
// So if the current span starts after the change, we know we've searched as far as we need to
|
||||
break;
|
||||
}
|
||||
owner = span.EditHandler.OwnsChange(span, change) ? span : owner;
|
||||
}
|
||||
|
||||
if (owner != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return owner;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"{0} Block at {1}::{2} (Gen:{3})",
|
||||
Type,
|
||||
Start,
|
||||
Length,
|
||||
ChunkGenerator);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as Block;
|
||||
return other != null &&
|
||||
Type == other.Type &&
|
||||
Equals(ChunkGenerator, other.ChunkGenerator) &&
|
||||
ChildrenEqual(Children, other.Children);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(Type);
|
||||
hashCodeCombiner.Add(ChunkGenerator);
|
||||
hashCodeCombiner.Add(Children);
|
||||
|
||||
return hashCodeCombiner;
|
||||
}
|
||||
|
||||
private static bool ChildrenEqual(IEnumerable<SyntaxTreeNode> left, IEnumerable<SyntaxTreeNode> right)
|
||||
{
|
||||
IEnumerator<SyntaxTreeNode> leftEnum = left.GetEnumerator();
|
||||
IEnumerator<SyntaxTreeNode> rightEnum = right.GetEnumerator();
|
||||
while (leftEnum.MoveNext())
|
||||
{
|
||||
if (!rightEnum.MoveNext() || // More items in left than in right
|
||||
!Equals(leftEnum.Current, rightEnum.Current))
|
||||
{
|
||||
// Nodes are not equal
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (rightEnum.MoveNext())
|
||||
{
|
||||
// More items in right than left
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool EquivalentTo(SyntaxTreeNode node)
|
||||
{
|
||||
var other = node as Block;
|
||||
if (other == null || other.Type != Type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Enumerable.SequenceEqual(Children, other.Children, EquivalenceComparer.Default);
|
||||
}
|
||||
|
||||
public override int GetEquivalenceHash()
|
||||
{
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(Type);
|
||||
foreach (var child in Children)
|
||||
{
|
||||
hashCodeCombiner.Add(child.GetEquivalenceHash());
|
||||
}
|
||||
|
||||
return hashCodeCombiner.CombinedHash;
|
||||
}
|
||||
|
||||
public override void Accept(ParserVisitor visitor)
|
||||
{
|
||||
visitor.VisitBlock(this);
|
||||
}
|
||||
|
||||
public override SyntaxTreeNode Clone()
|
||||
{
|
||||
var blockBuilder = new BlockBuilder(this);
|
||||
|
||||
blockBuilder.Children.Clear();
|
||||
for (var i = 0; i < Children.Count; i++)
|
||||
{
|
||||
var clonedChild = Children[i].Clone();
|
||||
blockBuilder.Children.Add(clonedChild);
|
||||
}
|
||||
|
||||
return blockBuilder.Build();
|
||||
}
|
||||
|
||||
internal void ChildChanged()
|
||||
{
|
||||
// A node in our graph has changed. We'll need to recompute our length the next time we're asked for it.
|
||||
_length = null;
|
||||
|
||||
Parent?.ChildChanged();
|
||||
}
|
||||
|
||||
private class EquivalenceComparer : IEqualityComparer<SyntaxTreeNode>
|
||||
{
|
||||
public static readonly EquivalenceComparer Default = new EquivalenceComparer();
|
||||
|
||||
private EquivalenceComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Equals(SyntaxTreeNode nodeX, SyntaxTreeNode nodeY)
|
||||
{
|
||||
if (nodeX == nodeY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return nodeX != null && nodeX.EquivalentTo(nodeY);
|
||||
}
|
||||
|
||||
public int GetHashCode(SyntaxTreeNode node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(node));
|
||||
}
|
||||
|
||||
return node.GetEquivalenceHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +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.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
internal class BlockBuilder
|
||||
{
|
||||
public BlockBuilder()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public BlockBuilder(Block original)
|
||||
{
|
||||
Type = original.Type;
|
||||
Children = new List<SyntaxTreeNode>(original.Children);
|
||||
ChunkGenerator = original.ChunkGenerator;
|
||||
}
|
||||
|
||||
public IParentChunkGenerator ChunkGenerator { get; set; }
|
||||
|
||||
public BlockKindInternal? Type { get; set; }
|
||||
|
||||
public List<SyntaxTreeNode> Children { get; private set; }
|
||||
|
||||
public virtual Block Build()
|
||||
{
|
||||
return new Block(this);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
Type = null;
|
||||
Children = new List<SyntaxTreeNode>();
|
||||
ChunkGenerator = ParentChunkGenerator.Null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +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.Language.Legacy
|
||||
{
|
||||
internal static class BlockExtensions
|
||||
{
|
||||
public static void LinkNodes(this Block self)
|
||||
{
|
||||
Span first = null;
|
||||
Span previous = null;
|
||||
foreach (Span span in self.Flatten())
|
||||
{
|
||||
if (first == null)
|
||||
{
|
||||
first = span;
|
||||
}
|
||||
span.Previous = previous;
|
||||
|
||||
if (previous != null)
|
||||
{
|
||||
previous.Next = span;
|
||||
}
|
||||
previous = span;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,64 +3,65 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
internal class CSharpLanguageCharacteristics : LanguageCharacteristics<CSharpTokenizer, CSharpToken, CSharpTokenType>
|
||||
internal class CSharpLanguageCharacteristics : LanguageCharacteristics<CSharpTokenizer>
|
||||
{
|
||||
private static readonly CSharpLanguageCharacteristics _instance = new CSharpLanguageCharacteristics();
|
||||
|
||||
private static Dictionary<CSharpTokenType, string> _tokenSamples = new Dictionary<CSharpTokenType, string>()
|
||||
private static Dictionary<SyntaxKind, string> _tokenSamples = new Dictionary<SyntaxKind, string>()
|
||||
{
|
||||
{ CSharpTokenType.Arrow, "->" },
|
||||
{ CSharpTokenType.Minus, "-" },
|
||||
{ CSharpTokenType.Decrement, "--" },
|
||||
{ CSharpTokenType.MinusAssign, "-=" },
|
||||
{ CSharpTokenType.NotEqual, "!=" },
|
||||
{ CSharpTokenType.Not, "!" },
|
||||
{ CSharpTokenType.Modulo, "%" },
|
||||
{ CSharpTokenType.ModuloAssign, "%=" },
|
||||
{ CSharpTokenType.AndAssign, "&=" },
|
||||
{ CSharpTokenType.And, "&" },
|
||||
{ CSharpTokenType.DoubleAnd, "&&" },
|
||||
{ CSharpTokenType.LeftParenthesis, "(" },
|
||||
{ CSharpTokenType.RightParenthesis, ")" },
|
||||
{ CSharpTokenType.Star, "*" },
|
||||
{ CSharpTokenType.MultiplyAssign, "*=" },
|
||||
{ CSharpTokenType.Comma, "," },
|
||||
{ CSharpTokenType.Dot, "." },
|
||||
{ CSharpTokenType.Slash, "/" },
|
||||
{ CSharpTokenType.DivideAssign, "/=" },
|
||||
{ CSharpTokenType.DoubleColon, "::" },
|
||||
{ CSharpTokenType.Colon, ":" },
|
||||
{ CSharpTokenType.Semicolon, ";" },
|
||||
{ CSharpTokenType.QuestionMark, "?" },
|
||||
{ CSharpTokenType.NullCoalesce, "??" },
|
||||
{ CSharpTokenType.RightBracket, "]" },
|
||||
{ CSharpTokenType.LeftBracket, "[" },
|
||||
{ CSharpTokenType.XorAssign, "^=" },
|
||||
{ CSharpTokenType.Xor, "^" },
|
||||
{ CSharpTokenType.LeftBrace, "{" },
|
||||
{ CSharpTokenType.OrAssign, "|=" },
|
||||
{ CSharpTokenType.DoubleOr, "||" },
|
||||
{ CSharpTokenType.Or, "|" },
|
||||
{ CSharpTokenType.RightBrace, "}" },
|
||||
{ CSharpTokenType.Tilde, "~" },
|
||||
{ CSharpTokenType.Plus, "+" },
|
||||
{ CSharpTokenType.PlusAssign, "+=" },
|
||||
{ CSharpTokenType.Increment, "++" },
|
||||
{ CSharpTokenType.LessThan, "<" },
|
||||
{ CSharpTokenType.LessThanEqual, "<=" },
|
||||
{ CSharpTokenType.LeftShift, "<<" },
|
||||
{ CSharpTokenType.LeftShiftAssign, "<<=" },
|
||||
{ CSharpTokenType.Assign, "=" },
|
||||
{ CSharpTokenType.Equals, "==" },
|
||||
{ CSharpTokenType.GreaterThan, ">" },
|
||||
{ CSharpTokenType.GreaterThanEqual, ">=" },
|
||||
{ CSharpTokenType.RightShift, ">>" },
|
||||
{ CSharpTokenType.RightShiftAssign, ">>=" },
|
||||
{ CSharpTokenType.Hash, "#" },
|
||||
{ CSharpTokenType.Transition, "@" },
|
||||
{ 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()
|
||||
|
|
@ -74,35 +75,35 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return new CSharpTokenizer(source);
|
||||
}
|
||||
|
||||
protected override CSharpToken CreateToken(string content, CSharpTokenType type, IReadOnlyList<RazorDiagnostic> errors)
|
||||
protected override SyntaxToken CreateToken(string content, SyntaxKind kind, IReadOnlyList<RazorDiagnostic> errors)
|
||||
{
|
||||
return new CSharpToken(content, type, errors);
|
||||
return SyntaxFactory.Token(kind, content, errors);
|
||||
}
|
||||
|
||||
public override string GetSample(CSharpTokenType type)
|
||||
public override string GetSample(SyntaxKind kind)
|
||||
{
|
||||
string sample;
|
||||
if (!_tokenSamples.TryGetValue(type, out sample))
|
||||
if (!_tokenSamples.TryGetValue(kind, out sample))
|
||||
{
|
||||
switch (type)
|
||||
switch (kind)
|
||||
{
|
||||
case CSharpTokenType.Identifier:
|
||||
case SyntaxKind.Identifier:
|
||||
return Resources.CSharpToken_Identifier;
|
||||
case CSharpTokenType.Keyword:
|
||||
case SyntaxKind.Keyword:
|
||||
return Resources.CSharpToken_Keyword;
|
||||
case CSharpTokenType.IntegerLiteral:
|
||||
case SyntaxKind.IntegerLiteral:
|
||||
return Resources.CSharpToken_IntegerLiteral;
|
||||
case CSharpTokenType.NewLine:
|
||||
case SyntaxKind.NewLine:
|
||||
return Resources.CSharpToken_Newline;
|
||||
case CSharpTokenType.WhiteSpace:
|
||||
case SyntaxKind.Whitespace:
|
||||
return Resources.CSharpToken_Whitespace;
|
||||
case CSharpTokenType.Comment:
|
||||
case SyntaxKind.CSharpComment:
|
||||
return Resources.CSharpToken_Comment;
|
||||
case CSharpTokenType.RealLiteral:
|
||||
case SyntaxKind.RealLiteral:
|
||||
return Resources.CSharpToken_RealLiteral;
|
||||
case CSharpTokenType.CharacterLiteral:
|
||||
case SyntaxKind.CharacterLiteral:
|
||||
return Resources.CSharpToken_CharacterLiteral;
|
||||
case CSharpTokenType.StringLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
return Resources.CSharpToken_StringLiteral;
|
||||
default:
|
||||
return Resources.Token_Unknown;
|
||||
|
|
@ -111,59 +112,59 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return sample;
|
||||
}
|
||||
|
||||
public override CSharpToken CreateMarkerToken()
|
||||
public override SyntaxToken CreateMarkerToken()
|
||||
{
|
||||
return new CSharpToken(string.Empty, CSharpTokenType.Unknown);
|
||||
return SyntaxFactory.Token(SyntaxKind.Marker, string.Empty);
|
||||
}
|
||||
|
||||
public override CSharpTokenType GetKnownTokenType(KnownTokenType type)
|
||||
public override SyntaxKind GetKnownTokenType(KnownTokenType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case KnownTokenType.Identifier:
|
||||
return CSharpTokenType.Identifier;
|
||||
return SyntaxKind.Identifier;
|
||||
case KnownTokenType.Keyword:
|
||||
return CSharpTokenType.Keyword;
|
||||
return SyntaxKind.Keyword;
|
||||
case KnownTokenType.NewLine:
|
||||
return CSharpTokenType.NewLine;
|
||||
case KnownTokenType.WhiteSpace:
|
||||
return CSharpTokenType.WhiteSpace;
|
||||
return SyntaxKind.NewLine;
|
||||
case KnownTokenType.Whitespace:
|
||||
return SyntaxKind.Whitespace;
|
||||
case KnownTokenType.Transition:
|
||||
return CSharpTokenType.Transition;
|
||||
return SyntaxKind.Transition;
|
||||
case KnownTokenType.CommentStart:
|
||||
return CSharpTokenType.RazorCommentTransition;
|
||||
return SyntaxKind.RazorCommentTransition;
|
||||
case KnownTokenType.CommentStar:
|
||||
return CSharpTokenType.RazorCommentStar;
|
||||
return SyntaxKind.RazorCommentStar;
|
||||
case KnownTokenType.CommentBody:
|
||||
return CSharpTokenType.RazorComment;
|
||||
return SyntaxKind.RazorCommentLiteral;
|
||||
default:
|
||||
return CSharpTokenType.Unknown;
|
||||
return SyntaxKind.Marker;
|
||||
}
|
||||
}
|
||||
|
||||
public override CSharpTokenType FlipBracket(CSharpTokenType bracket)
|
||||
public override SyntaxKind FlipBracket(SyntaxKind bracket)
|
||||
{
|
||||
switch (bracket)
|
||||
{
|
||||
case CSharpTokenType.LeftBrace:
|
||||
return CSharpTokenType.RightBrace;
|
||||
case CSharpTokenType.LeftBracket:
|
||||
return CSharpTokenType.RightBracket;
|
||||
case CSharpTokenType.LeftParenthesis:
|
||||
return CSharpTokenType.RightParenthesis;
|
||||
case CSharpTokenType.LessThan:
|
||||
return CSharpTokenType.GreaterThan;
|
||||
case CSharpTokenType.RightBrace:
|
||||
return CSharpTokenType.LeftBrace;
|
||||
case CSharpTokenType.RightBracket:
|
||||
return CSharpTokenType.LeftBracket;
|
||||
case CSharpTokenType.RightParenthesis:
|
||||
return CSharpTokenType.LeftParenthesis;
|
||||
case CSharpTokenType.GreaterThan:
|
||||
return CSharpTokenType.LessThan;
|
||||
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 CSharpTokenType.Unknown;
|
||||
return SyntaxKind.Marker;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,49 +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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
internal class CSharpToken : TokenBase<CSharpTokenType>
|
||||
{
|
||||
public CSharpToken(
|
||||
string content,
|
||||
CSharpTokenType type)
|
||||
: base(content, type, RazorDiagnostic.EmptyArray)
|
||||
{
|
||||
if (content == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(content));
|
||||
}
|
||||
}
|
||||
|
||||
public CSharpToken(
|
||||
string content,
|
||||
CSharpTokenType type,
|
||||
IReadOnlyList<RazorDiagnostic> errors)
|
||||
: base(content, type, errors)
|
||||
{
|
||||
if (content == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(content));
|
||||
}
|
||||
}
|
||||
|
||||
public CSharpKeyword? Keyword { get; set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as CSharpToken;
|
||||
return base.Equals(other) &&
|
||||
other.Keyword == Keyword;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
// Hash code should include only immutable properties.
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,75 +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.Language.Legacy
|
||||
{
|
||||
internal enum CSharpTokenType
|
||||
{
|
||||
Unknown,
|
||||
Identifier,
|
||||
Keyword,
|
||||
IntegerLiteral,
|
||||
NewLine,
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
RealLiteral,
|
||||
CharacterLiteral,
|
||||
StringLiteral,
|
||||
|
||||
// Operators
|
||||
Arrow,
|
||||
Minus,
|
||||
Decrement,
|
||||
MinusAssign,
|
||||
NotEqual,
|
||||
Not,
|
||||
Modulo,
|
||||
ModuloAssign,
|
||||
AndAssign,
|
||||
And,
|
||||
DoubleAnd,
|
||||
LeftParenthesis,
|
||||
RightParenthesis,
|
||||
Star,
|
||||
MultiplyAssign,
|
||||
Comma,
|
||||
Dot,
|
||||
Slash,
|
||||
DivideAssign,
|
||||
DoubleColon,
|
||||
Colon,
|
||||
Semicolon,
|
||||
QuestionMark,
|
||||
NullCoalesce,
|
||||
RightBracket,
|
||||
LeftBracket,
|
||||
XorAssign,
|
||||
Xor,
|
||||
LeftBrace,
|
||||
OrAssign,
|
||||
DoubleOr,
|
||||
Or,
|
||||
RightBrace,
|
||||
Tilde,
|
||||
Plus,
|
||||
PlusAssign,
|
||||
Increment,
|
||||
LessThan,
|
||||
LessThanEqual,
|
||||
LeftShift,
|
||||
LeftShiftAssign,
|
||||
Assign,
|
||||
Equals,
|
||||
GreaterThan,
|
||||
GreaterThanEqual,
|
||||
RightShift,
|
||||
RightShiftAssign,
|
||||
Hash,
|
||||
Transition,
|
||||
|
||||
// Razor specific
|
||||
RazorCommentTransition,
|
||||
RazorCommentStar,
|
||||
RazorComment
|
||||
}
|
||||
}
|
||||
|
|
@ -5,12 +5,13 @@ 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<CSharpToken, CSharpTokenType>
|
||||
internal class CSharpTokenizer : Tokenizer
|
||||
{
|
||||
private Dictionary<char, Func<CSharpTokenType>> _operatorHandlers;
|
||||
private Dictionary<char, Func<SyntaxKind>> _operatorHandlers;
|
||||
|
||||
private static readonly Dictionary<string, CSharpKeyword> _keywords = new Dictionary<string, CSharpKeyword>(StringComparer.Ordinal)
|
||||
{
|
||||
|
|
@ -100,31 +101,31 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
base.CurrentState = StartState;
|
||||
|
||||
_operatorHandlers = new Dictionary<char, Func<CSharpTokenType>>()
|
||||
_operatorHandlers = new Dictionary<char, Func<SyntaxKind>>()
|
||||
{
|
||||
{ '-', MinusOperator },
|
||||
{ '<', LessThanOperator },
|
||||
{ '>', GreaterThanOperator },
|
||||
{ '&', CreateTwoCharOperatorHandler(CSharpTokenType.And, '=', CSharpTokenType.AndAssign, '&', CSharpTokenType.DoubleAnd) },
|
||||
{ '|', CreateTwoCharOperatorHandler(CSharpTokenType.Or, '=', CSharpTokenType.OrAssign, '|', CSharpTokenType.DoubleOr) },
|
||||
{ '+', CreateTwoCharOperatorHandler(CSharpTokenType.Plus, '=', CSharpTokenType.PlusAssign, '+', CSharpTokenType.Increment) },
|
||||
{ '=', CreateTwoCharOperatorHandler(CSharpTokenType.Assign, '=', CSharpTokenType.Equals, '>', CSharpTokenType.GreaterThanEqual) },
|
||||
{ '!', CreateTwoCharOperatorHandler(CSharpTokenType.Not, '=', CSharpTokenType.NotEqual) },
|
||||
{ '%', CreateTwoCharOperatorHandler(CSharpTokenType.Modulo, '=', CSharpTokenType.ModuloAssign) },
|
||||
{ '*', CreateTwoCharOperatorHandler(CSharpTokenType.Star, '=', CSharpTokenType.MultiplyAssign) },
|
||||
{ ':', CreateTwoCharOperatorHandler(CSharpTokenType.Colon, ':', CSharpTokenType.DoubleColon) },
|
||||
{ '?', CreateTwoCharOperatorHandler(CSharpTokenType.QuestionMark, '?', CSharpTokenType.NullCoalesce) },
|
||||
{ '^', CreateTwoCharOperatorHandler(CSharpTokenType.Xor, '=', CSharpTokenType.XorAssign) },
|
||||
{ '(', () => CSharpTokenType.LeftParenthesis },
|
||||
{ ')', () => CSharpTokenType.RightParenthesis },
|
||||
{ '{', () => CSharpTokenType.LeftBrace },
|
||||
{ '}', () => CSharpTokenType.RightBrace },
|
||||
{ '[', () => CSharpTokenType.LeftBracket },
|
||||
{ ']', () => CSharpTokenType.RightBracket },
|
||||
{ ',', () => CSharpTokenType.Comma },
|
||||
{ ';', () => CSharpTokenType.Semicolon },
|
||||
{ '~', () => CSharpTokenType.Tilde },
|
||||
{ '#', () => CSharpTokenType.Hash }
|
||||
{ '&', 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 }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -132,11 +133,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
private new CSharpTokenizerState? CurrentState => (CSharpTokenizerState?)base.CurrentState;
|
||||
|
||||
public override CSharpTokenType RazorCommentType => CSharpTokenType.RazorComment;
|
||||
public override SyntaxKind RazorCommentKind => SyntaxKind.RazorCommentLiteral;
|
||||
|
||||
public override CSharpTokenType RazorCommentTransitionType => CSharpTokenType.RazorCommentTransition;
|
||||
public override SyntaxKind RazorCommentTransitionKind => SyntaxKind.RazorCommentTransition;
|
||||
|
||||
public override CSharpTokenType RazorCommentStarType => CSharpTokenType.RazorCommentStar;
|
||||
public override SyntaxKind RazorCommentStarKind => SyntaxKind.RazorCommentStar;
|
||||
|
||||
protected override StateResult Dispatch()
|
||||
{
|
||||
|
|
@ -169,7 +170,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
|
||||
// Optimize memory allocation by returning constants for the most frequent cases
|
||||
protected override string GetTokenContent(CSharpTokenType type)
|
||||
protected override string GetTokenContent(SyntaxKind type)
|
||||
{
|
||||
var tokenLength = Buffer.Length;
|
||||
|
||||
|
|
@ -177,7 +178,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case CSharpTokenType.IntegerLiteral:
|
||||
case SyntaxKind.IntegerLiteral:
|
||||
switch (Buffer[0])
|
||||
{
|
||||
case '0':
|
||||
|
|
@ -202,13 +203,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return "9";
|
||||
}
|
||||
break;
|
||||
case CSharpTokenType.NewLine:
|
||||
case SyntaxKind.NewLine:
|
||||
if (Buffer[0] == '\n')
|
||||
{
|
||||
return "\n";
|
||||
}
|
||||
break;
|
||||
case CSharpTokenType.WhiteSpace:
|
||||
case SyntaxKind.Whitespace:
|
||||
if (Buffer[0] == ' ')
|
||||
{
|
||||
return " ";
|
||||
|
|
@ -218,57 +219,57 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return "\t";
|
||||
}
|
||||
break;
|
||||
case CSharpTokenType.Minus:
|
||||
case SyntaxKind.Minus:
|
||||
return "-";
|
||||
case CSharpTokenType.Not:
|
||||
case SyntaxKind.Not:
|
||||
return "!";
|
||||
case CSharpTokenType.Modulo:
|
||||
case SyntaxKind.Modulo:
|
||||
return "%";
|
||||
case CSharpTokenType.And:
|
||||
case SyntaxKind.And:
|
||||
return "&";
|
||||
case CSharpTokenType.LeftParenthesis:
|
||||
case SyntaxKind.LeftParenthesis:
|
||||
return "(";
|
||||
case CSharpTokenType.RightParenthesis:
|
||||
case SyntaxKind.RightParenthesis:
|
||||
return ")";
|
||||
case CSharpTokenType.Star:
|
||||
case SyntaxKind.Star:
|
||||
return "*";
|
||||
case CSharpTokenType.Comma:
|
||||
case SyntaxKind.Comma:
|
||||
return ",";
|
||||
case CSharpTokenType.Dot:
|
||||
case SyntaxKind.Dot:
|
||||
return ".";
|
||||
case CSharpTokenType.Slash:
|
||||
case SyntaxKind.Slash:
|
||||
return "/";
|
||||
case CSharpTokenType.Colon:
|
||||
case SyntaxKind.Colon:
|
||||
return ":";
|
||||
case CSharpTokenType.Semicolon:
|
||||
case SyntaxKind.Semicolon:
|
||||
return ";";
|
||||
case CSharpTokenType.QuestionMark:
|
||||
case SyntaxKind.QuestionMark:
|
||||
return "?";
|
||||
case CSharpTokenType.RightBracket:
|
||||
case SyntaxKind.RightBracket:
|
||||
return "]";
|
||||
case CSharpTokenType.LeftBracket:
|
||||
case SyntaxKind.LeftBracket:
|
||||
return "[";
|
||||
case CSharpTokenType.Xor:
|
||||
case SyntaxKind.Xor:
|
||||
return "^";
|
||||
case CSharpTokenType.LeftBrace:
|
||||
case SyntaxKind.LeftBrace:
|
||||
return "{";
|
||||
case CSharpTokenType.Or:
|
||||
case SyntaxKind.Or:
|
||||
return "|";
|
||||
case CSharpTokenType.RightBrace:
|
||||
case SyntaxKind.RightBrace:
|
||||
return "}";
|
||||
case CSharpTokenType.Tilde:
|
||||
case SyntaxKind.Tilde:
|
||||
return "~";
|
||||
case CSharpTokenType.Plus:
|
||||
case SyntaxKind.Plus:
|
||||
return "+";
|
||||
case CSharpTokenType.LessThan:
|
||||
case SyntaxKind.LessThan:
|
||||
return "<";
|
||||
case CSharpTokenType.Assign:
|
||||
case SyntaxKind.Assign:
|
||||
return "=";
|
||||
case CSharpTokenType.GreaterThan:
|
||||
case SyntaxKind.GreaterThan:
|
||||
return ">";
|
||||
case CSharpTokenType.Hash:
|
||||
case SyntaxKind.Hash:
|
||||
return "#";
|
||||
case CSharpTokenType.Transition:
|
||||
case SyntaxKind.Transition:
|
||||
return "@";
|
||||
|
||||
}
|
||||
|
|
@ -277,53 +278,53 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case CSharpTokenType.NewLine:
|
||||
case SyntaxKind.NewLine:
|
||||
return "\r\n";
|
||||
case CSharpTokenType.Arrow:
|
||||
case SyntaxKind.Arrow:
|
||||
return "->";
|
||||
case CSharpTokenType.Decrement:
|
||||
case SyntaxKind.Decrement:
|
||||
return "--";
|
||||
case CSharpTokenType.MinusAssign:
|
||||
case SyntaxKind.MinusAssign:
|
||||
return "-=";
|
||||
case CSharpTokenType.NotEqual:
|
||||
case SyntaxKind.NotEqual:
|
||||
return "!=";
|
||||
case CSharpTokenType.ModuloAssign:
|
||||
case SyntaxKind.ModuloAssign:
|
||||
return "%=";
|
||||
case CSharpTokenType.AndAssign:
|
||||
case SyntaxKind.AndAssign:
|
||||
return "&=";
|
||||
case CSharpTokenType.DoubleAnd:
|
||||
case SyntaxKind.DoubleAnd:
|
||||
return "&&";
|
||||
case CSharpTokenType.MultiplyAssign:
|
||||
case SyntaxKind.MultiplyAssign:
|
||||
return "*=";
|
||||
case CSharpTokenType.DivideAssign:
|
||||
case SyntaxKind.DivideAssign:
|
||||
return "/=";
|
||||
case CSharpTokenType.DoubleColon:
|
||||
case SyntaxKind.DoubleColon:
|
||||
return "::";
|
||||
case CSharpTokenType.NullCoalesce:
|
||||
case SyntaxKind.NullCoalesce:
|
||||
return "??";
|
||||
case CSharpTokenType.XorAssign:
|
||||
case SyntaxKind.XorAssign:
|
||||
return "^=";
|
||||
case CSharpTokenType.OrAssign:
|
||||
case SyntaxKind.OrAssign:
|
||||
return "|=";
|
||||
case CSharpTokenType.DoubleOr:
|
||||
case SyntaxKind.DoubleOr:
|
||||
return "||";
|
||||
case CSharpTokenType.PlusAssign:
|
||||
case SyntaxKind.PlusAssign:
|
||||
return "+=";
|
||||
case CSharpTokenType.Increment:
|
||||
case SyntaxKind.Increment:
|
||||
return "++";
|
||||
case CSharpTokenType.LessThanEqual:
|
||||
case SyntaxKind.LessThanEqual:
|
||||
return "<=";
|
||||
case CSharpTokenType.LeftShift:
|
||||
case SyntaxKind.LeftShift:
|
||||
return "<<";
|
||||
case CSharpTokenType.Equals:
|
||||
case SyntaxKind.Equals:
|
||||
return "==";
|
||||
case CSharpTokenType.GreaterThanEqual:
|
||||
case SyntaxKind.GreaterThanEqual:
|
||||
if (Buffer[0] == '=')
|
||||
{
|
||||
return "=>";
|
||||
}
|
||||
return ">=";
|
||||
case CSharpTokenType.RightShift:
|
||||
case SyntaxKind.RightShift:
|
||||
return ">>";
|
||||
|
||||
|
||||
|
|
@ -333,9 +334,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case CSharpTokenType.LeftShiftAssign:
|
||||
case SyntaxKind.LeftShiftAssign:
|
||||
return "<<=";
|
||||
case CSharpTokenType.RightShiftAssign:
|
||||
case SyntaxKind.RightShiftAssign:
|
||||
return ">>=";
|
||||
}
|
||||
}
|
||||
|
|
@ -343,9 +344,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return base.GetTokenContent(type);
|
||||
}
|
||||
|
||||
protected override CSharpToken CreateToken(string content, CSharpTokenType type, IReadOnlyList<RazorDiagnostic> errors)
|
||||
protected override SyntaxToken CreateToken(string content, SyntaxKind kind, IReadOnlyList<RazorDiagnostic> errors)
|
||||
{
|
||||
return new CSharpToken(content, type, errors);
|
||||
return SyntaxFactory.Token(kind, content, errors);
|
||||
}
|
||||
|
||||
private StateResult Data()
|
||||
|
|
@ -359,13 +360,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
TakeCurrent();
|
||||
}
|
||||
return Stay(EndToken(CSharpTokenType.NewLine));
|
||||
return Stay(EndToken(SyntaxKind.NewLine));
|
||||
}
|
||||
else if (ParserHelpers.IsWhitespace(CurrentCharacter))
|
||||
{
|
||||
// CSharp Spec §2.3.3
|
||||
TakeUntil(c => !ParserHelpers.IsWhitespace(c));
|
||||
return Stay(EndToken(CSharpTokenType.WhiteSpace));
|
||||
return Stay(EndToken(SyntaxKind.Whitespace));
|
||||
}
|
||||
else if (IsIdentifierStart(CurrentCharacter))
|
||||
{
|
||||
|
|
@ -390,7 +391,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
return RealLiteral();
|
||||
}
|
||||
return Stay(Single(CSharpTokenType.Dot));
|
||||
return Stay(Single(SyntaxKind.Dot));
|
||||
case '/':
|
||||
TakeCurrent();
|
||||
if (CurrentCharacter == '/')
|
||||
|
|
@ -406,11 +407,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
else if (CurrentCharacter == '=')
|
||||
{
|
||||
TakeCurrent();
|
||||
return Stay(EndToken(CSharpTokenType.DivideAssign));
|
||||
return Stay(EndToken(SyntaxKind.DivideAssign));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Stay(EndToken(CSharpTokenType.Slash));
|
||||
return Stay(EndToken(SyntaxKind.Slash));
|
||||
}
|
||||
default:
|
||||
return Stay(EndToken(Operator()));
|
||||
|
|
@ -429,78 +430,78 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
return Transition(
|
||||
CSharpTokenizerState.AfterRazorCommentTransition,
|
||||
EndToken(CSharpTokenType.RazorCommentTransition));
|
||||
EndToken(SyntaxKind.RazorCommentTransition));
|
||||
}
|
||||
else if (CurrentCharacter == '@')
|
||||
{
|
||||
// Could be escaped comment transition
|
||||
return Transition(
|
||||
CSharpTokenizerState.EscapedRazorCommentTransition,
|
||||
EndToken(CSharpTokenType.Transition));
|
||||
EndToken(SyntaxKind.Transition));
|
||||
}
|
||||
|
||||
return Stay(EndToken(CSharpTokenType.Transition));
|
||||
return Stay(EndToken(SyntaxKind.Transition));
|
||||
}
|
||||
|
||||
private StateResult EscapedRazorCommentTransition()
|
||||
{
|
||||
TakeCurrent();
|
||||
return Transition(CSharpTokenizerState.Data, EndToken(CSharpTokenType.Transition));
|
||||
return Transition(CSharpTokenizerState.Data, EndToken(SyntaxKind.Transition));
|
||||
}
|
||||
|
||||
private CSharpTokenType Operator()
|
||||
private SyntaxKind Operator()
|
||||
{
|
||||
var first = CurrentCharacter;
|
||||
TakeCurrent();
|
||||
Func<CSharpTokenType> handler;
|
||||
Func<SyntaxKind> handler;
|
||||
if (_operatorHandlers.TryGetValue(first, out handler))
|
||||
{
|
||||
return handler();
|
||||
}
|
||||
return CSharpTokenType.Unknown;
|
||||
return SyntaxKind.Marker;
|
||||
}
|
||||
|
||||
private CSharpTokenType LessThanOperator()
|
||||
private SyntaxKind LessThanOperator()
|
||||
{
|
||||
if (CurrentCharacter == '=')
|
||||
{
|
||||
TakeCurrent();
|
||||
return CSharpTokenType.LessThanEqual;
|
||||
return SyntaxKind.LessThanEqual;
|
||||
}
|
||||
return CSharpTokenType.LessThan;
|
||||
return SyntaxKind.LessThan;
|
||||
}
|
||||
|
||||
private CSharpTokenType GreaterThanOperator()
|
||||
private SyntaxKind GreaterThanOperator()
|
||||
{
|
||||
if (CurrentCharacter == '=')
|
||||
{
|
||||
TakeCurrent();
|
||||
return CSharpTokenType.GreaterThanEqual;
|
||||
return SyntaxKind.GreaterThanEqual;
|
||||
}
|
||||
return CSharpTokenType.GreaterThan;
|
||||
return SyntaxKind.GreaterThan;
|
||||
}
|
||||
|
||||
private CSharpTokenType MinusOperator()
|
||||
private SyntaxKind MinusOperator()
|
||||
{
|
||||
if (CurrentCharacter == '>')
|
||||
{
|
||||
TakeCurrent();
|
||||
return CSharpTokenType.Arrow;
|
||||
return SyntaxKind.Arrow;
|
||||
}
|
||||
else if (CurrentCharacter == '-')
|
||||
{
|
||||
TakeCurrent();
|
||||
return CSharpTokenType.Decrement;
|
||||
return SyntaxKind.Decrement;
|
||||
}
|
||||
else if (CurrentCharacter == '=')
|
||||
{
|
||||
TakeCurrent();
|
||||
return CSharpTokenType.MinusAssign;
|
||||
return SyntaxKind.MinusAssign;
|
||||
}
|
||||
return CSharpTokenType.Minus;
|
||||
return SyntaxKind.Minus;
|
||||
}
|
||||
|
||||
private Func<CSharpTokenType> CreateTwoCharOperatorHandler(CSharpTokenType typeIfOnlyFirst, char second, CSharpTokenType typeIfBoth)
|
||||
private Func<SyntaxKind> CreateTwoCharOperatorHandler(SyntaxKind typeIfOnlyFirst, char second, SyntaxKind typeIfBoth)
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
|
|
@ -513,7 +514,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
};
|
||||
}
|
||||
|
||||
private Func<CSharpTokenType> CreateTwoCharOperatorHandler(CSharpTokenType typeIfOnlyFirst, char option1, CSharpTokenType typeIfOption1, char option2, CSharpTokenType typeIfOption2)
|
||||
private Func<SyntaxKind> CreateTwoCharOperatorHandler(SyntaxKind typeIfOnlyFirst, char option1, SyntaxKind typeIfOption1, char option2, SyntaxKind typeIfOption2)
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
|
|
@ -550,14 +551,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
|
||||
new SourceSpan(CurrentStart, contentLength: 1 /* end of file */)));
|
||||
}
|
||||
return Transition(CSharpTokenizerState.Data, EndToken(CSharpTokenType.StringLiteral));
|
||||
return Transition(CSharpTokenizerState.Data, EndToken(SyntaxKind.StringLiteral));
|
||||
}
|
||||
|
||||
private StateResult QuotedCharacterLiteral() => QuotedLiteral('\'', CSharpTokenType.CharacterLiteral);
|
||||
private StateResult QuotedCharacterLiteral() => QuotedLiteral('\'', SyntaxKind.CharacterLiteral);
|
||||
|
||||
private StateResult QuotedStringLiteral() => QuotedLiteral('\"', CSharpTokenType.StringLiteral);
|
||||
private StateResult QuotedStringLiteral() => QuotedLiteral('\"', SyntaxKind.StringLiteral);
|
||||
|
||||
private StateResult QuotedLiteral(char quote, CSharpTokenType literalType)
|
||||
private StateResult QuotedLiteral(char quote, SyntaxKind literalType)
|
||||
{
|
||||
TakeUntil(c => c == '\\' || c == quote || ParserHelpers.IsNewLine(c));
|
||||
if (CurrentCharacter == '\\')
|
||||
|
|
@ -594,7 +595,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
RazorDiagnosticFactory.CreateParsing_BlockCommentNotTerminated(
|
||||
new SourceSpan(CurrentStart, contentLength: 1 /* end of file */)));
|
||||
|
||||
return Transition(CSharpTokenizerState.Data, EndToken(CSharpTokenType.Comment));
|
||||
return Transition(CSharpTokenizerState.Data, EndToken(SyntaxKind.CSharpComment));
|
||||
}
|
||||
if (CurrentCharacter == '*')
|
||||
{
|
||||
|
|
@ -602,7 +603,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
if (CurrentCharacter == '/')
|
||||
{
|
||||
TakeCurrent();
|
||||
return Transition(CSharpTokenizerState.Data, EndToken(CSharpTokenType.Comment));
|
||||
return Transition(CSharpTokenizerState.Data, EndToken(SyntaxKind.CSharpComment));
|
||||
}
|
||||
}
|
||||
return Stay();
|
||||
|
|
@ -612,7 +613,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
private StateResult SingleLineComment()
|
||||
{
|
||||
TakeUntil(c => ParserHelpers.IsNewLine(c));
|
||||
return Stay(EndToken(CSharpTokenType.Comment));
|
||||
return Stay(EndToken(SyntaxKind.CSharpComment));
|
||||
}
|
||||
|
||||
// CSharp Spec §2.4.4
|
||||
|
|
@ -632,7 +633,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
TakeUntil(c => !IsHexDigit(c));
|
||||
TakeIntegerSuffix();
|
||||
return Stay(EndToken(CSharpTokenType.IntegerLiteral));
|
||||
return Stay(EndToken(SyntaxKind.IntegerLiteral));
|
||||
}
|
||||
|
||||
private StateResult DecimalLiteral()
|
||||
|
|
@ -650,7 +651,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
else
|
||||
{
|
||||
TakeIntegerSuffix();
|
||||
return Stay(EndToken(CSharpTokenType.IntegerLiteral));
|
||||
return Stay(EndToken(SyntaxKind.IntegerLiteral));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -669,7 +670,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
TakeCurrent();
|
||||
}
|
||||
return Stay(EndToken(CSharpTokenType.RealLiteral));
|
||||
return Stay(EndToken(SyntaxKind.RealLiteral));
|
||||
}
|
||||
|
||||
// CSharp Spec §2.4.4.3
|
||||
|
|
@ -708,21 +709,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
Debug.Assert(IsIdentifierStart(CurrentCharacter));
|
||||
TakeCurrent();
|
||||
TakeUntil(c => !IsIdentifierPart(c));
|
||||
CSharpToken token = null;
|
||||
SyntaxToken token = null;
|
||||
if (HaveContent)
|
||||
{
|
||||
CSharpKeyword keyword;
|
||||
var type = CSharpTokenType.Identifier;
|
||||
var type = SyntaxKind.Identifier;
|
||||
var tokenContent = Buffer.ToString();
|
||||
if (_keywords.TryGetValue(tokenContent, out keyword))
|
||||
{
|
||||
type = CSharpTokenType.Keyword;
|
||||
type = SyntaxKind.Keyword;
|
||||
}
|
||||
|
||||
token = new CSharpToken(tokenContent, type)
|
||||
{
|
||||
Keyword = type == CSharpTokenType.Keyword ? (CSharpKeyword?)keyword : null,
|
||||
};
|
||||
|
||||
token = SyntaxFactory.Token(type, tokenContent);
|
||||
|
||||
Buffer.Clear();
|
||||
CurrentErrors.Clear();
|
||||
|
|
@ -736,7 +734,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return Transition((int)state, result: null);
|
||||
}
|
||||
|
||||
private StateResult Transition(CSharpTokenizerState state, CSharpToken result)
|
||||
private StateResult Transition(CSharpTokenizerState state, SyntaxToken result)
|
||||
{
|
||||
return Transition((int)state, result);
|
||||
}
|
||||
|
|
@ -780,6 +778,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -1,25 +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.Language.Legacy
|
||||
{
|
||||
internal class ChunkGeneratorContext
|
||||
{
|
||||
public ChunkGeneratorContext(
|
||||
string className,
|
||||
string rootNamespace,
|
||||
string sourceFile,
|
||||
bool shouldGenerateLinePragmas)
|
||||
{
|
||||
SourceFile = shouldGenerateLinePragmas ? sourceFile : null;
|
||||
RootNamespace = rootNamespace;
|
||||
ClassName = className;
|
||||
}
|
||||
|
||||
public string SourceFile { get; internal set; }
|
||||
|
||||
public string RootNamespace { get; }
|
||||
|
||||
public string ClassName { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -4,16 +4,17 @@
|
|||
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<string, IEnumerable<IToken>> tokenizer) : base(tokenizer)
|
||||
public CodeBlockEditHandler(Func<string, IEnumerable<Syntax.InternalSyntax.SyntaxToken>> tokenizer) : base(tokenizer)
|
||||
{
|
||||
}
|
||||
|
||||
protected override PartialParseResultInternal CanAcceptChange(Span target, SourceChange change)
|
||||
protected override PartialParseResultInternal CanAcceptChange(SyntaxNode target, SourceChange change)
|
||||
{
|
||||
if (IsAcceptableDeletion(target, change))
|
||||
{
|
||||
|
|
@ -34,7 +35,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
|
||||
// Internal for testing
|
||||
internal static bool IsAcceptableReplacement(Span target, SourceChange change)
|
||||
internal static bool IsAcceptableReplacement(SyntaxNode target, SourceChange change)
|
||||
{
|
||||
if (!change.IsReplace)
|
||||
{
|
||||
|
|
@ -55,7 +56,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
|
||||
// Internal for testing
|
||||
internal static bool IsAcceptableDeletion(Span target, SourceChange change)
|
||||
internal static bool IsAcceptableDeletion(SyntaxNode target, SourceChange change)
|
||||
{
|
||||
if (!change.IsDelete)
|
||||
{
|
||||
|
|
@ -71,11 +72,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
|
||||
// Internal for testing
|
||||
internal static bool ModifiesInvalidContent(Span target, SourceChange change)
|
||||
internal static bool ModifiesInvalidContent(SyntaxNode target, SourceChange change)
|
||||
{
|
||||
var relativePosition = change.Span.AbsoluteIndex - target.Start.AbsoluteIndex;
|
||||
var relativePosition = change.Span.AbsoluteIndex - target.Position;
|
||||
|
||||
if (target.Content.IndexOfAny(new[] { '{', '}' }, relativePosition, change.Span.Length) >= 0)
|
||||
if (target.GetContent().IndexOfAny(new[] { '{', '}' }, relativePosition, change.Span.Length) >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,67 +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.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
internal class ConditionalAttributeCollapser : MarkupRewriter
|
||||
{
|
||||
protected override bool CanRewrite(Block block)
|
||||
{
|
||||
var generator = block.ChunkGenerator as AttributeBlockChunkGenerator;
|
||||
if (generator != null && block.Children.Count > 0)
|
||||
{
|
||||
// Perf: Avoid allocating an enumerator.
|
||||
for (var i = 0; i < block.Children.Count; i++)
|
||||
{
|
||||
if (!IsLiteralAttributeValue(block.Children[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override SyntaxTreeNode RewriteBlock(BlockBuilder parent, Block block)
|
||||
{
|
||||
// Collect the content of this node
|
||||
var builder = new StringBuilder();
|
||||
for (var i = 0; i < block.Children.Count; i++)
|
||||
{
|
||||
var childSpan = (Span)block.Children[i];
|
||||
builder.Append(childSpan.Content);
|
||||
}
|
||||
|
||||
// Create a new span containing this content
|
||||
var span = new SpanBuilder(block.Children[0].Start);
|
||||
|
||||
span.EditHandler = SpanEditHandler.CreateDefault(HtmlLanguageCharacteristics.Instance.TokenizeString);
|
||||
Debug.Assert(block.Children.Count > 0);
|
||||
var start = ((Span)block.Children[0]).Start;
|
||||
FillSpan(span, start, builder.ToString());
|
||||
return span.Build();
|
||||
}
|
||||
|
||||
private bool IsLiteralAttributeValue(SyntaxTreeNode node)
|
||||
{
|
||||
if (node.IsBlock)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var span = node as Span;
|
||||
Debug.Assert(span != null);
|
||||
|
||||
return span != null &&
|
||||
(span.ChunkGenerator is LiteralAttributeChunkGenerator ||
|
||||
span.ChunkGenerator is MarkupChunkGenerator ||
|
||||
span.ChunkGenerator == SpanChunkGenerator.Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue