Catch 15.7 up with dev

This change integrates most of the non-breaking work that we did in 2.1
including the updates to make Razor less coupled to MVC.
This commit is contained in:
Nate McMaster 2018-02-09 10:08:09 -08:00 committed by Ryan Nowak
parent c1b96eaabc
commit 13824c418e
690 changed files with 13155 additions and 7708 deletions

View File

@ -1,19 +1,17 @@
init:
- git config --global core.autocrlf true
- git config --global core.autocrlf true
branches:
only:
- master
- release
- dev
- /^(.*\/)?ci-.*$/
- /^rel\/.*/
- dev
- /^release\/.*$/
- /^(.*\/)?ci-.*$/
build_script:
- ps: .\run.ps1 default-build
- ps: .\run.ps1 default-build
clone_depth: 1
environment:
global:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: 1
test: off
deploy: off
test: 'off'
deploy: 'off'
os: Visual Studio 2017 Preview

2
.gitignore vendored
View File

@ -36,3 +36,5 @@ global.json
BenchmarkDotNet.Artifacts/
Microsoft.VisualStudio.RazorExtension.nuget.props
Microsoft.VisualStudio.RazorExtension.nuget.targets
msbuild.binlog
msbuild.log

View File

@ -3,25 +3,25 @@ sudo: required
dist: trusty
env:
global:
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
- DOTNET_CLI_TELEMETRY_OPTOUT: 1
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
- DOTNET_CLI_TELEMETRY_OPTOUT: 1
addons:
apt:
packages:
- libunwind8
- libunwind8
mono: none
os:
- linux
- osx
- linux
- osx
osx_image: xcode8.2
branches:
only:
- master
- release
- dev
- /^(.*\/)?ci-.*$/
- /^rel\/.*/
- dev
- /^release\/.*$/
- /^(.*\/)?ci-.*$/
before_install:
- if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; fi
- if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
/usr/local/lib/; fi
script:
- ./build.sh
- ./build.sh

View File

@ -1,4 +1,8 @@
<Project>
<Import
Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))\AspNetCoreSettings.props"
Condition=" '$(CI)' != 'true' AND '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))' != '' " />
<Import Project="version.props" />
<Import Project="build\dependencies.props" />
<Import Project="build\sources.props" />
@ -13,9 +17,6 @@
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AssemblySigningCertName>Microsoft</AssemblySigningCertName>
<!-- Generate full pdbs for desktop targeting projects on platforms that support generating full pdbs. -->
<DebugType Condition="'$(OS)'=='Windows_NT' AND '$(TargetFramework)'=='net46'">full</DebugType>
</PropertyGroup>
<ItemGroup>

View File

