| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954 |
- commit 5b28c06d6453696e98fb7bf32abe3aef09a5c26b
- Author: Ryan Nowak <[email protected]>
- Date: Fri Feb 2 17:41:14 2018 -0800
- Add prelimianry support for extensions to Razor (#2012)
-
- * Add prelimianry support for extensions to Razor
-
- This PR adds MSBuild insfrastructure to the SDK that can understand
- concepts we need to expose to the project, code generator and runtime
- like:
- - Language version
- - Configuration
- - Extensions (plugins)
-
- As an example of how this works, I've done the wireup for MVC. This will
- now generate assembly attributes in your application that can act as a
- source-of-truth for what should be included in runtime compilation, and
- it's all based on the project-file. This means that it can be delivered
- and configured by packages.
-
- The next step here is to implement a loader for RazorProjectEngine based
- on these primitives, and then use it in our CLI tools and MVC.
-
- The next step after that is to expose it in VS and VS4Mac through the
- project system.
- diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj
- index 37eafe0684a..401d07c0308 100644
- --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj
- +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Microsoft.AspNetCore.Mvc.Razor.Extensions.csproj
- @@ -12,6 +12,11 @@
- </Compile>
- </ItemGroup>
-
- + <ItemGroup>
- + <Content Include="build\**\*.props" PackagePath="build\" />
- + <Content Include="build\**\*.targets" PackagePath="build\" />
- + </ItemGroup>
- +
- <ItemGroup>
- <ProjectReference Include="../Microsoft.AspNetCore.Razor.Language/Microsoft.AspNetCore.Razor.Language.csproj" />
- <ProjectReference Include="../Microsoft.CodeAnalysis.Razor/Microsoft.CodeAnalysis.Razor.csproj" />
- diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.props b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.props
- new file mode 100644
- index 00000000000..8d2ac3b630a
- --- /dev/null
- +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.props
- @@ -0,0 +1,32 @@
- +<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>
- + </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>$(MSBuildThisFileDirectory)..\..\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll</AssemblyFilePath>
- + </RazorExtension>
- + </ItemGroup>
- +</Project>
- \ No newline at end of file
- diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.targets b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.targets
- new file mode 100644
- index 00000000000..61a0e7a8dc5
- --- /dev/null
- +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.targets
- @@ -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>
- \ No newline at end of file
- diff --git a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.props b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.props
- index 6549731539e..c25a2ab1748 100644
- --- a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.props
- +++ b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.props
- @@ -1,15 +1,29 @@
- <Project ToolsVersion="14.0" TreatAsLocalProperty="_RazorTaskFolder;_RazorTaskAssembly">
- <PropertyGroup>
- <!--
- - Used by the Web SDK if the Razor SDK can be used for compilation. This needs to live in a nuget package (not in the SDK)
- - so that it only shows up in supported versions.
- + Used by the Web SDK if the Razor SDK can be used for compilation. This needs to live in a nuget package (not in the SDK)
- + so that it only shows up in supported versions.
- -->
- <IsRazorCompilerReferenced>true</IsRazorCompilerReferenced>
-
- <!--
- - Location of the CodeGeneration targets. The SDK uses this to import the file ensuring deterministic import order.
- + Location of the CodeGeneration targets. The SDK uses this to import the file ensuring deterministic import order.
- -->
- <RazorCodeGenerationTargetsPath>$(MSBuildThisFileDirectory)Microsoft.AspNetCore.Razor.Design.CodeGeneration.targets</RazorCodeGenerationTargetsPath>
- +
- + <!--
- + Configures the language version of Razor. Supported and default values differ depending on the version of
- + the packages in use.
- +
- + Supported:
- + 2.0
- + 2.1
- + Latest = 2.1
- +
- + Default:
- + 2.1
- + -->
- + <RazorLangVersion Condition="'$(RazorLangVersion)'==''">2.1</RazorLangVersion>
- </PropertyGroup>
-
- <PropertyGroup>
- diff --git a/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs
- index 6193fcb066e..13c56c698e4 100644
- --- a/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs
- +++ b/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs
- @@ -1856,6 +1856,20 @@ namespace Microsoft.AspNetCore.Razor.Language
- internal static string FormatRazorProjectEngineMissingFeatureDependency(object p0, object p1)
- => string.Format(CultureInfo.CurrentCulture, GetString("RazorProjectEngineMissingFeatureDependency"), p0, p1);
-
- + /// <summary>
- + /// The Razor language version '{0}' is unrecognized or not supported by this version of Razor.
- + /// </summary>
- + internal static string RazorLanguageVersion_InvalidVersion
- + {
- + get => GetString("RazorLanguageVersion_InvalidVersion");
- + }
- +
- + /// <summary>
- + /// The Razor language version '{0}' is unrecognized or not supported by this version of Razor.
- + /// </summary>
- + internal static string FormatRazorLanguageVersion_InvalidVersion(object p0)
- + => string.Format(CultureInfo.CurrentCulture, GetString("RazorLanguageVersion_InvalidVersion"), p0);
- +
- private static string GetString(string name, params string[] formatterNames)
- {
- var value = _resourceManager.GetString(name);
- diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs
- index 103c3fbec51..0f00751497e 100644
- --- a/src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs
- +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs
- @@ -2,24 +2,58 @@
- // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
- using System;
- +using System.Collections.Generic;
- +using System.Linq;
-
- namespace Microsoft.AspNetCore.Razor.Language
- {
- public sealed class RazorConfiguration
- {
- - public static readonly RazorConfiguration Default = new RazorConfiguration(RazorLanguageVersion.Latest, designTime: false);
- + public static readonly RazorConfiguration Default = new RazorConfiguration(
- + RazorLanguageVersion.Latest,
- + "unnamed",
- + Array.Empty<RazorExtension>(),
- + designTime: false);
-
- - public RazorConfiguration(RazorLanguageVersion languageVersion, bool designTime)
- + // This is used only in some back-compat scenarios. We don't expose it because there's no
- + // use case for anyone else to use it.
- + internal static readonly RazorConfiguration DefaultDesignTime = new RazorConfiguration(
- + RazorLanguageVersion.Latest,
- + "unnamed",
- + Array.Empty<RazorExtension>(),
- + designTime: true);
- +
- + public RazorConfiguration(
- + RazorLanguageVersion languageVersion,
- + string configurationName,
- + IEnumerable<RazorExtension> extensions,
- + bool designTime)
- {
- if (languageVersion == null)
- {
- throw new ArgumentNullException(nameof(languageVersion));
- }
-
- + if (configurationName == null)
- + {
- + throw new ArgumentNullException(nameof(configurationName));
- + }
- +
- + if (extensions == null)
- + {
- + throw new ArgumentNullException(nameof(extensions));
- + }
- +
- LanguageVersion = languageVersion;
- + ConfigurationName = configurationName;
- + Extensions = extensions.ToArray();
- DesignTime = designTime;
- }
-
- + public string ConfigurationName { get; }
- +
- + public IReadOnlyList<RazorExtension> Extensions { get; }
- +
- public RazorLanguageVersion LanguageVersion { get; }
-
- public bool DesignTime { get; }
- diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs
- index 184afd70ace..a48c31893a0 100644
- --- a/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs
- +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs
- @@ -24,8 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Language
- return CreateDesignTime(configure: null);
- }
-
- - public static RazorEngine CreateDesignTime(Action<IRazorEngineBuilder> configure)
- - => CreateCore(new RazorConfiguration(RazorLanguageVersion.Latest, designTime: true), configure);
- + public static RazorEngine CreateDesignTime(Action<IRazorEngineBuilder> configure) => CreateCore(RazorConfiguration.DefaultDesignTime, configure);
-
- // Internal since RazorEngine APIs are going to be obsolete.
- internal static RazorEngine CreateCore(RazorConfiguration configuration, Action<IRazorEngineBuilder> configure)
- diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorExtension.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorExtension.cs
- new file mode 100644
- index 00000000000..feb94b0edef
- --- /dev/null
- +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorExtension.cs
- @@ -0,0 +1,10 @@
- +// Copyright(c) .NET Foundation.All rights reserved.
- +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
- +
- +namespace Microsoft.AspNetCore.Razor.Language
- +{
- + public abstract class RazorExtension
- + {
- + public abstract string ExtensionName { get; }
- + }
- +}
- diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorLanguageVersion.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorLanguageVersion.cs
- index 721c84ff00e..c2002908782 100644
- --- a/src/Microsoft.AspNetCore.Razor.Language/RazorLanguageVersion.cs
- +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorLanguageVersion.cs
- @@ -2,10 +2,12 @@
- // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
- using System;
- +using System.Diagnostics;
-
- namespace Microsoft.AspNetCore.Razor.Language
- {
- - public sealed class RazorLanguageVersion : IEquatable<RazorLanguageVersion>
- + [DebuggerDisplay("{" + nameof(DebuggerToString) + "(),nq}")]
- + public sealed class RazorLanguageVersion : IEquatable<RazorLanguageVersion>, IComparable<RazorLanguageVersion>
- {
- public static readonly RazorLanguageVersion Version_1_0 = new RazorLanguageVersion(1, 0);
-
- @@ -17,6 +19,60 @@ namespace Microsoft.AspNetCore.Razor.Language
-
- public static readonly RazorLanguageVersion Latest = Version_2_1;
-
- + public static bool TryParse(string languageVersion, out RazorLanguageVersion version)
- + {
- + if (languageVersion == null)
- + {
- + throw new ArgumentNullException(nameof(languageVersion));
- + }
- +
- + if (string.Equals(languageVersion, "latest", StringComparison.OrdinalIgnoreCase))
- + {
- + version = Version_2_1;
- + return true;
- + }
- + else if (languageVersion == "2.1")
- + {
- + version = Version_2_1;
- + return true;
- + }
- + else if (languageVersion == "2.0")
- + {
- + version = Version_2_0;
- + return true;
- + }
- + else if (languageVersion == "1.1")
- + {
- + version = Version_1_1;
- + return true;
- + }
- + else if (languageVersion == "1.0")
- + {
- + version = Version_1_0;
- + return true;
- + }
- +
- + version = null;
- + return false;
- + }
- +
- + public static RazorLanguageVersion Parse(string languageVersion)
- + {
- + if (languageVersion == null)
- + {
- + throw new ArgumentNullException(nameof(languageVersion));
- + }
- +
- + if (TryParse(languageVersion, out var parsed))
- + {
- + return parsed;
- + }
- +
- + throw new ArgumentException(
- + Resources.FormatRazorLanguageVersion_InvalidVersion(languageVersion),
- + nameof(languageVersion));
- + }
- +
- // Don't want anyone else constructing language versions.
- private RazorLanguageVersion(int major, int minor)
- {
- @@ -28,6 +84,22 @@ namespace Microsoft.AspNetCore.Razor.Language
-
- public int Minor { get; }
-
- + public int CompareTo(RazorLanguageVersion other)
- + {
- + if (other == null)
- + {
- + throw new ArgumentNullException(nameof(other));
- + }
- +
- + var result = Major.CompareTo(other.Major);
- + if (result != 0)
- + {
- + return result;
- + }
- +
- + return Minor.CompareTo(other.Minor);
- + }
- +
- public bool Equals(RazorLanguageVersion other)
- {
- if (other == null)
- @@ -44,7 +116,9 @@ namespace Microsoft.AspNetCore.Razor.Language
- // We don't need to do anything special for our hash code since reference equality is what we're going for.
- return base.GetHashCode();
- }
- +
- + public override string ToString() => $"{Major}.{Minor}";
-
- - public override string ToString() => $"Razor '{Major}.{Minor}'";
- + private string DebuggerToString() => $"Razor '{Major}.{Minor}'";
- }
- }
- diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorParserFeatureFlags.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorParserFeatureFlags.cs
- index 19b1d54e80b..0629eb9af86 100644
- --- a/src/Microsoft.AspNetCore.Razor.Language/RazorParserFeatureFlags.cs
- +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorParserFeatureFlags.cs
- @@ -9,8 +9,9 @@ namespace Microsoft.AspNetCore.Razor.Language
- {
- var allowMinimizedBooleanTagHelperAttributes = false;
-
- - if (version == RazorLanguageVersion.Version_2_1)
- + if (version.CompareTo(RazorLanguageVersion.Version_2_1) >= 0)
- {
- + // Added in 2.1
- allowMinimizedBooleanTagHelperAttributes = true;
- }
-
- diff --git a/src/Microsoft.AspNetCore.Razor.Language/Resources.resx b/src/Microsoft.AspNetCore.Razor.Language/Resources.resx
- index d2810420469..6413f1038b9 100644
- --- a/src/Microsoft.AspNetCore.Razor.Language/Resources.resx
- +++ b/src/Microsoft.AspNetCore.Razor.Language/Resources.resx
- @@ -533,4 +533,7 @@ Instead, wrap the contents of the block in "{{}}":
- <data name="RazorProjectEngineMissingFeatureDependency" xml:space="preserve">
- <value>The '{0}' is missing feature '{1}'.</value>
- </data>
- + <data name="RazorLanguageVersion_InvalidVersion" xml:space="preserve">
- + <value>The Razor language version '{0}' is unrecognized or not supported by this version of Razor.</value>
- + </data>
- </root>
- \ No newline at end of file
- diff --git a/src/Microsoft.AspNetCore.Razor.Runtime/Hosting/RazorConfigurationNameAttribute.cs b/src/Microsoft.AspNetCore.Razor.Runtime/Hosting/RazorConfigurationNameAttribute.cs
- new file mode 100644
- index 00000000000..034e64c3093
- --- /dev/null
- +++ b/src/Microsoft.AspNetCore.Razor.Runtime/Hosting/RazorConfigurationNameAttribute.cs
- @@ -0,0 +1,38 @@
- +// Copyright (c) .NET Foundation. All rights reserved.
- +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
- +
- +using System;
- +
- +namespace Microsoft.AspNetCore.Razor.Hosting
- +{
- + /// <summary>
- + /// Specifies the name of a Razor configuration as defined by the Razor SDK.
- + /// </summary>
- + /// <remarks>
- + /// This attribute is applied to an application's entry point assembly by the Razor SDK during the build,
- + /// so that the Razor configuration can be loaded at runtime based on the settings provided by the project
- + /// file.
- + /// </remarks>
- + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
- + public sealed class RazorConfigurationNameAttribute : Attribute
- + {
- + /// <summary>
- + /// Creates a new instance of <see cref="RazorConfigurationNameAttribute"/>.
- + /// </summary>
- + /// <param name="configurationName">The name of the Razor configuration.</param>
- + public RazorConfigurationNameAttribute(string configurationName)
- + {
- + if (configurationName == null)
- + {
- + throw new ArgumentNullException(nameof(configurationName));
- + }
- +
- + ConfigurationName = configurationName;
- + }
- +
- + /// <summary>
- + /// Gets the name of the Razor configuration.
- + /// </summary>
- + public string ConfigurationName { get; }
- + }
- +}
- \ No newline at end of file
- diff --git a/src/Microsoft.AspNetCore.Razor.Runtime/Hosting/RazorExtensionAssemblyNameAttribute.cs b/src/Microsoft.AspNetCore.Razor.Runtime/Hosting/RazorExtensionAssemblyNameAttribute.cs
- new file mode 100644
- index 00000000000..92a9d1c6ec7
- --- /dev/null
- +++ b/src/Microsoft.AspNetCore.Razor.Runtime/Hosting/RazorExtensionAssemblyNameAttribute.cs
- @@ -0,0 +1,50 @@
- +// Copyright (c) .NET Foundation. All rights reserved.
- +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
- +
- +using System;
- +
- +namespace Microsoft.AspNetCore.Razor.Hosting
- +{
- + /// <summary>
- + /// Specifies the name of a Razor extension as defined by the Razor SDK.
- + /// </summary>
- + /// <remarks>
- + /// This attribute is applied to an application's entry point assembly by the Razor SDK during the build,
- + /// so that the Razor configuration can be loaded at runtime based on the settings provided by the project
- + /// file.
- + /// </remarks>
- + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
- + public sealed class RazorExtensionAssemblyNameAttribute : Attribute
- + {
- + /// <summary>
- + /// Creates a new instance of <see cref="RazorExtensionAssemblyNameAttribute"/>.
- + /// </summary>
- + /// <param name="extensionName">The name of the extension.</param>
- + /// <param name="assemblyName">The assembly name of the extension.</param>
- + public RazorExtensionAssemblyNameAttribute(string extensionName, string assemblyName)
- + {
- + if (extensionName == null)
- + {
- + throw new ArgumentNullException(nameof(extensionName));
- + }
- +
- + if (assemblyName == null)
- + {
- + throw new ArgumentNullException(nameof(assemblyName));
- + }
- +
- + ExtensionName = extensionName;
- + AssemblyName = assemblyName;
- + }
- +
- + /// <summary>
- + /// Gets the assembly name of the extension.
- + /// </summary>
- + public string AssemblyName { get; }
- +
- + /// <summary>
- + /// Gets the name of the extension.
- + /// </summary>
- + public string ExtensionName { get; }
- + }
- +}
- \ No newline at end of file
- diff --git a/src/Microsoft.AspNetCore.Razor.Runtime/Hosting/RazorLanguageVersionAttribute.cs b/src/Microsoft.AspNetCore.Razor.Runtime/Hosting/RazorLanguageVersionAttribute.cs
- new file mode 100644
- index 00000000000..8f261143d04
- --- /dev/null
- +++ b/src/Microsoft.AspNetCore.Razor.Runtime/Hosting/RazorLanguageVersionAttribute.cs
- @@ -0,0 +1,38 @@
- +// Copyright (c) .NET Foundation. All rights reserved.
- +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
- +
- +using System;
- +
- +namespace Microsoft.AspNetCore.Razor.Hosting
- +{
- + /// <summary>
- + /// Specifies the name of a Razor configuration as defined by the Razor SDK.
- + /// </summary>
- + /// <remarks>
- + /// This attribute is part of a set of metadata attributes that can be applied to an assembly at build
- + /// time by the Razor SDK. These attributes allow the Razor configuration to be loaded at runtime based
- + /// on the settings originally provided by the project file.
- + /// </remarks>
- + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
- + public sealed class RazorLanguageVersionAttribute : Attribute
- + {
- + /// <summary>
- + /// Creates a new instance of <see cref="RazorLanguageVersionAttribute"/>.
- + /// </summary>
- + /// <param name="languageVersion">The language version of Razor</param>
- + public RazorLanguageVersionAttribute(string languageVersion)
- + {
- + if (languageVersion == null)
- + {
- + throw new ArgumentNullException(nameof(languageVersion));
- + }
- +
- + LanguageVersion = languageVersion;
- + }
- +
- + /// <summary>
- + /// Gets the Razor language version.
- + /// </summary>
- + public string LanguageVersion { get; }
- + }
- +}
- \ No newline at end of file
- diff --git a/src/Microsoft.NET.Sdk.Razor/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets b/src/Microsoft.NET.Sdk.Razor/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets
- index a081f46aaf8..99109a78d4f 100644
- --- a/src/Microsoft.NET.Sdk.Razor/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets
- +++ b/src/Microsoft.NET.Sdk.Razor/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets
- @@ -161,6 +161,46 @@ Copyright (c) .NET Foundation. All rights reserved.
- <Target Name="RazorCompile" DependsOnTargets="$(RazorCompileDependsOn)">
- </Target>
-
- + <!--
- + Generates assembly attributes in support for Razor runtime code generation. This is a set of standard
- + metadata attributes (defined in Microsoft.AspNetCore.Razor.Runtime) that capture the build-time
- + Razor configuration of an application to be used at runtime.
- +
- + This allows the project file to act as the source of truth for the applicable Razor configuration regardless
- + of how Razor is used.
- +
- + The SDK expects configurations that use runtime compilation to set $(GenerateRazorAssemblyInfo) to true,
- + it will be unset by default.
- + -->
- + <Target
- + Name="RazorGetAssemblyAttributes"
- + AfterTargets="GetAssemblyAttributes"
- + Condition="'$(GenerateRazorAssemblyInfo)'=='true' and '$(RazorDefaultConfiguration)'!=''">
- +
- + <ItemGroup>
- + <_ResolvedRazorConfiguration Include="@(RazorConfiguration)" Condition="'%(RazorConfiguration.Identity)'=='$(RazorDefaultConfiguration)'" />
- + <_ResolvedRazorExtensionName Include="%(_ResolvedRazorConfiguration.Extensions)"/>
- + </ItemGroup>
- +
- + <FindInList List="@(RazorExtension)" ItemSpecToFind="%(_ResolvedRazorExtensionName.Identity)">
- + <Output TaskParameter="ItemFound" ItemName="_ResolvedRazorExtension" />
- + </FindInList>
- +
- + <ItemGroup>
- + <AssemblyAttribute Include="Microsoft.AspNetCore.Razor.Hosting.RazorLanguageVersionAttribute">
- + <_Parameter1>$(RazorLangVersion)</_Parameter1>
- + </AssemblyAttribute>
- + <AssemblyAttribute Include="Microsoft.AspNetCore.Razor.Hosting.RazorConfigurationNameAttribute">
- + <_Parameter1>$(RazorDefaultConfiguration)</_Parameter1>
- + </AssemblyAttribute>
- + <AssemblyAttribute Include="Microsoft.AspNetCore.Razor.Hosting.RazorExtensionAssemblyNameAttribute" Condition="'%(_ResolvedRazorExtension.AssemblyName)'!=''">
- + <_Parameter1>%(_ResolvedRazorExtension.Identity)</_Parameter1>
- + <_Parameter2>%(_ResolvedRazorExtension.AssemblyName)</_Parameter2>
- + </AssemblyAttribute>
- + </ItemGroup>
- +
- + </Target>
- +
- <!--
- Gathers input source files for code generation. This is a separate target so that we can avoid
- lots of work when there are no inputs for code generation.
- diff --git a/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs b/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs
- index a82d1b8e94c..ab5518bb463 100644
- --- a/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs
- +++ b/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs
- @@ -43,7 +43,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
- var project = FindProject(projectPath);
- var configuration = (project?.Configuration as MvcExtensibilityConfiguration) ?? DefaultConfiguration;
- var razorLanguageVersion = configuration.LanguageVersion;
- - var razorConfiguration = new RazorConfiguration(razorLanguageVersion, designTime: true);
- + var razorConfiguration = new RazorConfiguration(razorLanguageVersion, "unnamed", Array.Empty<RazorExtension>(), designTime: true);
-
- RazorEngine engine;
- if (razorLanguageVersion.Major == 1)
- diff --git a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/Assert.cs b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/Assert.cs
- index 35cb880c1af..1cf20d0e817 100644
- --- a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/Assert.cs
- +++ b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/Assert.cs
- @@ -100,6 +100,50 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
- throw new BuildOutputMissingException(result, match);
- }
-
- + public static void FileContainsLine(MSBuildResult result, string filePath, string match)
- + {
- + if (result == null)
- + {
- + throw new ArgumentNullException(nameof(result));
- + }
- +
- + filePath = Path.Combine(result.Project.DirectoryPath, filePath);
- + FileExists(result, filePath);
- +
- + var lines = File.ReadAllLines(filePath);
- + for (var i = 0; i < lines.Length; i++)
- + {
- + var line = lines[i].Trim();
- + if (line == match)
- + {
- + return;
- + }
- + }
- +
- + throw new FileContentMissingException(result, filePath, File.ReadAllText(filePath), match);
- + }
- +
- + public static void FileDoesNotContainLine(MSBuildResult result, string filePath, string match)
- + {
- + if (result == null)
- + {
- + throw new ArgumentNullException(nameof(result));
- + }
- +
- + filePath = Path.Combine(result.Project.DirectoryPath, filePath);
- + FileExists(result, filePath);
- +
- + var lines = File.ReadAllLines(filePath);
- + for (var i = 0; i < lines.Length; i++)
- + {
- + var line = lines[i].Trim();
- + if (line == match)
- + {
- + throw new FileContentFoundException(result, filePath, File.ReadAllText(filePath), match);
- + }
- + }
- + }
- +
- public static void FileExists(MSBuildResult result, params string[] paths)
- {
- if (result == null)
- @@ -304,6 +348,66 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
- protected override string Heading => $"Build did not contain the line: '{Match}'.";
- }
-
- + private class FileContentFoundException : MSBuildXunitException
- + {
- + public FileContentFoundException(MSBuildResult result, string filePath, string content, string match)
- + : base(result)
- + {
- + FilePath = filePath;
- + Content = content;
- + Match = match;
- + }
- +
- + public string Content { get; }
- +
- + public string FilePath { get; }
- +
- + public string Match { get; }
- +
- + protected override string Heading
- + {
- + get
- + {
- + var builder = new StringBuilder();
- + builder.AppendFormat("File content of '{0}' should not contain line: '{1}'.", FilePath, Match);
- + builder.AppendLine();
- + builder.AppendLine();
- + builder.AppendLine(Content);
- + return builder.ToString();
- + }
- + }
- + }
- +
- + private class FileContentMissingException : MSBuildXunitException
- + {
- + public FileContentMissingException(MSBuildResult result, string filePath, string content, string match)
- + : base(result)
- + {
- + FilePath = filePath;
- + Content = content;
- + Match = match;
- + }
- +
- + public string Content { get; }
- +
- + public string FilePath { get; }
- +
- + public string Match { get; }
- +
- + protected override string Heading
- + {
- + get
- + {
- + var builder = new StringBuilder();
- + builder.AppendFormat("File content of '{0}' did not contain the line: '{1}'.", FilePath, Match);
- + builder.AppendLine();
- + builder.AppendLine();
- + builder.AppendLine(Content);
- + return builder.ToString();
- + }
- + }
- + }
- +
- private class FileMissingException : MSBuildXunitException
- {
- public FileMissingException(MSBuildResult result, string filePath)
- diff --git a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/ConfigurationMetadataIntegrationTest.cs b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/ConfigurationMetadataIntegrationTest.cs
- new file mode 100644
- index 00000000000..f527157a89a
- --- /dev/null
- +++ b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/ConfigurationMetadataIntegrationTest.cs
- @@ -0,0 +1,90 @@
- +// Copyright (c) .NET Foundation. All rights reserved.
- +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
- +
- +using System.IO;
- +using System.Threading.Tasks;
- +using Xunit;
- +
- +namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
- +{
- + public class ConfigurationMetadataIntegrationTest : MSBuildIntegrationTestBase
- + {
- + [Fact]
- + [InitializeTestProject("SimpleMvc")]
- + public async Task Build_WithMvc_AddsConfigurationMetadata()
- + {
- + var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true");
- +
- + Assert.BuildPassed(result);
- +
- + Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.PrecompiledViews.dll");
- + Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.PrecompiledViews.pdb");
- +
- + Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.AssemblyInfo.cs");
- + Assert.FileContainsLine(
- + result,
- + Path.Combine(IntermediateOutputPath, "SimpleMvc.AssemblyInfo.cs"),
- + "[assembly: Microsoft.AspNetCore.Razor.Hosting.RazorLanguageVersionAttribute(\"2.1\")]");
- + Assert.FileContainsLine(
- + result,
- + Path.Combine(IntermediateOutputPath, "SimpleMvc.AssemblyInfo.cs"),
- + "[assembly: Microsoft.AspNetCore.Razor.Hosting.RazorConfigurationNameAttribute(\"MVC-2.1\")]");
- + Assert.FileContainsLine(
- + result,
- + Path.Combine(IntermediateOutputPath, "SimpleMvc.AssemblyInfo.cs"),
- + "[assembly: Microsoft.AspNetCore.Razor.Hosting.RazorExtensionAssemblyNameAttribute(\"MVC-2.1\", \"Microsoft.AspNetCore.Mvc.Razor.Extensions\")]");
- + }
- +
- + [Fact]
- + [InitializeTestProject("SimpleMvc")]
- + public async Task Build_WithGenerateRazorAssemblyInfo_False_SuppressesConfigurationMetadata()
- + {
- + var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true /p:GenerateRazorAssemblyInfo=false");
- +
- + Assert.BuildPassed(result);
- +
- + Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.PrecompiledViews.dll");
- + Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.PrecompiledViews.pdb");
- +
- + Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.AssemblyInfo.cs");
- + Assert.FileDoesNotContainLine(
- + result,
- + Path.Combine(IntermediateOutputPath, "SimpleMvc.AssemblyInfo.cs"),
- + "[assembly: Microsoft.AspNetCore.Razor.Hosting.RazorLanguageVersionAttribute(\"2.1\")]");
- + Assert.FileDoesNotContainLine(
- + result,
- + Path.Combine(IntermediateOutputPath, "SimpleMvc.AssemblyInfo.cs"),
- + "[assembly: Microsoft.AspNetCore.Razor.Hosting.RazorConfigurationNameAttribute(\"MVC-2.1\")]");
- + Assert.FileDoesNotContainLine(
- + result,
- + Path.Combine(IntermediateOutputPath, "SimpleMvc.AssemblyInfo.cs"),
- + "[assembly: Microsoft.AspNetCore.Razor.Hosting.RazorExtensionAssemblyNameAttribute(\"MVC-2.1\", \"Microsoft.AspNetCore.Razor.Extensions\")]");
- + }
- +
- + [Fact]
- + [InitializeTestProject("ClassLibrary")]
- + public async Task Build_ForClassLibrary_SuppressesConfigurationMetadata()
- + {
- + var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true");
- +
- + Assert.BuildPassed(result);
- +
- + Assert.FileExists(result, IntermediateOutputPath, "ClassLibrary.PrecompiledViews.dll");
- + Assert.FileExists(result, IntermediateOutputPath, "ClassLibrary.PrecompiledViews.pdb");
- +
- + Assert.FileExists(result, IntermediateOutputPath, "ClassLibrary.AssemblyInfo.cs");
- + Assert.FileDoesNotContainLine(
- + result,
- + Path.Combine(IntermediateOutputPath, "ClassLibrary.AssemblyInfo.cs"),
- + "[assembly: Microsoft.AspNetCore.Razor.Hosting.RazorLanguageVersionAttribute(\"2.1\")]");
- + Assert.FileDoesNotContainLine(
- + result,
- + Path.Combine(IntermediateOutputPath, "ClassLibrary.AssemblyInfo.cs"),
- + "[assembly: Microsoft.AspNetCore.Razor.Hosting.RazorConfigurationNameAttribute(\"MVC-2.1\")]");
- + Assert.FileDoesNotContainLine(
- + result,
- + Path.Combine(IntermediateOutputPath, "ClassLibrary.AssemblyInfo.cs"),
- + "[assembly: Microsoft.AspNetCore.Razor.Hosting.RazorExtensionAssemblyNameAttribute(\"MVC-2.1\", \"Microsoft.AspNetCore.Razor.Extensions\")]");
- + }
- + }
- +}
- diff --git a/test/testapps/AppWithP2PReference/AppWithP2PReference.csproj b/test/testapps/AppWithP2PReference/AppWithP2PReference.csproj
- index ac5bb850141..2dc2432d05c 100644
- --- a/test/testapps/AppWithP2PReference/AppWithP2PReference.csproj
- +++ b/test/testapps/AppWithP2PReference/AppWithP2PReference.csproj
- @@ -1,10 +1,13 @@
- -<Project Sdk="Microsoft.NET.Sdk.Web">
- +<Project>
- +
- + <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk.Web" />
- +
- <PropertyGroup>
- <_RazorMSBuildRoot>$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\bin\$(Configuration)\netstandard2.0\</_RazorMSBuildRoot>
- </PropertyGroup>
- -
- <Import Project="$(SolutionRoot)src\Microsoft.NET.Sdk.Razor\SDK\Sdk.props" />
- <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props" />
- + <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.props" />
-
- <PropertyGroup>
- <TargetFramework>netcoreapp2.0</TargetFramework>
- @@ -18,4 +21,9 @@
- <ItemGroup>
- <ProjectReference Include="..\ClassLibrary\ClassLibrary.csproj"/>
- </ItemGroup>
- +
- + <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.targets" />
- +
- + <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk.Web" />
- + <Import Project="$(SolutionRoot)src\Microsoft.NET.Sdk.Razor\SDK\Sdk.targets" />
- </Project>
- diff --git a/test/testapps/ClassLibrary/ClassLibrary.csproj b/test/testapps/ClassLibrary/ClassLibrary.csproj
- index 86cb453382a..f4e970b76f5 100644
- --- a/test/testapps/ClassLibrary/ClassLibrary.csproj
- +++ b/test/testapps/ClassLibrary/ClassLibrary.csproj
- @@ -1,10 +1,14 @@
- -<Project Sdk="Microsoft.NET.Sdk">
- +<Project>
- +
- + <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
- +
- <PropertyGroup>
- <_RazorMSBuildRoot>$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\bin\$(Configuration)\netstandard2.0\</_RazorMSBuildRoot>
- </PropertyGroup>
-
- <Import Project="$(SolutionRoot)src\Microsoft.NET.Sdk.Razor\SDK\Sdk.props" />
- <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props" />
- + <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.props" />
-
- <PropertyGroup>
- <TargetFramework>netcoreapp2.0</TargetFramework>
- @@ -20,4 +24,10 @@
- <Pack>false</Pack>
- </Content>
- </ItemGroup>
- +
- + <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.targets" />
- +
- + <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
- + <Import Project="$(SolutionRoot)src\Microsoft.NET.Sdk.Razor\SDK\Sdk.targets" />
- +
- </Project>
- diff --git a/test/testapps/Directory.Build.targets b/test/testapps/Directory.Build.targets
- index 4f2e91835cc..8c119d5413b 100644
- --- a/test/testapps/Directory.Build.targets
- +++ b/test/testapps/Directory.Build.targets
- @@ -1,3 +1,2 @@
- <Project>
- - <Import Project="$(SolutionRoot)src\Microsoft.NET.Sdk.Razor\SDK\Sdk.targets" />
- </Project>
- diff --git a/test/testapps/SimpleMvc/SimpleMvc.csproj b/test/testapps/SimpleMvc/SimpleMvc.csproj
- index 4525726119d..d2f6e05d851 100644
- --- a/test/testapps/SimpleMvc/SimpleMvc.csproj
- +++ b/test/testapps/SimpleMvc/SimpleMvc.csproj
- @@ -1,10 +1,14 @@
- -<Project Sdk="Microsoft.NET.Sdk.Web">
- +<Project>
- +
- + <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk.Web" />
- +
- <PropertyGroup>
- <_RazorMSBuildRoot>$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\bin\$(Configuration)\netstandard2.0\</_RazorMSBuildRoot>
- </PropertyGroup>
-
- <Import Project="$(SolutionRoot)src\Microsoft.NET.Sdk.Razor\SDK\Sdk.props" />
- <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props" />
- + <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.props" />
-
- <PropertyGroup>
- <TargetFramework>netcoreapp2.0</TargetFramework>
- @@ -15,4 +19,9 @@
-
- <!-- Test Placeholder -->
-
- + <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.targets" />
- +
- + <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk.Web" />
- + <Import Project="$(SolutionRoot)src\Microsoft.NET.Sdk.Razor\SDK\Sdk.targets" />
- +
- </Project>
- diff --git a/test/testapps/SimplePages/SimplePages.csproj b/test/testapps/SimplePages/SimplePages.csproj
- index 4525726119d..12865d018c4 100644
- --- a/test/testapps/SimplePages/SimplePages.csproj
- +++ b/test/testapps/SimplePages/SimplePages.csproj
- @@ -1,10 +1,14 @@
- -<Project Sdk="Microsoft.NET.Sdk.Web">
- +<Project>
- +
- + <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk.Web" />
- +
- <PropertyGroup>
- <_RazorMSBuildRoot>$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\bin\$(Configuration)\netstandard2.0\</_RazorMSBuildRoot>
- </PropertyGroup>
-
- <Import Project="$(SolutionRoot)src\Microsoft.NET.Sdk.Razor\SDK\Sdk.props" />
- <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props" />
- + <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.props" />
-
- <PropertyGroup>
- <TargetFramework>netcoreapp2.0</TargetFramework>
- @@ -15,4 +19,9 @@
-
- <!-- Test Placeholder -->
-
- + <Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.targets" />
- +
- + <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk.Web" />
- + <Import Project="$(SolutionRoot)src\Microsoft.NET.Sdk.Razor\SDK\Sdk.targets" />
- +
- </Project>
|