diff --git a/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs
index adb2a92453..1f95e0176c 100644
--- a/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs
@@ -822,6 +822,20 @@ namespace Microsoft.AspNetCore.Razor.Language
internal static string FormatSectionDirective_NameToken_Name()
=> GetString("SectionDirective_NameToken_Name");
+ ///
+ /// The Razor language version '{0}' is unrecognized or not supported by this version of Razor.
+ ///
+ internal static string RazorLanguageVersion_InvalidVersion
+ {
+ get => GetString("RazorLanguageVersion_InvalidVersion");
+ }
+
+ ///
+ /// The Razor language version '{0}' is unrecognized or not supported by this version of Razor.
+ ///
+ 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 32420721ee..0f00751497 100644
--- a/src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs
+++ b/src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs
@@ -2,25 +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 DefaultRuntime = new RazorConfiguration(RazorLanguageVersion.Latest, designTime: false);
- public static readonly RazorConfiguration DefaultDesignTime = new RazorConfiguration(RazorLanguageVersion.Latest, designTime: true);
+ public static readonly RazorConfiguration Default = new RazorConfiguration(
+ RazorLanguageVersion.Latest,
+ "unnamed",
+ Array.Empty(),
+ 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(),
+ designTime: true);
+
+ public RazorConfiguration(
+ RazorLanguageVersion languageVersion,
+ string configurationName,
+ IEnumerable 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 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 0fe5e14d19..aa06b9f9ab 100644
--- a/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs
+++ b/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs
@@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Razor.Language
return Create(configure: null);
}
- public static RazorEngine Create(Action configure) => CreateCore(RazorConfiguration.DefaultRuntime, configure);
+ public static RazorEngine Create(Action configure) => CreateCore(RazorConfiguration.Default, configure);
public static RazorEngine CreateDesignTime()
{
diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorExtension.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorExtension.cs
new file mode 100644
index 0000000000..feb94b0ede
--- /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 721c84ff00..c200290878 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
+ [DebuggerDisplay("{" + nameof(DebuggerToString) + "(),nq}")]
+ public sealed class RazorLanguageVersion : IEquatable, IComparable
{
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 19b1d54e80..0629eb9af8 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 54df909c15..35b511066d 100644
--- a/src/Microsoft.AspNetCore.Razor.Language/Resources.resx
+++ b/src/Microsoft.AspNetCore.Razor.Language/Resources.resx
@@ -291,4 +291,7 @@
SectionName
+
+ The Razor language version '{0}' is unrecognized or not supported by this version of Razor.
+
\ 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 0000000000..034e64c309
--- /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
+{
+ ///
+ /// Specifies the name of a Razor configuration as defined by the Razor SDK.
+ ///
+ ///
+ /// 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.
+ ///
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
+ public sealed class RazorConfigurationNameAttribute : Attribute
+ {
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The name of the Razor configuration.
+ public RazorConfigurationNameAttribute(string configurationName)
+ {
+ if (configurationName == null)
+ {
+ throw new ArgumentNullException(nameof(configurationName));
+ }
+
+ ConfigurationName = configurationName;
+ }
+
+ ///
+ /// Gets the name of the Razor configuration.
+ ///
+ 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 0000000000..92a9d1c6ec
--- /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
+{
+ ///
+ /// Specifies the name of a Razor extension as defined by the Razor SDK.
+ ///
+ ///
+ /// 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.
+ ///
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
+ public sealed class RazorExtensionAssemblyNameAttribute : Attribute
+ {
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The name of the extension.
+ /// The assembly name of the extension.
+ 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;
+ }
+
+ ///
+ /// Gets the assembly name of the extension.
+ ///
+ public string AssemblyName { get; }
+
+ ///
+ /// Gets the name of the extension.
+ ///
+ 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 0000000000..8f261143d0
--- /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
+{
+ ///
+ /// Specifies the name of a Razor configuration as defined by the Razor SDK.
+ ///
+ ///
+ /// 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.
+ ///
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
+ public sealed class RazorLanguageVersionAttribute : Attribute
+ {
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The language version of Razor
+ public RazorLanguageVersionAttribute(string languageVersion)
+ {
+ if (languageVersion == null)
+ {
+ throw new ArgumentNullException(nameof(languageVersion));
+ }
+
+ LanguageVersion = languageVersion;
+ }
+
+ ///
+ /// Gets the Razor language version.
+ ///
+ public string LanguageVersion { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs b/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs
index a82d1b8e94..ab5518bb46 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(), designTime: true);
RazorEngine engine;
if (razorLanguageVersion.Major == 1)