@ -1,224 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26820.0
MinimumVisualStudioVersion = 15.0.26730.03
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}"
ProjectSection(SolutionItems) = preProject
src\Directory.Build.props = src\Directory.Build.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{92463391-81BE-462B-AC3C-78C6C760741F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor", "src\Microsoft.AspNetCore.Razor\Microsoft.AspNetCore.Razor.csproj", "{EDA30434-C567-44DC-B8B6-2566A7F77163}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Runtime", "src\Microsoft.AspNetCore.Razor.Runtime\Microsoft.AspNetCore.Razor.Runtime.csproj", "{D0196096-1B01-4133-AACE-1A10A0F7247C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F8C12DD6-659D-405A-AA27-FB22AD92A010}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
NuGet.config = NuGet.config
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorPageGenerator", "src\RazorPageGenerator\RazorPageGenerator.csproj", "{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Language", "src\Microsoft.AspNetCore.Razor.Language\Microsoft.AspNetCore.Razor.Language.csproj", "{932F3C9C-A6C0-40D3-BA50-9309886242FC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Language.Test", "test\Microsoft.AspNetCore.Razor.Language.Test\Microsoft.AspNetCore.Razor.Language.Test.csproj", "{969357A4-CCF1-46D9-B002-9AA072AFC75C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Runtime.Test", "test\Microsoft.AspNetCore.Razor.Runtime.Test\Microsoft.AspNetCore.Razor.Runtime.Test.csproj", "{277AB67E-9C8D-4799-A18C-C628E70A8664}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Razor.Workspaces", "src\Microsoft.CodeAnalysis.Razor.Workspaces\Microsoft.CodeAnalysis.Razor.Workspaces.csproj", "{0F265874-C592-448B-BC4F-3430AB03E0DC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Remote.Razor", "src\Microsoft.CodeAnalysis.Remote.Razor\Microsoft.CodeAnalysis.Remote.Razor.csproj", "{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Razor", "src\Microsoft.CodeAnalysis.Razor\Microsoft.CodeAnalysis.Razor.csproj", "{42403DAF-F0BC-4F3A-B7F2-46D7013345D8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Razor.Test", "test\Microsoft.CodeAnalysis.Razor.Test\Microsoft.CodeAnalysis.Razor.Test.csproj", "{7A8A1664-37CE-4376-81CA-1862CF5F91D9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorPageGenerator.Test", "test\RazorPageGenerator.Test\RazorPageGenerator.Test.csproj", "{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Razor.Extensions", "src\Microsoft.AspNetCore.Mvc.Razor.Extensions\Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj", "{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Razor.Extensions.Test", "test\Microsoft.AspNetCore.Mvc.Razor.Extensions.Test\Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj", "{7CFD5646-A757-4498-9E01-9C8528ED60AE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test.Common", "test\Microsoft.AspNetCore.Razor.Test.Common\Microsoft.AspNetCore.Razor.Test.Common.csproj", "{078AEF36-F319-4CE2-BAA2-5B58A6536B46}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Performance", "test\Microsoft.AspNetCore.Razor.Performance\Microsoft.AspNetCore.Razor.Performance.csproj", "{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test.MvcShim", "test\Microsoft.AspNetCore.Razor.Test.MvcShim\Microsoft.AspNetCore.Razor.Test.MvcShim.csproj", "{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Razor.Workspaces.Test", "test\Microsoft.CodeAnalysis.Razor.Workspaces.Test\Microsoft.CodeAnalysis.Razor.Workspaces.Test.csproj", "{C61AAE12-5007-4205-A220-68F354A7F235}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
DebugNoVSIX|Any CPU = DebugNoVSIX|Any CPU
Release|Any CPU = Release|Any CPU
ReleaseNoVSIX|Any CPU = ReleaseNoVSIX|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EDA30434-C567-44DC-B8B6-2566A7F77163}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDA30434-C567-44DC-B8B6-2566A7F77163}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDA30434-C567-44DC-B8B6-2566A7F77163}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{EDA30434-C567-44DC-B8B6-2566A7F77163}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{EDA30434-C567-44DC-B8B6-2566A7F77163}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDA30434-C567-44DC-B8B6-2566A7F77163}.Release|Any CPU.Build.0 = Release|Any CPU
{EDA30434-C567-44DC-B8B6-2566A7F77163}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{EDA30434-C567-44DC-B8B6-2566A7F77163}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{D0196096-1B01-4133-AACE-1A10A0F7247C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D0196096-1B01-4133-AACE-1A10A0F7247C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0196096-1B01-4133-AACE-1A10A0F7247C}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{D0196096-1B01-4133-AACE-1A10A0F7247C}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{D0196096-1B01-4133-AACE-1A10A0F7247C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0196096-1B01-4133-AACE-1A10A0F7247C}.Release|Any CPU.Build.0 = Release|Any CPU
{D0196096-1B01-4133-AACE-1A10A0F7247C}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{D0196096-1B01-4133-AACE-1A10A0F7247C}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}.Release|Any CPU.Build.0 = Release|Any CPU
{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{932F3C9C-A6C0-40D3-BA50-9309886242FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{932F3C9C-A6C0-40D3-BA50-9309886242FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{932F3C9C-A6C0-40D3-BA50-9309886242FC}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{932F3C9C-A6C0-40D3-BA50-9309886242FC}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{932F3C9C-A6C0-40D3-BA50-9309886242FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{932F3C9C-A6C0-40D3-BA50-9309886242FC}.Release|Any CPU.Build.0 = Release|Any CPU
{932F3C9C-A6C0-40D3-BA50-9309886242FC}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{932F3C9C-A6C0-40D3-BA50-9309886242FC}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{969357A4-CCF1-46D9-B002-9AA072AFC75C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{969357A4-CCF1-46D9-B002-9AA072AFC75C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{969357A4-CCF1-46D9-B002-9AA072AFC75C}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{969357A4-CCF1-46D9-B002-9AA072AFC75C}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{969357A4-CCF1-46D9-B002-9AA072AFC75C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{969357A4-CCF1-46D9-B002-9AA072AFC75C}.Release|Any CPU.Build.0 = Release|Any CPU
{969357A4-CCF1-46D9-B002-9AA072AFC75C}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{969357A4-CCF1-46D9-B002-9AA072AFC75C}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{277AB67E-9C8D-4799-A18C-C628E70A8664}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{277AB67E-9C8D-4799-A18C-C628E70A8664}.Debug|Any CPU.Build.0 = Debug|Any CPU
{277AB67E-9C8D-4799-A18C-C628E70A8664}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{277AB67E-9C8D-4799-A18C-C628E70A8664}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{277AB67E-9C8D-4799-A18C-C628E70A8664}.Release|Any CPU.ActiveCfg = Release|Any CPU
{277AB67E-9C8D-4799-A18C-C628E70A8664}.Release|Any CPU.Build.0 = Release|Any CPU
{277AB67E-9C8D-4799-A18C-C628E70A8664}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{277AB67E-9C8D-4799-A18C-C628E70A8664}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{0F265874-C592-448B-BC4F-3430AB03E0DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F265874-C592-448B-BC4F-3430AB03E0DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F265874-C592-448B-BC4F-3430AB03E0DC}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{0F265874-C592-448B-BC4F-3430AB03E0DC}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{0F265874-C592-448B-BC4F-3430AB03E0DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F265874-C592-448B-BC4F-3430AB03E0DC}.Release|Any CPU.Build.0 = Release|Any CPU
{0F265874-C592-448B-BC4F-3430AB03E0DC}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{0F265874-C592-448B-BC4F-3430AB03E0DC}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.Release|Any CPU.Build.0 = Release|Any CPU
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{42403DAF-F0BC-4F3A-B7F2-46D7013345D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42403DAF-F0BC-4F3A-B7F2-46D7013345D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42403DAF-F0BC-4F3A-B7F2-46D7013345D8}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{42403DAF-F0BC-4F3A-B7F2-46D7013345D8}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{42403DAF-F0BC-4F3A-B7F2-46D7013345D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42403DAF-F0BC-4F3A-B7F2-46D7013345D8}.Release|Any CPU.Build.0 = Release|Any CPU
{42403DAF-F0BC-4F3A-B7F2-46D7013345D8}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{42403DAF-F0BC-4F3A-B7F2-46D7013345D8}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{7A8A1664-37CE-4376-81CA-1862CF5F91D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7A8A1664-37CE-4376-81CA-1862CF5F91D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A8A1664-37CE-4376-81CA-1862CF5F91D9}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{7A8A1664-37CE-4376-81CA-1862CF5F91D9}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{7A8A1664-37CE-4376-81CA-1862CF5F91D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A8A1664-37CE-4376-81CA-1862CF5F91D9}.Release|Any CPU.Build.0 = Release|Any CPU
{7A8A1664-37CE-4376-81CA-1862CF5F91D9}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{7A8A1664-37CE-4376-81CA-1862CF5F91D9}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63}.Release|Any CPU.Build.0 = Release|Any CPU
{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15}.Debug|Any CPU.Build.0 = Debug|Any CPU
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15}.Release|Any CPU.ActiveCfg = Release|Any CPU
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15}.Release|Any CPU.Build.0 = Release|Any CPU
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{7CFD5646-A757-4498-9E01-9C8528ED60AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7CFD5646-A757-4498-9E01-9C8528ED60AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CFD5646-A757-4498-9E01-9C8528ED60AE}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{7CFD5646-A757-4498-9E01-9C8528ED60AE}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{7CFD5646-A757-4498-9E01-9C8528ED60AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CFD5646-A757-4498-9E01-9C8528ED60AE}.Release|Any CPU.Build.0 = Release|Any CPU
{7CFD5646-A757-4498-9E01-9C8528ED60AE}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{7CFD5646-A757-4498-9E01-9C8528ED60AE}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.Debug|Any CPU.Build.0 = Debug|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.Release|Any CPU.Build.0 = Release|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.Release|Any CPU.Build.0 = Release|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.Release|Any CPU.Build.0 = Release|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{C61AAE12-5007-4205-A220-68F354A7F235}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C61AAE12-5007-4205-A220-68F354A7F235}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C61AAE12-5007-4205-A220-68F354A7F235}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{C61AAE12-5007-4205-A220-68F354A7F235}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{C61AAE12-5007-4205-A220-68F354A7F235}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C61AAE12-5007-4205-A220-68F354A7F235}.Release|Any CPU.Build.0 = Release|Any CPU
{C61AAE12-5007-4205-A220-68F354A7F235}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{C61AAE12-5007-4205-A220-68F354A7F235}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{EDA30434-C567-44DC-B8B6-2566A7F77163} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{D0196096-1B01-4133-AACE-1A10A0F7247C} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{932F3C9C-A6C0-40D3-BA50-9309886242FC} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{969357A4-CCF1-46D9-B002-9AA072AFC75C} = {92463391-81BE-462B-AC3C-78C6C760741F}
{277AB67E-9C8D-4799-A18C-C628E70A8664} = {92463391-81BE-462B-AC3C-78C6C760741F}
{0F265874-C592-448B-BC4F-3430AB03E0DC} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{42403DAF-F0BC-4F3A-B7F2-46D7013345D8} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{7A8A1664-37CE-4376-81CA-1862CF5F91D9} = {92463391-81BE-462B-AC3C-78C6C760741F}
{96EB1BD4-B8E0-4F52-A068-BBCACA7E3F63} = {92463391-81BE-462B-AC3C-78C6C760741F}
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{7CFD5646-A757-4498-9E01-9C8528ED60AE} = {92463391-81BE-462B-AC3C-78C6C760741F}
{078AEF36-F319-4CE2-BAA2-5B58A6536B46} = {92463391-81BE-462B-AC3C-78C6C760741F}
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58} = {92463391-81BE-462B-AC3C-78C6C760741F}
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90} = {92463391-81BE-462B-AC3C-78C6C760741F}
{C61AAE12-5007-4205-A220-68F354A7F235} = {92463391-81BE-462B-AC3C-78C6C760741F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {057E86AD-8BD3-4E03-978C-42B8A5A3C024}
EndGlobalSection
EndGlobal

View File

@ -53,8 +53,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Ra
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test.Common", "test\Microsoft.AspNetCore.Razor.Test.Common\Microsoft.AspNetCore.Razor.Test.Common.csproj", "{078AEF36-F319-4CE2-BAA2-5B58A6536B46}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Performance", "test\Microsoft.AspNetCore.Razor.Performance\Microsoft.AspNetCore.Razor.Performance.csproj", "{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test.MvcShim", "test\Microsoft.AspNetCore.Razor.Test.MvcShim\Microsoft.AspNetCore.Razor.Test.MvcShim.csproj", "{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Razor.Workspaces.Test", "test\Microsoft.CodeAnalysis.Razor.Workspaces.Test\Microsoft.CodeAnalysis.Razor.Workspaces.Test.csproj", "{C61AAE12-5007-4205-A220-68F354A7F235}"
@ -75,6 +73,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.Mac.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.Mac.LanguageServices.Razor", "src\Microsoft.VisualStudio.Mac.LanguageServices.Razor\Microsoft.VisualStudio.Mac.LanguageServices.Razor.csproj", "{95B18DEE-8B45-4CF0-B9F8-CCBAF3B5251A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{4595A6F1-81C5-4A0A-A3DC-81F108523AEC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Performance", "benchmarks\Microsoft.AspNetCore.Razor.Performance\Microsoft.AspNetCore.Razor.Performance.csproj", "{BE1CE01F-5342-4075-BD46-DB4D857BC1FE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Razor.Workspaces.Test.Common", "test\Microsoft.CodeAnalysis.Razor.Workspaces.Test.Common\Microsoft.CodeAnalysis.Razor.Workspaces.Test.Common.csproj", "{E41C50E7-79D0-442C-832A-E6B1A2EF4B67}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test", "test\Microsoft.AspNetCore.Razor.Test\Microsoft.AspNetCore.Razor.Test.csproj", "{93F116E1-9421-4D55-BF3E-F8DDF8F2172C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -217,14 +223,6 @@ Global
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.Release|Any CPU.Build.0 = Release|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{078AEF36-F319-4CE2-BAA2-5B58A6536B46}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.Release|Any CPU.Build.0 = Release|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
@ -305,6 +303,30 @@ Global
{95B18DEE-8B45-4CF0-B9F8-CCBAF3B5251A}.Release|Any CPU.Build.0 = Release|Any CPU
{95B18DEE-8B45-4CF0-B9F8-CCBAF3B5251A}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{95B18DEE-8B45-4CF0-B9F8-CCBAF3B5251A}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{BE1CE01F-5342-4075-BD46-DB4D857BC1FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE1CE01F-5342-4075-BD46-DB4D857BC1FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE1CE01F-5342-4075-BD46-DB4D857BC1FE}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{BE1CE01F-5342-4075-BD46-DB4D857BC1FE}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{BE1CE01F-5342-4075-BD46-DB4D857BC1FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE1CE01F-5342-4075-BD46-DB4D857BC1FE}.Release|Any CPU.Build.0 = Release|Any CPU
{BE1CE01F-5342-4075-BD46-DB4D857BC1FE}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{BE1CE01F-5342-4075-BD46-DB4D857BC1FE}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{E41C50E7-79D0-442C-832A-E6B1A2EF4B67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E41C50E7-79D0-442C-832A-E6B1A2EF4B67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E41C50E7-79D0-442C-832A-E6B1A2EF4B67}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{E41C50E7-79D0-442C-832A-E6B1A2EF4B67}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{E41C50E7-79D0-442C-832A-E6B1A2EF4B67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E41C50E7-79D0-442C-832A-E6B1A2EF4B67}.Release|Any CPU.Build.0 = Release|Any CPU
{E41C50E7-79D0-442C-832A-E6B1A2EF4B67}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{E41C50E7-79D0-442C-832A-E6B1A2EF4B67}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{93F116E1-9421-4D55-BF3E-F8DDF8F2172C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93F116E1-9421-4D55-BF3E-F8DDF8F2172C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93F116E1-9421-4D55-BF3E-F8DDF8F2172C}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{93F116E1-9421-4D55-BF3E-F8DDF8F2172C}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{93F116E1-9421-4D55-BF3E-F8DDF8F2172C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93F116E1-9421-4D55-BF3E-F8DDF8F2172C}.Release|Any CPU.Build.0 = Release|Any CPU
{93F116E1-9421-4D55-BF3E-F8DDF8F2172C}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{93F116E1-9421-4D55-BF3E-F8DDF8F2172C}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -327,7 +349,6 @@ Global
{995F2FEB-65FA-4399-B1C0-16E0B3FBDB15} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{7CFD5646-A757-4498-9E01-9C8528ED60AE} = {92463391-81BE-462B-AC3C-78C6C760741F}
{078AEF36-F319-4CE2-BAA2-5B58A6536B46} = {92463391-81BE-462B-AC3C-78C6C760741F}
{82C23CF8-95FF-40F7-BF50-3AD9EE21ED58} = {92463391-81BE-462B-AC3C-78C6C760741F}
{8F165A3F-A18C-4649-AA08-C0E1BA5F5C90} = {92463391-81BE-462B-AC3C-78C6C760741F}
{C61AAE12-5007-4205-A220-68F354A7F235} = {92463391-81BE-462B-AC3C-78C6C760741F}
{F1538809-7347-45D2-A7AC-C1D89CF0BBD4} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
@ -338,6 +359,9 @@ Global
{FC684D4F-D23C-407C-9C68-E10EF3B38560} = {92463391-81BE-462B-AC3C-78C6C760741F}
{FAF9986F-E086-4513-9D52-F7BF5FFCF31D} = {C0CC1E1F-1559-44DE-93A8-63259CEA2AAB}
{95B18DEE-8B45-4CF0-B9F8-CCBAF3B5251A} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{BE1CE01F-5342-4075-BD46-DB4D857BC1FE} = {4595A6F1-81C5-4A0A-A3DC-81F108523AEC}
{E41C50E7-79D0-442C-832A-E6B1A2EF4B67} = {92463391-81BE-462B-AC3C-78C6C760741F}
{93F116E1-9421-4D55-BF3E-F8DDF8F2172C} = {92463391-81BE-462B-AC3C-78C6C760741F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0035341D-175A-4D05-95E6-F1C2785A1E26}

View File

@ -0,0 +1 @@
[assembly: BenchmarkDotNet.Attributes.AspNetCoreBenchmark]

View File

@ -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.Collections.Generic;
using System.IO;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
@ -10,7 +9,6 @@ using Microsoft.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Razor.Performance
{
[Config(typeof(CoreConfig))]
public class CodeGenerationBenchmark
{
public CodeGenerationBenchmark()
@ -22,33 +20,22 @@ namespace Microsoft.AspNetCore.Razor.Performance
}
var root = current;
var fileSystem = RazorProjectFileSystem.Create(root.FullName);
ProjectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem, b => RazorExtensions.Register(b)); ;
var engine = RazorEngine.Create(b => { RazorExtensions.Register(b); });
var project = RazorProject.Create(root.FullName);
DesignTimeTemplateEngine = new MvcRazorTemplateEngine(RazorEngine.CreateDesignTime(b => { RazorExtensions.Register(b); }), project);
RuntimeTemplateEngine = new MvcRazorTemplateEngine(RazorEngine.Create(b => { RazorExtensions.Register(b); }), project);
var codeDocument = RuntimeTemplateEngine.CreateCodeDocument(Path.Combine(root.FullName, "MSN.cshtml"));
Imports = codeDocument.Imports;
MSN = codeDocument.Source;
MSN = fileSystem.GetItem(Path.Combine(root.FullName, "MSN.cshtml"));
}
public RazorTemplateEngine DesignTimeTemplateEngine { get; }
public RazorProjectEngine ProjectEngine { get; }
public RazorTemplateEngine RuntimeTemplateEngine { get; }
public IReadOnlyList<RazorSourceDocument> Imports { get; }
public RazorSourceDocument MSN { get; }
public RazorProjectItem MSN { get; }
[Benchmark(Description = "Razor Design Time Code Generation of MSN.com")]
public void CodeGeneration_DesignTime_LargeStaticFile()
{
var codeDocument = RazorCodeDocument.Create(MSN, Imports);
var generated = DesignTimeTemplateEngine.GenerateCode(codeDocument);
var codeDocument = ProjectEngine.ProcessDesignTime(MSN);
var generated = codeDocument.GetCSharpDocument();
if (generated.Diagnostics.Count != 0)
{
@ -59,8 +46,8 @@ namespace Microsoft.AspNetCore.Razor.Performance
[Benchmark(Description = "Razor Runtime Code Generation of MSN.com")]
public void CodeGeneration_Runtime_LargeStaticFile()
{
var codeDocument = RazorCodeDocument.Create(MSN, Imports);
var generated = RuntimeTemplateEngine.GenerateCode(codeDocument);
var codeDocument = ProjectEngine.Process(MSN);
var generated = codeDocument.GetCSharpDocument();
if (generated.Diagnostics.Count != 0)
{

View File

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<OutputType>Exe</OutputType>
<ServerGarbageCollection>true</ServerGarbageCollection>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc.Razor.Extensions\Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\src\Microsoft.VisualStudio.LanguageServices.Razor\RazorDiagnosticJsonConverter.cs">
<Link>Shared\RazorDiagnosticJsonConverter.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft.VisualStudio.LanguageServices.Razor\TagHelperDescriptorJsonConverter.cs">
<Link>Shared\TagHelperDescriptorJsonConverter.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="$(BenchmarkDotNetPackageVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.BenchmarkRunner.Sources" Version="$(MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion)" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,54 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.VisualStudio.LanguageServices.Razor;
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Razor.Performance
{
public class TagHelperSerializationBenchmark
{
private readonly byte[] _tagHelperBuffer;
public TagHelperSerializationBenchmark()
{
var current = new DirectoryInfo(AppContext.BaseDirectory);
while (current != null && !File.Exists(Path.Combine(current.FullName, "taghelpers.json")))
{
current = current.Parent;
}
var tagHelperFilePath = Path.Combine(current.FullName, "taghelpers.json");
_tagHelperBuffer = File.ReadAllBytes(tagHelperFilePath);
}
[Benchmark(Description = "Razor TagHelper Serialization")]
public void TagHelper_Serialization_RoundTrip()
{
var serializer = new JsonSerializer();
serializer.Converters.Add(new RazorDiagnosticJsonConverter());
serializer.Converters.Add(new TagHelperDescriptorJsonConverter());
// Deserialize from json file.
IReadOnlyList<TagHelperDescriptor> tagHelpers;
using (var stream = new MemoryStream(_tagHelperBuffer))
using (var reader = new JsonTextReader(new StreamReader(stream)))
{
tagHelpers = serializer.Deserialize<IReadOnlyList<TagHelperDescriptor>>(reader);
}
// Serialize back to json.
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream, Encoding.UTF8, bufferSize: 4096))
{
serializer.Serialize(writer, tagHelpers);
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -8,6 +8,7 @@
<VSIXOutputPath>$(BuildDir)$(VSIXName).vsix</VSIXOutputPath>
<VSIXManifestOutputPath>$(BuildDir)$(VSIXName).json</VSIXManifestOutputPath>
<VSIXProject>$(RepositoryRoot)tooling\$(VSIXName)\$(VSIXName).csproj</VSIXProject>
<VSIXSymbolsOutputPath>$(BuildDir)$(VSIXName).pdb</VSIXSymbolsOutputPath>
<VSIXArtifactCategory>shipoob</VSIXArtifactCategory>
</PropertyGroup>
@ -27,6 +28,13 @@
<PackageId>$(VSIXName)</PackageId>
</ArtifactInfo>
<ArtifactInfo Include="$(VSIXSymbolsOutputPath)">
<ArtifactType>SymbolsFile</ArtifactType>
<Category>$(VSIXArtifactCategory)</Category>
<Dependencies>$(VSIXName).vsix</Dependencies>
<DebugType>full</DebugType>
</ArtifactInfo>
<ArtifactInfo Include="$(VSIXManifestOutputPath)">
<ArtifactType>VsixPackageManifestFile</ArtifactType>
<Category>$(VSIXArtifactCategory)</Category>
@ -36,6 +44,7 @@
<FilesToSign Include="$(VSIXOutputPath)" Certificate="Vsix" />
<FilesToExcludeFromSigning Include="$(VSIXManifestOutputPath)" />
<FilesToExcludeFromSigning Include="$(VSIXSymbolsOutputPath)" />
</ItemGroup>
</Target>
@ -93,6 +102,7 @@
/flp:LogFile=$(VSIXLogFilePath);
/p:DeployExtension=false;
/p:TargetVSIXContainer=$(VSIXOutputPath);
/p:SymbolsPublishDir=$(BuildDir);
/p:Configuration=$(Configuration);" />
</ItemGroup>

View File

@ -1,16 +1,17 @@
<Project>
<Project>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<PropertyGroup Label="Package Versions">
<BenchmarkDotNetPackageVersion>0.10.11</BenchmarkDotNetPackageVersion>
<InternalAspNetCoreSdkPackageVersion>2.1.0-preview1-15651</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftCodeAnalysisCommonPackageVersion>2.3.1</MicrosoftCodeAnalysisCommonPackageVersion>
<MicrosoftCodeAnalysisCSharpPackageVersion>2.3.1</MicrosoftCodeAnalysisCSharpPackageVersion>
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
<InternalAspNetCoreSdkPackageVersion>2.1.0-preview2-15704</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.1.0-preview2-30077</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>2.1.0-preview2-30106</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0-preview2-30106</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftCodeAnalysisCommonPackageVersion>2.4.0</MicrosoftCodeAnalysisCommonPackageVersion>
<MicrosoftCodeAnalysisCSharpPackageVersion>2.4.0</MicrosoftCodeAnalysisCSharpPackageVersion>
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>2.1.0-preview2-30106</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>2.1.0-preview2-30106</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
<MicrosoftExtensionsDependencyModelPackageVersion>2.1.0-preview2-25711-01</MicrosoftExtensionsDependencyModelPackageVersion>
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
<MicrosoftExtensionsWebEncodersPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsWebEncodersPackageVersion>
@ -33,7 +34,7 @@
<MicrosoftVisualStudioShellInteropPackageVersion>7.10.6071</MicrosoftVisualStudioShellInteropPackageVersion>
<MonoAddinsPackageVersion>1.3.7</MonoAddinsPackageVersion>
<MoqPackageVersion>4.7.49</MoqPackageVersion>
<NETStandard20PackageVersion>2.0.0</NETStandard20PackageVersion>
<NETStandardLibrary20PackageVersion>2.0.1</NETStandardLibrary20PackageVersion>
<NewtonsoftJsonPackageVersion>10.0.1</NewtonsoftJsonPackageVersion>
<StreamJsonRpcPackageVersion>1.1.92</StreamJsonRpcPackageVersion>
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.5.0-preview1-26016-05</SystemDiagnosticsDiagnosticSourcePackageVersion>
@ -52,5 +53,6 @@
<XunitPackageVersion>2.3.1</XunitPackageVersion>
<XunitRunnerVisualStudioPackageVersion>2.3.1</XunitRunnerVisualStudioPackageVersion>
</PropertyGroup>
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
</Project>

View File

@ -1,12 +1,16 @@
<Project>
<Import Project="dependencies.props" />
<PropertyGroup>
<EnableBenchmarkValidation>true</EnableBenchmarkValidation>
</PropertyGroup>
<ItemGroup>
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.VisualStudio.LanguageServices.Razor.Test\Microsoft.VisualStudio.LanguageServices.Razor.Test.csproj" Condition="'$(OS)'!='Windows_NT'" />
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.AspNetCore.Razor.Test.Common\Microsoft.AspNetCore.Razor.Test.Common.csproj" />
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.VisualStudio.Editor.Razor.Test\Microsoft.VisualStudio.Editor.Razor.Test.csproj" Condition="'$(OS)'!='Windows_NT'" />
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.CodeAnalysis.Razor.Workspaces.Test.Common\Microsoft.CodeAnalysis.Razor.Workspaces.Test.Common.csproj" />
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.VisualStudio.Editor.Razor.Test.Common\Microsoft.VisualStudio.Editor.Razor.Test.Common.csproj" />
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.AspNetCore.Razor.Performance\Microsoft.AspNetCore.Razor.Performance.csproj" />
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.AspNetCore.Razor.Test.MvcShim\Microsoft.AspNetCore.Razor.Test.MvcShim.csproj" />
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X\Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X.csproj" />
<ExcludeSolutions Include="$(RepositoryRoot)Razor.Slim.sln" />

View File

@ -1,7 +1,2 @@
<<<<<<< HEAD
version:2.1.0-preview2-15696
commithash:85ae1301d1a2ff19aab6837cc657699ccca719b5
=======
version:2.1.0-preview2-15704
commithash:21fdd9f5254226f407a2b4b3ef963693c2fd7998
>>>>>>> Update KoreBuild

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Html;
using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Razor.TagHelpers.Testing
{
@ -35,11 +34,7 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers.Testing
public int GetHashCode(TagHelperAttribute attribute)
{
var hashCodeCombiner = HashCodeCombiner.Start();
hashCodeCombiner.Add(attribute.GetHashCode());
hashCodeCombiner.Add(attribute.Name, StringComparer.Ordinal);
return hashCodeCombiner.CombinedHash;
return attribute.GetHashCode();
}
private string GetString(object value)

View File

@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)'=='.NETFramework' AND '$(OutputType)'=='library'">
<PackageReference Include="NETStandard.Library" Version="$(NETStandard20PackageVersion)" />
<PackageReference Include="NETStandard.Library" Version="$(NETStandardLibrary20PackageVersion)" />
</ItemGroup>
</Project>

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Globalization;
using System.Text;
@ -8,6 +9,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
{
internal static class CSharpIdentifier
{
private const string CshtmlExtension = ".cshtml";
public static string GetClassNameFromPath(string path)
{
if (string.IsNullOrEmpty(path))
@ -15,6 +18,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
return path;
}
if (path.EndsWith(CshtmlExtension, StringComparison.OrdinalIgnoreCase))
{
path = path.Substring(0, path.Length - CshtmlExtension.Length);
}
return SanitizeClassName(path);
}

View File

@ -24,8 +24,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
builder.Description = Resources.InjectDirective_Description;
});
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
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());
@ -99,5 +104,20 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
}
}
}
#region Obsolete
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
}
}

View File

@ -13,10 +13,6 @@
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.HashCodeCombiner.Sources" PrivateAssets="All" Version="$(MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../Microsoft.AspNetCore.Razor.Language/Microsoft.AspNetCore.Razor.Language.csproj" />
<ProjectReference Include="../Microsoft.CodeAnalysis.Razor/Microsoft.CodeAnalysis.Razor.csproj" />

View File

@ -21,10 +21,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
builder.Description = Resources.ModelDirective_Description;
});
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new Pass(builder.DesignTime));
builder.Features.Add(new Pass());
return builder;
}
@ -59,13 +64,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass
{
private readonly bool _designTime;
public Pass(bool designTime)
{
_designTime = designTime;
}
// Runs after the @inherits directive
public override int Order => 5;
@ -74,7 +72,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
var visitor = new Visitor();
var modelType = GetModelType(documentNode, visitor);
if (_designTime)
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.
@ -128,5 +126,19 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
}
}
}
#region Obsolete
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
}
}

View File

@ -0,0 +1,89 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
{
internal class MvcImportProjectFeature : RazorProjectEngineFeatureBase, IImportProjectFeature
{
private const string ImportsFileName = "_ViewImports.cshtml";
public IReadOnlyList<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
";
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);
}
}
}

View File

@ -26,13 +26,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
Options.DefaultImports = GetDefaultImports();
}
/// <inheritsdoc />
public override RazorCodeDocument CreateCodeDocument(RazorProjectItem projectItem)
{
var codeDocument = base.CreateCodeDocument(projectItem);
codeDocument.SetRelativePath(projectItem.FilePath);
return codeDocument;
return base.CreateCodeDocument(projectItem);
}
// Internal for testing.

View File

@ -20,12 +20,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
ClassDeclarationIntermediateNode @class,
MethodDeclarationIntermediateNode method)
{
var filePath = codeDocument.GetRelativePath() ?? codeDocument.Source.FilePath;
base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method);
@namespace.Content = "AspNetCore";
var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath;
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
@class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>";
@class.Modifiers.Clear();

View File

@ -1,34 +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 Microsoft.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
{
internal static class RazorCodeDocumentExtensions
{
private const string RelativePathKey = "relative-path";
public static string GetRelativePath(this RazorCodeDocument document)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
return document.Items[RelativePathKey] as string;
}
public static void SetRelativePath(this RazorCodeDocument document, string relativePath)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
document.Items[RelativePathKey] = relativePath;
}
}
}

