From 80f943caef2dcc4309743c8896eb6344dac3326a 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, 219 insertions(+), 86 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 e1b32b7613..6193fcb066 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs @@ -668,20 +668,6 @@ namespace Microsoft.AspNetCore.Razor.Language internal static string FormatInvalidOperation_SpanIsNotChangeOwner(object p0, object p1) => string.Format(CultureInfo.CurrentCulture, GetString("InvalidOperation_SpanIsNotChangeOwner"), p0, p1); - /// - /// 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); - /// /// Invalid tag helper directive look up text '{0}'. The correct look up text format is: "name, assemblyName". /// 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 9a3c5da8a2..dc2ef5d2e4 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs @@ -17,25 +17,35 @@ namespace Microsoft.AspNetCore.Razor.Language return Create(configure: null); } - public static RazorEngine Create(Action configure) - { - var builder = new DefaultRazorEngineBuilder(designTime: false); - AddDefaults(builder); - AddDefaultRuntimeFeatures(builder.Features); - 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); - AddDefaultDesignTimeFeatures(builder.Features); + + if (configuration.DesignTime) + { + AddDefaultDesignTimeFeatures(configuration, builder.Features); + } + else + { + AddDefaultRuntimeFeatures(configuration, builder.Features); + } + configure?.Invoke(builder); return builder.Build(); } @@ -129,10 +139,10 @@ namespace Microsoft.AspNetCore.Razor.Language features.Add(configurationFeature); } - internal static void AddDefaultRuntimeFeatures(ICollection features) + internal static void AddDefaultRuntimeFeatures(RazorConfiguration configuration, ICollection features) { // Configure options - features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorParserOptions.LatestRazorLanguageVersion)); + features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: configuration.LanguageVersion)); features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); // Intermediate Node Passes @@ -146,10 +156,10 @@ namespace Microsoft.AspNetCore.Razor.Language targetExtension.TargetExtensions.Add(new PreallocatedAttributeTargetExtension()); } - internal static void AddDefaultDesignTimeFeatures(ICollection features) + internal static void AddDefaultDesignTimeFeatures(RazorConfiguration configuration, ICollection features) { // Configure options - features.Add(new DefaultRazorParserOptionsFeature(designTime: true, version: RazorParserOptions.LatestRazorLanguageVersion)); + features.Add(new DefaultRazorParserOptionsFeature(designTime: true, version: configuration.LanguageVersion)); features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: true)); features.Add(new SuppressChecksumOptionsFeature()); @@ -171,3 +181,4 @@ namespace Microsoft.AspNetCore.Razor.Language public abstract void Process(RazorCodeDocument document); } } + 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 1001ecdb8e..d281042046 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Resources.resx +++ b/src/Microsoft.AspNetCore.Razor.Language/Resources.resx @@ -260,9 +260,6 @@ The node '{0}' is not the owner of change '{1}'. - - Provided value for razor language version is unsupported or invalid: '{0}'. - Invalid tag helper directive look up text '{0}'. The correct look up text format is: "name, assemblyName". 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 423ae8566a..5e83b06042 100644 --- a/test/Microsoft.VisualStudio.Editor.Razor.Test/DefaultTemplateEngineFactoryServiceTest.cs +++ b/test/Microsoft.VisualStudio.Editor.Razor.Test/DefaultTemplateEngineFactoryServiceTest.cs @@ -43,6 +43,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")))), @@ -72,6 +73,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")))), @@ -101,6 +103,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")))), @@ -129,6 +132,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")))),