From a01fa1c5b651e554d92629ffadad64d0fe158fb5 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Tue, 23 Jan 2018 16:39:42 -0800 Subject: [PATCH] Flow RazorLanguageVersion to RazorEngine. - Restructured RazorLanguageVersion to be a sealed concrete type to enable things like `RazorLanguageVersion.Latest`; it also allows us to make broader changes in the future. Also, in the future if we want to add support for overriding operators to enable greater than comparisons we can as well. - Removed version validity checks because we restrict who can construct a `RazorLanguageVersion` now. This way we don't have to check for valid versions all throughout our code. - Added a simple `ProjectExtensibilityConfiguration` => `RazorLanguageVersion` method in the `DefaultProjectExtensibilityConfigurationFactory` to temporarily enable letting the system operate on the `RazorLanguageVersion`. Eventually that entire class will change. #1961 --- .../Properties/Resources.Designer.cs | 14 ----- .../RazorConfiguration.cs | 28 ++++++++++ .../RazorEngine.cs | 41 +++++++++------ .../RazorLanguageVersion.cs | 49 +++++++++++------ .../RazorParserFeatureFlags.cs | 9 +--- .../RazorParserOptions.cs | 10 ++-- .../Resources.resx | 3 -- ...rojectExtensibilityConfigurationFactory.cs | 41 +++++++++++++++ .../MvcExtensibilityConfiguration.cs | 22 +++++--- .../ProjectExtensibilityConfiguration.cs | 3 ++ .../DefaultTemplateEngineFactoryService.cs | 9 ++-- .../DefaultRazorParsingPhaseTest.cs | 6 +-- .../RazorParserFeatureFlagsTest.cs | 14 +---- ...ctExtensibilityConfigurationFactoryTest.cs | 52 +++++++++++++++++++ ...DefaultTemplateEngineFactoryServiceTest.cs | 4 ++ 15 files changed, 218 insertions(+), 87 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs diff --git a/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs index 59b579dc00..adb2a92453 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs @@ -682,20 +682,6 @@ namespace Microsoft.AspNetCore.Razor.Language internal static string FormatTagHelperPrefixDirective_Description() => GetString("TagHelperPrefixDirective_Description"); - /// - /// Provided value for razor language version is unsupported or invalid: '{0}'. - /// - internal static string InvalidRazorLanguageVersion - { - get => GetString("InvalidRazorLanguageVersion"); - } - - /// - /// Provided value for razor language version is unsupported or invalid: '{0}'. - /// - internal static string FormatInvalidRazorLanguageVersion(object p0) - => string.Format(CultureInfo.CurrentCulture, GetString("InvalidRazorLanguageVersion"), p0); - /// /// Add tag helpers from the specified type name and assembly name. Specify '*' for the type name to include all tag helper types from the specified assembly. /// diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs new file mode 100644 index 0000000000..32420721ee --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorConfiguration.cs @@ -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; + +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 RazorConfiguration(RazorLanguageVersion languageVersion, bool designTime) + { + if (languageVersion == null) + { + throw new ArgumentNullException(nameof(languageVersion)); + } + + LanguageVersion = languageVersion; + DesignTime = designTime; + } + + 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 2d506da665..0fe5e14d19 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs @@ -15,26 +15,35 @@ namespace Microsoft.AspNetCore.Razor.Language return Create(configure: null); } - public static RazorEngine Create(Action configure) - { - var builder = new DefaultRazorEngineBuilder(designTime: false); - AddDefaults(builder); - AddRuntimeDefaults(builder); - configure?.Invoke(builder); - return builder.Build(); - } - + public static RazorEngine Create(Action configure) => CreateCore(RazorConfiguration.DefaultRuntime, configure); public static RazorEngine CreateDesignTime() { return CreateDesignTime(configure: null); } - public static RazorEngine CreateDesignTime(Action configure) + public static RazorEngine CreateDesignTime(Action configure) => CreateCore(RazorConfiguration.DefaultDesignTime, configure); + + // Internal since RazorEngine APIs are going to be obsolete. + internal static RazorEngine CreateCore(RazorConfiguration configuration, Action configure) { - var builder = new DefaultRazorEngineBuilder(designTime: true); + if (configuration == null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + var builder = new DefaultRazorEngineBuilder(configuration.DesignTime); AddDefaults(builder); - AddDesignTimeDefaults(builder); + + if (configuration.DesignTime) + { + AddDesignTimeDefaults(configuration, builder); + } + else + { + AddRuntimeDefaults(configuration, builder); + } + configure?.Invoke(builder); return builder.Build(); } @@ -99,10 +108,10 @@ namespace Microsoft.AspNetCore.Razor.Language builder.Features.Add(configurationFeature); } - internal static void AddRuntimeDefaults(IRazorEngineBuilder builder) + internal static void AddRuntimeDefaults(RazorConfiguration configuration, IRazorEngineBuilder builder) { // Configure options - builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorParserOptions.LatestRazorLanguageVersion)); + builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: configuration.LanguageVersion)); builder.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); // Intermediate Node Passes @@ -113,10 +122,10 @@ namespace Microsoft.AspNetCore.Razor.Language builder.AddTargetExtension(new PreallocatedAttributeTargetExtension()); } - internal static void AddDesignTimeDefaults(IRazorEngineBuilder builder) + internal static void AddDesignTimeDefaults(RazorConfiguration configuration, IRazorEngineBuilder builder) { // Configure options - builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: true, version: RazorParserOptions.LatestRazorLanguageVersion)); + builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: true, version: configuration.LanguageVersion)); builder.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: true)); builder.Features.Add(new SuppressChecksumOptionsFeature()); diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorLanguageVersion.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorLanguageVersion.cs index 122118d2cb..721c84ff00 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorLanguageVersion.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorLanguageVersion.cs @@ -1,33 +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.Language { - public enum RazorLanguageVersion + public sealed class RazorLanguageVersion : IEquatable { - Version1_0 = 1, + public static readonly RazorLanguageVersion Version_1_0 = new RazorLanguageVersion(1, 0); - Version1_1 = 2, + public static readonly RazorLanguageVersion Version_1_1 = new RazorLanguageVersion(1, 1); - Version2_0 = 3, + public static readonly RazorLanguageVersion Version_2_0 = new RazorLanguageVersion(2, 0); - Version2_1 = 4, - } + public static readonly RazorLanguageVersion Version_2_1 = new RazorLanguageVersion(2, 1); - internal static class RazorLanguageVersionExtensions - { - internal static bool IsValid(this RazorLanguageVersion version) + public static readonly RazorLanguageVersion Latest = Version_2_1; + + // Don't want anyone else constructing language versions. + private RazorLanguageVersion(int major, int minor) { - switch (version) + Major = major; + Minor = minor; + } + + public int Major { get; } + + public int Minor { get; } + + public bool Equals(RazorLanguageVersion other) + { + if (other == null) { - case RazorLanguageVersion.Version1_0: - case RazorLanguageVersion.Version1_1: - case RazorLanguageVersion.Version2_0: - case RazorLanguageVersion.Version2_1: - return true; + return false; } - return false; + // We're the only one who can create RazorLanguageVersions so reference equality is sufficient. + return ReferenceEquals(this, other); } + + public override int GetHashCode() + { + // 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() => $"Razor '{Major}.{Minor}'"; } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorParserFeatureFlags.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorParserFeatureFlags.cs index fed78efb43..19b1d54e80 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorParserFeatureFlags.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorParserFeatureFlags.cs @@ -1,22 +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 System; - namespace Microsoft.AspNetCore.Razor.Language { internal abstract class RazorParserFeatureFlags { public static RazorParserFeatureFlags Create(RazorLanguageVersion version) { - if (!version.IsValid()) - { - throw new ArgumentException(Resources.FormatInvalidRazorLanguageVersion(version.ToString())); - } - var allowMinimizedBooleanTagHelperAttributes = false; - if (version == RazorLanguageVersion.Version2_1) + if (version == RazorLanguageVersion.Version_2_1) { allowMinimizedBooleanTagHelperAttributes = true; } diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorParserOptions.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorParserOptions.cs index 47f91c0343..3438cdfbe3 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorParserOptions.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorParserOptions.cs @@ -8,15 +8,13 @@ namespace Microsoft.AspNetCore.Razor.Language { public abstract class RazorParserOptions { - internal static readonly RazorLanguageVersion LatestRazorLanguageVersion = RazorLanguageVersion.Version2_1; - public static RazorParserOptions CreateDefault() { return new DefaultRazorParserOptions( Array.Empty(), designTime: false, parseLeadingDirectives: false, - version: LatestRazorLanguageVersion); + version: RazorLanguageVersion.Latest); } public static RazorParserOptions Create(Action configure) @@ -26,7 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Language throw new ArgumentNullException(nameof(configure)); } - var builder = new DefaultRazorParserOptionsBuilder(designTime: false, version: LatestRazorLanguageVersion); + var builder = new DefaultRazorParserOptionsBuilder(designTime: false, version: RazorLanguageVersion.Latest); configure(builder); var options = builder.Build(); @@ -40,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language throw new ArgumentNullException(nameof(configure)); } - var builder = new DefaultRazorParserOptionsBuilder(designTime: true, version: LatestRazorLanguageVersion); + var builder = new DefaultRazorParserOptionsBuilder(designTime: true, version: RazorLanguageVersion.Latest); configure(builder); var options = builder.Build(); @@ -61,7 +59,7 @@ namespace Microsoft.AspNetCore.Razor.Language /// public abstract bool ParseLeadingDirectives { get; } - public virtual RazorLanguageVersion Version { get; } = LatestRazorLanguageVersion; + public virtual RazorLanguageVersion Version { get; } = RazorLanguageVersion.Latest; internal virtual RazorParserFeatureFlags FeatureFlags { get; } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Resources.resx b/src/Microsoft.AspNetCore.Razor.Language/Resources.resx index aab3ca7f13..54df909c15 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Resources.resx +++ b/src/Microsoft.AspNetCore.Razor.Language/Resources.resx @@ -261,9 +261,6 @@ Specify a prefix that is required in an element name for it to be included in Tag Helper processing. - - Provided value for razor language version is unsupported or invalid: '{0}'. - Add tag helpers from the specified type name and assembly name. Specify '*' for the type name to include all tag helper types from the specified assembly. diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/DefaultProjectExtensibilityConfigurationFactory.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/DefaultProjectExtensibilityConfigurationFactory.cs index 6c972f271a..d1c21ff88f 100644 --- a/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/DefaultProjectExtensibilityConfigurationFactory.cs +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/DefaultProjectExtensibilityConfigurationFactory.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; namespace Microsoft.CodeAnalysis.Razor.ProjectSystem { @@ -72,10 +73,14 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem } } + RazorLanguageVersion languageVersion = null; if (razorAssembly != null && mvcAssembly != null) { + languageVersion = GetLanguageVersion(razorAssembly); + // This means we've definitely found a supported Razor version and an MVC version. return new MvcExtensibilityConfiguration( + languageVersion, ProjectExtensibilityConfigurationKind.ApproximateMatch, new ProjectExtensibilityAssembly(razorAssembly), new ProjectExtensibilityAssembly(mvcAssembly)); @@ -92,10 +97,46 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem mvcAssembly = new AssemblyIdentity(MvcAssemblyName, DefaultMvcVersion); } + if (languageVersion == null) + { + languageVersion = GetLanguageVersion(razorAssembly); + } + return new MvcExtensibilityConfiguration( + languageVersion, ProjectExtensibilityConfigurationKind.Fallback, new ProjectExtensibilityAssembly(razorAssembly), new ProjectExtensibilityAssembly(mvcAssembly)); } + + // Internal for testing + internal static RazorLanguageVersion GetLanguageVersion(AssemblyIdentity razorAssembly) + { + // This is inferred from the assembly for now, the Razor language version will eventually flow from MSBuild. + + var razorAssemblyVersion = razorAssembly.Version; + if (razorAssemblyVersion.Major == 1) + { + if (razorAssemblyVersion.Minor >= 1) + { + return RazorLanguageVersion.Version_1_1; + } + + return RazorLanguageVersion.Version_1_0; + } + + if (razorAssemblyVersion.Major == 2) + { + if (razorAssemblyVersion.Minor >= 1) + { + return RazorLanguageVersion.Version_2_1; + } + + return RazorLanguageVersion.Version_2_0; + } + + // Couldn't determine version based off of assembly, fallback to latest. + return RazorLanguageVersion.Latest; + } } } diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/MvcExtensibilityConfiguration.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/MvcExtensibilityConfiguration.cs index 8f63970733..dfe2b88904 100644 --- a/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/MvcExtensibilityConfiguration.cs +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/MvcExtensibilityConfiguration.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Razor.Language; using Microsoft.Extensions.Internal; namespace Microsoft.CodeAnalysis.Razor.ProjectSystem @@ -11,6 +12,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem internal class MvcExtensibilityConfiguration : ProjectExtensibilityConfiguration { public MvcExtensibilityConfiguration( + RazorLanguageVersion languageVersion, ProjectExtensibilityConfigurationKind kind, ProjectExtensibilityAssembly razorAssembly, ProjectExtensibilityAssembly mvcAssembly) @@ -28,19 +30,24 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem Kind = kind; RazorAssembly = razorAssembly; MvcAssembly = mvcAssembly; + LanguageVersion = languageVersion; Assemblies = new[] { RazorAssembly, MvcAssembly, }; } public override IReadOnlyList Assemblies { get; } - // MVC: '2.0.0' (fallback) or MVC: '2.1.3' - public override string DisplayName => $"MVC: {MvcAssembly.Identity.Version.ToString(3)}" + (Kind == ProjectExtensibilityConfigurationKind.Fallback? " (fallback)" : string.Empty); + // MVC: '2.0.0' (fallback) | Razor Language '2.0.0' + // or + // MVC: '2.1.3' | Razor Language '2.1.3' + public override string DisplayName => $"MVC: {MvcAssembly.Identity.Version.ToString(3)}" + (Kind == ProjectExtensibilityConfigurationKind.Fallback? " (fallback)" : string.Empty) + " | " + LanguageVersion; public override ProjectExtensibilityConfigurationKind Kind { get; } public override ProjectExtensibilityAssembly RazorAssembly { get; } + public override RazorLanguageVersion LanguageVersion { get; } + public ProjectExtensibilityAssembly MvcAssembly { get; } public override bool Equals(ProjectExtensibilityConfiguration other) @@ -51,10 +58,11 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem } // We're intentionally ignoring the 'Kind' here. That's mostly for diagnostics and doesn't influence any behavior. - return Enumerable.SequenceEqual( - Assemblies.OrderBy(a => a.Identity.Name).Select(a => a.Identity), - other.Assemblies.OrderBy(a => a.Identity.Name).Select(a => a.Identity), - AssemblyIdentityEqualityComparer.NameAndVersion); + return LanguageVersion == other.LanguageVersion && + Enumerable.SequenceEqual( + Assemblies.OrderBy(a => a.Identity.Name).Select(a => a.Identity), + other.Assemblies.OrderBy(a => a.Identity.Name).Select(a => a.Identity), + AssemblyIdentityEqualityComparer.NameAndVersion); } public override int GetHashCode() @@ -65,6 +73,8 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem hash.Add(assembly); } + hash.Add(LanguageVersion); + return hash; } diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectExtensibilityConfiguration.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectExtensibilityConfiguration.cs index 23115a334a..a868c4781d 100644 --- a/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectExtensibilityConfiguration.cs +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectExtensibilityConfiguration.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language; namespace Microsoft.CodeAnalysis.Razor.ProjectSystem { @@ -16,6 +17,8 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem public abstract ProjectExtensibilityAssembly RazorAssembly { get; } + public abstract RazorLanguageVersion LanguageVersion { get; } + public abstract bool Equals(ProjectExtensibilityConfiguration other); public abstract override int GetHashCode(); diff --git a/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs b/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs index 27639fa63e..a82d1b8e94 100644 --- a/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs +++ b/src/Microsoft.VisualStudio.Editor.Razor/DefaultTemplateEngineFactoryService.cs @@ -15,6 +15,7 @@ namespace Microsoft.VisualStudio.Editor.Razor internal class DefaultTemplateEngineFactoryService : RazorTemplateEngineFactoryService { private readonly static MvcExtensibilityConfiguration DefaultConfiguration = new MvcExtensibilityConfiguration( + RazorLanguageVersion.Version_2_0, ProjectExtensibilityConfigurationKind.Fallback, new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Razor.Language", new Version("2.0.0.0"))), new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Mvc.Razor", new Version("2.0.0.0")))); @@ -41,11 +42,13 @@ namespace Microsoft.VisualStudio.Editor.Razor // In 15.5 we expect projectPath to be a directory, NOT the path to the csproj. var project = FindProject(projectPath); var configuration = (project?.Configuration as MvcExtensibilityConfiguration) ?? DefaultConfiguration; + var razorLanguageVersion = configuration.LanguageVersion; + var razorConfiguration = new RazorConfiguration(razorLanguageVersion, designTime: true); RazorEngine engine; - if (configuration.RazorAssembly.Identity.Version.Major == 1) + if (razorLanguageVersion.Major == 1) { - engine = RazorEngine.CreateDesignTime(b => + engine = RazorEngine.CreateCore(razorConfiguration, b => { configure?.Invoke(b); @@ -63,7 +66,7 @@ namespace Microsoft.VisualStudio.Editor.Razor } else { - engine = RazorEngine.CreateDesignTime(b => + engine = RazorEngine.CreateCore(razorConfiguration, b => { configure?.Invoke(b); diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorParsingPhaseTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorParsingPhaseTest.cs index c495e9ab09..f7a2e7ef90 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorParsingPhaseTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorParsingPhaseTest.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Razor.Language var engine = RazorEngine.CreateEmpty(builder => { builder.Phases.Add(phase); - builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorParserOptions.LatestRazorLanguageVersion)); + builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorLanguageVersion.Latest)); }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Razor.Language var engine = RazorEngine.CreateEmpty((builder) => { builder.Phases.Add(phase); - builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorParserOptions.LatestRazorLanguageVersion)); + builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorLanguageVersion.Latest)); builder.Features.Add(new MyParserOptionsFeature()); }); @@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Razor.Language var engine = RazorEngine.CreateEmpty((builder) => { builder.Phases.Add(phase); - builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorParserOptions.LatestRazorLanguageVersion)); + builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorLanguageVersion.Latest)); builder.Features.Add(new MyParserOptionsFeature()); }); diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/RazorParserFeatureFlagsTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/RazorParserFeatureFlagsTest.cs index e0b5c090b0..db57a33fdf 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/RazorParserFeatureFlagsTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/RazorParserFeatureFlagsTest.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Razor.Language public void Create_LatestVersion_AllowsMinimizedBooleanTagHelperAttributes() { // Arrange & Act - var context = RazorParserFeatureFlags.Create(RazorLanguageVersion.Version2_1); + var context = RazorParserFeatureFlags.Create(RazorLanguageVersion.Version_2_1); // Assert Assert.True(context.AllowMinimizedBooleanTagHelperAttributes); @@ -22,20 +22,10 @@ namespace Microsoft.AspNetCore.Razor.Language public void Create_OlderVersion_DoesNotAllowMinimizedBooleanTagHelperAttributes() { // Arrange & Act - var context = RazorParserFeatureFlags.Create(RazorLanguageVersion.Version1_1); + var context = RazorParserFeatureFlags.Create(RazorLanguageVersion.Version_1_1); // Assert Assert.False(context.AllowMinimizedBooleanTagHelperAttributes); } - - [Fact] - public void Create_UnknownVersion_Throws() - { - // Arrange, Act & Assert - var exception = Assert.Throws( - () => RazorParserFeatureFlags.Create(0)); - - Assert.Equal("Provided value for razor language version is unsupported or invalid: '0'.", exception.Message); - } } } diff --git a/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/DefaultProjectExtensibilityConfigurationFactoryTest.cs b/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/DefaultProjectExtensibilityConfigurationFactoryTest.cs index 4df841a401..633ac9f797 100644 --- a/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/DefaultProjectExtensibilityConfigurationFactoryTest.cs +++ b/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/DefaultProjectExtensibilityConfigurationFactoryTest.cs @@ -2,12 +2,64 @@ // 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 Xunit; namespace Microsoft.CodeAnalysis.Razor.ProjectSystem { public class DefaultProjectExtensibilityConfigurationFactoryTest { + public static TheoryData LanguageVersionMappingData + { + get + { + return new TheoryData + { + { new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("1.0.0.0")), RazorLanguageVersion.Version_1_0 }, + { new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("1.1.0.0")), RazorLanguageVersion.Version_1_1 }, + { new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("2.0.0.0")), RazorLanguageVersion.Version_2_0 }, + { new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("2.1.0.0")), RazorLanguageVersion.Version_2_1 }, + }; + } + } + + [Theory] + [MemberData(nameof(LanguageVersionMappingData))] + public void GetLanguageVersion_MapsExactVersionsCorrectly(AssemblyIdentity assemblyIdentity, RazorLanguageVersion expectedVersion) + { + // Act + var languageVersion = DefaultProjectExtensibilityConfigurationFactory.GetLanguageVersion(assemblyIdentity); + + // Assert + Assert.Same(expectedVersion, languageVersion); + } + + [Fact] + public void GetLanguageVersion_MapsFuture_1_0_VersionsCorrectly() + { + // Arrange + var assemblyIdentity = new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("1.3.0.0")); + + // Act + var languageVersion = DefaultProjectExtensibilityConfigurationFactory.GetLanguageVersion(assemblyIdentity); + + // Assert + Assert.Same(RazorLanguageVersion.Version_1_1, languageVersion); + } + + [Fact] + public void GetLanguageVersion_MapsFuture_2_0_VersionsCorrectly() + { + // Arrange + var assemblyIdentity = new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("2.3.0.0")); + + // Act + var languageVersion = DefaultProjectExtensibilityConfigurationFactory.GetLanguageVersion(assemblyIdentity); + + // Assert + Assert.Same(RazorLanguageVersion.Latest, languageVersion); + } + [Theory] [InlineData("1.0.0.0", "1.0.0.0")] [InlineData("1.1.0.0", "1.1.0.0")] diff --git a/test/Microsoft.VisualStudio.Editor.Razor.Test/DefaultTemplateEngineFactoryServiceTest.cs b/test/Microsoft.VisualStudio.Editor.Razor.Test/DefaultTemplateEngineFactoryServiceTest.cs index 863b02110f..adeee1685c 100644 --- a/test/Microsoft.VisualStudio.Editor.Razor.Test/DefaultTemplateEngineFactoryServiceTest.cs +++ b/test/Microsoft.VisualStudio.Editor.Razor.Test/DefaultTemplateEngineFactoryServiceTest.cs @@ -38,6 +38,7 @@ namespace Microsoft.VisualStudio.Editor.Razor projectManager.ProjectUpdated(new ProjectSnapshotUpdateContext(Project) { Configuration = new MvcExtensibilityConfiguration( + RazorLanguageVersion.Version_2_0, ProjectExtensibilityConfigurationKind.ApproximateMatch, new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Mvc.Razor", new Version("2.0.0.0"))), new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("2.0.0.0")))), @@ -67,6 +68,7 @@ namespace Microsoft.VisualStudio.Editor.Razor projectManager.ProjectUpdated(new ProjectSnapshotUpdateContext(Project) { Configuration = new MvcExtensibilityConfiguration( + RazorLanguageVersion.Version_1_1, ProjectExtensibilityConfigurationKind.ApproximateMatch, new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Mvc.Razor", new Version("1.1.3.0"))), new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("1.1.3.0")))), @@ -96,6 +98,7 @@ namespace Microsoft.VisualStudio.Editor.Razor projectManager.ProjectUpdated(new ProjectSnapshotUpdateContext(Project) { Configuration = new MvcExtensibilityConfiguration( + RazorLanguageVersion.Version_1_0, ProjectExtensibilityConfigurationKind.ApproximateMatch, new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Mvc.Razor", new Version("1.0.0.0"))), new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("1.0.0.0")))), @@ -124,6 +127,7 @@ namespace Microsoft.VisualStudio.Editor.Razor projectManager.ProjectUpdated(new ProjectSnapshotUpdateContext(Project) { Configuration = new MvcExtensibilityConfiguration( + RazorLanguageVersion.Latest, ProjectExtensibilityConfigurationKind.ApproximateMatch, new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Mvc.Razor", new Version("3.0.0.0"))), new ProjectExtensibilityAssembly(new AssemblyIdentity("Microsoft.AspNetCore.Razor", new Version("3.0.0.0")))),