View File

@ -9,8 +9,54 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
{
public static class RazorExtensions
{
public static void Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
InjectDirective.Register(builder);
ModelDirective.Register(builder);
FunctionsDirective.Register(builder);
InheritsDirective.Register(builder);
// Register section directive with the 1.x compatible target extension.
builder.AddDirective(SectionDirective.Directive);
builder.Features.Add(new SectionDirectivePass());
builder.AddTargetExtension(new LegacySectionTargetExtension());
builder.AddTargetExtension(new TemplateTargetExtension()
{
TemplateTypeName = "global::Microsoft.AspNetCore.Mvc.Razor.HelperResult",
});
builder.Features.Add(new ModelExpressionPass());
builder.Features.Add(new MvcViewDocumentClassifierPass());
builder.SetImportFeature(new MvcImportProjectFeature());
}
public static void RegisterViewComponentTagHelpers(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Features.Add(new ViewComponentTagHelperPass());
builder.AddTargetExtension(new ViewComponentTagHelperTargetExtension());
}
#region Obsolete
public static void Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
EnsureDesignTime(builder);
InjectDirective.Register(builder);
@ -35,6 +81,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
public static void RegisterViewComponentTagHelpers(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
EnsureDesignTime(builder);
builder.Features.Add(new ViewComponentTagHelperPass());
@ -50,5 +101,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
throw new NotSupportedException(Resources.RuntimeCodeGenerationNotSupported);
}
#endregion
}
}

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
{
private const string DiagnosticPrefix = "RZ";
public static readonly RazorDiagnosticDescriptor ViewComponent_CannotFindMethod =
internal static readonly RazorDiagnosticDescriptor ViewComponent_CannotFindMethod =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3900",
() => ViewComponentResources.ViewComponent_CannotFindMethod,
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
return diagnostic;
}
public static readonly RazorDiagnosticDescriptor ViewComponent_AmbiguousMethods =
internal static readonly RazorDiagnosticDescriptor ViewComponent_AmbiguousMethods =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3901",
() => ViewComponentResources.ViewComponent_AmbiguousMethods,
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
return diagnostic;
}
public static readonly RazorDiagnosticDescriptor ViewComponent_AsyncMethod_ShouldReturnTask =
internal static readonly RazorDiagnosticDescriptor ViewComponent_AsyncMethod_ShouldReturnTask =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3902",
() => ViewComponentResources.ViewComponent_AsyncMethod_ShouldReturnTask,
@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
return diagnostic;
}
public static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_ShouldReturnValue =
internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_ShouldReturnValue =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3903",
() => ViewComponentResources.ViewComponent_SyncMethod_ShouldReturnValue,
@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
return diagnostic;
}
public static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_CannotReturnTask =
internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_CannotReturnTask =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3904",
() => ViewComponentResources.ViewComponent_SyncMethod_CannotReturnTask,

View File

@ -14,6 +14,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
if (documentNode.Options.DesignTime)
{
return;
}
var @namespace = documentNode.FindPrimaryNamespace();
if (@namespace == null || string.IsNullOrEmpty(@namespace.Content))
{
@ -29,8 +34,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
}
var generatedTypeName = $"{@namespace.Content}.{@class.ClassName}";
var path = codeDocument.GetRelativePath();
var escapedPath = EscapeAsVerbatimLiteral(path);
// 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)
@ -40,7 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
else if (documentNode.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind &&
PageDirective.TryGetPageDirective(documentNode, out var pageDirective))
{
var escapedRoutePrefix = EscapeAsVerbatimLiteral(pageDirective.RouteTemplate);
var escapedRoutePrefix = MakeVerbatimStringLiteral(pageDirective.RouteTemplate);
attribute = $"[assembly:{RazorPageAttribute}({escapedPath}, typeof({generatedTypeName}), {escapedRoutePrefix})]";
}
else
@ -61,7 +71,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
documentNode.Children.Insert(index, pageAttribute);
}
private static string EscapeAsVerbatimLiteral(string value)
private static string MakeVerbatimStringLiteral(string value)
{
if (value == null)
{
@ -71,5 +81,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
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;
}
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Globalization;
using System.Text;
@ -8,6 +9,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
internal static class CSharpIdentifier
{
private const string CshtmlExtension = ".cshtml";
public static string GetClassNameFromPath(string path)
{
if (string.IsNullOrEmpty(path))
@ -15,6 +18,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
return path;
}
if (path.EndsWith(CshtmlExtension, StringComparison.OrdinalIgnoreCase))
{
path = path.Substring(0, path.Length - CshtmlExtension.Length);
}
return SanitizeClassName(path);
}

View File

@ -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
{
internal class ExtensionInitializer : RazorExtensionInitializer
{
public override void Initialize(RazorProjectEngineBuilder builder)
{
RazorExtensions.Register(builder);
}
}
}

View File

@ -24,8 +24,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
builder.Description = Resources.InjectDirective_Description;
});
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
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());
@ -99,5 +104,20 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
}
}
}
#region Obsolete
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
}
}

View File

@ -15,6 +15,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
if (documentNode.Options.DesignTime)
{
return;
}
var walker = new Visitor();
walker.VisitDocument(documentNode);

View File

@ -13,7 +13,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.HashCodeCombiner.Sources" PrivateAssets="All" Version="$(MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion)" />
<Content Include="build\**\*.props" PackagePath="build\" />
<Content Include="build\**\*.targets" PackagePath="build\" />
</ItemGroup>
<ItemGroup>

View File

@ -21,10 +21,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
builder.Description = Resources.ModelDirective_Description;
});
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new Pass(builder.DesignTime));
builder.Features.Add(new Pass());
return builder;
}
@ -66,13 +71,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass
{
private readonly bool _designTime;
public Pass(bool designTime)
{
_designTime = designTime;
}
// Runs after the @inherits directive
public override int Order => 5;
@ -81,7 +79,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
var visitor = new Visitor();
var modelType = GetModelType(documentNode, visitor);
if (_designTime)
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.
@ -135,5 +133,19 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
}
}
}
#region Obsolete
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
}
}

View File

@ -0,0 +1,91 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
internal class MvcImportProjectFeature : RazorProjectEngineFeatureBase, IImportProjectFeature
{
private const string ImportsFileName = "_ViewImports.cshtml";
public IReadOnlyList<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);
}
}
}

View File

@ -26,13 +26,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
Options.DefaultImports = GetDefaultImports();
}
/// <inheritsdoc />
public override RazorCodeDocument CreateCodeDocument(RazorProjectItem projectItem)
{
var codeDocument = base.CreateCodeDocument(projectItem);
codeDocument.SetRelativePath(projectItem.FilePath);
return codeDocument;
return base.CreateCodeDocument(projectItem);
}
// Internal for testing.

View File

@ -20,12 +20,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
ClassDeclarationIntermediateNode @class,
MethodDeclarationIntermediateNode method)
{
var filePath = codeDocument.GetRelativePath() ?? codeDocument.Source.FilePath;
base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method);
@namespace.Content = "AspNetCore";
var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath;
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
@class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>";
@class.Modifiers.Clear();

View File

