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")))),