Skip to content

Commit 25e5a4f

Browse files
authored
Infer Razor Configuration \ RazorLangVersion based on TFM (dotnet/razor#343)
* Infer Razor Configuration \ RazorLangVersion based on TFM Fixes #6392 \n\nCommit migrated from dotnet/razor@cfee40a
1 parent 2c39457 commit 25e5a4f

39 files changed

+775
-234
lines changed

src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorLanguageVersion.cs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Microsoft.AspNetCore.Razor.Language
88
{
9+
// Note: RazorSDK is aware of version monikers such as "latest", and "experimental". Update it if we introduce new monikers.
910
[DebuggerDisplay("{" + nameof(DebuggerToString) + "(),nq}")]
1011
public sealed class RazorLanguageVersion : IEquatable<RazorLanguageVersion>, IComparable<RazorLanguageVersion>
1112
{

src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ Copyright (c) .NET Foundation. All rights reserved.
1212

1313
<Project ToolsVersion="14.0">
1414

15+
<!-- Wire up RazorComponentGenerateCore only once we know we are importing this target file. This prevents avoidable build failures. -->
16+
<PropertyGroup>
17+
<RazorComponentGenerateDependsOn>
18+
$(RazorComponentGenerateDependsOn);
19+
RazorComponentGenerateCore
20+
</RazorComponentGenerateDependsOn>
21+
</PropertyGroup>
22+
1523
<PropertyGroup>
1624
<!-- Used for tracking inputs to component generation -->
1725
<_RazorComponentInputHash></_RazorComponentInputHash>

src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Configuration.targets

+15-16
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ Copyright (c) .NET Foundation. All rights reserved.
1111
-->
1212
<Project ToolsVersion="14.0">
1313

14-
<PropertyGroup>
15-
<_TargetingNETCoreApp30OrLater Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND '$(_TargetFrameworkVersionWithoutV)' &gt; '2.9'">true</_TargetingNETCoreApp30OrLater>
16-
</PropertyGroup>
17-
1814
<!--
1915
Initialize properties and items inferred using the project version. This file is not imported in projects referencing
2016
MVC \ Razor 2.2 or earlier since values specified here are provided via targets and props imported from NuGet packages
@@ -27,16 +23,24 @@ Copyright (c) .NET Foundation. All rights reserved.
2723
would be to detect whether the ASP.NET Core shared framework is referenced.
2824
-->
2925
<PropertyGroup>
26+
<!-- Continue setting this property to maintain compat with legacy Razor.Design -->
27+
<IsRazorCompilerReferenced Condition="'$(IsRazorCompilerReferenced)'==''">true</IsRazorCompilerReferenced>
28+
</PropertyGroup>
29+
30+
<!--
31+
Configure MVC specific configuration if the application uses a configuration that supports MVC.
32+
-->
33+
<PropertyGroup Condition="'$(AddRazorSupportForMvc)' == 'true'">
3034
<!--
3135
MVC uses a ProvideApplicationPartFactoryAttribute on the generated assembly to load compiled views from assembly. Set this to false, to prevent generating this attribute.
3236
-->
33-
<GenerateProvideApplicationPartFactoryAttribute Condition="'$(GenerateProvideApplicationPartFactoryAttribute)'==''">$(_TargetingNETCoreApp30OrLater)</GenerateProvideApplicationPartFactoryAttribute>
37+
<GenerateProvideApplicationPartFactoryAttribute Condition="'$(GenerateProvideApplicationPartFactoryAttribute)'==''">true</GenerateProvideApplicationPartFactoryAttribute>
3438

3539
<!--
3640
Determines if the Sdk is allowed to add additional attributes to the project assembly.
3741
For instance, MVC will generally want to add attributes to support view discovery and runtime compilation.
3842
-->
39-
<GenerateRazorAssemblyInfo Condition="'$(GenerateRazorAssemblyInfo)'==''">$(_TargetingNETCoreApp30OrLater)</GenerateRazorAssemblyInfo>
43+
<GenerateRazorAssemblyInfo Condition="'$(GenerateRazorAssemblyInfo)'==''">true</GenerateRazorAssemblyInfo>
4044

4145
<!--
4246
MVC will generally want to add support for runtime compilation, but only for applications.
@@ -47,20 +51,14 @@ Copyright (c) .NET Foundation. All rights reserved.
4751
The type name of the ApplicationPartFactory applied to the generated Razor file.
4852
-->
4953
<ProvideApplicationPartFactoryAttributeTypeName Condition="'$(ProvideApplicationPartFactoryAttributeTypeName)' == ''">Microsoft.AspNetCore.Mvc.ApplicationParts.CompiledRazorAssemblyApplicationPartFactory, Microsoft.AspNetCore.Mvc.Razor</ProvideApplicationPartFactoryAttributeTypeName>
50-
51-
<!-- Continue setting this property to maintain compat with legacy Razor.Design -->
52-
<IsRazorCompilerReferenced Condition="'$(IsRazorCompilerReferenced)'==''">true</IsRazorCompilerReferenced>
53-
</PropertyGroup>
54-
55-
<PropertyGroup Condition="'$(RazorLangVersion)'==''">
56-
<RazorLangVersion Condition="'$(_TargetingNETCoreApp30OrLater)' == 'true'">3.0</RazorLangVersion>
5754
</PropertyGroup>
5855

5956
<!--
60-
Set the primary configuration supported by this SDK as the default configuration for Razor.
57+
Determine the default Razor configuration
6158
-->
6259
<PropertyGroup Condition="'$(RazorDefaultConfiguration)'==''">
63-
<RazorDefaultConfiguration Condition="'$(_TargetingNETCoreApp30OrLater)' == 'true'">MVC-3.0</RazorDefaultConfiguration>
60+
<RazorDefaultConfiguration Condition="'$(AddRazorSupportForMvc)'=='true'">MVC-3.0</RazorDefaultConfiguration>
61+
<RazorDefaultConfiguration Condition="'$(RazorDefaultConfiguration)'==''">Default</RazorDefaultConfiguration>
6462
</PropertyGroup>
6563

6664
<ItemGroup>
@@ -69,7 +67,8 @@ Copyright (c) .NET Foundation. All rights reserved.
6967
it here. The IDE is hardcoded to inject 2.0 support when needed. The settings flowing through MSBuild should reflect
7068
the project's runtime.
7169
-->
72-
<RazorConfiguration Include="MVC-3.0">
70+
<RazorConfiguration Include="Default" />
71+
<RazorConfiguration Include="MVC-3.0" >
7372
<Extensions>MVC-3.0;$(CustomRazorExtension)</Extensions>
7473
</RazorConfiguration>
7574
</ItemGroup>

src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ Copyright (c) .NET Foundation. All rights reserved.
2626
Defines the ability to understand the configuration for the Razor language service provided by
2727
the runtime/toolset packages. Introduced in 2.1
2828
-->
29-
<ProjectCapability Include="DotNetCoreRazorConfiguration" Condition="'$(_TargetingNETCoreApp30OrLater)'=='true'"/>
30-
29+
<ProjectCapability Include="DotNetCoreRazorConfiguration" Condition="'$(_Targeting30OrNewerRazorLangVersion)' == 'true'"/>
3130

3231
<!--
3332
Activates the set of nesting behaviors we want from solution explorer.

src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets

+96-20
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
99
Copyright (c) .NET Foundation. All rights reserved.
1010
***********************************************************************************************
1111
-->
12-
<Project ToolsVersion="14.0" TreatAsLocalProperty="_RazorSdkTasksTFM">
12+
<Project ToolsVersion="14.0" TreatAsLocalProperty="_RazorSdkTasksTFM;_Targeting30OrNewerRazorLangVersion">
1313
<!--
1414
Targets supporting Razor MSBuild integration. Contain support for generating C# code using Razor
1515
and including the generated code in the project lifecycle, including compiling, publishing and producing
@@ -28,9 +28,38 @@ Copyright (c) .NET Foundation. All rights reserved.
2828
<_RazorSdkTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core'">netstandard2.0</_RazorSdkTasksTFM>
2929
<_RazorSdkTasksTFM Condition=" '$(_RazorSdkTasksTFM)' == ''">net46</_RazorSdkTasksTFM>
3030
<RazorSdkBuildTasksAssembly>$(RazorSdkBuildTasksDirectoryRoot)$(_RazorSdkTasksTFM)\Microsoft.NET.Sdk.Razor.Tasks.dll</RazorSdkBuildTasksAssembly>
31+
</PropertyGroup>
3132

33+
<!-- Resolve the RazorLangVersion based on values imported or TFM. -->
34+
<PropertyGroup>
3235
<_TargetFrameworkVersionWithoutV>$(TargetFrameworkVersion.TrimStart('vV'))</_TargetFrameworkVersionWithoutV>
33-
<_EnableAllInclusiveRazorSdk Condition="'$(_EnableInclusiveRazorSdk)' == '' AND '$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND '$(_TargetFrameworkVersionWithoutV)' &gt; '2.9'">true</_EnableAllInclusiveRazorSdk>
36+
37+
<!--
38+
Infer the RazorLangVersion if no value was specified. When adding support for newer target frameworks, list newer language versions first.
39+
-->
40+
<RazorLangVersion Condition="'$(RazorLangVersion)' == '' AND '$(_TargetFrameworkVersionWithoutV)' &gt; '2.9'">3.0</RazorLangVersion>
41+
42+
<!--
43+
In 3.0, we expect RazorLangVersion to either be specified in the template or inferred via TFM. In 2.x, RazorLangVersion is
44+
specified via the Razor.Design package. We'll default to a version of 2.1, the earliest version that the SDK supports.
45+
A 2.1 version should result in a build warning if the project contains Components.
46+
-->
47+
<RazorLangVersion Condition="'$(RazorLangVersion)' == ''">2.1</RazorLangVersion>
48+
49+
<!-- Keep this in sync with RazorLangVersion.cs if we introduce new text based values. -->
50+
<_Targeting30OrNewerRazorLangVersion Condition="
51+
'$(RazorLangVersion)' == 'Latest' OR
52+
'$(RazorLangVersion)' == 'Experimental' OR
53+
('$(RazorLangVersion)' != '' AND '$(RazorLangVersion)' &gt; '2.9')">true</_Targeting30OrNewerRazorLangVersion>
54+
</PropertyGroup>
55+
56+
57+
<PropertyGroup>
58+
<!--
59+
The property IsRazorCompilerReferenced is defined by the 2.x Razor.Design package. We can use this as a best guess to determine if a project is targeting 2.x or earlier.
60+
This is useful to provide 3.0 or newer specific build warnings. However, since it's not very reliable, we should not use this to make build-altering decisions.
61+
-->
62+
<_IsTargetingRazor2X Condition="'$(IsRazorCompilerReferenced)'=='true'">true</_IsTargetingRazor2X>
3463
</PropertyGroup>
3564

3665
<!--
@@ -47,12 +76,14 @@ Copyright (c) .NET Foundation. All rights reserved.
4776
AssignRazorGenerateTargetPaths;
4877
ResolveAssemblyReferenceRazorGenerateInputs;
4978
_CheckForMissingRazorCompiler;
79+
_CheckForIncorrectMvcConfiguration;
5080
ResolveTagHelperRazorGenerateInputs
5181
</PrepareForRazorGenerateDependsOn>
5282

5383
<PrepareForRazorComponentGenerateDependsOn>
5484
ResolveRazorConfiguration;
5585
ResolveRazorComponentInputs;
86+
_CheckForIncorrectComponentsConfiguration;
5687
AssignRazorComponentTargetPaths;
5788
</PrepareForRazorComponentGenerateDependsOn>
5889

@@ -63,8 +94,7 @@ Copyright (c) .NET Foundation. All rights reserved.
6394
</RazorGenerateDependsOn>
6495

6596
<RazorComponentGenerateDependsOn>
66-
PrepareForRazorComponentGenerate;
67-
RazorComponentGenerateCore
97+
PrepareForRazorComponentGenerate
6898
</RazorComponentGenerateDependsOn>
6999

70100
<PrepareForRazorCompileDependsOn>
@@ -155,7 +185,7 @@ Copyright (c) .NET Foundation. All rights reserved.
155185
<!--
156186
Use the suffix .Views when producing compiled view assemblies. This matches the requirements for Mvc's ViewsFeatureProvider.
157187
-->
158-
<RazorTargetNameSuffix Condition="'$(_EnableInclusiveRazorSdk)' == '' AND '$(RazorTargetNameSuffix)'==''">.Views</RazorTargetNameSuffix>
188+
<RazorTargetNameSuffix Condition="'$(RazorTargetNameSuffix)'=='' AND '$(_Targeting30OrNewerRazorLangVersion)' == 'true'">.Views</RazorTargetNameSuffix>
159189

160190
<!-- Suffix appended to $(TargetName) to produce $(RazorTargetName), the name of the assembly produced by Razor -->
161191
<RazorTargetNameSuffix Condition="'$(RazorTargetNameSuffix)' == ''">.Razor</RazorTargetNameSuffix>
@@ -216,8 +246,16 @@ Copyright (c) .NET Foundation. All rights reserved.
216246
<_RazorDebugSymbolsProduced Condition="'$(DebugType)'=='embedded'">false</_RazorDebugSymbolsProduced>
217247
</PropertyGroup>
218248

219-
<!-- Resolve the toolset to use -->
220-
<PropertyGroup>
249+
<!--
250+
Resolve the toolset to use. This specifically applies to compilation with 2.x projects where compilation could be performed either using
251+
the PrecompilationTool (Microsoft.AspNetCore.Mvc.Razor.ViewCompilation) or the RazorSDK and we have to infer the tool that is to be used.
252+
In 3.0 or later, there is only the RazorSdk.
253+
-->
254+
<PropertyGroup Condition="'$(_Targeting30OrNewerRazorLangVersion)' == 'true'">
255+
<ResolvedRazorCompileToolset>RazorSdk</ResolvedRazorCompileToolset>
256+
</PropertyGroup>
257+
258+
<PropertyGroup Condition="'$(ResolvedRazorCompileToolset)' == ''">
221259
<!-- Default value for the property 'MvcRazorCompileOnPublish' is empty. If it has been explicitly enabled, continue using precompilation. -->
222260
<ResolvedRazorCompileToolset Condition="'$(MvcRazorCompileOnPublish)' == 'true'">PrecompilationTool</ResolvedRazorCompileToolset>
223261

@@ -228,7 +266,7 @@ Copyright (c) .NET Foundation. All rights reserved.
228266
<ResolvedRazorCompileToolset Condition="'$(MvcRazorCompileOnPublish)' == '' AND '$(RazorCompileToolset)' == 'RazorSdk'">$(RazorCompileToolset)</ResolvedRazorCompileToolset>
229267

230268
<!-- If RazorSdk is not referenced, fall-back to Precompilation tool when referenced by a 2.2 or earlier targeting project. -->
231-
<ResolvedRazorCompileToolset Condition="'$(ResolvedRazorCompileToolset)' == 'RazorSdk' And '$(IsRazorCompilerReferenced)' != 'true' AND '$(_EnableAllInclusiveRazorSdk)' != 'true'">PrecompilationTool</ResolvedRazorCompileToolset>
269+
<ResolvedRazorCompileToolset Condition="'$(ResolvedRazorCompileToolset)' == 'RazorSdk' And '$(IsRazorCompilerReferenced)' != 'true'">PrecompilationTool</ResolvedRazorCompileToolset>
232270

233271
<!-- Previous versions of the precompilation tool still depends on the msbuild property 'MvcRazorCompileOnPublish'. Hence, setting it to the old default value -->
234272
<MvcRazorCompileOnPublish Condition="'$(MvcRazorCompileOnPublish)' == ''">true</MvcRazorCompileOnPublish>
@@ -281,12 +319,12 @@ Copyright (c) .NET Foundation. All rights reserved.
281319
Condition="'$(IsRazorCompilerReferenced)' == 'true' AND '$(RazorCodeGenerationTargetsPath)' != '' AND Exists('$(RazorCodeGenerationTargetsPath)')" />
282320

283321
<!-- When targeting 3.x and later projects, we have to infer configuration by inspecting the project. -->
284-
<Import Project="Microsoft.NET.Sdk.Razor.Configuration.targets" Condition="'$(_EnableAllInclusiveRazorSdk)' == 'true'" />
322+
<Import Project="Microsoft.NET.Sdk.Razor.Configuration.targets" Condition="'$(_Targeting30OrNewerRazorLangVersion)' == 'true'" />
285323

286-
<!-- For projects targeting 3.x and later, use the compiler that ships in the Sdk -->
287-
<Import Project="Microsoft.NET.Sdk.Razor.CodeGeneration.targets" Condition="'$(_EnableAllInclusiveRazorSdk)' == 'true'" />
324+
<!-- For projects targeting 3.x and later, use the compiler that ships in the SDK -->
325+
<Import Project="Microsoft.NET.Sdk.Razor.CodeGeneration.targets" Condition="'$(_Targeting30OrNewerRazorLangVersion)' == 'true'" />
288326

289-
<Import Project="Microsoft.NET.Sdk.Razor.Component.targets" />
327+
<Import Project="Microsoft.NET.Sdk.Razor.Component.targets" Condition="'$(_Targeting30OrNewerRazorLangVersion)' == 'true'" />
290328

291329
<Import Project="Microsoft.NET.Sdk.Razor.GenerateAssemblyInfo.targets" />
292330

@@ -319,15 +357,28 @@ Copyright (c) .NET Foundation. All rights reserved.
319357
Computes the applicable @(ResolvedRazorConfiguration) and @(ResolvedRazorExtension) items that match the project's
320358
configuration.
321359
-->
322-
<Target
323-
Name="ResolveRazorConfiguration"
324-
Condition="'$(RazorDefaultConfiguration)'!=''">
325-
326-
<ItemGroup>
360+
<Target Name="ResolveRazorConfiguration">
361+
<ItemGroup Condition="'$(RazorDefaultConfiguration)'!=''">
327362
<ResolvedRazorConfiguration Include="@(RazorConfiguration->WithMetadataValue('Identity', '$(RazorDefaultConfiguration)')->Distinct())" />
328363
</ItemGroup>
329364

330-
<FindInList List="@(RazorExtension)" ItemSpecToFind="@(ResolvedRazorConfiguration->Metadata('Extensions'))">
365+
<!--
366+
ResolvedRazorConfiguration should only ever have one item in it. If misconfigured, we may resolve more than one item which
367+
may result in incorrect results or poorly worded build errors.
368+
-->
369+
<Warning Text="Unable to resolve a Razor configuration for the value '$(_RazorConfiguration)'. Available configurations '@(RazorConfiguration)'.'"
370+
Code="RazorSDK1000"
371+
Condition="'@(ResolvedRazorConfiguration->Count())' == '0'" />
372+
373+
<Warning Text="More than one Razor configuration was resolved for the value '$(_RazorConfiguration)'. Available configurations '@(RazorConfiguration)'.
374+
A common cause is a reference to an incompatible version of the 'Microsoft.AspNetCore.Mvc' or 'Microsoft.AspNetCore.Razor.Design' package."
375+
Code="RazorSDK1001"
376+
Condition="'@(ResolvedRazorConfiguration->Count())' &gt; '1'" />
377+
378+
<FindInList
379+
List="@(RazorExtension)"
380+
ItemSpecToFind="@(ResolvedRazorConfiguration->Metadata('Extensions'))"
381+
Condition="'@(ResolvedRazorConfiguration->HasMetadata('Extensions')->Count())' != '0'">
331382
<Output TaskParameter="ItemFound" ItemName="ResolvedRazorExtension" />
332383
</FindInList>
333384
</Target>
@@ -729,9 +780,34 @@ Copyright (c) .NET Foundation. All rights reserved.
729780

730781
<Target Name="_CheckForMissingRazorCompiler" Condition="'$(IsRazorCompilerReferenced)' != 'true'">
731782
<Error
783+
Code="RAZORSDK1003"
732784
Text="A PackageReference for 'Microsoft.AspNetCore.Razor.Design' was not included in your project. This package is required to compile Razor files. Typically, a
733-
transitive reference to 'Microsoft.AspNetCore.Razor.Design' and references required to compile Razor files are obtained by adding a PackageReference
734-
for 'Microsoft.AspNetCore.Mvc' in your project. For more information, see https://go.microsoft.com/fwlink/?linkid=868374." />
785+
transitive reference to 'Microsoft.AspNetCore.Razor.Design' and references required to compile Razor files are obtained by adding a PackageReference
786+
for 'Microsoft.AspNetCore.Mvc' in your project. For more information, see https://go.microsoft.com/fwlink/?linkid=868374." />
787+
</Target>
788+
789+
<Target Name="_CheckForIncorrectMvcConfiguration"
790+
Condition="'@(ResolvedRazorConfiguration)' == 'Default' AND
791+
('$(RazorCompileOnBuild)' == 'true' OR '$(RazorCompileOnPublish)' =='true') AND
792+
'@(RazorGenerate->Count())' != '0' AND
793+
'$(_Targeting30OrNewerRazorLangVersion)' == 'true' AND
794+
'$(_IsTargetingRazor2X)' != 'true'">
795+
<Warning
796+
Code="RAZORSDK1004"
797+
Text="One or more Razor view or page files were found, but the project is not configured to add Razor support for MVC. The MSBuild property 'AddRazorSupportForMvc' must be set to correctly
798+
compile Razor files that target MVC. For more information, see https://go.microsoft.com/fwlink/?linkid=868374." />
799+
</Target>
800+
801+
<Target Name="_CheckForIncorrectComponentsConfiguration"
802+
Condition="('$(RazorCompileOnBuild)' == 'true' OR '$(RazorCompileOnPublish)' =='true') AND
803+
'@(RazorComponent->Count())' != '0' AND
804+
'$(_Targeting30OrNewerRazorLangVersion)' != 'true' AND
805+
'$(_IsTargetingRazor2X)' != 'true'">
806+
807+
<Warning
808+
Code="RAZORSDK1005"
809+
Text="One or more Razor component files (.razor) were found, but the project is not configured to compile Razor Components. Configure the project by targeting RazorLangVersion 3.0 or newer.
810+
For more information, see https://go.microsoft.com/fwlink/?linkid=868374." />
735811
</Target>
736812

737813
<Target Name="_ResolveRazorTargetPath">

0 commit comments

Comments
 (0)