@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
builder.Description = Resources.NamespaceDirective_Description;
});
public static void Register(IRazorEngineBuilder builder)
public static void Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
@ -66,22 +66,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
return;
}
if (TryComputeNamespace(codeDocument.Source.FilePath, directive, out var computedNamespace))
{
// Beautify the class name since we're using a hierarchy for namespaces.
var @class = visitor.FirstClass;
var prefix = CSharpIdentifier.SanitizeClassName(Path.GetFileNameWithoutExtension(codeDocument.Source.FilePath));
if (@class != null && documentNode.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind)
{
@class.ClassName = prefix + "_Page";
}
else if (@class != null && documentNode.DocumentKind == MvcViewDocumentClassifierPass.MvcViewDocumentKind)
{
@class.ClassName = prefix + "_View";
}
}
@namespace.Content = computedNamespace;
@namespace.Content = GetNamespace(codeDocument.Source.FilePath, directive);
}
}
@ -92,7 +77,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
//
// 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 bool TryComputeNamespace(string source, DirectiveIntermediateNode directive, out string @namespace)
internal static string GetNamespace(string source, DirectiveIntermediateNode directive)
{
var directiveSource = NormalizeDirectory(directive.Source?.FilePath);
@ -100,15 +85,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
if (string.IsNullOrEmpty(baseNamespace))
{
// The namespace directive was incomplete.
@namespace = string.Empty;
return false;
return string.Empty;
}
if (string.IsNullOrEmpty(source) || directiveSource == null)
{
// No sources, can't compute a suffix.
@namespace = baseNamespace;
return false;
return baseNamespace;
}
// We're specifically using OrdinalIgnoreCase here because Razor treats all paths as case-insensitive.
@ -116,8 +99,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
source.Length <= directiveSource.Length)
{
// The imports are not from the directory hierarchy, can't compute a suffix.
@namespace = baseNamespace;
return false;
return baseNamespace;
}
// OK so that this point we know that the 'imports' file containing this directive is in the directory
@ -136,8 +118,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
builder.Append(CSharpIdentifier.SanitizeClassName(segments[i]));
}
@namespace = builder.ToString();
return true;
return builder.ToString();
}
// We want to normalize the path of the file containing the '@namespace' directive to just the containing
@ -205,5 +186,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
base.VisitDirective(node);
}
}
#region Obsolete
public static void Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException();
}
builder.AddDirective(Directive);
builder.Features.Add(new Pass());
}
#endregion
}
}

View File

@ -32,8 +32,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
public IntermediateNode DirectiveNode { get; }
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
return builder;
}
@ -98,5 +103,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
}
}
}
#region Obsolete
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
return builder;
}
#endregion
}
}

View File

@ -2,5 +2,11 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
using Microsoft.AspNetCore.Razor.Language;
[assembly: ProvideRazorExtensionInitializer("MVC-2.0", typeof(ExtensionInitializer))]
[assembly: ProvideRazorExtensionInitializer("MVC-2.1", typeof(ExtensionInitializer))]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

View File

@ -1,34 +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 Microsoft.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
internal static class RazorCodeDocumentExtensions
{
private const string RelativePathKey = "relative-path";
public static string GetRelativePath(this RazorCodeDocument document)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
return document.Items[RelativePathKey] as string;
}
public static void SetRelativePath(this RazorCodeDocument document, string relativePath)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
document.Items[RelativePathKey] = relativePath;
}
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
@ -8,8 +9,49 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
public static class RazorExtensions
{
public static void Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
InjectDirective.Register(builder);
ModelDirective.Register(builder);
NamespaceDirective.Register(builder);
PageDirective.Register(builder);
FunctionsDirective.Register(builder);
InheritsDirective.Register(builder);
SectionDirective.Register(builder);
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());
}
#region Obsolete
public static void Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
InjectDirective.Register(builder);
ModelDirective.Register(builder);
NamespaceDirective.Register(builder);
@ -37,5 +79,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
builder.Features.Add(new InstrumentationPass());
}
}
#endregion
}
}

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
private const string DiagnosticPrefix = "RZ";
public static readonly RazorDiagnosticDescriptor ViewComponent_CannotFindMethod =
internal static readonly RazorDiagnosticDescriptor ViewComponent_CannotFindMethod =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3900",
() => ViewComponentResources.ViewComponent_CannotFindMethod,
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
return diagnostic;
}
public static readonly RazorDiagnosticDescriptor ViewComponent_AmbiguousMethods =
internal static readonly RazorDiagnosticDescriptor ViewComponent_AmbiguousMethods =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3901",
() => ViewComponentResources.ViewComponent_AmbiguousMethods,
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
return diagnostic;
}
public static readonly RazorDiagnosticDescriptor ViewComponent_AsyncMethod_ShouldReturnTask =
internal static readonly RazorDiagnosticDescriptor ViewComponent_AsyncMethod_ShouldReturnTask =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3902",
() => ViewComponentResources.ViewComponent_AsyncMethod_ShouldReturnTask,
@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
return diagnostic;
}
public static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_ShouldReturnValue =
internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_ShouldReturnValue =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3903",
() => ViewComponentResources.ViewComponent_SyncMethod_ShouldReturnValue,
@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
return diagnostic;
}
public static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_CannotReturnTask =
internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_CannotReturnTask =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3904",
() => ViewComponentResources.ViewComponent_SyncMethod_CannotReturnTask,
@ -100,7 +100,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
return diagnostic;
}
public static readonly RazorDiagnosticDescriptor PageDirective_CannotBeImported =
internal static readonly RazorDiagnosticDescriptor PageDirective_CannotBeImported =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3905",
() => Resources.PageDirectiveCannotBeImported,

View File

@ -24,13 +24,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
ClassDeclarationIntermediateNode @class,
MethodDeclarationIntermediateNode method)
{
var filePath = codeDocument.GetRelativePath() ?? codeDocument.Source.FilePath;
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;
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
@class.Modifiers.Clear();

View File

@ -0,0 +1,35 @@
<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>
<!-- 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>

View File

@ -0,0 +1,9 @@
<Project>
<PropertyGroup>
<!--
MVC will generally want to add support for runtime compilation, but only for applications.
-->
<GenerateRazorAssemblyInfo Condition="'$(GenerateRazorAssemblyInfo)'=='' and '$(OutputType)'=='Exe'">true</GenerateRazorAssemblyInfo>
</PropertyGroup>
</Project>

View File

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language

View File

@ -0,0 +1,31 @@
// Copyright(c) .NET Foundation.All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class AssemblyExtension : RazorExtension
{
public AssemblyExtension(string extensionName, Assembly assembly)
{
if (extensionName == null)
{
throw new ArgumentNullException(nameof(extensionName));
}
if (assembly == null)
{
throw new ArgumentNullException(nameof(assembly));
}
ExtensionName = extensionName;
Assembly = assembly;
}
public override string ExtensionName { get; }
public Assembly Assembly { get; }
}
}

View File

@ -0,0 +1,28 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
namespace Microsoft.AspNetCore.Razor.Language
{
internal static class Checksum
{
public static string BytesToString(byte[] bytes)
{
if (bytes == null)
{
throw new ArgumentNullException(nameof(bytes));
}
var result = new StringBuilder(bytes.Length);
for (var i = 0; i < bytes.Length; i++)
{
// The x2 format means lowercase hex, where each byte is a 2-character string.
result.Append(bytes[i].ToString("x2"));
}
return result.ToString();
}
}
}

View File

@ -3,6 +3,7 @@
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
@ -67,28 +68,52 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
if (!Context.Options.SuppressChecksum)
{
// See http://msdn.microsoft.com/en-us/library/system.codedom.codechecksumpragma.checksumalgorithmid.aspx
const string Sha1AlgorithmId = "{ff1816ec-aa5e-4d10-87f7-6f4963833460}";
// And https://github.com/dotnet/roslyn/blob/614299ff83da9959fa07131c6d0ffbc58873b6ae/src/Compilers/Core/Portable/PEWriter/DebugSourceDocument.cs#L67
//
// We only support algorithms that the debugger understands, which is currently SHA1 and SHA256.
string algorithmId;
var algorithm = Context.SourceDocument.GetChecksumAlgorithm();
if (string.Equals(algorithm, HashAlgorithmName.SHA256.Name, StringComparison.Ordinal))
{
algorithmId = "{8829d00f-11b8-4213-878b-770e8597ac16}";
}
else if (string.Equals(algorithm, HashAlgorithmName.SHA1.Name, StringComparison.Ordinal) ||
// In 2.0, we didn't actually expose the name of the algorithm, so it's possible we could get null here.
// If that's the case, we just assume SHA1 since that's the only thing we supported in 2.0.
algorithm == null)
{
algorithmId = "{ff1816ec-aa5e-4d10-87f7-6f4963833460}";
}
else
{
var supportedAlgorithms = string.Join(" ", new string[]
{
HashAlgorithmName.SHA1.Name,
HashAlgorithmName.SHA256.Name
});
var message = Resources.FormatUnsupportedChecksumAlgorithm(
algorithm,
supportedAlgorithms,
nameof(RazorCodeGenerationOptions) + "." + nameof(RazorCodeGenerationOptions.SuppressChecksum),
bool.TrueString);
throw new InvalidOperationException(message);
}
var sourceDocument = Context.SourceDocument;
var checksum = sourceDocument.GetChecksum();
var fileHashBuilder = new StringBuilder(checksum.Length * 2);
foreach (var value in checksum)
{
fileHashBuilder.Append(value.ToString("x2"));
}
var bytes = fileHashBuilder.ToString();
if (!string.IsNullOrEmpty(bytes))
var checksum = Checksum.BytesToString(sourceDocument.GetChecksum());
if (!string.IsNullOrEmpty(checksum))
{
Context.CodeWriter
.Write("#pragma checksum \"")
.Write(sourceDocument.FilePath)
.Write("\" \"")
.Write(Sha1AlgorithmId)
.Write(algorithmId)
.Write("\" \"")
.Write(bytes)
.Write(checksum)
.WriteLine("\"");
}
}

View File

@ -45,11 +45,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{
var directiveStart = block.Children.First(child => !child.IsBlock && ((Span)child).Kind == SpanKindInternal.Transition).Start;
var errorLength = /* @ */ 1 + SectionDirective.Directive.Directive.Length;
var error = RazorDiagnostic.Create(
new RazorError(
LegacyResources.FormatParseError_Sections_Cannot_Be_Nested(LegacyResources.SectionExample_CS),
directiveStart,
errorLength));
var error = RazorDiagnosticFactory.CreateParsing_SectionsCannotBeNested(new SourceSpan(directiveStart, errorLength));
chunkGenerator.Diagnostics.Add(error);
}

View File

@ -0,0 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultImportProjectFeature : RazorProjectEngineFeatureBase, IImportProjectFeature
{
public IReadOnlyList<RazorProjectItem> GetImports(RazorProjectItem projectItem) => Array.Empty<RazorProjectItem>();
}
}

View File

@ -5,12 +5,18 @@ namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorCodeGenerationOptions : RazorCodeGenerationOptions
{
public DefaultRazorCodeGenerationOptions(bool indentWithTabs, int indentSize, bool designTime, bool suppressChecksum)
public DefaultRazorCodeGenerationOptions(
bool indentWithTabs,
int indentSize,
bool designTime,
bool suppressChecksum,
bool supressMetadataAttributes)
{
IndentWithTabs = indentWithTabs;
IndentSize = indentSize;
DesignTime = designTime;
SuppressChecksum = suppressChecksum;
SuppressMetadataAttributes = supressMetadataAttributes;
}
public override bool DesignTime { get; }

View File

@ -1,26 +1,45 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorCodeGenerationOptionsBuilder : RazorCodeGenerationOptionsBuilder
{
public DefaultRazorCodeGenerationOptionsBuilder(bool designTime)
private bool _designTime;
public DefaultRazorCodeGenerationOptionsBuilder(RazorConfiguration configuration)
{
DesignTime = designTime;
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
}
public override bool DesignTime { get; }
public DefaultRazorCodeGenerationOptionsBuilder(bool designTime)
{
_designTime = designTime;
}
public override RazorConfiguration Configuration { get; }
public override bool DesignTime => _designTime;
public override int IndentSize { get; set; } = 4;
public override bool IndentWithTabs { get; set; }
public override bool SuppressChecksum { get; set; }
public override RazorCodeGenerationOptions Build()
{
return new DefaultRazorCodeGenerationOptions(IndentWithTabs, IndentSize, DesignTime, SuppressChecksum);
return new DefaultRazorCodeGenerationOptions(IndentWithTabs, IndentSize, DesignTime, SuppressChecksum, SuppressMetadataAttributes);
}
public override void SetDesignTime(bool designTime)
{
_designTime = designTime;
}
}
}

View File

@ -0,0 +1,32 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorCodeGenerationOptionsFactoryProjectFeature : RazorProjectEngineFeatureBase, IRazorCodeGenerationOptionsFactoryProjectFeature
{
private IConfigureRazorCodeGenerationOptionsFeature[] _configureOptions;
protected override void OnInitialized()
{
_configureOptions = ProjectEngine.EngineFeatures.OfType<IConfigureRazorCodeGenerationOptionsFeature>().ToArray();
}
public RazorCodeGenerationOptions Create(Action<RazorCodeGenerationOptionsBuilder> configure)
{
var builder = new DefaultRazorCodeGenerationOptionsBuilder(ProjectEngine.Configuration);
configure?.Invoke(builder);
for (var i = 0; i < _configureOptions.Length; i++)
{
_configureOptions[i].Configure(builder);
}
var options = builder.Build();
return options;
}
}
}

View File

@ -5,7 +5,9 @@ using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
#pragma warning disable CS0618 // Type or member is obsolete
internal class DefaultRazorCodeGenerationOptionsFeature : RazorEngineFeatureBase, IRazorCodeGenerationOptionsFeature
#pragma warning restore CS0618 // Type or member is obsolete
{
private readonly bool _designTime;
private IConfigureRazorCodeGenerationOptionsFeature[] _configureOptions;
@ -22,15 +24,15 @@ namespace Microsoft.AspNetCore.Razor.Language
public RazorCodeGenerationOptions GetOptions()
{
var builder = new DefaultRazorCodeGenerationOptionsBuilder(_designTime);
return _designTime ? RazorCodeGenerationOptions.CreateDesignTime(ConfigureOptions) : RazorCodeGenerationOptions.Create(ConfigureOptions);
}
private void ConfigureOptions(RazorCodeGenerationOptionsBuilder builder)
{
for (var i = 0; i < _configureOptions.Length; i++)
{
_configureOptions[i].Configure(builder);
}
var options = builder.Build();
return options;
}
}
}

View File

@ -8,26 +8,29 @@ namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorDiagnostic : RazorDiagnostic
{
private readonly RazorDiagnosticDescriptor _descriptor;
private readonly object[] _args;
internal DefaultRazorDiagnostic(RazorDiagnosticDescriptor descriptor, SourceSpan span, object[] args)
{
_descriptor = descriptor;
Descriptor = descriptor;
Span = span;
_args = args;
Args = args;
}
public override string Id => _descriptor.Id;
public override string Id => Descriptor.Id;
public override RazorDiagnosticSeverity Severity => _descriptor.Severity;
public override RazorDiagnosticSeverity Severity => Descriptor.Severity;
public override SourceSpan Span { get; }
// Internal for testing
internal RazorDiagnosticDescriptor Descriptor { get; }
// Internal for testing
internal object[] Args { get; }
public override string GetMessage(IFormatProvider formatProvider)
{
var format = _descriptor.GetMessageFormat();
return string.Format(formatProvider, format, _args);
var format = Descriptor.GetMessageFormat();
return string.Format(formatProvider, format, Args);
}
public override bool Equals(RazorDiagnostic obj)
@ -38,7 +41,7 @@ namespace Microsoft.AspNetCore.Razor.Language
return false;
}
if (!_descriptor.Equals(other._descriptor))
if (!Descriptor.Equals(other.Descriptor))
{
return false;
}
@ -48,14 +51,14 @@ namespace Microsoft.AspNetCore.Razor.Language
return false;
}
if (_args.Length != other._args.Length)
if (Args.Length != other.Args.Length)
{
return false;
}
for (var i = 0; i < _args.Length; i++)
for (var i = 0; i < Args.Length; i++)
{
if (!_args[i].Equals(other._args[i]))
if (!Args[i].Equals(other.Args[i]))
{
return false;
}
@ -67,12 +70,12 @@ namespace Microsoft.AspNetCore.Razor.Language
public override int GetHashCode()
{
var hash = new HashCodeCombiner();
hash.Add(_descriptor.GetHashCode());
hash.Add(Descriptor.GetHashCode());
hash.Add(Span.GetHashCode());
for (var i = 0; i < _args.Length; i++)
for (var i = 0; i < Args.Length; i++)
{
hash.Add(_args[i]);
hash.Add(Args[i]);
}
return hash;

View File

@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language
{
#pragma warning disable CS0618 // Type or member is obsolete
internal class DefaultRazorIntermediateNodeLoweringPhase : RazorEnginePhaseBase, IRazorIntermediateNodeLoweringPhase
{
private IRazorCodeGenerationOptionsFeature _optionsFeature;
@ -31,7 +32,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
document.Options = _optionsFeature.GetOptions();
document.Options = codeDocument.GetCodeGenerationOptions() ?? _optionsFeature.GetOptions();
var namespaces = new Dictionary<string, SourceSpan?>(StringComparer.Ordinal);
@ -785,4 +786,5 @@ namespace Microsoft.AspNetCore.Razor.Language
private static bool IsMalformed(List<RazorDiagnostic> diagnostics)
=> diagnostics.Count > 0 && diagnostics.Any(diagnostic => diagnostic.Severity == RazorDiagnosticSeverity.Error);
}
#pragma warning restore CS0618 // Type or member is obsolete
}

View File

@ -9,23 +9,43 @@ namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorParserOptionsBuilder : RazorParserOptionsBuilder
{
public DefaultRazorParserOptionsBuilder(bool designTime, RazorLanguageVersion version)
private bool _designTime;
public DefaultRazorParserOptionsBuilder(RazorConfiguration configuration)
{
DesignTime = designTime;
Version = version;
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
Configuration = configuration;
LanguageVersion = configuration.LanguageVersion;
}
public override bool DesignTime { get; }
public DefaultRazorParserOptionsBuilder(bool designTime, RazorLanguageVersion version)
{
_designTime = designTime;
LanguageVersion = version;
}
public override RazorConfiguration Configuration { get; }
public override bool DesignTime => _designTime;
public override ICollection<DirectiveDescriptor> Directives { get; } = new List<DirectiveDescriptor>();
public override bool ParseLeadingDirectives { get; set; }
public override RazorLanguageVersion Version { get; }
public override RazorLanguageVersion LanguageVersion { get; }
public override RazorParserOptions Build()
{
return new DefaultRazorParserOptions(Directives.ToArray(), DesignTime, ParseLeadingDirectives, Version);
return new DefaultRazorParserOptions(Directives.ToArray(), DesignTime, ParseLeadingDirectives, LanguageVersion);
}
public override void SetDesignTime(bool designTime)
{
_designTime = designTime;
}
}
}

View File

@ -0,0 +1,32 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorParserOptionsFactoryProjectFeature : RazorProjectEngineFeatureBase, IRazorParserOptionsFactoryProjectFeature
{
private IConfigureRazorParserOptionsFeature[] _configureOptions;
protected override void OnInitialized()
{
_configureOptions = ProjectEngine.EngineFeatures.OfType<IConfigureRazorParserOptionsFeature>().ToArray();
}
public RazorParserOptions Create(Action<RazorParserOptionsBuilder> configure)
{
var builder = new DefaultRazorParserOptionsBuilder(ProjectEngine.Configuration);
configure?.Invoke(builder);
for (var i = 0; i < _configureOptions.Length; i++)
{
_configureOptions[i].Configure(builder);
}
var options = builder.Build();
return options;
}
}
}

View File

@ -5,7 +5,9 @@ using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
#pragma warning disable CS0618 // Type or member is obsolete
internal class DefaultRazorParserOptionsFeature : RazorEngineFeatureBase, IRazorParserOptionsFeature
#pragma warning restore CS0618 // Type or member is obsolete
{
private readonly bool _designTime;
private readonly RazorLanguageVersion _version;

View File

@ -3,6 +3,7 @@
namespace Microsoft.AspNetCore.Razor.Language
{
#pragma warning disable CS0618 // Type or member is obsolete
internal class DefaultRazorParsingPhase : RazorEnginePhaseBase, IRazorParsingPhase
{
private IRazorParserOptionsFeature _optionsFeature;
@ -14,7 +15,7 @@ namespace Microsoft.AspNetCore.Razor.Language
protected override void ExecuteCore(RazorCodeDocument codeDocument)
{
var options = _optionsFeature.GetOptions();
var options = codeDocument.GetParserOptions() ??_optionsFeature.GetOptions();
var syntaxTree = RazorSyntaxTree.Parse(codeDocument.Source, options);
codeDocument.SetSyntaxTree(syntaxTree);
@ -26,4 +27,5 @@ namespace Microsoft.AspNetCore.Razor.Language
codeDocument.SetImportSyntaxTrees(importSyntaxTrees);
}
}
#pragma warning restore CS0618 // Type or member is obsolete
}

View File

@ -0,0 +1,154 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorProjectEngine : RazorProjectEngine
{
public DefaultRazorProjectEngine(
RazorConfiguration configuration,
RazorEngine engine,
RazorProjectFileSystem fileSystem,
IReadOnlyList<IRazorProjectEngineFeature> projectFeatures)
{
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
if (engine == null)
{
throw new ArgumentNullException(nameof(engine));
}
if (fileSystem == null)
{
throw new ArgumentNullException(nameof(fileSystem));
}
if (projectFeatures == null)
{
throw new ArgumentNullException(nameof(projectFeatures));
}
Configuration = configuration;
Engine = engine;
FileSystem = fileSystem;
ProjectFeatures = projectFeatures;
for (var i = 0; i < projectFeatures.Count; i++)
{
projectFeatures[i].ProjectEngine = this;
}
}
public override RazorConfiguration Configuration { get; }
public override RazorProjectFileSystem FileSystem { get; }
public override RazorEngine Engine { get; }
public override IReadOnlyList<IRazorProjectEngineFeature> ProjectFeatures { get; }
protected override RazorCodeDocument CreateCodeDocumentCore(RazorProjectItem projectItem)
{
if (projectItem == null)
{
throw new ArgumentNullException(nameof(projectItem));
}
var sourceDocument = RazorSourceDocument.ReadFrom(projectItem);
var importFeature = GetRequiredFeature<IImportProjectFeature>();
var importItems = importFeature.GetImports(projectItem);
var importSourceDocuments = importItems.Select(ConvertToSourceDocument);
var parserOptions = GetRequiredFeature<IRazorParserOptionsFactoryProjectFeature>().Create(ConfigureParserOptions);
var codeGenerationOptions = GetRequiredFeature<IRazorCodeGenerationOptionsFactoryProjectFeature>().Create(ConfigureCodeGenerationOptions);
return RazorCodeDocument.Create(sourceDocument, importSourceDocuments, parserOptions, codeGenerationOptions);
}
protected override RazorCodeDocument CreateCodeDocumentDesignTimeCore(RazorProjectItem projectItem)
{
if (projectItem == null)
{
throw new ArgumentNullException(nameof(projectItem));
}
var sourceDocument = RazorSourceDocument.ReadFrom(projectItem);
var importFeature = GetRequiredFeature<IImportProjectFeature>();
var importItems = importFeature.GetImports(projectItem);
var importSourceDocuments = importItems.Select(ConvertToSourceDocument);
var parserOptions = GetRequiredFeature<IRazorParserOptionsFactoryProjectFeature>().Create(ConfigureDesignTimeParserOptions);
var codeGenerationOptions = GetRequiredFeature<IRazorCodeGenerationOptionsFactoryProjectFeature>().Create(ConfigureDesignTimeCodeGenerationOptions);
return RazorCodeDocument.Create(sourceDocument, importSourceDocuments, parserOptions, codeGenerationOptions);
}
protected override void ProcessCore(RazorCodeDocument codeDocument)
{
if (codeDocument == null)
{
throw new ArgumentNullException(nameof(codeDocument));
}
Engine.Process(codeDocument);
}
private TFeature GetRequiredFeature<TFeature>() where TFeature : IRazorProjectEngineFeature
{
var feature = ProjectFeatures.OfType<TFeature>().FirstOrDefault();
if (feature == null)
{
throw new InvalidOperationException(
Resources.FormatRazorProjectEngineMissingFeatureDependency(
typeof(RazorProjectEngine).FullName,
typeof(TFeature).FullName));
}
return feature;
}
private void ConfigureParserOptions(RazorParserOptionsBuilder builder)
{
}
private void ConfigureDesignTimeParserOptions(RazorParserOptionsBuilder builder)
{
builder.SetDesignTime(true);
}
private void ConfigureCodeGenerationOptions(RazorCodeGenerationOptionsBuilder builder)
{
}
private void ConfigureDesignTimeCodeGenerationOptions(RazorCodeGenerationOptionsBuilder builder)
{
builder.SetDesignTime(true);
builder.SuppressChecksum = true;
builder.SuppressMetadataAttributes = true;
}
// Internal for testing
internal static RazorSourceDocument ConvertToSourceDocument(RazorProjectItem importItem)
{
if (importItem.Exists)
{
// Normal import, has file paths, content etc.
return RazorSourceDocument.ReadFrom(importItem);
}
// Marker import, doesn't exist, used as an identifier for "there could be something here".
var sourceDocumentProperties = new RazorSourceDocumentProperties(importItem.FilePath, importItem.RelativePhysicalPath);
return RazorSourceDocument.Create(string.Empty, sourceDocumentProperties);
}
}
}

View File

@ -0,0 +1,56 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorProjectEngineBuilder : RazorProjectEngineBuilder
{
public DefaultRazorProjectEngineBuilder(RazorConfiguration configuration, RazorProjectFileSystem fileSystem)
{
if (fileSystem == null)
{
throw new ArgumentNullException(nameof(fileSystem));
}
Configuration = configuration;
FileSystem = fileSystem;
Features = new List<IRazorFeature>();
Phases = new List<IRazorEnginePhase>();
}
public override RazorConfiguration Configuration { get; }
public override RazorProjectFileSystem FileSystem { get; }
public override ICollection<IRazorFeature> Features { get; }
public override IList<IRazorEnginePhase> Phases { get; }
public override RazorProjectEngine Build()
{
var engine = RazorEngine.CreateEmpty(ConfigureRazorEngine);
var projectFeatures = Features.OfType<IRazorProjectEngineFeature>().ToArray();
var projectEngine = new DefaultRazorProjectEngine(Configuration, engine, FileSystem, projectFeatures);
return projectEngine;
}
private void ConfigureRazorEngine(IRazorEngineBuilder engineBuilder)
{
var engineFeatures = Features.OfType<IRazorEngineFeature>();
foreach (var engineFeature in engineFeatures)
{
engineBuilder.Features.Add(engineFeature);
}
for (var i = 0; i < Phases.Count; i++)
{
engineBuilder.Phases.Add(Phases[i]);
}
}
}
}

View File

@ -8,15 +8,15 @@ using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class FileSystemRazorProject : RazorProject
internal class DefaultRazorProjectFileSystem : RazorProjectFileSystem
{
public FileSystemRazorProject(string root)
public DefaultRazorProjectFileSystem(string root)
{
if (string.IsNullOrEmpty(root))
{
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(root));
}
Root = root.Replace('\\', '/').TrimEnd('/');
}
@ -36,16 +36,24 @@ namespace Microsoft.AspNetCore.Razor.Language
.EnumerateFiles("*.cshtml", SearchOption.AllDirectories)
.Select(file =>
{
var relativePath = file.FullName.Substring(absoluteBasePath.Length).Replace(Path.DirectorySeparatorChar, '/');
return new FileSystemRazorProjectItem(basePath, relativePath, file);
var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator
var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/');
return new DefaultRazorProjectItem(basePath, filePath, relativePhysicalPath, file);
});
}
public override RazorProjectItem GetItem(string path)
{
var absoluteBasePath = NormalizeAndEnsureValidPath("/");
var absolutePath = NormalizeAndEnsureValidPath(path);
return new FileSystemRazorProjectItem("/", path, new FileInfo(absolutePath));
var file = new FileInfo(absolutePath);
var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator
var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/');
return new DefaultRazorProjectItem("/", filePath, relativePhysicalPath, new FileInfo(absolutePath));
}
protected override string NormalizeAndEnsureValidPath(string path)

View File

@ -5,18 +5,20 @@ using System.IO;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class FileSystemRazorProjectItem : RazorProjectItem
internal class DefaultRazorProjectItem : RazorProjectItem
{
/// <summary>
/// Initializes a new instance of <see cref="FileSystemRazorProjectItem"/>.
/// Initializes a new instance of <see cref="DefaultRazorProjectItem"/>.
/// </summary>
/// <param name="basePath">The base path.</param>
/// <param name="path">The path.</param>
/// <param name="relativePhysicalPath">The physical path of the base path.</param>
/// <param name="filePath">The path.</param>
/// <param name="file">The <see cref="FileInfo"/>.</param>
public FileSystemRazorProjectItem(string basePath, string path, FileInfo file)
public DefaultRazorProjectItem(string basePath, string filePath, string relativePhysicalPath, FileInfo file)
{
BasePath = basePath;
FilePath = path;
FilePath = filePath;
RelativePhysicalPath = relativePhysicalPath;
File = file;
}
@ -30,6 +32,8 @@ namespace Microsoft.AspNetCore.Razor.Language
public override string PhysicalPath => File.FullName;
public override Stream Read() => File.OpenRead();
public override string RelativePhysicalPath { get; }
public override Stream Read() => new FileStream(PhysicalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
}
}

View File

@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Razor.Language
// We have an exact match for the start of a line.
Debug.Assert(_lineStarts[index] == position);
return new SourceLocation(_document.FilePath, position, index, characterIndex: 0);
return new SourceLocation(_document.GetFilePathForDisplay(), position, index, characterIndex: 0);
}
@ -59,12 +59,12 @@ namespace Microsoft.AspNetCore.Razor.Language
if (index == -1)
{
// There's no preceding line, so it's based on the start of the string
return new SourceLocation(_document.FilePath, position, 0, position);
return new SourceLocation(_document.GetFilePathForDisplay(), position, 0, position);
}
else
{
var characterIndex = position - _lineStarts[index];
return new SourceLocation(_document.FilePath, position, index, characterIndex);
return new SourceLocation(_document.GetFilePathForDisplay(), position, index, characterIndex);
}
}

View File

@ -58,9 +58,8 @@ namespace Microsoft.AspNetCore.Razor.Language
var root = syntaxTree.Root;
root = rewriter.Rewrite(root, errorSink);
// Temporary code while we're still using legacy diagnostics in the SyntaxTree.
var errorList = new List<RazorDiagnostic>();
errorList.AddRange(errorSink.Errors.Select(error => RazorDiagnostic.Create(error)));
errorList.AddRange(errorSink.Errors);
errorList.AddRange(descriptors.SelectMany(d => d.GetAllDiagnostics()));

View File

@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class EmptyProjectFileSystem : RazorProjectFileSystem
{
public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
{
NormalizeAndEnsureValidPath(basePath);
return Enumerable.Empty<RazorProjectItem>();
}
public override RazorProjectItem GetItem(string path)
{
NormalizeAndEnsureValidPath(path);
return new NotFoundProjectItem(string.Empty, path);
}
}
}

View File

@ -0,0 +1,41 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
// The default scheme for identifiers matches MVC's view engine paths:
// 1. Normalize backslash to forward-slash
// 2. Always include leading slash
// 3. Always include file name and extensions
internal class DefaultMetadataIdentifierFeature : RazorEngineFeatureBase, IMetadataIdentifierFeature
{
public string GetIdentifier(RazorCodeDocument codeDocument, RazorSourceDocument sourceDocument)
{
if (codeDocument == null)
{
throw new ArgumentNullException(nameof(codeDocument));
}
if (sourceDocument == null)
{
throw new ArgumentNullException(nameof(sourceDocument));
}
if (string.IsNullOrEmpty(sourceDocument.RelativePath))
{
return null;
}
var identifier = sourceDocument.RelativePath;
identifier = identifier.Replace("\\", "/");
if (!identifier.StartsWith("/"))
{
identifier = "/" + identifier;
}
return identifier;
}
}
}

View File

@ -16,8 +16,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
private static readonly string[] PrivateModifiers = new string[] { "private" };
public bool DesignTime { get; set; }
public string RunnerVariableName { get; set; } = "__tagHelperRunner";
public string StringValueBufferVariableName { get; set; } = "__tagHelperStringValueBuffer";
@ -82,7 +80,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
throw new InvalidOperationException(message);
}
if (DesignTime)
if (context.Options.DesignTime)
{
context.RenderChildren(node);
}
@ -136,7 +134,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
.Write(CreateTagHelperMethodName)
.WriteLine("<global::" + node.TypeName + ">();");
if (!DesignTime)
if (!context.Options.DesignTime)
{
context.CodeWriter.WriteInstanceMethodInvocation(
ExecutionContextVariableName,
@ -153,7 +151,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
throw new InvalidOperationException(message);
}
if (!DesignTime)
if (!context.Options.DesignTime)
{
context.CodeWriter
.Write("await ")
@ -200,7 +198,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
throw new InvalidOperationException(message);
}
if (DesignTime)
if (context.Options.DesignTime)
{
context.RenderChildren(node);
}
@ -284,7 +282,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
throw new InvalidOperationException(message);
}
if (!DesignTime)
if (!context.Options.DesignTime)
{
// Ensure that the property we're trying to set has initialized its dictionary bound properties.
if (node.IsIndexerNameMatch &&
@ -338,7 +336,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
// If we get there, this is the first time seeing this property so we need to evaluate the expression.
if (node.BoundAttribute.ExpectsStringValue(node.AttributeName))
{
if (DesignTime)
if (context.Options.DesignTime)
{
context.RenderChildren(node);
@ -370,7 +368,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
}
else
{
if (DesignTime)
if (context.Options.DesignTime)
{
var firstMappedChild = node.Children.FirstOrDefault(child => child.Source != null) as IntermediateNode;
var valueStart = firstMappedChild?.Source;
@ -456,7 +454,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
}
}
if (!DesignTime)
if (!context.Options.DesignTime)
{
// We need to inform the context of the attribute value.
context.CodeWriter
@ -474,7 +472,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
public void WriteTagHelperRuntime(CodeRenderingContext context, DefaultTagHelperRuntimeIntermediateNode node)
{
if (!DesignTime)
if (!context.Options.DesignTime)
{
context.CodeWriter.WriteLine("#line hidden");
@ -550,7 +548,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
}
}
private void RenderTagHelperAttributeInline(
// Internal for testing
internal void RenderTagHelperAttributeInline(
CodeRenderingContext context,
DefaultTagHelperPropertyIntermediateNode property,
IntermediateNode node,
@ -565,7 +564,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
}
else if (node is IntermediateToken token)
{
if (DesignTime && node.Source != null)
if (context.Options.DesignTime && node.Source != null)
{
context.AddSourceMappingFor(node);
}
@ -574,20 +573,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
}
else if (node is CSharpCodeIntermediateNode)
{
var error = new RazorError(
LegacyResources.TagHelpers_CodeBlocks_NotSupported_InAttributes,
SourceLocation.FromSpan(span),
span == null ? -1 : span.Value.Length);
context.Diagnostics.Add(RazorDiagnostic.Create(error));
var diagnostic = RazorDiagnosticFactory.CreateTagHelper_CodeBlocksNotSupportedInAttributes(span ?? SourceSpan.Undefined);
context.Diagnostics.Add(diagnostic);
}
else if (node is TemplateIntermediateNode)
{
var expectedTypeName = property.IsIndexerNameMatch ? property.BoundAttribute.IndexerTypeName : property.BoundAttribute.TypeName;
var error = new RazorError(
LegacyResources.FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(expectedTypeName),
SourceLocation.FromSpan(span),
span == null ? -1 : span.Value.Length);
context.Diagnostics.Add(RazorDiagnostic.Create(error));
var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(span ?? SourceSpan.Undefined, expectedTypeName);
context.Diagnostics.Add(diagnostic);
}
}

View File

@ -15,6 +15,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
// Only supports design time. This pass rewrites directives so they will have the right design time
// behavior and would break things if it ran for runtime.
if (!documentNode.Options.DesignTime)
{
return;
}
var walker = new DesignTimeHelperWalker();
walker.VisitDocument(documentNode);
}

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
@ -15,10 +16,28 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
builder.Description = Resources.FunctionsDirective_Description;
});
public static void Register(IRazorEngineBuilder builder)
public static void Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new FunctionsDirectivePass());
}
#region Obsolete
public static void Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new FunctionsDirectivePass());
}
#endregion
}
}

View File

@ -0,0 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal interface IMetadataAttributeTargetExtension : ICodeTargetExtension
{
void WriteRazorCompiledItemAttribute(CodeRenderingContext context, RazorCompiledItemAttributeIntermediateNode node);
void WriteRazorSourceChecksumAttribute(CodeRenderingContext context, RazorSourceChecksumAttributeIntermediateNode node);
}
}

View File

@ -0,0 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal interface IMetadataIdentifierFeature : IRazorEngineFeature
{
string GetIdentifier(RazorCodeDocument codeDocument, RazorSourceDocument sourceDocument);
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
@ -17,10 +18,28 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
builder.Description = Resources.InheritsDirective_Description;
});
public static void Register(IRazorEngineBuilder builder)
public static void Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new InheritsDirectivePass());
}
#region Obsolete
public static void Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new InheritsDirectivePass());
}
#endregion
}
}

View File

@ -0,0 +1,128 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
// Optimization pass is the best choice for this class. It's not an optimization, but it also doesn't add semantically
// meaningful information.
internal class MetadataAttributePass : IntermediateNodePassBase, IRazorOptimizationPass
{
private IMetadataIdentifierFeature _identifierFeature;
protected override void OnInitialized()
{
_identifierFeature = Engine.Features.OfType<IMetadataIdentifierFeature>().FirstOrDefault();
}
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
if (documentNode.Options == null || documentNode.Options.SuppressMetadataAttributes)
{
// Metadata attributes are turned off (or options not populated), nothing to do.
return;
}
// We need to be able to compute the data we need for the [RazorCompiledItem] attribute - that includes
// a full type name, and a document kind, and optionally an identifier.
//
// If we can't use [RazorCompiledItem] then we don't care about the rest of the attributes.
var @namespace = documentNode.FindPrimaryNamespace();
if (@namespace == null || string.IsNullOrEmpty(@namespace.Content))
{
// No namespace node or it's incomplete. Skip.
return;
}
var @class = documentNode.FindPrimaryClass();
if (@class == null || string.IsNullOrEmpty(@class.ClassName))
{
// No class node or it's incomplete. Skip.
return;
}
if (documentNode.DocumentKind == null)
{
// No document kind. Skip.
return;
}
var identifier = _identifierFeature?.GetIdentifier(codeDocument, codeDocument.Source);
if (identifier == null)
{
// No identifier. Skip
return;
}
// [RazorCompiledItem] is an [assembly: ... ] attribute, so it needs to be applied at the global scope.
documentNode.Children.Insert(0, new RazorCompiledItemAttributeIntermediateNode()
{
TypeName = @namespace.Content + "." + @class.ClassName,
Kind = documentNode.DocumentKind,
Identifier = identifier,
});
// Now we need to add a [RazorSourceChecksum] for the source and for each import
// these are class attributes, so we need to find the insertion point to put them
// right before the class.
var insert = (int?)null;
for (var j = 0; j < @namespace.Children.Count; j++)
{
if (object.ReferenceEquals(@namespace.Children[j], @class))
{
insert = j;
break;
}
}
if (insert == null)
{
// Can't find a place to put the attributes, just bail.
return;
}
// Checksum of the main source
var checksum = codeDocument.Source.GetChecksum();
var checksumAlgorithm = codeDocument.Source.GetChecksumAlgorithm();
if (checksum == null || checksum.Length == 0 || checksumAlgorithm == null || identifier == null)
{
// Don't generate anything unless we have all of the required information.
return;
}
@namespace.Children.Insert((int)insert++, new RazorSourceChecksumAttributeIntermediateNode()
{
Checksum = checksum,
ChecksumAlgorithm = checksumAlgorithm,
Identifier = identifier,
});
// Now process the checksums of the imports
Debug.Assert(_identifierFeature != null);
for (var i = 0; i < codeDocument.Imports.Count; i++)
{
var import = codeDocument.Imports[i];
checksum = import.GetChecksum();
checksumAlgorithm = import.GetChecksumAlgorithm();
identifier = _identifierFeature.GetIdentifier(codeDocument, import);
if (checksum == null || checksum.Length == 0 || checksumAlgorithm == null || identifier == null)
{
// It's ok to skip an import if we don't have all of the required information.
continue;
}
@namespace.Children.Insert((int)insert++, new RazorSourceChecksumAttributeIntermediateNode()
{
Checksum = checksum,
ChecksumAlgorithm = checksumAlgorithm,
Identifier = identifier,
});
}
}
}
}

View File

@ -0,0 +1,63 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal class MetadataAttributeTargetExtension : IMetadataAttributeTargetExtension
{
public string CompiledItemAttributeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute";
public string SourceChecksumAttributeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute";
public void WriteRazorCompiledItemAttribute(CodeRenderingContext context, RazorCompiledItemAttributeIntermediateNode node)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (node == null)
{
throw new ArgumentNullException(nameof(node));
}
// [assembly: global::...RazorCompiledItem(typeof({node.TypeName}), @"{node.Kind}", @"{node.Identifier}")]
context.CodeWriter.Write("[assembly: ");
context.CodeWriter.Write(CompiledItemAttributeName);
context.CodeWriter.Write("(typeof(");
context.CodeWriter.Write(node.TypeName);
context.CodeWriter.Write("), @\"");
context.CodeWriter.Write(node.Kind);
context.CodeWriter.Write("\", @\"");
context.CodeWriter.Write(node.Identifier);
context.CodeWriter.WriteLine("\")]");
}
public void WriteRazorSourceChecksumAttribute(CodeRenderingContext context, RazorSourceChecksumAttributeIntermediateNode node)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (node == null)
{
throw new ArgumentNullException(nameof(node));
}
// [global::...RazorSourceChecksum(@"{node.ChecksumAlgorithm}", @"{node.Checksum}", @"{node.Identifier}")]
context.CodeWriter.Write("[");
context.CodeWriter.Write(SourceChecksumAttributeName);
context.CodeWriter.Write("(@\"");
context.CodeWriter.Write(node.ChecksumAlgorithm);
context.CodeWriter.Write("\", @\"");
context.CodeWriter.Write(Checksum.BytesToString(node.Checksum));
context.CodeWriter.Write("\", @\"");
context.CodeWriter.Write(node.Identifier);
context.CodeWriter.WriteLine("\")]");
}
}
}

View File

@ -15,6 +15,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
// There's no value in executing this pass at design time, it just prevents some allocations.
if (documentNode.Options.DesignTime)
{
return;
}
var walker = new PreallocatedTagHelperWalker();
walker.VisitDocument(documentNode);
}

View File

@ -0,0 +1,52 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal sealed class RazorCompiledItemAttributeIntermediateNode : ExtensionIntermediateNode
{
public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly;
public string TypeName { get; set; }
public string Kind { get; set; }
public string Identifier { get; set; }
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<RazorCompiledItemAttributeIntermediateNode>(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<IMetadataAttributeTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IMetadataAttributeTargetExtension>(context);
return;
}
extension.WriteRazorCompiledItemAttribute(context, this);
}
}
}

View File

@ -0,0 +1,52 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal sealed class RazorSourceChecksumAttributeIntermediateNode : ExtensionIntermediateNode
{
public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly;
public byte[] Checksum { get; set; }
public string ChecksumAlgorithm { get; set; }
public string Identifier { get; set; }
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<RazorSourceChecksumAttributeIntermediateNode>(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<IMetadataAttributeTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IMetadataAttributeTargetExtension>(context);
return;
}
extension.WriteRazorSourceChecksumAttribute(context, this);
}
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
@ -16,11 +17,30 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
builder.Description = Resources.SectionDirective_Description;
});
public static void Register(IRazorEngineBuilder builder)
public static void Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new SectionDirectivePass());
builder.AddTargetExtension(new SectionTargetExtension());
}
#region Obsolete
public static void Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new SectionDirectivePass());
builder.AddTargetExtension(new SectionTargetExtension());
}
#endregion
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
namespace Microsoft.AspNetCore.Razor.Language
{
public interface IImportProjectFeature : IRazorProjectEngineFeature
{
IReadOnlyList<RazorProjectItem> GetImports(RazorProjectItem projectItem);
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Razor.Language
{
internal interface IRazorCodeGenerationOptionsFactoryProjectFeature : IRazorProjectEngineFeature
{
RazorCodeGenerationOptions Create(Action<RazorCodeGenerationOptionsBuilder> configure);
}
}

View File

@ -1,8 +1,11 @@
// Copyright(c) .NET Foundation.All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Razor.Language
{
[Obsolete("In Razor 2.1 and newer, use RazorCodeDocument.GetCodeGenerationOptions().")]
public interface IRazorCodeGenerationOptionsFeature : IRazorEngineFeature
{
RazorCodeGenerationOptions GetOptions();

View File

@ -3,7 +3,7 @@
namespace Microsoft.AspNetCore.Razor.Language
{
public interface IRazorEngineFeature
public interface IRazorEngineFeature : IRazorFeature
{
RazorEngine Engine { get; set; }
}

View File

@ -0,0 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Razor.Language
{
public interface IRazorFeature
{
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Razor.Language
{
internal interface IRazorParserOptionsFactoryProjectFeature : IRazorProjectEngineFeature
{
RazorParserOptions Create(Action<RazorParserOptionsBuilder> configure);
}
}

View File

@ -1,8 +1,11 @@
// Copyright(c) .NET Foundation.All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Razor.Language
{
[Obsolete("In Razor 2.1 and newer, use RazorCodeDocument.GetParserOptions().")]
public interface IRazorParserOptionsFeature : IRazorEngineFeature
{
RazorParserOptions GetOptions();

View File

@ -0,0 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Razor.Language
{
public interface IRazorProjectEngineFeature : IRazorFeature
{
RazorProjectEngine ProjectEngine { get; set; }
}
}

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Razor.Language
private readonly int _length;
private byte[] _checksum;
public LargeTextSourceDocument(StreamReader reader, int chunkMaxLength, Encoding encoding, string fileName)
public LargeTextSourceDocument(StreamReader reader, int chunkMaxLength, Encoding encoding, RazorSourceDocumentProperties properties)
{
if (reader == null)
{
@ -32,9 +32,15 @@ namespace Microsoft.AspNetCore.Razor.Language
throw new ArgumentNullException(nameof(encoding));
}
if (properties == null)
{
throw new ArgumentNullException(nameof(properties));
}
_chunkMaxLength = chunkMaxLength;
Encoding = encoding;
FilePath = fileName;
FilePath = properties.FilePath;
RelativePath = properties.RelativePath;
ReadChunks(reader, _chunkMaxLength, out _length, out _chunks);
_lines = new DefaultRazorSourceLineCollection(this);
@ -59,6 +65,8 @@ namespace Microsoft.AspNetCore.Razor.Language
public override RazorSourceLineCollection Lines => _lines;
public override string RelativePath { get; }
public override void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
{
if (destination == null)

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
if (type == null)
{
throw new InvalidOperationException(LegacyResources.Block_Type_Not_Specified);
throw new InvalidOperationException(Resources.Block_Type_Not_Specified);
}
Type = type.Value;
@ -234,6 +234,20 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
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.

View File

@ -196,7 +196,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
if (Context == null)
{
throw new InvalidOperationException(LegacyResources.Parser_Context_Not_Set);
throw new InvalidOperationException(Resources.Parser_Context_Not_Set);
}
Span.Start = CurrentLocation;
@ -296,10 +296,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
StringComparison.Ordinal))
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatParseError_HelperDirectiveNotAvailable(
SyntaxConstants.CSharp.HelperKeyword),
CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_HelperDirectiveNotAvailable(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length)));
}
Context.Builder.CurrentBlock.Type = BlockKindInternal.Expression;
@ -344,24 +342,21 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (At(CSharpSymbolType.WhiteSpace) || At(CSharpSymbolType.NewLine))
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_CS,
CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_UnexpectedWhiteSpaceAtStartOfCodeBlock(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length)));
}
else if (EndOfFile)
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.ParseError_Unexpected_EndOfFile_At_Start_Of_CodeBlock,
length: 1 /* end of file */);
RazorDiagnosticFactory.CreateParsing_UnexpectedEndOfFileAtStartOfCodeBlock(
new SourceSpan(CurrentStart, contentLength: 1 /* end of file */)));
}
else
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatParseError_Unexpected_Character_At_Start_Of_CodeBlock_CS(
CurrentSymbol.Content),
CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length),
CurrentSymbol.Content));
}
}
finally
@ -375,7 +370,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
private void VerbatimBlock()
{
Assert(CSharpSymbolType.LeftBrace);
var block = new Block(LegacyResources.BlockName_Code, CurrentStart);
var block = new Block(Resources.BlockName_Code, CurrentStart);
AcceptAndMoveNext();
// Set up the "{" span and output
@ -614,7 +609,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
private void ExplicitExpression()
{
var block = new Block(LegacyResources.BlockName_ExplicitExpression, CurrentStart);
var block = new Block(Resources.BlockName_ExplicitExpression, CurrentStart);
Assert(CSharpSymbolType.LeftParenthesis);
AcceptAndMoveNext();
Span.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
@ -634,9 +629,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
AcceptUntil(CSharpSymbolType.LessThan);
Context.ErrorSink.OnError(
block.Start,
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, ")", "("),
length: 1 /* ( */);
RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
new SourceSpan(block.Start, contentLength: 1 /* ( */), block.Name, ")", "("));
}
// If necessary, put an empty-content marker symbol here
@ -664,9 +658,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (Context.Builder.ActiveBlocks.Any(block => block.Type == BlockKindInternal.Template))
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.ParseError_InlineMarkup_Blocks_Cannot_Be_Nested,
length: 1 /* @ */);
RazorDiagnosticFactory.CreateParsing_InlineMarkupBlocksCannotBeNested(
new SourceSpan(CurrentStart, contentLength: 1 /* @ */)));
}
Output(SpanKindInternal.Code);
using (Context.Builder.StartBlock(BlockKindInternal.Template))
@ -767,9 +760,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
protected virtual void ReservedDirective(bool topLevel)
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatParseError_ReservedWord(CurrentSymbol.Content),
CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_ReservedWord(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length), CurrentSymbol.Content));
AcceptAndMoveNext();
Span.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
Span.ChunkGenerator = SpanChunkGenerator.Null;
@ -850,9 +843,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (!topLevel)
{
Context.ErrorSink.OnError(
block.Start,
LegacyResources.ParseError_NamespaceImportAndTypeAlias_Cannot_Exist_Within_CodeBlock,
block.Name.Length);
RazorDiagnosticFactory.CreateParsing_NamespaceImportAndTypeAliasCannotExistWithinCodeBlock(
new SourceSpan(block.Start, block.Name.Length)));
StandardStatement();
}
else
@ -1170,11 +1162,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (!At(CSharpSymbolType.LeftBrace))
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatParseError_SingleLine_ControlFlowStatements_Not_Allowed(
RazorDiagnosticFactory.CreateParsing_SingleLineControlFlowStatementsNotAllowed(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length),
Language.GetSample(CSharpSymbolType.LeftBrace),
CurrentSymbol.Content),
CurrentSymbol.Content.Length);
CurrentSymbol.Content));
}
// Parse the statement and then we're done
@ -1333,9 +1324,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (type == CSharpSymbolType.Transition && !isSingleLineMarkup)
{
Context.ErrorSink.OnError(
loc,
LegacyResources.ParseError_AtInCode_Must_Be_Followed_By_Colon_Paren_Or_Identifier_Start,
length: 1 /* @ */);
RazorDiagnosticFactory.CreateParsing_AtInCodeMustBeFollowedByColonParenOrIdentifierStart(
new SourceSpan(loc, contentLength: 1 /* @ */)));
}
// Markup block
@ -1365,7 +1355,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
break;
case CSharpSymbolType.LeftBrace:
// Verbatim Block
block = block ?? new Block(LegacyResources.BlockName_Code, CurrentStart);
block = block ?? new Block(Resources.BlockName_Code, CurrentStart);
AcceptAndMoveNext();
CodeBlock(block);
break;
@ -1417,9 +1407,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (At(CSharpSymbolType.LeftBrace))
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.ParseError_Unexpected_Nested_CodeBlock,
length: 1 /* { */);
RazorDiagnosticFactory.CreateParsing_UnexpectedNestedCodeBlock(
new SourceSpan(CurrentStart, contentLength: 1 /* { */)));
}
// @( or @foo - Nested expression, parse a child block
@ -1513,9 +1502,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (EndOfFile)
{
Context.ErrorSink.OnError(
block.Start,
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, '}', '{'),
length: 1 /* { OR } */);
RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
new SourceSpan(block.Start, contentLength: 1 /* { OR } */), block.Name, "}", "{"));
}
else if (acceptTerminatingBrace)
{
@ -1624,9 +1612,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
var currentDirective = CurrentSymbol.Content;
Context.ErrorSink.OnError(
CurrentStart,
Resources.FormatDirectiveMustAppearAtStartOfLine(currentDirective),
length: currentDirective.Length);
RazorDiagnosticFactory.CreateParsing_DirectiveMustAppearAtStartOfLine(
new SourceSpan(CurrentStart, currentDirective.Length), currentDirective));
break;
}
}
@ -1662,9 +1649,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
!EndOfFile)
{
Context.ErrorSink.OnError(
CurrentStart,
Resources.FormatDirectiveTokensMustBeSeparatedByWhitespace(descriptor.Directive),
length: CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_DirectiveTokensMustBeSeparatedByWhitespace(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length), descriptor.Directive));
return;
}
@ -1700,9 +1686,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
else if (EndOfFile)
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatUnexpectedEOFAfterDirective(descriptor.Directive, tokenDescriptor.Kind.ToString().ToLowerInvariant()),
length: 1);
RazorDiagnosticFactory.CreateParsing_UnexpectedEOFAfterDirective(
new SourceSpan(CurrentStart, contentLength: 1),
descriptor.Directive,
tokenDescriptor.Kind.ToString().ToLowerInvariant()));
return;
}
@ -1712,9 +1699,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (!NamespaceOrTypeName())
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatDirectiveExpectsTypeName(descriptor.Directive),
CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_DirectiveExpectsTypeName(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length), descriptor.Directive));
return;
}
@ -1724,9 +1710,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (!QualifiedIdentifier(out var identifierLength))
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatDirectiveExpectsNamespace(descriptor.Directive),
identifierLength);
RazorDiagnosticFactory.CreateParsing_DirectiveExpectsNamespace(
new SourceSpan(CurrentStart, identifierLength), descriptor.Directive));
return;
}
@ -1740,9 +1725,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
else
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatDirectiveExpectsIdentifier(descriptor.Directive),
CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_DirectiveExpectsIdentifier(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length), descriptor.Directive));
return;
}
break;
@ -1755,9 +1739,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
else
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatDirectiveExpectsQuotedStringLiteral(descriptor.Directive),
CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_DirectiveExpectsQuotedStringLiteral(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length), descriptor.Directive));
return;
}
break;
@ -1789,9 +1772,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
else if (!EndOfFile)
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatUnexpectedDirectiveLiteral(descriptor.Directive, LegacyResources.ErrorComponent_Newline),
CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_UnexpectedDirectiveLiteral(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length),
descriptor.Directive,
Resources.ErrorComponent_Newline));
}
Span.ChunkGenerator = SpanChunkGenerator.Null;
@ -1840,8 +1824,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
if (directiveErrorSink.Errors.Count > 0)
{
var directiveDiagnostics = directiveErrorSink.Errors.Select(error => RazorDiagnostic.Create(error));
directiveChunkGenerator.Diagnostics.AddRange(directiveDiagnostics);
directiveChunkGenerator.Diagnostics.AddRange(directiveErrorSink.Errors);
}
Context.ErrorSink = savedErrorSink;
@ -1855,18 +1838,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
if (Context.SeenDirectives.Contains(descriptor.Directive))
{
UsageError(Resources.FormatDuplicateDirective(descriptor.Directive));
// There will always be at least 1 child because of the `@` transition.
var directiveStart = Context.Builder.CurrentBlock.Children.First().Start;
var errorLength = /* @ */ 1 + descriptor.Directive.Length;
Context.ErrorSink.OnError(
RazorDiagnosticFactory.CreateParsing_DuplicateDirective(
new SourceSpan(directiveStart, errorLength), descriptor.Directive));
return;
}
}
void UsageError(string message)
{
// There wil always be at least 1 child because of the `@` transition.
var directiveStart = Context.Builder.CurrentBlock.Children.First().Start;
var errorLength = /* @ */ 1 + descriptor.Directive.Length;
Context.ErrorSink.OnError(directiveStart, message, errorLength);
}
}
private void ParseDirectiveBlock(DirectiveDescriptor descriptor, Action<SourceLocation> parseChildren)
@ -1874,16 +1855,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (EndOfFile)
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatUnexpectedEOFAfterDirective(descriptor.Directive, "{"),
length: 1 /* { */);
RazorDiagnosticFactory.CreateParsing_UnexpectedEOFAfterDirective(
new SourceSpan(CurrentStart, contentLength: 1 /* { */), descriptor.Directive, "{"));
}
else if (!At(CSharpSymbolType.LeftBrace))
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatUnexpectedDirectiveLiteral(descriptor.Directive, "{"),
CurrentSymbol.Content.Length);
RazorDiagnosticFactory.CreateParsing_UnexpectedDirectiveLiteral(
new SourceSpan(CurrentStart, CurrentSymbol.Content.Length), descriptor.Directive, "{"));
}
else
{
@ -1901,9 +1880,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
editHandler.AutoCompleteString = "}";
Context.ErrorSink.OnError(
startingBraceLocation,
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF(descriptor.Directive, "}", "{"),
length: 1 /* } */);
RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
new SourceSpan(startingBraceLocation, contentLength: 1 /* } */), descriptor.Directive, "}", "{"));
}
else
{
@ -1924,8 +1902,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
var directiveStart = Context.Builder.CurrentBlock.Children.First().Start;
var errorLength = /* @ */ 1 + SyntaxConstants.CSharp.TagHelperPrefixKeyword.Length;
duplicateDiagnostic = RazorDiagnosticFactory.CreateParsing_DuplicateDirective(
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
new SourceSpan(directiveStart, errorLength));
new SourceSpan(directiveStart, errorLength),
SyntaxConstants.CSharp.TagHelperPrefixKeyword);
}
TagHelperDirective(
@ -1958,11 +1936,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (char.IsWhiteSpace(character) || InvalidNonWhitespaceNameCharacters.Contains(character))
{
diagnostics.Add(
RazorDiagnostic.Create(
new RazorError(
Resources.FormatInvalidTagHelperPrefixValue(SyntaxConstants.CSharp.TagHelperPrefixKeyword, character, prefix),
directiveLocation,
prefix.Length)));
RazorDiagnosticFactory.CreateParsing_InvalidTagHelperPrefixValue(
new SourceSpan(directiveLocation, prefix.Length),
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
character,
prefix));
return;
}
@ -2037,11 +2015,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
text.EndsWith("'"))
{
errors.Add(
RazorDiagnostic.Create(
new RazorError(
Resources.FormatInvalidTagHelperLookupText(text),
directiveLocation,
Math.Max(text.Length, 1))));
RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
new SourceSpan(directiveLocation, Math.Max(text.Length, 1)), text));
return directive;
}
@ -2100,59 +2075,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
Debug.Assert(string.Equals(CurrentSymbol.Content, directive, StringComparison.Ordinal));
}
protected void BaseTypeDirective(string noTypeNameError, Func<string, SpanChunkGenerator> createChunkGenerator)
{
var keywordStartLocation = Span.Start;
// Set the block type
Context.Builder.CurrentBlock.Type = BlockKindInternal.Directive;
var keywordLength = Span.End.AbsoluteIndex - Span.Start.AbsoluteIndex;
// Accept whitespace
var remainingWhitespace = AcceptSingleWhiteSpaceCharacter();
if (Span.Symbols.Count > 1)
{
Span.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
}
Output(SpanKindInternal.MetaCode);
if (remainingWhitespace != null)
{
Accept(remainingWhitespace);
}
AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true));
if (EndOfFile || At(CSharpSymbolType.WhiteSpace) || At(CSharpSymbolType.NewLine))
{
Context.ErrorSink.OnError(
keywordStartLocation,
noTypeNameError,
keywordLength);
}
// Parse to the end of the line
AcceptUntil(CSharpSymbolType.NewLine);
if (!Context.DesignTimeMode)
{
// We want the newline to be treated as code, but it causes issues at design-time.
Optional(CSharpSymbolType.NewLine);
}
// Pull out the type name
var baseType = string.Concat(Span.Symbols.Select(s => s.Content));
// Set up chunk generation
Span.ChunkGenerator = createChunkGenerator(baseType.Trim());
// Output the span and finish the block
CompleteBlock();
Output(SpanKindInternal.Code, AcceptedCharactersInternal.AnyExceptNewline);
}
private void TagHelperDirective(string keyword, Func<string, List<RazorDiagnostic>, ISpanChunkGenerator> chunkGeneratorFactory)
{
AssertDirective(keyword);
@ -2190,9 +2112,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (EndOfFile || At(CSharpSymbolType.NewLine))
{
Context.ErrorSink.OnError(
keywordStartLocation,
LegacyResources.FormatParseError_DirectiveMustHaveValue(keyword),
keywordLength);
RazorDiagnosticFactory.CreateParsing_DirectiveMustHaveValue(
new SourceSpan(keywordStartLocation, keywordLength), keyword));
directiveValue = string.Empty;
}
@ -2213,9 +2134,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (startsWithQuote != endsWithQuote)
{
Context.ErrorSink.OnError(
startLocation,
LegacyResources.FormatParseError_IncompleteQuotesAroundDirective(keyword),
rawValue.Length);
RazorDiagnosticFactory.CreateParsing_IncompleteQuotesAroundDirective(
new SourceSpan(startLocation, rawValue.Length), keyword));
}
directiveValue = rawValue;
@ -2223,17 +2143,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
}
finally
{
List<RazorDiagnostic> directiveErrors;
if (directiveErrorSink.Errors.Count > 0)
{
directiveErrors = directiveErrorSink.Errors.Select(RazorDiagnostic.Create).ToList();
}
else
{
directiveErrors = new List<RazorDiagnostic>();
}
Span.ChunkGenerator = chunkGeneratorFactory(directiveValue, directiveErrors);
Span.ChunkGenerator = chunkGeneratorFactory(directiveValue, directiveErrorSink.Errors.ToList());
Context.ErrorSink = savedErrorSink;
}

View File

@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
return new CSharpTokenizer(source);
}
protected override CSharpSymbol CreateSymbol(string content, CSharpSymbolType type, IReadOnlyList<RazorError> errors)
protected override CSharpSymbol CreateSymbol(string content, CSharpSymbolType type, IReadOnlyList<RazorDiagnostic> errors)
{
return new CSharpSymbol(content, type, errors);
}
@ -87,25 +87,25 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
switch (type)
{
case CSharpSymbolType.Identifier:
return LegacyResources.CSharpSymbol_Identifier;
return Resources.CSharpSymbol_Identifier;
case CSharpSymbolType.Keyword:
return LegacyResources.CSharpSymbol_Keyword;
return Resources.CSharpSymbol_Keyword;
case CSharpSymbolType.IntegerLiteral:
return LegacyResources.CSharpSymbol_IntegerLiteral;
return Resources.CSharpSymbol_IntegerLiteral;
case CSharpSymbolType.NewLine:
return LegacyResources.CSharpSymbol_Newline;
return Resources.CSharpSymbol_Newline;
case CSharpSymbolType.WhiteSpace:
return LegacyResources.CSharpSymbol_Whitespace;
return Resources.CSharpSymbol_Whitespace;
case CSharpSymbolType.Comment:
return LegacyResources.CSharpSymbol_Comment;
return Resources.CSharpSymbol_Comment;
case CSharpSymbolType.RealLiteral:
return LegacyResources.CSharpSymbol_RealLiteral;
return Resources.CSharpSymbol_RealLiteral;
case CSharpSymbolType.CharacterLiteral:
return LegacyResources.CSharpSymbol_CharacterLiteral;
return Resources.CSharpSymbol_CharacterLiteral;
case CSharpSymbolType.StringLiteral:
return LegacyResources.CSharpSymbol_StringLiteral;
return Resources.CSharpSymbol_StringLiteral;
default:
return LegacyResources.Symbol_Unknown;
return Resources.Symbol_Unknown;
}
}
return sample;

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
public CSharpSymbol(
string content,
CSharpSymbolType type)
: base(content, type, RazorError.EmptyArray)
: base(content, type, RazorDiagnostic.EmptyArray)
{
if (content == null)
{
@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
public CSharpSymbol(
string content,
CSharpSymbolType type,
IReadOnlyList<RazorError> errors)
IReadOnlyList<RazorDiagnostic> errors)
: base(content, type, errors)
{
if (content == null)

View File

@ -343,7 +343,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
return base.GetSymbolContent(type);
}
protected override CSharpSymbol CreateSymbol(string content, CSharpSymbolType type, IReadOnlyList<RazorError> errors)
protected override CSharpSymbol CreateSymbol(string content, CSharpSymbolType type, IReadOnlyList<RazorDiagnostic> errors)
{
return new CSharpSymbol(content, type, errors);
}
@ -547,10 +547,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
else if (EndOfFile)
{
CurrentErrors.Add(
new RazorError(
LegacyResources.ParseError_Unterminated_String_Literal,
CurrentStart,
length: 1 /* end of file */));
RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
new SourceSpan(CurrentStart, contentLength: 1 /* end of file */)));
}
return Transition(CSharpTokenizerState.Data, EndSymbol(CSharpSymbolType.StringLiteral));
}
@ -576,10 +574,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
else if (EndOfFile || ParserHelpers.IsNewLine(CurrentCharacter))
{
CurrentErrors.Add(
new RazorError(
LegacyResources.ParseError_Unterminated_String_Literal,
CurrentStart,
length: 1 /* " */));
RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
new SourceSpan(CurrentStart, contentLength: 1 /* " */)));
}
else
{
@ -595,10 +591,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (EndOfFile)
{
CurrentErrors.Add(
new RazorError(
LegacyResources.ParseError_BlockComment_Not_Terminated,
CurrentStart,
length: 1 /* end of file */));
RazorDiagnosticFactory.CreateParsing_BlockCommentNotTerminated(
new SourceSpan(CurrentStart, contentLength: 1 /* end of file */)));
return Transition(CSharpTokenizerState.Data, EndSymbol(CSharpSymbolType.Comment));
}
if (CurrentCharacter == '*')

View File

@ -6,41 +6,29 @@ using System.Collections.Generic;
namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
/// <summary>
/// Used to manage <see cref="RazorError"/>s encountered during the Razor parsing phase.
/// Used to manage <see cref="RazorDiagnostic"/>s encountered during the Razor parsing phase.
/// </summary>
internal class ErrorSink
{
private readonly List<RazorError> _errors;
private readonly List<RazorDiagnostic> _errors;
/// <summary>
/// Instantiates a new instance of <see cref="ErrorSink"/>.
/// </summary>
public ErrorSink()
{
_errors = new List<RazorError>();
_errors = new List<RazorDiagnostic>();
}
/// <summary>
/// <see cref="RazorError"/>s collected.
/// <see cref="RazorDiagnostic"/>s collected.
/// </summary>
public IReadOnlyList<RazorError> Errors => _errors;
public IReadOnlyList<RazorDiagnostic> Errors => _errors;
/// <summary>
/// Tracks the given <paramref name="error"/>.
/// </summary>
/// <param name="error">The <see cref="RazorError"/> to track.</param>
public void OnError(RazorError error) =>_errors.Add(error);
/// <summary>
/// Creates and tracks a new <see cref="RazorError"/>.
/// </summary>
/// <param name="location"><see cref="SourceLocation"/> of the error.</param>
/// <param name="message">A message describing the error.</param>
/// <param name="length">The length of the error.</param>
public void OnError(SourceLocation location, string message, int length)
{
var error = new RazorError(message, location, length);
_errors.Add(error);
}
/// <param name="error">The <see cref="RazorDiagnostic"/> to track.</param>
public void OnError(RazorDiagnostic error) =>_errors.Add(error);
}
}

View File

@ -24,11 +24,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
switch (type)
{
case HtmlSymbolType.Text:
return LegacyResources.HtmlSymbol_Text;
return Resources.HtmlSymbol_Text;
case HtmlSymbolType.WhiteSpace:
return LegacyResources.HtmlSymbol_WhiteSpace;
return Resources.HtmlSymbol_WhiteSpace;
case HtmlSymbolType.NewLine:
return LegacyResources.HtmlSymbol_NewLine;
return Resources.HtmlSymbol_NewLine;
case HtmlSymbolType.OpenAngle:
return "<";
case HtmlSymbolType.Bang:
@ -56,13 +56,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
case HtmlSymbolType.Colon:
return ":";
case HtmlSymbolType.RazorComment:
return LegacyResources.HtmlSymbol_RazorComment;
return Resources.HtmlSymbol_RazorComment;
case HtmlSymbolType.RazorCommentStar:
return "*";
case HtmlSymbolType.RazorCommentTransition:
return "@";
default:
return LegacyResources.Symbol_Unknown;
return Resources.Symbol_Unknown;
}
}
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
}
}
protected override HtmlSymbol CreateSymbol(string content, HtmlSymbolType type, IReadOnlyList<RazorError> errors)
protected override HtmlSymbol CreateSymbol(string content, HtmlSymbolType type, IReadOnlyList<RazorDiagnostic> errors)
{
return new HtmlSymbol(content, type, errors);
}

Some files were not shown because too many files have changed in this diff Show More