From d81dd600c497dd59e3c741185a45fa4ccfd3ab00 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 25 Oct 2024 12:38:33 +1100 Subject: [PATCH 01/14] Add UseRoslynTokenizer onto ProjectWorkspaceState and plumb through --- .../src/CSharp/ParseOptionsExtensions.cs | 13 +++++++++++++ .../RazorSourceGenerator.RazorProviders.cs | 3 +-- .../RazorLanguageServerBenchmarkBase.cs | 2 +- .../ProjectSystem/ProjectWorkspaceState.cs | 16 +++++++++++----- .../Formatters/ProjectWorkspaceStateFormatter.cs | 8 +++++--- .../MessagePack/SerializationFormat.cs | 2 +- .../Utilities/RazorProjectInfoFactory.cs | 8 ++++++-- .../Utilities/StreamExtensions.NetCore.cs | 2 +- .../ProjectSystem/ProjectState.cs | 2 ++ .../ProjectSystem/RemoteProjectSnapshot.cs | 3 +++ .../Host/ProjectSnapshotManagerProxy.cs | 2 +- .../ProjectWorkspaceStateGenerator.cs | 9 +++++---- .../ObjectReaders.cs | 3 ++- .../ObjectWriters.cs | 1 + .../SerializationFormat.cs | 2 +- 15 files changed, 54 insertions(+), 22 deletions(-) create mode 100644 src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ParseOptionsExtensions.cs diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ParseOptionsExtensions.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ParseOptionsExtensions.cs new file mode 100644 index 00000000000..1a8df97be5f --- /dev/null +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ParseOptionsExtensions.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.CodeAnalysis.Razor.Compiler.CSharp; + +internal static class ParseOptionsExtensions +{ + public static bool UseRoslynTokenizer(this ParseOptions parseOptions) + => parseOptions.Features.TryGetValue("use-roslyn-tokenizer", out var useRoslynTokenizerValue) + && string.Equals(useRoslynTokenizerValue, "true", StringComparison.OrdinalIgnoreCase); +} diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.RazorProviders.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.RazorProviders.cs index 09a02e57bd5..9cf4e699a3b 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.RazorProviders.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.RazorProviders.cs @@ -56,8 +56,7 @@ public partial class RazorSourceGenerator var razorConfiguration = new RazorConfiguration(razorLanguageVersion, configurationName ?? "default", Extensions: [], UseConsolidatedMvcViews: true, SuppressAddComponentParameter: !isComponentParameterSupported); // We use the new tokenizer only when requested for now. - var useRoslynTokenizer = parseOptions.Features.TryGetValue("use-roslyn-tokenizer", out var useRoslynTokenizerValue) - && string.Equals(useRoslynTokenizerValue, "true", StringComparison.OrdinalIgnoreCase); + var useRoslynTokenizer = parseOptions.UseRoslynTokenizer(); var razorSourceGenerationOptions = new RazorSourceGenerationOptions() { diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs index e999c1f1613..49ed9807ca9 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs @@ -73,7 +73,7 @@ await projectManager.UpdateAsync( { updater.ProjectAdded(hostProject); var tagHelpers = CommonResources.LegacyTagHelpers; - var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, CodeAnalysis.CSharp.LanguageVersion.CSharp11); + var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer: false, CodeAnalysis.CSharp.LanguageVersion.CSharp11); updater.ProjectWorkspaceStateChanged(hostProject.Key, projectWorkspaceState); updater.DocumentAdded(hostProject.Key, hostDocument, textLoader); }, diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs index b4c2c9548fb..aac2826724a 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs @@ -12,30 +12,34 @@ namespace Microsoft.AspNetCore.Razor.ProjectSystem; internal sealed class ProjectWorkspaceState : IEquatable { - public static readonly ProjectWorkspaceState Default = new(ImmutableArray.Empty, LanguageVersion.Default); + public static readonly ProjectWorkspaceState Default = new(ImmutableArray.Empty, useRoslynTokenizer: false, LanguageVersion.Default); public ImmutableArray TagHelpers { get; } public LanguageVersion CSharpLanguageVersion { get; } + public bool UseRoslynTokenizer { get; } private ProjectWorkspaceState( ImmutableArray tagHelpers, + bool useRoslynTokenizer, LanguageVersion csharpLanguageVersion) { TagHelpers = tagHelpers; CSharpLanguageVersion = csharpLanguageVersion; + UseRoslynTokenizer = useRoslynTokenizer; } public static ProjectWorkspaceState Create( ImmutableArray tagHelpers, + bool useRoslynTokenizer, LanguageVersion csharpLanguageVersion = LanguageVersion.Default) => tagHelpers.IsEmpty && csharpLanguageVersion == LanguageVersion.Default ? Default - : new(tagHelpers, csharpLanguageVersion); + : new(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); - public static ProjectWorkspaceState Create(LanguageVersion csharpLanguageVersion) + public static ProjectWorkspaceState Create(LanguageVersion csharpLanguageVersion, bool useRoslynTokenizer) => csharpLanguageVersion == LanguageVersion.Default ? Default - : new(ImmutableArray.Empty, csharpLanguageVersion); + : new(ImmutableArray.Empty, useRoslynTokenizer, csharpLanguageVersion); public override bool Equals(object? obj) => obj is ProjectWorkspaceState other && Equals(other); @@ -43,7 +47,8 @@ public override bool Equals(object? obj) public bool Equals(ProjectWorkspaceState? other) => other is not null && TagHelpers.SequenceEqual(other.TagHelpers) && - CSharpLanguageVersion == other.CSharpLanguageVersion; + CSharpLanguageVersion == other.CSharpLanguageVersion && + UseRoslynTokenizer == other.UseRoslynTokenizer; public override int GetHashCode() { @@ -51,6 +56,7 @@ public override int GetHashCode() hash.Add(TagHelpers); hash.Add(CSharpLanguageVersion); + hash.Add(UseRoslynTokenizer); return hash.CombinedHash; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs index 60a9894b1da..a93ba7352e6 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs @@ -22,7 +22,7 @@ private ProjectWorkspaceStateFormatter() public override ProjectWorkspaceState Deserialize(ref MessagePackReader reader, SerializerCachingOptions options) { - reader.ReadArrayHeaderAndVerify(3); + reader.ReadArrayHeaderAndVerify(4); var checksums = reader.Deserialize>(options); @@ -47,19 +47,21 @@ public override ProjectWorkspaceState Deserialize(ref MessagePackReader reader, } var tagHelpers = builder.DrainToImmutable(); + var useRoslynTokenizer = reader.ReadBoolean(); var csharpLanguageVersion = (LanguageVersion)reader.ReadInt32(); - return ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion); + return ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); } public override void Serialize(ref MessagePackWriter writer, ProjectWorkspaceState value, SerializerCachingOptions options) { - writer.WriteArrayHeader(3); + writer.WriteArrayHeader(4); var checksums = value.TagHelpers.SelectAsArray(x => x.Checksum); writer.Serialize(checksums, options); writer.Serialize(value.TagHelpers, options); + writer.Write(value.UseRoslynTokenizer); writer.Write((int)value.CSharpLanguageVersion); } } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/SerializationFormat.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/SerializationFormat.cs index 0fc5c52667c..bb7d6524f7b 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/SerializationFormat.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/SerializationFormat.cs @@ -9,5 +9,5 @@ internal static class SerializationFormat // or any of the types that compose it changes. This includes: RazorConfiguration, // ProjectWorkspaceState, TagHelperDescriptor, and DocumentSnapshotHandle. // NOTE: If this version is changed, a coordinated insertion is required between Roslyn and Razor for the C# extension. - public const int Version = 6; + public const int Version = 7; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs index bb518d231a5..3592946450c 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs @@ -19,6 +19,7 @@ using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.Compiler.CSharp; +using Microsoft.NET.Sdk.Razor.SourceGenerators; namespace Microsoft.AspNetCore.Razor.Utilities; @@ -56,7 +57,9 @@ static RazorProjectInfoFactory() return null; } - var csharpLanguageVersion = (project.ParseOptions as CSharpParseOptions)?.LanguageVersion ?? LanguageVersion.Default; + var cSharpParseOptions = project.ParseOptions as CSharpParseOptions ?? CSharpParseOptions.Default; + var csharpLanguageVersion = cSharpParseOptions.LanguageVersion; + var useRoslynTokenizer = cSharpParseOptions.UseRoslynTokenizer(); var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); if (compilation is null) @@ -77,6 +80,7 @@ static RazorProjectInfoFactory() builder.SetCSharpLanguageVersion(csharpLanguageVersion); builder.SetSupportLocalizedComponentNames(); // ProjectState in MS.CA.Razor.Workspaces does this, so I'm doing it too! + builder.Features.Add(new ConfigureRazorParserOptions(useRoslynTokenizer, cSharpParseOptions)); }; var engineFactory = ProjectEngineFactories.DefaultProvider.GetFactory(configuration); @@ -88,7 +92,7 @@ static RazorProjectInfoFactory() var tagHelpers = await project.GetTagHelpersAsync(engine, NoOpTelemetryReporter.Instance, cancellationToken).ConfigureAwait(false); - var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion); + var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); return new RazorProjectInfo( projectKey: new ProjectKey(intermediateOutputPath), diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/StreamExtensions.NetCore.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/StreamExtensions.NetCore.cs index 81abc7a2a16..45562ebbd82 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/StreamExtensions.NetCore.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/StreamExtensions.NetCore.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. -using Microsoft.AspNetCore.Razor.ProjectSystem; using System; using System.Buffers; using System.Diagnostics; @@ -9,6 +8,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.ProjectSystem; namespace Microsoft.AspNetCore.Razor.Utilities; diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs index 9e753414420..1e1e7383991 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Razor.Utilities; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; +using Microsoft.NET.Sdk.Razor.SourceGenerators; namespace Microsoft.CodeAnalysis.Razor.ProjectSystem; @@ -209,6 +210,7 @@ RazorProjectEngine CreateProjectEngine() builder.SetRootNamespace(HostProject.RootNamespace); builder.SetCSharpLanguageVersion(CSharpLanguageVersion); builder.SetSupportLocalizedComponentNames(); + builder.Features.Add(new ConfigureRazorParserOptions(useRoslynTokenizer: ProjectWorkspaceState.UseRoslynTokenizer, CSharpParseOptions.Default)); }); } } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/RemoteProjectSnapshot.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/RemoteProjectSnapshot.cs index e970f1067dc..1720c1a09be 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/RemoteProjectSnapshot.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/RemoteProjectSnapshot.cs @@ -19,6 +19,7 @@ using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.Compiler.CSharp; using Microsoft.CodeAnalysis.Razor.ProjectSystem; +using Microsoft.NET.Sdk.Razor.SourceGenerators; using Microsoft.VisualStudio.Threading; namespace Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; @@ -51,6 +52,7 @@ public RemoteProjectSnapshot(Project project, RemoteSolutionSnapshot solutionSna _lazyProjectEngine = new AsyncLazy(async () => { var configuration = await _lazyConfiguration.GetValueAsync(); + var csharpParseOptions = project.ParseOptions as CSharpParseOptions ?? CSharpParseOptions.Default; return ProjectEngineFactories.DefaultProvider.Create( configuration, rootDirectoryPath: Path.GetDirectoryName(FilePath).AssumeNotNull(), @@ -59,6 +61,7 @@ public RemoteProjectSnapshot(Project project, RemoteSolutionSnapshot solutionSna builder.SetRootNamespace(RootNamespace); builder.SetCSharpLanguageVersion(CSharpLanguageVersion); builder.SetSupportLocalizedComponentNames(); + builder.Features.Add(new ConfigureRazorParserOptions(useRoslynTokenizer: csharpParseOptions.UseRoslynTokenizer(), csharpParseOptions)); }); }, joinableTaskFactory: null); diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs index 7ae74da1e67..1c4c683f69d 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs @@ -101,7 +101,7 @@ internal async Task CalculateUpdatedStateAsync } var tagHelpers = await project.GetTagHelpersAsync(CancellationToken.None).ConfigureAwait(false); - var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, project.CSharpLanguageVersion); + var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, project.ProjectWorkspaceState.UseRoslynTokenizer, project.CSharpLanguageVersion); var projectFilePath = _session.ConvertLocalPathToSharedUri(project.FilePath); var intermediateOutputPath = _session.ConvertLocalPathToSharedUri(project.IntermediateOutputPath); var projectHandleProxy = new ProjectSnapshotHandleProxy(projectFilePath, intermediateOutputPath, project.Configuration, project.RootNamespace, projectWorkspaceState); diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs index e6b29390c64..ab902dbf64b 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Razor.Telemetry; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Razor.Compiler.CSharp; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Razor.Workspaces; @@ -279,9 +280,9 @@ private void ReleaseSemaphore(ProjectKey projectKey) try { - var csharpLanguageVersion = workspaceProject.ParseOptions is CSharpParseOptions csharpParseOptions - ? csharpParseOptions.LanguageVersion - : LanguageVersion.Default; + var csharpParseOptions = workspaceProject.ParseOptions as CSharpParseOptions ?? CSharpParseOptions.Default; + var csharpLanguageVersion = csharpParseOptions.LanguageVersion; + var useRoslynTokenizer = csharpParseOptions.UseRoslynTokenizer(); using var _ = StopwatchPool.GetPooledObject(out var watch); @@ -305,7 +306,7 @@ private void ReleaseSemaphore(ProjectKey projectKey) Project: {projectSnapshot.FilePath} """); - return ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion); + return ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); } catch (OperationCanceledException) { diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs index 91ae5629e82..6b58bb2f716 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs @@ -102,9 +102,10 @@ public static DocumentSnapshotHandle ReadDocumentSnapshotHandleFromProperties(Js public static ProjectWorkspaceState ReadProjectWorkspaceStateFromProperties(JsonDataReader reader) { var tagHelpers = reader.ReadImmutableArrayOrEmpty(nameof(ProjectWorkspaceState.TagHelpers), static r => ReadTagHelper(r, useCache: true)); + var useRoslynTokenizer = reader.ReadBooleanOrFalse(nameof(ProjectWorkspaceState.UseRoslynTokenizer)); var csharpLanguageVersion = (LanguageVersion)reader.ReadInt32OrZero(nameof(ProjectWorkspaceState.CSharpLanguageVersion)); - return ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion); + return ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); } public static TagHelperDescriptor ReadTagHelper(JsonDataReader reader, bool useCache) diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs index aad91449d2b..688cf508c42 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs @@ -84,6 +84,7 @@ public static void Write(JsonDataWriter writer, ProjectWorkspaceState? value) public static void WriteProperties(JsonDataWriter writer, ProjectWorkspaceState value) { writer.WriteArrayIfNotDefaultOrEmpty(nameof(value.TagHelpers), value.TagHelpers, Write); + writer.WriteIfNotFalse(nameof(value.UseRoslynTokenizer), value.UseRoslynTokenizer); writer.WriteIfNotZero(nameof(value.CSharpLanguageVersion), (int)value.CSharpLanguageVersion); } diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/SerializationFormat.cs b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/SerializationFormat.cs index c6a8db23f4a..f0941e5b38b 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/SerializationFormat.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/SerializationFormat.cs @@ -9,5 +9,5 @@ internal static class SerializationFormat // or any of the types that compose it changes. This includes: RazorConfiguration, // ProjectWorkspaceState, TagHelperDescriptor, and DocumentSnapshotHandle. // NOTE: If this version is changed, a coordinated insertion is required between Roslyn and Razor for the C# extension. - public const int Version = 6; + public const int Version = 7; } From 1e660568b6b9e11e0842b41005acba5d031f7560 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 25 Oct 2024 14:24:00 +1100 Subject: [PATCH 02/14] Update tests --- .../Kendo.Mvc.Examples.project.razor.json | 3 +- .../Resources/project.razor.json | 3 +- .../ProjectSystem/ProjectWorkspaceState.cs | 4 +-- .../Serialization/SerializerValidationTest.cs | 5 +--- .../StreamExtensionTests.NetCore.cs | 2 +- .../ProjectStateGeneratedOutputTest.cs | 28 +++++++++++++++++-- .../ProjectSystem/ProjectStateTest.cs | 4 +-- 7 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json index 9104b499f89..659d51a68de 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json @@ -1,5 +1,5 @@ { - "__Version": 6, + "__Version": 7, "ProjectKey": "C:\\Users\\admin\\location\\Kendo.Mvc.Examples\\obj\\Debug\\net7.0\\", "FilePath": "C:\\Users\\admin\\location\\Kendo.Mvc.Examples\\Kendo.Mvc.Examples.csproj", "Configuration": { @@ -159527,6 +159527,7 @@ } } ], + "UseRoslynTokenizer": false, "CSharpLanguageVersion": 1100 }, "RootNamespace": "Kendo.Mvc.Examples", diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json index d1525d22f3a..a3d958bbca6 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json @@ -1,5 +1,5 @@ { - "__Version": 6, + "__Version": 7, "ProjectKey": "C:\\Users\\admin\\location\\blazorserver\\obj\\Debug\\net7.0\\", "FilePath": "C:\\Users\\admin\\location\\blazorserver\\blazorserver.csproj", "Configuration": { @@ -16126,6 +16126,7 @@ } } ], + "UseRoslynTokenizer": false, "CSharpLanguageVersion": 800 }, "RootNamespace": "blazorserver", diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs index aac2826724a..866bc4a2999 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs @@ -30,13 +30,13 @@ private ProjectWorkspaceState( public static ProjectWorkspaceState Create( ImmutableArray tagHelpers, - bool useRoslynTokenizer, + bool useRoslynTokenizer = false, LanguageVersion csharpLanguageVersion = LanguageVersion.Default) => tagHelpers.IsEmpty && csharpLanguageVersion == LanguageVersion.Default ? Default : new(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); - public static ProjectWorkspaceState Create(LanguageVersion csharpLanguageVersion, bool useRoslynTokenizer) + public static ProjectWorkspaceState Create(LanguageVersion csharpLanguageVersion, bool useRoslynTokenizer = false) => csharpLanguageVersion == LanguageVersion.Default ? Default : new(ImmutableArray.Empty, useRoslynTokenizer, csharpLanguageVersion); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/Serialization/SerializerValidationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/Serialization/SerializerValidationTest.cs index 5cd9e7e4863..8ea8b59428f 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/Serialization/SerializerValidationTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/Serialization/SerializerValidationTest.cs @@ -3,7 +3,6 @@ using System.Collections.Immutable; using System.IO; -using System.Reflection; using MessagePack; using MessagePack.Resolvers; using Microsoft.AspNetCore.Razor.Language; @@ -12,15 +11,13 @@ using Microsoft.AspNetCore.Razor.Serialization.Json; using Microsoft.AspNetCore.Razor.Serialization.MessagePack.Resolvers; using Microsoft.AspNetCore.Razor.Test.Common; -using Microsoft.CodeAnalysis.Razor.Logging; using Xunit; using Xunit.Abstractions; -using MessagePackSerializationFormat = Microsoft.AspNetCore.Razor.Serialization.MessagePack.SerializationFormat; namespace Microsoft.AspNetCore.Razor.ProjectEngineHost.Test.Serialization; public class SerializerValidationTest(ITestOutputHelper testOutput) : ToolingTestBase(testOutput) -{ +{ [Theory] [InlineData("Kendo.Mvc.Examples.project.razor.json")] [InlineData("project.razor.json")] diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs index 8895137d798..f7b1cdb3399 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs @@ -77,7 +77,7 @@ public async Task SerializeProjectInfo() .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name")) .Build(); - var projectWorkspaceState = ProjectWorkspaceState.Create([tagHelper], CodeAnalysis.CSharp.LanguageVersion.Latest); + var projectWorkspaceState = ProjectWorkspaceState.Create([tagHelper], useRoslynTokenizer: true, CodeAnalysis.CSharp.LanguageVersion.Latest); var projectInfo = new RazorProjectInfo( new ProjectKey("TestProject"), diff --git a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs index 7e80b2537b7..fe6795fcafc 100644 --- a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs +++ b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs @@ -190,11 +190,35 @@ public async Task ProjectWorkspaceStateChange_WithProjectWorkspaceState_CSharpLa // Arrange var csharp8ValidConfiguration = new RazorConfiguration(RazorLanguageVersion.Version_3_0, _hostProject.Configuration.ConfigurationName, _hostProject.Configuration.Extensions); var hostProject = TestProjectData.SomeProject with { Configuration = csharp8ValidConfiguration }; - var originalWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, LanguageVersion.CSharp7); + var originalWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, useRoslynTokenizer: false, LanguageVersion.CSharp7); var original = ProjectState.Create(ProjectEngineFactoryProvider, hostProject, originalWorkspaceState) .WithAddedHostDocument(_hostDocument, TestMocks.CreateTextLoader("@DateTime.Now", VersionStamp.Default)); - var changedWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, LanguageVersion.CSharp8); + var changedWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, useRoslynTokenizer: false, LanguageVersion.CSharp8); + + var (originalOutput, originalInputVersion) = await GetOutputAsync(original, _hostDocument, DisposalToken); + + // Act + var state = original.WithProjectWorkspaceState(changedWorkspaceState); + + // Assert + var (actualOutput, actualInputVersion) = await GetOutputAsync(state, _hostDocument, DisposalToken); + Assert.NotSame(originalOutput, actualOutput); + Assert.NotEqual(originalInputVersion, actualInputVersion); + Assert.Equal(state.ProjectWorkspaceStateVersion, actualInputVersion); + } + + [Fact] + public async Task ProjectWorkspaceStateChange_WithProjectWorkspaceState_UseRoslynTokenizerChange_DoesNotCacheOutput() + { + // Arrange + var csharp8ValidConfiguration = new RazorConfiguration(RazorLanguageVersion.Version_3_0, _hostProject.Configuration.ConfigurationName, _hostProject.Configuration.Extensions); + var hostProject = TestProjectData.SomeProject with { Configuration = csharp8ValidConfiguration }; + var originalWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, useRoslynTokenizer: false, LanguageVersion.CSharp7); + var original = + ProjectState.Create(ProjectEngineFactoryProvider, hostProject, originalWorkspaceState) + .WithAddedHostDocument(_hostDocument, TestMocks.CreateTextLoader("@DateTime.Now", VersionStamp.Default)); + var changedWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, useRoslynTokenizer: true, LanguageVersion.CSharp7); var (originalOutput, originalInputVersion) = await GetOutputAsync(original, _hostDocument, DisposalToken); diff --git a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs index 2658d893683..3009b6511a7 100644 --- a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs +++ b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs @@ -654,7 +654,7 @@ public void ProjectState_WithProjectWorkspaceState_Changed() var originalTagHelpers = original.TagHelpers; var originalProjectWorkspaceStateVersion = original.ProjectWorkspaceStateVersion; - var changed = ProjectWorkspaceState.Create(_projectWorkspaceState.TagHelpers, LanguageVersion.CSharp6); + var changed = ProjectWorkspaceState.Create(_projectWorkspaceState.TagHelpers, useRoslynTokenizer: false, LanguageVersion.CSharp6); // Act var state = original.WithProjectWorkspaceState(changed); @@ -727,7 +727,7 @@ public void ProjectState_WithProjectWorkspaceState_IdenticalState_Caches() _ = original.TagHelpers; _ = original.ProjectWorkspaceStateVersion; - var changed = ProjectWorkspaceState.Create(original.TagHelpers, original.CSharpLanguageVersion); + var changed = ProjectWorkspaceState.Create(original.TagHelpers, original.ProjectWorkspaceState.UseRoslynTokenizer, original.CSharpLanguageVersion); // Act var state = original.WithProjectWorkspaceState(changed); From 6702e25e5330e8b4271e40a4a1c15bb23af59ea6 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 25 Oct 2024 14:53:08 +1100 Subject: [PATCH 03/14] Invalidate project engine when UseRoslynTokenizer changes --- .../ProjectSystem/ProjectState.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs index 1e1e7383991..bbb5418aafc 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs @@ -151,14 +151,15 @@ private ProjectState( else { ProjectWorkspaceStateVersion = Version; - } - if ((difference & ClearProjectWorkspaceStateVersionMask) != 0 && - CSharpLanguageVersion != older.CSharpLanguageVersion) - { - // C# language version changed. This impacts the ProjectEngine, reset it. - _projectEngine = null; - ConfigurationVersion = Version; + // CSharpLanguageVersion and UseRoslynTokenizer are part of the ProjectWorkspaceState, but they affect the project engine + // so we check for those specifically changing, and clear that. + if (CSharpLanguageVersion != older.CSharpLanguageVersion || + ProjectWorkspaceState.UseRoslynTokenizer != older.ProjectWorkspaceState.UseRoslynTokenizer) + { + _projectEngine = null; + ConfigurationVersion = Version; + } } } From 51ba92b676fa697c3177a2b0e44539de1fccaf1c Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 25 Oct 2024 15:54:59 +1100 Subject: [PATCH 04/14] Allow the workspace state generator to also update the project configuration --- .../ProjectWorkspaceStateGenerator.cs | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs index ab902dbf64b..fe062846013 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs @@ -6,6 +6,7 @@ using System.ComponentModel.Composition; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.AspNetCore.Razor.ProjectSystem; using Microsoft.AspNetCore.Razor.Telemetry; @@ -139,9 +140,7 @@ private async Task UpdateWorkspaceStateAsync(Project? workspaceProject, IProject return; } - var workspaceState = await GetProjectWorkspaceStateAsync(workspaceProject, projectSnapshot, cancellationToken); - - if (workspaceState is null) + if (await GetProjectWorkspaceStateAndConfigurationAsync(workspaceProject, projectSnapshot, cancellationToken) is not var (workspaceState, configuration)) { _logger.LogTrace($"Didn't receive {nameof(ProjectWorkspaceState)} for '{projectKey}'"); return; @@ -154,11 +153,15 @@ private async Task UpdateWorkspaceStateAsync(Project? workspaceProject, IProject _logger.LogTrace($"Received {nameof(ProjectWorkspaceState)} with {workspaceState.TagHelpers.Length} tag helper(s) for '{projectKey}'"); + // We got a possibly changed configuration, but need a host project to update. Fortunately everything will no-op if this + // is unchanged + var hostProject = new HostProject(projectSnapshot.FilePath, projectSnapshot.IntermediateOutputPath, configuration, projectSnapshot.RootNamespace, projectSnapshot.DisplayName); + await _projectManager .UpdateAsync( static (updater, state) => { - var (projectKey, workspaceState, logger, cancellationToken) = state; + var (projectKey, workspaceState, hostProject, logger, cancellationToken) = state; if (cancellationToken.IsCancellationRequested) { @@ -166,9 +169,10 @@ await _projectManager } logger.LogTrace($"Updating project with {workspaceState.TagHelpers.Length} tag helper(s) for '{projectKey}'"); + updater.ProjectConfigurationChanged(hostProject); updater.ProjectWorkspaceStateChanged(projectKey, workspaceState); }, - state: (projectKey, workspaceState, _logger, cancellationToken), + state: (projectKey, workspaceState, hostProject, _logger, cancellationToken), cancellationToken) .ConfigureAwait(false); } @@ -257,7 +261,7 @@ private void ReleaseSemaphore(ProjectKey projectKey) /// Attempts to produce a from the provide and . /// Returns if an error is encountered. /// - private async Task GetProjectWorkspaceStateAsync( + private async Task<(ProjectWorkspaceState, RazorConfiguration)?> GetProjectWorkspaceStateAndConfigurationAsync( Project? workspaceProject, IProjectSnapshot projectSnapshot, CancellationToken cancellationToken) @@ -266,7 +270,7 @@ private void ReleaseSemaphore(ProjectKey projectKey) // we just a default ProjectWorkspaceState. if (workspaceProject is null) { - return ProjectWorkspaceState.Default; + return (ProjectWorkspaceState.Default, RazorConfiguration.Default); } _logger.LogTrace($"Starting tag helper discovery for {projectSnapshot.FilePath}"); @@ -284,6 +288,10 @@ private void ReleaseSemaphore(ProjectKey projectKey) var csharpLanguageVersion = csharpParseOptions.LanguageVersion; var useRoslynTokenizer = csharpParseOptions.UseRoslynTokenizer(); + var compilation = await workspaceProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + var suppressAddComponentParameter = compilation is not null && !compilation.HasAddComponentParameter(); + var configuration = projectSnapshot.Configuration with { SuppressAddComponentParameter = suppressAddComponentParameter }; + using var _ = StopwatchPool.GetPooledObject(out var watch); watch.Restart(); @@ -306,7 +314,7 @@ private void ReleaseSemaphore(ProjectKey projectKey) Project: {projectSnapshot.FilePath} """); - return ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); + return (ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion), configuration); } catch (OperationCanceledException) { From 349b1589e345228a21c7fa23d291ad123d3fb026 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 28 Oct 2024 12:35:37 +1100 Subject: [PATCH 05/14] Fix updating of SuppressAddComponentParameter --- .../ProjectSystem/RazorProjectService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs index 25f498d7213..8c611d79776 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -374,7 +374,8 @@ private Task AddOrUpdateProjectCoreAsync( var currentConfiguration = project.Configuration; var currentRootNamespace = project.RootNamespace; if (currentConfiguration.ConfigurationName == configuration?.ConfigurationName && - currentRootNamespace == rootNamespace) + currentRootNamespace == rootNamespace && + currentConfiguration.SuppressAddComponentParameter == configuration?.SuppressAddComponentParameter) { _logger.LogTrace($"Updating project '{project.Key}'. The project is already using configuration '{configuration.ConfigurationName}' and root namespace '{rootNamespace}'."); return; From 66b94d68dd16373644f141bf5968619e6da2b893 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 28 Oct 2024 13:15:13 +1100 Subject: [PATCH 06/14] Misc PR feedback --- .../ProjectSystem/ProjectWorkspaceState.cs | 4 ++-- .../Utilities/RazorProjectInfoFactory.cs | 8 ++++---- .../Serialization/SerializerValidationTest.cs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs index 866bc4a2999..71407fc55fa 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs @@ -46,9 +46,9 @@ public override bool Equals(object? obj) public bool Equals(ProjectWorkspaceState? other) => other is not null && - TagHelpers.SequenceEqual(other.TagHelpers) && CSharpLanguageVersion == other.CSharpLanguageVersion && - UseRoslynTokenizer == other.UseRoslynTokenizer; + UseRoslynTokenizer == other.UseRoslynTokenizer && + TagHelpers.SequenceEqual(other.TagHelpers); public override int GetHashCode() { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs index 3592946450c..b8c8f253e15 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs @@ -57,9 +57,9 @@ static RazorProjectInfoFactory() return null; } - var cSharpParseOptions = project.ParseOptions as CSharpParseOptions ?? CSharpParseOptions.Default; - var csharpLanguageVersion = cSharpParseOptions.LanguageVersion; - var useRoslynTokenizer = cSharpParseOptions.UseRoslynTokenizer(); + var csharpParseOptions = project.ParseOptions as CSharpParseOptions ?? CSharpParseOptions.Default; + var csharpLanguageVersion = csharpParseOptions.LanguageVersion; + var useRoslynTokenizer = csharpParseOptions.UseRoslynTokenizer(); var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); if (compilation is null) @@ -80,7 +80,7 @@ static RazorProjectInfoFactory() builder.SetCSharpLanguageVersion(csharpLanguageVersion); builder.SetSupportLocalizedComponentNames(); // ProjectState in MS.CA.Razor.Workspaces does this, so I'm doing it too! - builder.Features.Add(new ConfigureRazorParserOptions(useRoslynTokenizer, cSharpParseOptions)); + builder.Features.Add(new ConfigureRazorParserOptions(useRoslynTokenizer, csharpParseOptions)); }; var engineFactory = ProjectEngineFactories.DefaultProvider.GetFactory(configuration); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/Serialization/SerializerValidationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/Serialization/SerializerValidationTest.cs index 8ea8b59428f..97a8f86c57a 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/Serialization/SerializerValidationTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/Serialization/SerializerValidationTest.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Razor.ProjectEngineHost.Test.Serialization; public class SerializerValidationTest(ITestOutputHelper testOutput) : ToolingTestBase(testOutput) -{ +{ [Theory] [InlineData("Kendo.Mvc.Examples.project.razor.json")] [InlineData("project.razor.json")] From 12476a893028ec8e64684113ed08551dfbf24d7f Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 28 Oct 2024 13:15:50 +1100 Subject: [PATCH 07/14] Stop piecemeal checking individual properties, and rely on the equals overload of the configuration object --- .../ProjectSystem/RazorProjectService.cs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs index 8c611d79776..e797c50a4a6 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -371,13 +371,11 @@ private Task AddOrUpdateProjectCoreAsync( updater.ProjectWorkspaceStateChanged(project.Key, projectWorkspaceState); - var currentConfiguration = project.Configuration; var currentRootNamespace = project.RootNamespace; - if (currentConfiguration.ConfigurationName == configuration?.ConfigurationName && - currentRootNamespace == rootNamespace && - currentConfiguration.SuppressAddComponentParameter == configuration?.SuppressAddComponentParameter) + if (project.Configuration == configuration && + currentRootNamespace == rootNamespace) { - _logger.LogTrace($"Updating project '{project.Key}'. The project is already using configuration '{configuration.ConfigurationName}' and root namespace '{rootNamespace}'."); + _logger.LogTrace($"Skipping configuration update for '{project.Key}' as the configuration and root namespace are unchanged."); return; } @@ -386,14 +384,9 @@ private Task AddOrUpdateProjectCoreAsync( configuration = FallbackRazorConfiguration.Latest; _logger.LogInformation($"Updating project '{project.Key}' to use the latest configuration ('{configuration.ConfigurationName}')'."); } - else if (currentConfiguration.ConfigurationName != configuration.ConfigurationName) + else { - _logger.LogInformation($"Updating project '{project.Key}' to Razor configuration '{configuration.ConfigurationName}' with language version '{configuration.LanguageVersion}'."); - } - - if (currentRootNamespace != rootNamespace) - { - _logger.LogInformation($"Updating project '{project.Key}''s root namespace to '{rootNamespace}'."); + _logger.LogInformation($"Updating project '{project.Key}' to Razor configuration '{configuration.ConfigurationName}', namespace '{rootNamespace}', with language version '{configuration.LanguageVersion}'."); } var hostProject = new HostProject(project.FilePath, project.IntermediateOutputPath, configuration, rootNamespace, displayName); From 90c0db6bfcdb3bc095931c30b1b13b85765d3f63 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 28 Oct 2024 14:06:41 +1100 Subject: [PATCH 08/14] Move UseRoslynTokenizer to RazorConfiguration --- .../src/Language/RazorConfiguration.cs | 8 ++++-- .../RazorLanguageServerBenchmarkBase.cs | 2 +- .../Kendo.Mvc.Examples.project.razor.json | 2 +- .../Resources/project.razor.json | 2 +- .../ProjectSystem/ProjectWorkspaceState.cs | 14 +++------- .../ProjectWorkspaceStateFormatter.cs | 8 ++---- .../Formatters/RazorConfigurationFormatter.cs | 17 +++++++---- .../Utilities/RazorProjectInfoFactory.cs | 2 +- .../ProjectSystem/ProjectState.cs | 17 ++++++----- .../Host/ProjectSnapshotManagerProxy.cs | 2 +- .../ProjectWorkspaceStateGenerator.cs | 8 ++++-- .../StreamExtensionTests.NetCore.cs | 2 +- .../ProjectStateGeneratedOutputTest.cs | 28 ++----------------- .../ProjectSystem/ProjectStateTest.cs | 4 +-- .../ObjectReaders.cs | 6 ++-- .../ObjectWriters.cs | 3 +- 16 files changed, 53 insertions(+), 72 deletions(-) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs index 83cd64698d1..94c0e9ae266 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs @@ -13,7 +13,8 @@ public sealed record class RazorConfiguration( ImmutableArray Extensions, bool UseConsolidatedMvcViews = true, bool SuppressAddComponentParameter = false, - LanguageServerFlags? LanguageServerFlags = null) + LanguageServerFlags? LanguageServerFlags = null, + bool UseRoslynTokenizer = false) { public static readonly RazorConfiguration Default = new( RazorLanguageVersion.Latest, @@ -21,7 +22,8 @@ public sealed record class RazorConfiguration( Extensions: [], UseConsolidatedMvcViews: true, SuppressAddComponentParameter: false, - LanguageServerFlags: null); + LanguageServerFlags: null, + UseRoslynTokenizer: false); public bool Equals(RazorConfiguration? other) => other is not null && @@ -30,6 +32,7 @@ public bool Equals(RazorConfiguration? other) SuppressAddComponentParameter == other.SuppressAddComponentParameter && LanguageServerFlags == other.LanguageServerFlags && UseConsolidatedMvcViews == other.UseConsolidatedMvcViews && + UseRoslynTokenizer == other.UseRoslynTokenizer && Extensions.SequenceEqual(other.Extensions); public override int GetHashCode() @@ -41,6 +44,7 @@ public override int GetHashCode() hash.Add(SuppressAddComponentParameter); hash.Add(UseConsolidatedMvcViews); hash.Add(LanguageServerFlags); + hash.Add(UseRoslynTokenizer); return hash; } } diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs index 49ed9807ca9..e999c1f1613 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs @@ -73,7 +73,7 @@ await projectManager.UpdateAsync( { updater.ProjectAdded(hostProject); var tagHelpers = CommonResources.LegacyTagHelpers; - var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer: false, CodeAnalysis.CSharp.LanguageVersion.CSharp11); + var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, CodeAnalysis.CSharp.LanguageVersion.CSharp11); updater.ProjectWorkspaceStateChanged(hostProject.Key, projectWorkspaceState); updater.DocumentAdded(hostProject.Key, hostDocument, textLoader); }, diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json index 659d51a68de..0c4280d8b35 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json @@ -5,6 +5,7 @@ "Configuration": { "ConfigurationName": "MVC-3.0", "LanguageVersion": "7.0", + "UseRoslynTokenizer": true, "Extensions": [ "MVC-3.0" ] @@ -159527,7 +159528,6 @@ } } ], - "UseRoslynTokenizer": false, "CSharpLanguageVersion": 1100 }, "RootNamespace": "Kendo.Mvc.Examples", diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json index a3d958bbca6..0bd019c2146 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json @@ -5,6 +5,7 @@ "Configuration": { "ConfigurationName": "MVC-3.0", "LanguageVersion": "3.0", + "UseRoslynTokenizer": true, "Extensions": [ "MVC-3.0" ] }, "ProjectWorkspaceState": { @@ -16126,7 +16127,6 @@ } } ], - "UseRoslynTokenizer": false, "CSharpLanguageVersion": 800 }, "RootNamespace": "blazorserver", diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs index 71407fc55fa..041e7cd3bf6 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs @@ -12,34 +12,30 @@ namespace Microsoft.AspNetCore.Razor.ProjectSystem; internal sealed class ProjectWorkspaceState : IEquatable { - public static readonly ProjectWorkspaceState Default = new(ImmutableArray.Empty, useRoslynTokenizer: false, LanguageVersion.Default); + public static readonly ProjectWorkspaceState Default = new(ImmutableArray.Empty, LanguageVersion.Default); public ImmutableArray TagHelpers { get; } public LanguageVersion CSharpLanguageVersion { get; } - public bool UseRoslynTokenizer { get; } private ProjectWorkspaceState( ImmutableArray tagHelpers, - bool useRoslynTokenizer, LanguageVersion csharpLanguageVersion) { TagHelpers = tagHelpers; CSharpLanguageVersion = csharpLanguageVersion; - UseRoslynTokenizer = useRoslynTokenizer; } public static ProjectWorkspaceState Create( ImmutableArray tagHelpers, - bool useRoslynTokenizer = false, LanguageVersion csharpLanguageVersion = LanguageVersion.Default) => tagHelpers.IsEmpty && csharpLanguageVersion == LanguageVersion.Default ? Default - : new(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); + : new(tagHelpers, csharpLanguageVersion); - public static ProjectWorkspaceState Create(LanguageVersion csharpLanguageVersion, bool useRoslynTokenizer = false) + public static ProjectWorkspaceState Create(LanguageVersion csharpLanguageVersion) => csharpLanguageVersion == LanguageVersion.Default ? Default - : new(ImmutableArray.Empty, useRoslynTokenizer, csharpLanguageVersion); + : new(ImmutableArray.Empty, csharpLanguageVersion); public override bool Equals(object? obj) => obj is ProjectWorkspaceState other && Equals(other); @@ -47,7 +43,6 @@ public override bool Equals(object? obj) public bool Equals(ProjectWorkspaceState? other) => other is not null && CSharpLanguageVersion == other.CSharpLanguageVersion && - UseRoslynTokenizer == other.UseRoslynTokenizer && TagHelpers.SequenceEqual(other.TagHelpers); public override int GetHashCode() @@ -56,7 +51,6 @@ public override int GetHashCode() hash.Add(TagHelpers); hash.Add(CSharpLanguageVersion); - hash.Add(UseRoslynTokenizer); return hash.CombinedHash; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs index a93ba7352e6..60a9894b1da 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs @@ -22,7 +22,7 @@ private ProjectWorkspaceStateFormatter() public override ProjectWorkspaceState Deserialize(ref MessagePackReader reader, SerializerCachingOptions options) { - reader.ReadArrayHeaderAndVerify(4); + reader.ReadArrayHeaderAndVerify(3); var checksums = reader.Deserialize>(options); @@ -47,21 +47,19 @@ public override ProjectWorkspaceState Deserialize(ref MessagePackReader reader, } var tagHelpers = builder.DrainToImmutable(); - var useRoslynTokenizer = reader.ReadBoolean(); var csharpLanguageVersion = (LanguageVersion)reader.ReadInt32(); - return ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); + return ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion); } public override void Serialize(ref MessagePackWriter writer, ProjectWorkspaceState value, SerializerCachingOptions options) { - writer.WriteArrayHeader(4); + writer.WriteArrayHeader(3); var checksums = value.TagHelpers.SelectAsArray(x => x.Checksum); writer.Serialize(checksums, options); writer.Serialize(value.TagHelpers, options); - writer.Write(value.UseRoslynTokenizer); writer.Write((int)value.CSharpLanguageVersion); } } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/RazorConfigurationFormatter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/RazorConfigurationFormatter.cs index 6232c1fabdb..366ba8c02b0 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/RazorConfigurationFormatter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/RazorConfigurationFormatter.cs @@ -11,6 +11,10 @@ internal sealed class RazorConfigurationFormatter : ValueFormatter Instance = new RazorConfigurationFormatter(); + // The count of properties in RazorConfiguration that are serialized. The number of Extensions will be added + // to this, for the final serialized value count. + private const int SerializedPropertyCount = 5; + private RazorConfigurationFormatter() { } @@ -24,8 +28,9 @@ public override RazorConfiguration Deserialize(ref MessagePackReader reader, Ser var languageVersionText = CachedStringFormatter.Instance.Deserialize(ref reader, options) ?? string.Empty; var suppressAddComponentParameter = reader.ReadBoolean(); var useConsolidatedMvcViews = reader.ReadBoolean(); + var useRoslynTokenizer = reader.ReadBoolean(); - count -= 4; + count -= SerializedPropertyCount; using var builder = new PooledArrayBuilder(); @@ -46,14 +51,15 @@ public override RazorConfiguration Deserialize(ref MessagePackReader reader, Ser configurationName, extensions, UseConsolidatedMvcViews: useConsolidatedMvcViews, - SuppressAddComponentParameter: suppressAddComponentParameter); + SuppressAddComponentParameter: suppressAddComponentParameter, + UseRoslynTokenizer: useRoslynTokenizer); } public override void Serialize(ref MessagePackWriter writer, RazorConfiguration value, SerializerCachingOptions options) { - // Write 4 values + 1 value per extension. + // Write SerializedPropertyCount values + 1 value per extension. var extensions = value.Extensions; - var count = extensions.Length + 4; + var count = extensions.Length + SerializedPropertyCount; writer.WriteArrayHeader(count); @@ -70,8 +76,9 @@ public override void Serialize(ref MessagePackWriter writer, RazorConfiguration writer.Write(value.SuppressAddComponentParameter); writer.Write(value.UseConsolidatedMvcViews); + writer.Write(value.UseRoslynTokenizer); - count -= 4; + count -= SerializedPropertyCount; for (var i = 0; i < count; i++) { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs index b8c8f253e15..6baf1605dc5 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Utilities/RazorProjectInfoFactory.cs @@ -92,7 +92,7 @@ static RazorProjectInfoFactory() var tagHelpers = await project.GetTagHelpersAsync(engine, NoOpTelemetryReporter.Instance, cancellationToken).ConfigureAwait(false); - var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); + var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion); return new RazorProjectInfo( projectKey: new ProjectKey(intermediateOutputPath), diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs index bbb5418aafc..358076f4bc4 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs @@ -151,15 +151,14 @@ private ProjectState( else { ProjectWorkspaceStateVersion = Version; + } - // CSharpLanguageVersion and UseRoslynTokenizer are part of the ProjectWorkspaceState, but they affect the project engine - // so we check for those specifically changing, and clear that. - if (CSharpLanguageVersion != older.CSharpLanguageVersion || - ProjectWorkspaceState.UseRoslynTokenizer != older.ProjectWorkspaceState.UseRoslynTokenizer) - { - _projectEngine = null; - ConfigurationVersion = Version; - } + if ((difference & ClearProjectWorkspaceStateVersionMask) != 0 && + CSharpLanguageVersion != older.CSharpLanguageVersion) + { + // C# language version changed. This impacts the ProjectEngine, reset it. + _projectEngine = null; + ConfigurationVersion = Version; } } @@ -211,7 +210,7 @@ RazorProjectEngine CreateProjectEngine() builder.SetRootNamespace(HostProject.RootNamespace); builder.SetCSharpLanguageVersion(CSharpLanguageVersion); builder.SetSupportLocalizedComponentNames(); - builder.Features.Add(new ConfigureRazorParserOptions(useRoslynTokenizer: ProjectWorkspaceState.UseRoslynTokenizer, CSharpParseOptions.Default)); + builder.Features.Add(new ConfigureRazorParserOptions(useRoslynTokenizer: configuration.UseRoslynTokenizer, CSharpParseOptions.Default)); }); } } diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs index 1c4c683f69d..7ae74da1e67 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs @@ -101,7 +101,7 @@ internal async Task CalculateUpdatedStateAsync } var tagHelpers = await project.GetTagHelpersAsync(CancellationToken.None).ConfigureAwait(false); - var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, project.ProjectWorkspaceState.UseRoslynTokenizer, project.CSharpLanguageVersion); + var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, project.CSharpLanguageVersion); var projectFilePath = _session.ConvertLocalPathToSharedUri(project.FilePath); var intermediateOutputPath = _session.ConvertLocalPathToSharedUri(project.IntermediateOutputPath); var projectHandleProxy = new ProjectSnapshotHandleProxy(projectFilePath, intermediateOutputPath, project.Configuration, project.RootNamespace, projectWorkspaceState); diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs index fe062846013..77496320ac3 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs @@ -290,7 +290,11 @@ private void ReleaseSemaphore(ProjectKey projectKey) var compilation = await workspaceProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var suppressAddComponentParameter = compilation is not null && !compilation.HasAddComponentParameter(); - var configuration = projectSnapshot.Configuration with { SuppressAddComponentParameter = suppressAddComponentParameter }; + var configuration = projectSnapshot.Configuration with + { + SuppressAddComponentParameter = suppressAddComponentParameter, + UseRoslynTokenizer = useRoslynTokenizer, + }; using var _ = StopwatchPool.GetPooledObject(out var watch); @@ -314,7 +318,7 @@ private void ReleaseSemaphore(ProjectKey projectKey) Project: {projectSnapshot.FilePath} """); - return (ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion), configuration); + return (ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion), configuration); } catch (OperationCanceledException) { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs index f7b1cdb3399..8895137d798 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs @@ -77,7 +77,7 @@ public async Task SerializeProjectInfo() .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name")) .Build(); - var projectWorkspaceState = ProjectWorkspaceState.Create([tagHelper], useRoslynTokenizer: true, CodeAnalysis.CSharp.LanguageVersion.Latest); + var projectWorkspaceState = ProjectWorkspaceState.Create([tagHelper], CodeAnalysis.CSharp.LanguageVersion.Latest); var projectInfo = new RazorProjectInfo( new ProjectKey("TestProject"), diff --git a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs index fe6795fcafc..7e80b2537b7 100644 --- a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs +++ b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs @@ -190,35 +190,11 @@ public async Task ProjectWorkspaceStateChange_WithProjectWorkspaceState_CSharpLa // Arrange var csharp8ValidConfiguration = new RazorConfiguration(RazorLanguageVersion.Version_3_0, _hostProject.Configuration.ConfigurationName, _hostProject.Configuration.Extensions); var hostProject = TestProjectData.SomeProject with { Configuration = csharp8ValidConfiguration }; - var originalWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, useRoslynTokenizer: false, LanguageVersion.CSharp7); + var originalWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, LanguageVersion.CSharp7); var original = ProjectState.Create(ProjectEngineFactoryProvider, hostProject, originalWorkspaceState) .WithAddedHostDocument(_hostDocument, TestMocks.CreateTextLoader("@DateTime.Now", VersionStamp.Default)); - var changedWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, useRoslynTokenizer: false, LanguageVersion.CSharp8); - - var (originalOutput, originalInputVersion) = await GetOutputAsync(original, _hostDocument, DisposalToken); - - // Act - var state = original.WithProjectWorkspaceState(changedWorkspaceState); - - // Assert - var (actualOutput, actualInputVersion) = await GetOutputAsync(state, _hostDocument, DisposalToken); - Assert.NotSame(originalOutput, actualOutput); - Assert.NotEqual(originalInputVersion, actualInputVersion); - Assert.Equal(state.ProjectWorkspaceStateVersion, actualInputVersion); - } - - [Fact] - public async Task ProjectWorkspaceStateChange_WithProjectWorkspaceState_UseRoslynTokenizerChange_DoesNotCacheOutput() - { - // Arrange - var csharp8ValidConfiguration = new RazorConfiguration(RazorLanguageVersion.Version_3_0, _hostProject.Configuration.ConfigurationName, _hostProject.Configuration.Extensions); - var hostProject = TestProjectData.SomeProject with { Configuration = csharp8ValidConfiguration }; - var originalWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, useRoslynTokenizer: false, LanguageVersion.CSharp7); - var original = - ProjectState.Create(ProjectEngineFactoryProvider, hostProject, originalWorkspaceState) - .WithAddedHostDocument(_hostDocument, TestMocks.CreateTextLoader("@DateTime.Now", VersionStamp.Default)); - var changedWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, useRoslynTokenizer: true, LanguageVersion.CSharp7); + var changedWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, LanguageVersion.CSharp8); var (originalOutput, originalInputVersion) = await GetOutputAsync(original, _hostDocument, DisposalToken); diff --git a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs index 3009b6511a7..2658d893683 100644 --- a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs +++ b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs @@ -654,7 +654,7 @@ public void ProjectState_WithProjectWorkspaceState_Changed() var originalTagHelpers = original.TagHelpers; var originalProjectWorkspaceStateVersion = original.ProjectWorkspaceStateVersion; - var changed = ProjectWorkspaceState.Create(_projectWorkspaceState.TagHelpers, useRoslynTokenizer: false, LanguageVersion.CSharp6); + var changed = ProjectWorkspaceState.Create(_projectWorkspaceState.TagHelpers, LanguageVersion.CSharp6); // Act var state = original.WithProjectWorkspaceState(changed); @@ -727,7 +727,7 @@ public void ProjectState_WithProjectWorkspaceState_IdenticalState_Caches() _ = original.TagHelpers; _ = original.ProjectWorkspaceStateVersion; - var changed = ProjectWorkspaceState.Create(original.TagHelpers, original.ProjectWorkspaceState.UseRoslynTokenizer, original.CSharpLanguageVersion); + var changed = ProjectWorkspaceState.Create(original.TagHelpers, original.CSharpLanguageVersion); // Act var state = original.WithProjectWorkspaceState(changed); diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs index 6b58bb2f716..4185ea3e7f9 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs @@ -44,6 +44,7 @@ public static RazorConfiguration ReadConfigurationFromProperties(JsonDataReader var languageVersionText = reader.ReadNonNullString(nameof(RazorConfiguration.LanguageVersion)); var suppressAddComponentParameter = reader.ReadBooleanOrFalse(nameof(RazorConfiguration.SuppressAddComponentParameter)); var useConsolidatedMvcViews = reader.ReadBooleanOrTrue(nameof(RazorConfiguration.UseConsolidatedMvcViews)); + var useRoslynTokenizer = reader.ReadBooleanOrFalse(nameof(RazorConfiguration.UseRoslynTokenizer)); var extensions = reader.ReadImmutableArrayOrEmpty(nameof(RazorConfiguration.Extensions), static r => { @@ -55,7 +56,7 @@ public static RazorConfiguration ReadConfigurationFromProperties(JsonDataReader ? version : RazorLanguageVersion.Version_2_1; - return new(languageVersion, configurationName, extensions, SuppressAddComponentParameter: suppressAddComponentParameter); + return new(languageVersion, configurationName, extensions, SuppressAddComponentParameter: suppressAddComponentParameter, UseRoslynTokenizer: useRoslynTokenizer); } public static RazorDiagnostic ReadDiagnostic(JsonDataReader reader) @@ -102,10 +103,9 @@ public static DocumentSnapshotHandle ReadDocumentSnapshotHandleFromProperties(Js public static ProjectWorkspaceState ReadProjectWorkspaceStateFromProperties(JsonDataReader reader) { var tagHelpers = reader.ReadImmutableArrayOrEmpty(nameof(ProjectWorkspaceState.TagHelpers), static r => ReadTagHelper(r, useCache: true)); - var useRoslynTokenizer = reader.ReadBooleanOrFalse(nameof(ProjectWorkspaceState.UseRoslynTokenizer)); var csharpLanguageVersion = (LanguageVersion)reader.ReadInt32OrZero(nameof(ProjectWorkspaceState.CSharpLanguageVersion)); - return ProjectWorkspaceState.Create(tagHelpers, useRoslynTokenizer, csharpLanguageVersion); + return ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion); } public static TagHelperDescriptor ReadTagHelper(JsonDataReader reader, bool useCache) diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs index 688cf508c42..df1a252ed65 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs @@ -37,6 +37,7 @@ public static void WriteProperties(JsonDataWriter writer, RazorConfiguration val writer.WriteIfNotFalse(nameof(value.SuppressAddComponentParameter), value.SuppressAddComponentParameter); writer.WriteIfNotTrue(nameof(value.UseConsolidatedMvcViews), value.UseConsolidatedMvcViews); + writer.WriteIfNotFalse(nameof(value.UseRoslynTokenizer), value.UseRoslynTokenizer); writer.WriteArrayIfNotNullOrEmpty(nameof(value.Extensions), value.Extensions, static (w, v) => w.Write(v.ExtensionName)); } @@ -84,8 +85,6 @@ public static void Write(JsonDataWriter writer, ProjectWorkspaceState? value) public static void WriteProperties(JsonDataWriter writer, ProjectWorkspaceState value) { writer.WriteArrayIfNotDefaultOrEmpty(nameof(value.TagHelpers), value.TagHelpers, Write); - writer.WriteIfNotFalse(nameof(value.UseRoslynTokenizer), value.UseRoslynTokenizer); - writer.WriteIfNotZero(nameof(value.CSharpLanguageVersion), (int)value.CSharpLanguageVersion); } public static void Write(JsonDataWriter writer, TagHelperDescriptor? value) From f6e3f1c275f4b9656eef8cf22759c24543fb847f Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 28 Oct 2024 14:10:23 +1100 Subject: [PATCH 09/14] Just specify defaults once --- .../src/Language/RazorConfiguration.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs index 94c0e9ae266..4c649de04d7 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs @@ -19,11 +19,7 @@ public sealed record class RazorConfiguration( public static readonly RazorConfiguration Default = new( RazorLanguageVersion.Latest, ConfigurationName: "unnamed", - Extensions: [], - UseConsolidatedMvcViews: true, - SuppressAddComponentParameter: false, - LanguageServerFlags: null, - UseRoslynTokenizer: false); + Extensions: []); public bool Equals(RazorConfiguration? other) => other is not null && From 04375f603443b7e72a66c838c6efc9b09a5365fb Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 28 Oct 2024 14:37:42 +1100 Subject: [PATCH 10/14] Move CSharpLanguageVersion to RazorConfiguration --- .../src/Language/RazorConfiguration.cs | 6 ++- .../RazorLanguageServerBenchmarkBase.cs | 2 +- .../Kendo.Mvc.Examples.project.razor.json | 4 +- .../Resources/project.razor.json | 4 +- .../ProjectSystem/RazorProjectService.cs | 2 +- .../ProjectSystem/ProjectWorkspaceState.cs | 22 +++------- .../ProjectWorkspaceStateFormatter.cs | 9 ++-- .../Formatters/RazorConfigurationFormatter.cs | 8 +++- .../Utilities/RazorProjectInfoFactory.cs | 2 +- .../ProjectSystem/ProjectState.cs | 10 +---- .../Host/ProjectSnapshotManagerProxy.cs | 2 +- .../ProjectWorkspaceStateGenerator.cs | 3 +- .../EphemeralProjectSnapshot.cs | 2 +- .../OpenDocumentGeneratorTest.cs | 7 +--- .../RazorProjectServiceTest.cs | 3 +- .../SerializationTest.cs | 4 +- .../StreamExtensionTests.NetCore.cs | 2 +- .../TestMocks.cs | 4 +- .../ProjectStateGeneratedOutputTest.cs | 25 ----------- .../ProjectSystem/ProjectStateTest.cs | 42 +------------------ .../ObjectReaders.cs | 4 +- .../ObjectWriters.cs | 1 + 22 files changed, 42 insertions(+), 126 deletions(-) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs index 4c649de04d7..e49485e47f7 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorConfiguration.cs @@ -3,6 +3,7 @@ using System.Collections.Immutable; using System.Linq; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.Extensions.Internal; namespace Microsoft.AspNetCore.Razor.Language; @@ -14,7 +15,8 @@ public sealed record class RazorConfiguration( bool UseConsolidatedMvcViews = true, bool SuppressAddComponentParameter = false, LanguageServerFlags? LanguageServerFlags = null, - bool UseRoslynTokenizer = false) + bool UseRoslynTokenizer = false, + LanguageVersion CSharpLanguageVersion = LanguageVersion.Default) { public static readonly RazorConfiguration Default = new( RazorLanguageVersion.Latest, @@ -29,6 +31,7 @@ public bool Equals(RazorConfiguration? other) LanguageServerFlags == other.LanguageServerFlags && UseConsolidatedMvcViews == other.UseConsolidatedMvcViews && UseRoslynTokenizer == other.UseRoslynTokenizer && + CSharpLanguageVersion == other.CSharpLanguageVersion && Extensions.SequenceEqual(other.Extensions); public override int GetHashCode() @@ -41,6 +44,7 @@ public override int GetHashCode() hash.Add(UseConsolidatedMvcViews); hash.Add(LanguageServerFlags); hash.Add(UseRoslynTokenizer); + hash.Add(CSharpLanguageVersion); return hash; } } diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs index e999c1f1613..c50b5d9543a 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs @@ -73,7 +73,7 @@ await projectManager.UpdateAsync( { updater.ProjectAdded(hostProject); var tagHelpers = CommonResources.LegacyTagHelpers; - var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, CodeAnalysis.CSharp.LanguageVersion.CSharp11); + var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers); updater.ProjectWorkspaceStateChanged(hostProject.Key, projectWorkspaceState); updater.DocumentAdded(hostProject.Key, hostDocument, textLoader); }, diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json index 0c4280d8b35..1bf7c4e050d 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/Telerik/Kendo.Mvc.Examples.project.razor.json @@ -6,6 +6,7 @@ "ConfigurationName": "MVC-3.0", "LanguageVersion": "7.0", "UseRoslynTokenizer": true, + "CSharpLanguageVersion": 1100, "Extensions": [ "MVC-3.0" ] @@ -159527,8 +159528,7 @@ "Runtime.Name": "Components.None" } } - ], - "CSharpLanguageVersion": 1100 + ] }, "RootNamespace": "Kendo.Mvc.Examples", "Documents": [ diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json index 0bd019c2146..e00a7130e2f 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Resources/project.razor.json @@ -6,6 +6,7 @@ "ConfigurationName": "MVC-3.0", "LanguageVersion": "3.0", "UseRoslynTokenizer": true, + "CSharpLanguageVersion": 800, "Extensions": [ "MVC-3.0" ] }, "ProjectWorkspaceState": { @@ -16126,8 +16127,7 @@ "Runtime.Name": "Components.None" } } - ], - "CSharpLanguageVersion": 800 + ] }, "RootNamespace": "blazorserver", "Documents": [ diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs index e797c50a4a6..52dc25f7a83 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -366,7 +366,7 @@ private Task AddOrUpdateProjectCoreAsync( if (!projectWorkspaceState.Equals(ProjectWorkspaceState.Default)) { - _logger.LogInformation($"Updating project '{project.Key}' TagHelpers ({projectWorkspaceState.TagHelpers.Length}) and C# Language Version ({projectWorkspaceState.CSharpLanguageVersion})."); + _logger.LogInformation($"Updating project '{project.Key}' TagHelpers ({projectWorkspaceState.TagHelpers.Length})."); } updater.ProjectWorkspaceStateChanged(project.Key, projectWorkspaceState); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs index 041e7cd3bf6..f8eb552ce80 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectSystem/ProjectWorkspaceState.cs @@ -5,44 +5,33 @@ using System.Collections.Immutable; using System.Linq; using Microsoft.AspNetCore.Razor.Language; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.Extensions.Internal; namespace Microsoft.AspNetCore.Razor.ProjectSystem; internal sealed class ProjectWorkspaceState : IEquatable { - public static readonly ProjectWorkspaceState Default = new(ImmutableArray.Empty, LanguageVersion.Default); + public static readonly ProjectWorkspaceState Default = new(ImmutableArray.Empty); public ImmutableArray TagHelpers { get; } - public LanguageVersion CSharpLanguageVersion { get; } private ProjectWorkspaceState( - ImmutableArray tagHelpers, - LanguageVersion csharpLanguageVersion) + ImmutableArray tagHelpers) { TagHelpers = tagHelpers; - CSharpLanguageVersion = csharpLanguageVersion; } public static ProjectWorkspaceState Create( - ImmutableArray tagHelpers, - LanguageVersion csharpLanguageVersion = LanguageVersion.Default) - => tagHelpers.IsEmpty && csharpLanguageVersion == LanguageVersion.Default + ImmutableArray tagHelpers) + => tagHelpers.IsEmpty ? Default - : new(tagHelpers, csharpLanguageVersion); - - public static ProjectWorkspaceState Create(LanguageVersion csharpLanguageVersion) - => csharpLanguageVersion == LanguageVersion.Default - ? Default - : new(ImmutableArray.Empty, csharpLanguageVersion); + : new(tagHelpers); public override bool Equals(object? obj) => obj is ProjectWorkspaceState other && Equals(other); public bool Equals(ProjectWorkspaceState? other) => other is not null && - CSharpLanguageVersion == other.CSharpLanguageVersion && TagHelpers.SequenceEqual(other.TagHelpers); public override int GetHashCode() @@ -50,7 +39,6 @@ public override int GetHashCode() var hash = HashCodeCombiner.Start(); hash.Add(TagHelpers); - hash.Add(CSharpLanguageVersion); return hash.CombinedHash; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs index 60a9894b1da..156c443958e 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/ProjectWorkspaceStateFormatter.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Razor.ProjectSystem; using Microsoft.AspNetCore.Razor.Serialization.MessagePack.Formatters.TagHelpers; using Microsoft.AspNetCore.Razor.Utilities; -using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.AspNetCore.Razor.Serialization.MessagePack.Formatters; @@ -22,7 +21,7 @@ private ProjectWorkspaceStateFormatter() public override ProjectWorkspaceState Deserialize(ref MessagePackReader reader, SerializerCachingOptions options) { - reader.ReadArrayHeaderAndVerify(3); + reader.ReadArrayHeaderAndVerify(2); var checksums = reader.Deserialize>(options); @@ -47,19 +46,17 @@ public override ProjectWorkspaceState Deserialize(ref MessagePackReader reader, } var tagHelpers = builder.DrainToImmutable(); - var csharpLanguageVersion = (LanguageVersion)reader.ReadInt32(); - return ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion); + return ProjectWorkspaceState.Create(tagHelpers); } public override void Serialize(ref MessagePackWriter writer, ProjectWorkspaceState value, SerializerCachingOptions options) { - writer.WriteArrayHeader(3); + writer.WriteArrayHeader(2); var checksums = value.TagHelpers.SelectAsArray(x => x.Checksum); writer.Serialize(checksums, options); writer.Serialize(value.TagHelpers, options); - writer.Write((int)value.CSharpLanguageVersion); } } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/RazorConfigurationFormatter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/RazorConfigurationFormatter.cs index 366ba8c02b0..4bb6b57f8a1 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/RazorConfigurationFormatter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/MessagePack/Formatters/RazorConfigurationFormatter.cs @@ -4,6 +4,7 @@ using MessagePack; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; +using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.AspNetCore.Razor.Serialization.MessagePack.Formatters; @@ -13,7 +14,7 @@ internal sealed class RazorConfigurationFormatter : ValueFormatter TagHelpers => ProjectWorkspaceState.TagHelpers; - public LanguageVersion CSharpLanguageVersion => ProjectWorkspaceState.CSharpLanguageVersion; + public LanguageVersion CSharpLanguageVersion => HostProject.Configuration.CSharpLanguageVersion; /// /// Gets the version of this project, INCLUDING content changes. The is diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs index 7ae74da1e67..b38129fa399 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Host/ProjectSnapshotManagerProxy.cs @@ -101,7 +101,7 @@ internal async Task CalculateUpdatedStateAsync } var tagHelpers = await project.GetTagHelpersAsync(CancellationToken.None).ConfigureAwait(false); - var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, project.CSharpLanguageVersion); + var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers); var projectFilePath = _session.ConvertLocalPathToSharedUri(project.FilePath); var intermediateOutputPath = _session.ConvertLocalPathToSharedUri(project.IntermediateOutputPath); var projectHandleProxy = new ProjectSnapshotHandleProxy(projectFilePath, intermediateOutputPath, project.Configuration, project.RootNamespace, projectWorkspaceState); diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs index 77496320ac3..5b5be19c6be 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs @@ -294,6 +294,7 @@ private void ReleaseSemaphore(ProjectKey projectKey) { SuppressAddComponentParameter = suppressAddComponentParameter, UseRoslynTokenizer = useRoslynTokenizer, + CSharpLanguageVersion = csharpLanguageVersion }; using var _ = StopwatchPool.GetPooledObject(out var watch); @@ -318,7 +319,7 @@ private void ReleaseSemaphore(ProjectKey projectKey) Project: {projectSnapshot.FilePath} """); - return (ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion), configuration); + return (ProjectWorkspaceState.Create(tagHelpers), configuration); } catch (OperationCanceledException) { diff --git a/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/EphemeralProjectSnapshot.cs b/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/EphemeralProjectSnapshot.cs index 48ec5599ffb..281d0f95bb9 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/EphemeralProjectSnapshot.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/EphemeralProjectSnapshot.cs @@ -50,7 +50,7 @@ public EphemeralProjectSnapshot(IProjectEngineFactoryProvider projectEngineFacto public VersionStamp Version => VersionStamp.Default; - public LanguageVersion CSharpLanguageVersion => ProjectWorkspaceState.CSharpLanguageVersion; + public LanguageVersion CSharpLanguageVersion => Configuration.CSharpLanguageVersion; public ValueTask> GetTagHelpersAsync(CancellationToken cancellationToken) => new(ProjectWorkspaceState.TagHelpers); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/OpenDocumentGeneratorTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/OpenDocumentGeneratorTest.cs index 7c05c89c158..a2d8d67c4f7 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/OpenDocumentGeneratorTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/OpenDocumentGeneratorTest.cs @@ -9,7 +9,6 @@ using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer; using Microsoft.AspNetCore.Razor.Test.Common.ProjectSystem; using Microsoft.AspNetCore.Razor.Test.Common.Workspaces; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; using Xunit; @@ -142,8 +141,7 @@ await projectManager.UpdateAsync(updater => updater.DocumentAdded(_hostProject1.Key, _documents[0], _documents[0].CreateEmptyTextLoader()); // Act - updater.ProjectWorkspaceStateChanged(_hostProject1.Key, - ProjectWorkspaceState.Create(LanguageVersion.CSharp8)); + updater.ProjectWorkspaceStateChanged(_hostProject1.Key, ProjectWorkspaceState.Default); }); // Assert @@ -166,8 +164,7 @@ await projectManager.UpdateAsync(updater => updater.DocumentOpened(_hostProject1.Key, _documents[0].FilePath, SourceText.From(string.Empty)); // Act - updater.ProjectWorkspaceStateChanged(_hostProject1.Key, - ProjectWorkspaceState.Create(LanguageVersion.CSharp8)); + updater.ProjectWorkspaceStateChanged(_hostProject1.Key, ProjectWorkspaceState.Default); }); // Assert diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs index a12f848949f..504d2bd5e27 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs @@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer; using Microsoft.AspNetCore.Razor.Test.Common.ProjectSystem; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; using Moq; @@ -66,7 +65,7 @@ await _projectManager.UpdateAsync(updater => updater.ProjectAdded(hostProject); }); - var projectWorkspaceState = ProjectWorkspaceState.Create(LanguageVersion.LatestMajor); + var projectWorkspaceState = ProjectWorkspaceState.Default; // Act await _projectInfoListener.UpdatedAsync(new RazorProjectInfo( diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/SerializationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/SerializationTest.cs index c910ea76606..50ca8dd6db9 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/SerializationTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/SerializationTest.cs @@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Razor.Serialization; using Microsoft.AspNetCore.Razor.Serialization.Json; using Microsoft.AspNetCore.Razor.Test.Common; -using Microsoft.CodeAnalysis.CSharp; using Newtonsoft.Json.Linq; using Xunit; using Xunit.Abstractions; @@ -26,8 +25,7 @@ public SerializationTest(ITestOutputHelper testOutput) _configuration = new(languageVersion, "Custom", [new("TestExtension")]); _projectWorkspaceState = ProjectWorkspaceState.Create( - tagHelpers: [TagHelperDescriptorBuilder.Create("Test", "TestAssembly").Build()], - csharpLanguageVersion: LanguageVersion.LatestMajor); + tagHelpers: [TagHelperDescriptorBuilder.Create("Test", "TestAssembly").Build()]); } [Fact] diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs index 8895137d798..965779a4bd8 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.ProjectEngineHost.Test/StreamExtensionTests.NetCore.cs @@ -77,7 +77,7 @@ public async Task SerializeProjectInfo() .TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name")) .Build(); - var projectWorkspaceState = ProjectWorkspaceState.Create([tagHelper], CodeAnalysis.CSharp.LanguageVersion.Latest); + var projectWorkspaceState = ProjectWorkspaceState.Create([tagHelper]); var projectInfo = new RazorProjectInfo( new ProjectKey("TestProject"), diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/TestMocks.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/TestMocks.cs index 9abf55ceff3..97571789e5e 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/TestMocks.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/TestMocks.cs @@ -116,13 +116,13 @@ public static IProjectSnapshot CreateProjectSnapshot(HostProject hostProject, Pr .Returns(hostProject.RootNamespace); mock.SetupGet(x => x.DisplayName) .Returns(hostProject.DisplayName); + mock.SetupGet(x => x.CSharpLanguageVersion) + .Returns(hostProject.Configuration.CSharpLanguageVersion); if (projectWorkspaceState is not null) { mock.SetupGet(x => x.ProjectWorkspaceState) .Returns(projectWorkspaceState); - mock.SetupGet(x => x.CSharpLanguageVersion) - .Returns(projectWorkspaceState.CSharpLanguageVersion); mock.Setup(x => x.GetTagHelpersAsync(It.IsAny())) .ReturnsAsync(projectWorkspaceState.TagHelpers); } diff --git a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs index 7e80b2537b7..64dbd8b65b8 100644 --- a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs +++ b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateGeneratedOutputTest.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Razor.ProjectSystem; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.AspNetCore.Razor.Test.Common.Workspaces; -using Microsoft.CodeAnalysis.CSharp; using Xunit; using Xunit.Abstractions; @@ -184,30 +183,6 @@ public async Task ProjectWorkspaceStateChange_WithTagHelperChange_DoesNotCacheOu Assert.Equal(state.ProjectWorkspaceStateVersion, actualInputVersion); } - [Fact] - public async Task ProjectWorkspaceStateChange_WithProjectWorkspaceState_CSharpLanguageVersionChange_DoesNotCacheOutput() - { - // Arrange - var csharp8ValidConfiguration = new RazorConfiguration(RazorLanguageVersion.Version_3_0, _hostProject.Configuration.ConfigurationName, _hostProject.Configuration.Extensions); - var hostProject = TestProjectData.SomeProject with { Configuration = csharp8ValidConfiguration }; - var originalWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, LanguageVersion.CSharp7); - var original = - ProjectState.Create(ProjectEngineFactoryProvider, hostProject, originalWorkspaceState) - .WithAddedHostDocument(_hostDocument, TestMocks.CreateTextLoader("@DateTime.Now", VersionStamp.Default)); - var changedWorkspaceState = ProjectWorkspaceState.Create(_someTagHelpers, LanguageVersion.CSharp8); - - var (originalOutput, originalInputVersion) = await GetOutputAsync(original, _hostDocument, DisposalToken); - - // Act - var state = original.WithProjectWorkspaceState(changedWorkspaceState); - - // Assert - var (actualOutput, actualInputVersion) = await GetOutputAsync(state, _hostDocument, DisposalToken); - Assert.NotSame(originalOutput, actualOutput); - Assert.NotEqual(originalInputVersion, actualInputVersion); - Assert.Equal(state.ProjectWorkspaceStateVersion, actualInputVersion); - } - [Fact] public async Task ConfigurationChange_DoesNotCacheOutput() { diff --git a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs index 2658d893683..334a5c016c5 100644 --- a/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs +++ b/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/ProjectSystem/ProjectStateTest.cs @@ -9,7 +9,6 @@ using Microsoft.AspNetCore.Razor.ProjectSystem; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.AspNetCore.Razor.Test.Common.Workspaces; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; using Xunit; using Xunit.Abstractions; @@ -642,45 +641,6 @@ public void ProjectState_WithHostProject_ResetsImportedDocuments() Assert.Equal(TestProjectData.SomeProjectFile1.FilePath, documentFilePath); } - [Fact] - public void ProjectState_WithProjectWorkspaceState_Changed() - { - // Arrange - var original = ProjectState.Create(ProjectEngineFactoryProvider, _hostProject, _projectWorkspaceState) - .WithAddedHostDocument(_documents[2], DocumentState.EmptyLoader) - .WithAddedHostDocument(_documents[1], DocumentState.EmptyLoader); - - // Force init - var originalTagHelpers = original.TagHelpers; - var originalProjectWorkspaceStateVersion = original.ProjectWorkspaceStateVersion; - - var changed = ProjectWorkspaceState.Create(_projectWorkspaceState.TagHelpers, LanguageVersion.CSharp6); - - // Act - var state = original.WithProjectWorkspaceState(changed); - - // Assert - Assert.NotEqual(original.Version, state.Version); - Assert.Same(changed, state.ProjectWorkspaceState); - - var actualTagHelpers = state.TagHelpers; - var actualProjectWorkspaceStateVersion = state.ProjectWorkspaceStateVersion; - - // The C# language version changed, and the tag helpers didn't change - Assert.NotSame(original.ProjectEngine, state.ProjectEngine); - - Assert.Equal(originalTagHelpers.Length, actualTagHelpers.Length); - for (var i = 0; i < originalTagHelpers.Length; i++) - { - Assert.Same(originalTagHelpers[i], actualTagHelpers[i]); - } - - Assert.NotEqual(originalProjectWorkspaceStateVersion, actualProjectWorkspaceStateVersion); - - Assert.NotSame(original.Documents[_documents[1].FilePath], state.Documents[_documents[1].FilePath]); - Assert.NotSame(original.Documents[_documents[2].FilePath], state.Documents[_documents[2].FilePath]); - } - [Fact] public void ProjectState_WithProjectWorkspaceState_Changed_TagHelpersChanged() { @@ -727,7 +687,7 @@ public void ProjectState_WithProjectWorkspaceState_IdenticalState_Caches() _ = original.TagHelpers; _ = original.ProjectWorkspaceStateVersion; - var changed = ProjectWorkspaceState.Create(original.TagHelpers, original.CSharpLanguageVersion); + var changed = ProjectWorkspaceState.Create(original.TagHelpers); // Act var state = original.WithProjectWorkspaceState(changed); diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs index 4185ea3e7f9..ed7f469a31b 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectReaders.cs @@ -45,6 +45,7 @@ public static RazorConfiguration ReadConfigurationFromProperties(JsonDataReader var suppressAddComponentParameter = reader.ReadBooleanOrFalse(nameof(RazorConfiguration.SuppressAddComponentParameter)); var useConsolidatedMvcViews = reader.ReadBooleanOrTrue(nameof(RazorConfiguration.UseConsolidatedMvcViews)); var useRoslynTokenizer = reader.ReadBooleanOrFalse(nameof(RazorConfiguration.UseRoslynTokenizer)); + var csharpLanguageVersion = (LanguageVersion)reader.ReadInt32OrZero(nameof(RazorConfiguration.CSharpLanguageVersion)); var extensions = reader.ReadImmutableArrayOrEmpty(nameof(RazorConfiguration.Extensions), static r => { @@ -103,9 +104,8 @@ public static DocumentSnapshotHandle ReadDocumentSnapshotHandleFromProperties(Js public static ProjectWorkspaceState ReadProjectWorkspaceStateFromProperties(JsonDataReader reader) { var tagHelpers = reader.ReadImmutableArrayOrEmpty(nameof(ProjectWorkspaceState.TagHelpers), static r => ReadTagHelper(r, useCache: true)); - var csharpLanguageVersion = (LanguageVersion)reader.ReadInt32OrZero(nameof(ProjectWorkspaceState.CSharpLanguageVersion)); - return ProjectWorkspaceState.Create(tagHelpers, csharpLanguageVersion); + return ProjectWorkspaceState.Create(tagHelpers); } public static TagHelperDescriptor ReadTagHelper(JsonDataReader reader, bool useCache) diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs index df1a252ed65..c03051e73c9 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Serialization.Json/ObjectWriters.cs @@ -38,6 +38,7 @@ public static void WriteProperties(JsonDataWriter writer, RazorConfiguration val writer.WriteIfNotFalse(nameof(value.SuppressAddComponentParameter), value.SuppressAddComponentParameter); writer.WriteIfNotTrue(nameof(value.UseConsolidatedMvcViews), value.UseConsolidatedMvcViews); writer.WriteIfNotFalse(nameof(value.UseRoslynTokenizer), value.UseRoslynTokenizer); + writer.WriteIfNotZero(nameof(value.CSharpLanguageVersion), (int)value.CSharpLanguageVersion); writer.WriteArrayIfNotNullOrEmpty(nameof(value.Extensions), value.Extensions, static (w, v) => w.Write(v.ExtensionName)); } From 1e8e1f1a57e66681dfcbff3342f61eef865ec3c4 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 28 Oct 2024 14:42:22 +1100 Subject: [PATCH 11/14] Remove CSharpLanguageVersion from project classes, so it's clear where it comes from --- .../ProjectSystem/IProjectSnapshot.cs | 2 -- .../ProjectSystem/ProjectSnapshot.cs | 2 -- .../ProjectSystem/ProjectState.cs | 4 +--- .../EphemeralProjectSnapshot.cs | 3 --- .../Parsing/VisualStudioRazorParser.cs | 2 +- .../ProjectSystem/IProjectSnapshotManagerExtensionsTest.cs | 2 +- .../ProjectSystem/TestProjectSnapshot.cs | 1 - .../TestMocks.cs | 2 -- 8 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IProjectSnapshot.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IProjectSnapshot.cs index 3494b7c108d..ea4d2ea12de 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IProjectSnapshot.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IProjectSnapshot.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.ProjectSystem; -using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.CodeAnalysis.Razor.ProjectSystem; @@ -32,7 +31,6 @@ internal interface IProjectSnapshot string? RootNamespace { get; } string DisplayName { get; } VersionStamp Version { get; } - LanguageVersion CSharpLanguageVersion { get; } ProjectWorkspaceState ProjectWorkspaceState { get; } RazorProjectEngine GetProjectEngine(); diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectSnapshot.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectSnapshot.cs index 8f844402e2e..e2fe87b71a8 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectSnapshot.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectSnapshot.cs @@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.AspNetCore.Razor.ProjectSystem; using Microsoft.AspNetCore.Razor.Utilities; -using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.CodeAnalysis.Razor.ProjectSystem; @@ -32,7 +31,6 @@ internal sealed class ProjectSnapshot(ProjectState state) : IProjectSnapshot public string? RootNamespace => _state.HostProject.RootNamespace; public string DisplayName => _state.HostProject.DisplayName; public VersionStamp Version => _state.Version; - public LanguageVersion CSharpLanguageVersion => _state.CSharpLanguageVersion; public ProjectWorkspaceState ProjectWorkspaceState => _state.ProjectWorkspaceState; public int DocumentCount => _state.Documents.Count; diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs index 8057e8c94d6..1fe54321749 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs @@ -166,8 +166,6 @@ private ProjectState( public ImmutableArray TagHelpers => ProjectWorkspaceState.TagHelpers; - public LanguageVersion CSharpLanguageVersion => HostProject.Configuration.CSharpLanguageVersion; - /// /// Gets the version of this project, INCLUDING content changes. The is /// incremented for each new instance created. @@ -200,7 +198,7 @@ RazorProjectEngine CreateProjectEngine() return _projectEngineFactoryProvider.Create(configuration, rootDirectoryPath, builder => { builder.SetRootNamespace(HostProject.RootNamespace); - builder.SetCSharpLanguageVersion(CSharpLanguageVersion); + builder.SetCSharpLanguageVersion(configuration.CSharpLanguageVersion); builder.SetSupportLocalizedComponentNames(); builder.Features.Add(new ConfigureRazorParserOptions(useRoslynTokenizer: configuration.UseRoslynTokenizer, CSharpParseOptions.Default)); }); diff --git a/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/EphemeralProjectSnapshot.cs b/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/EphemeralProjectSnapshot.cs index 281d0f95bb9..8257de4f3f9 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/EphemeralProjectSnapshot.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/EphemeralProjectSnapshot.cs @@ -12,7 +12,6 @@ using Microsoft.AspNetCore.Razor.ProjectEngineHost; using Microsoft.AspNetCore.Razor.ProjectSystem; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Razor.ProjectSystem; namespace Microsoft.VisualStudio.LegacyEditor.Razor; @@ -50,8 +49,6 @@ public EphemeralProjectSnapshot(IProjectEngineFactoryProvider projectEngineFacto public VersionStamp Version => VersionStamp.Default; - public LanguageVersion CSharpLanguageVersion => Configuration.CSharpLanguageVersion; - public ValueTask> GetTagHelpersAsync(CancellationToken cancellationToken) => new(ProjectWorkspaceState.TagHelpers); public ProjectWorkspaceState ProjectWorkspaceState => ProjectWorkspaceState.Default; diff --git a/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/Parsing/VisualStudioRazorParser.cs b/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/Parsing/VisualStudioRazorParser.cs index ebc69bd57fa..67d2ab55309 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/Parsing/VisualStudioRazorParser.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LegacyEditor.Razor/Parsing/VisualStudioRazorParser.cs @@ -494,7 +494,7 @@ private void ConfigureProjectEngine(RazorProjectEngineBuilder builder) var projectSnapshot = _documentTracker.ProjectSnapshot; if (projectSnapshot != null) { - builder.SetCSharpLanguageVersion(projectSnapshot.CSharpLanguageVersion); + builder.SetCSharpLanguageVersion(projectSnapshot.Configuration.CSharpLanguageVersion); } builder.SetRootNamespace(projectSnapshot?.RootNamespace); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/ProjectSystem/IProjectSnapshotManagerExtensionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/ProjectSystem/IProjectSnapshotManagerExtensionsTest.cs index c124083560f..8523658e6e3 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/ProjectSystem/IProjectSnapshotManagerExtensionsTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/ProjectSystem/IProjectSnapshotManagerExtensionsTest.cs @@ -266,7 +266,7 @@ await projectManager.UpdateAsync(updater => private static void AssertSnapshotsEqual(IProjectSnapshot first, IProjectSnapshot second) { Assert.Equal(first.FilePath, second.FilePath); - Assert.Equal(first.CSharpLanguageVersion, second.CSharpLanguageVersion); + Assert.Equal(first.Configuration, second.Configuration); Assert.Equal(first.RootNamespace, second.RootNamespace); } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/ProjectSystem/TestProjectSnapshot.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/ProjectSystem/TestProjectSnapshot.cs index 731bf4a98dd..c094f233b34 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/ProjectSystem/TestProjectSnapshot.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/ProjectSystem/TestProjectSnapshot.cs @@ -44,7 +44,6 @@ public static TestProjectSnapshot Create(string filePath, ProjectWorkspaceState? public string IntermediateOutputPath => RealSnapshot.IntermediateOutputPath; public string? RootNamespace => RealSnapshot.RootNamespace; public string DisplayName => RealSnapshot.DisplayName; - public LanguageVersion CSharpLanguageVersion => RealSnapshot.CSharpLanguageVersion; public ProjectWorkspaceState ProjectWorkspaceState => RealSnapshot.ProjectWorkspaceState; public VersionStamp Version => RealSnapshot.Version; diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/TestMocks.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/TestMocks.cs index 97571789e5e..cdbc6c655d3 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/TestMocks.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/TestMocks.cs @@ -116,8 +116,6 @@ public static IProjectSnapshot CreateProjectSnapshot(HostProject hostProject, Pr .Returns(hostProject.RootNamespace); mock.SetupGet(x => x.DisplayName) .Returns(hostProject.DisplayName); - mock.SetupGet(x => x.CSharpLanguageVersion) - .Returns(hostProject.Configuration.CSharpLanguageVersion); if (projectWorkspaceState is not null) { From 0ee391d1c44cb56e5d51d16b48e4d1e10d2031b5 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 28 Oct 2024 14:47:12 +1100 Subject: [PATCH 12/14] Rename classes for clarity --- ...or.cs => IRoslynProjectChangeProcessor.cs} | 2 +- ...> RoslynProjectChangeDetector.Comparer.cs} | 2 +- ...ctor.cs => RoslynProjectChangeDetector.cs} | 14 +++--- ...lynProjectChangeProcessor.TestAccessor.cs} | 4 +- ...oslynProjectChangeProcessor.UpdateItem.cs} | 2 +- ...tor.cs => RoslynProjectChangeProcessor.cs} | 8 ++-- ...tionUpdatesProjectSnapshotChangeTrigger.cs | 10 ++--- ....cs => RoslynProjectChangeDetectorTest.cs} | 44 +++++++++---------- ...cs => TestRoslynProjectChangeProcessor.cs} | 2 +- ...cs => RoslynProjectChangeProcessorTest.cs} | 14 +++--- ...UpdatesProjectSnapshotChangeTriggerTest.cs | 12 ++--- 11 files changed, 57 insertions(+), 57 deletions(-) rename src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/{IProjectWorkspaceStateGenerator.cs => IRoslynProjectChangeProcessor.cs} (88%) rename src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/{WorkspaceProjectStateChangeDetector.Comparer.cs => RoslynProjectChangeDetector.Comparer.cs} (94%) rename src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/{WorkspaceProjectStateChangeDetector.cs => RoslynProjectChangeDetector.cs} (97%) rename src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/{ProjectWorkspaceStateGenerator.TestAccessor.cs => RoslynProjectChangeProcessor.TestAccessor.cs} (93%) rename src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/{ProjectWorkspaceStateGenerator.UpdateItem.cs => RoslynProjectChangeProcessor.UpdateItem.cs} (95%) rename src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/{ProjectWorkspaceStateGenerator.cs => RoslynProjectChangeProcessor.cs} (98%) rename src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/{WorkspaceProjectStateChangeDetectorTest.cs => RoslynProjectChangeDetectorTest.cs} (94%) rename src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/{TestProjectWorkspaceStateGenerator.cs => TestRoslynProjectChangeProcessor.cs} (95%) rename src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/{ProjectWorkspaceStateGeneratorTest.cs => RoslynProjectChangeProcessorTest.cs} (92%) diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/IProjectWorkspaceStateGenerator.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/IRoslynProjectChangeProcessor.cs similarity index 88% rename from src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/IProjectWorkspaceStateGenerator.cs rename to src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/IRoslynProjectChangeProcessor.cs index 8bf2287cc10..b94fceb6597 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/IProjectWorkspaceStateGenerator.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/IRoslynProjectChangeProcessor.cs @@ -6,7 +6,7 @@ namespace Microsoft.VisualStudio.Razor; -internal interface IProjectWorkspaceStateGenerator +internal interface IRoslynProjectChangeProcessor { void EnqueueUpdate(Project? workspaceProject, IProjectSnapshot projectSnapshot); diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/WorkspaceProjectStateChangeDetector.Comparer.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.Comparer.cs similarity index 94% rename from src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/WorkspaceProjectStateChangeDetector.Comparer.cs rename to src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.Comparer.cs index a99454a01e3..dfc378d2de0 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/WorkspaceProjectStateChangeDetector.Comparer.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.Comparer.cs @@ -8,7 +8,7 @@ namespace Microsoft.VisualStudio.Razor; -internal partial class WorkspaceProjectStateChangeDetector +internal partial class RoslynProjectChangeDetector { private sealed class Comparer : IEqualityComparer<(Project?, IProjectSnapshot)> { diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/WorkspaceProjectStateChangeDetector.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.cs similarity index 97% rename from src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/WorkspaceProjectStateChangeDetector.cs rename to src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.cs index 0d45fd4a82a..258e6522011 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/WorkspaceProjectStateChangeDetector.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.cs @@ -20,11 +20,11 @@ namespace Microsoft.VisualStudio.Razor; [Export(typeof(IRazorStartupService))] -internal partial class WorkspaceProjectStateChangeDetector : IRazorStartupService, IDisposable +internal partial class RoslynProjectChangeDetector : IRazorStartupService, IDisposable { private static readonly TimeSpan s_delay = TimeSpan.FromSeconds(1); - private readonly IProjectWorkspaceStateGenerator _generator; + private readonly IRoslynProjectChangeProcessor _generator; private readonly IProjectSnapshotManager _projectManager; private readonly LanguageServerFeatureOptions _options; private readonly CodeAnalysis.Workspace _workspace; @@ -35,8 +35,8 @@ internal partial class WorkspaceProjectStateChangeDetector : IRazorStartupServic private WorkspaceChangedListener? _workspaceChangedListener; [ImportingConstructor] - public WorkspaceProjectStateChangeDetector( - IProjectWorkspaceStateGenerator generator, + public RoslynProjectChangeDetector( + IRoslynProjectChangeProcessor generator, IProjectSnapshotManager projectManager, LanguageServerFeatureOptions options, IWorkspaceProvider workspaceProvider) @@ -44,8 +44,8 @@ public WorkspaceProjectStateChangeDetector( { } - public WorkspaceProjectStateChangeDetector( - IProjectWorkspaceStateGenerator generator, + public RoslynProjectChangeDetector( + IRoslynProjectChangeProcessor generator, IProjectSnapshotManager projectManager, LanguageServerFeatureOptions options, IWorkspaceProvider workspaceProvider, @@ -414,7 +414,7 @@ private bool TryGetProjectSnapshot(Project? project, [NotNullWhen(true)] out IPr internal TestAccessor GetTestAccessor() => new(this); - internal sealed class TestAccessor(WorkspaceProjectStateChangeDetector instance) + internal sealed class TestAccessor(RoslynProjectChangeDetector instance) { public void CancelExistingWork() { diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.TestAccessor.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeProcessor.TestAccessor.cs similarity index 93% rename from src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.TestAccessor.cs rename to src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeProcessor.TestAccessor.cs index 089fb498809..c57b68d32a9 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.TestAccessor.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeProcessor.TestAccessor.cs @@ -8,11 +8,11 @@ namespace Microsoft.VisualStudio.Razor; -internal sealed partial class ProjectWorkspaceStateGenerator +internal sealed partial class RoslynProjectChangeProcessor { internal TestAccessor GetTestAccessor() => new(this); - internal sealed class TestAccessor(ProjectWorkspaceStateGenerator instance) + internal sealed class TestAccessor(RoslynProjectChangeProcessor instance) { public interface IUpdateItem { diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.UpdateItem.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeProcessor.UpdateItem.cs similarity index 95% rename from src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.UpdateItem.cs rename to src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeProcessor.UpdateItem.cs index 63ff4cc45e9..10e1afbeb49 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.UpdateItem.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeProcessor.UpdateItem.cs @@ -7,7 +7,7 @@ namespace Microsoft.VisualStudio.Razor; -internal sealed partial class ProjectWorkspaceStateGenerator +internal sealed partial class RoslynProjectChangeProcessor { private sealed class UpdateItem { diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeProcessor.cs similarity index 98% rename from src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs rename to src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeProcessor.cs index 5b5be19c6be..4d8f9a62f47 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectWorkspaceStateGenerator.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeProcessor.cs @@ -19,21 +19,21 @@ namespace Microsoft.VisualStudio.Razor; -[Export(typeof(IProjectWorkspaceStateGenerator))] +[Export(typeof(IRoslynProjectChangeProcessor))] [method: ImportingConstructor] -internal sealed partial class ProjectWorkspaceStateGenerator( +internal sealed partial class RoslynProjectChangeProcessor( IProjectSnapshotManager projectManager, ITagHelperResolver tagHelperResolver, ILoggerFactory loggerFactory, ITelemetryReporter telemetryReporter) - : IProjectWorkspaceStateGenerator, IDisposable + : IRoslynProjectChangeProcessor, IDisposable { // SemaphoreSlim is banned. See https://github.com/dotnet/razor/issues/10390 for more info. #pragma warning disable RS0030 // Do not use banned APIs private readonly IProjectSnapshotManager _projectManager = projectManager; private readonly ITagHelperResolver _tagHelperResolver = tagHelperResolver; - private readonly ILogger _logger = loggerFactory.GetOrCreateLogger(); + private readonly ILogger _logger = loggerFactory.GetOrCreateLogger(); private readonly ITelemetryReporter _telemetryReporter = telemetryReporter; private readonly SemaphoreSlim _semaphore = new(initialCount: 1); diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/VsSolutionUpdatesProjectSnapshotChangeTrigger.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/VsSolutionUpdatesProjectSnapshotChangeTrigger.cs index c1e9de5988f..7286defb341 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/VsSolutionUpdatesProjectSnapshotChangeTrigger.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/VsSolutionUpdatesProjectSnapshotChangeTrigger.cs @@ -21,7 +21,7 @@ internal class VsSolutionUpdatesProjectSnapshotChangeTrigger : IRazorStartupServ { private readonly IServiceProvider _serviceProvider; private readonly IProjectSnapshotManager _projectManager; - private readonly IProjectWorkspaceStateGenerator _workspaceStateGenerator; + private readonly IRoslynProjectChangeProcessor _projectChangeProcessor; private readonly IWorkspaceProvider _workspaceProvider; private readonly JoinableTaskFactory _jtf; private readonly CancellationTokenSource _disposeTokenSource; @@ -36,13 +36,13 @@ internal class VsSolutionUpdatesProjectSnapshotChangeTrigger : IRazorStartupServ public VsSolutionUpdatesProjectSnapshotChangeTrigger( [Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider, IProjectSnapshotManager projectManager, - IProjectWorkspaceStateGenerator workspaceStateGenerator, + IRoslynProjectChangeProcessor projectChangeProcessor, IWorkspaceProvider workspaceProvider, JoinableTaskContext joinableTaskContext) { _serviceProvider = serviceProvider; _projectManager = projectManager; - _workspaceStateGenerator = workspaceStateGenerator; + _projectChangeProcessor = projectChangeProcessor; _workspaceProvider = workspaceProvider; _jtf = joinableTaskContext.Factory; @@ -110,7 +110,7 @@ private void ProjectManager_Changed(object sender, ProjectChangeEventArgs args) if (args.SolutionIsClosing) { // If the solution is closing, cancel all existing updates. - _workspaceStateGenerator.CancelUpdates(); + _projectChangeProcessor.CancelUpdates(); } } @@ -133,7 +133,7 @@ private async Task OnProjectBuiltAsync(IVsHierarchy projectHierarchy, Cancellati { // Trigger a tag helper update by forcing the project manager to see the workspace Project // from the current solution. - _workspaceStateGenerator.EnqueueUpdate(workspaceProject, projectSnapshot); + _projectChangeProcessor.EnqueueUpdate(workspaceProject, projectSnapshot); } } } diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/WorkspaceProjectStateChangeDetectorTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/RoslynProjectChangeDetectorTest.cs similarity index 94% rename from src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/WorkspaceProjectStateChangeDetectorTest.cs rename to src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/RoslynProjectChangeDetectorTest.cs index 586c6ba2455..090508b92f3 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/WorkspaceProjectStateChangeDetectorTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/RoslynProjectChangeDetectorTest.cs @@ -18,7 +18,7 @@ namespace Microsoft.VisualStudio.Razor.ProjectSystem; -public class WorkspaceProjectStateChangeDetectorTest : VisualStudioWorkspaceTestBase +public class RoslynProjectChangeDetectorTest : VisualStudioWorkspaceTestBase { private readonly HostProject _hostProjectOne; private readonly HostProject _hostProjectTwo; @@ -36,7 +36,7 @@ public class WorkspaceProjectStateChangeDetectorTest : VisualStudioWorkspaceTest private readonly DocumentId _backgroundVirtualCSharpDocumentId; private readonly DocumentId _partialComponentClassDocumentId; - public WorkspaceProjectStateChangeDetectorTest(ITestOutputHelper testOutput) + public RoslynProjectChangeDetectorTest(ITestOutputHelper testOutput) : base(testOutput) { _emptySolution = Workspace.CurrentSolution; @@ -122,7 +122,7 @@ public WorkspaceProjectStateChangeDetectorTest(ITestOutputHelper testOutput) public async Task SolutionClosing_StopsActiveWork() { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -164,7 +164,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentEvents_EnqueuesUpdatesForDependentProjects(WorkspaceChangeKind kind) { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -205,7 +205,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_ProjectEvents_EnqueuesUpdatesForDependentProjects(WorkspaceChangeKind kind) { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -248,7 +248,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_SolutionEvents_EnqueuesUpdatesForProjectsInSolution(WorkspaceChangeKind kind) { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -282,7 +282,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_SolutionEvents_EnqueuesStateClear_EnqueuesSolutionProjectUpdates(WorkspaceChangeKind kind) { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -322,7 +322,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_ProjectChangeEvents_UpdatesProjectState_AfterDelay(WorkspaceChangeKind kind) { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -358,7 +358,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentChanged_BackgroundVirtualCS_UpdatesProjectState_AfterDelay() { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -390,7 +390,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentChanged_CSHTML_UpdatesProjectState_AfterDelay() { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -422,7 +422,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentChanged_Razor_UpdatesProjectState_AfterDelay() { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -454,7 +454,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentChanged_PartialComponent_UpdatesProjectState_AfterDelay() { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -504,7 +504,7 @@ public interface IComponent {} public async Task WorkspaceChanged_ProjectRemovedEvent_QueuesProjectStateRemoval() { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -532,7 +532,7 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_ProjectAddedEvent_AddsProject() { // Arrange - var generator = new TestProjectWorkspaceStateGenerator(); + var generator = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); using var detector = CreateDetector(generator, projectManager); var detectorAccessor = detector.GetTestAccessor(); @@ -576,7 +576,7 @@ public partial class TestComponent{} await document.GetSemanticModelAsync(); // Act - var result = WorkspaceProjectStateChangeDetector.IsPartialComponentClass(document); + var result = RoslynProjectChangeDetector.IsPartialComponentClass(document); // Assert Assert.False(result); @@ -605,7 +605,7 @@ public interface IComponent {} await document.GetSemanticModelAsync(); // Act - var result = WorkspaceProjectStateChangeDetector.IsPartialComponentClass(document); + var result = RoslynProjectChangeDetector.IsPartialComponentClass(document); // Assert Assert.True(result); @@ -630,7 +630,7 @@ public interface IComponent {} Assert.NotNull(document); // Act - var result = WorkspaceProjectStateChangeDetector.IsPartialComponentClass(document); + var result = RoslynProjectChangeDetector.IsPartialComponentClass(document); // Assert Assert.False(result); @@ -657,7 +657,7 @@ public interface IComponent {} await document.GetSyntaxRootAsync(); // Act - var result = WorkspaceProjectStateChangeDetector.IsPartialComponentClass(document); + var result = RoslynProjectChangeDetector.IsPartialComponentClass(document); // Assert Assert.False(result); @@ -680,7 +680,7 @@ public async Task IsPartialComponentClass_NonClass_ReturnsFalse() await document.GetSemanticModelAsync(); // Act - var result = WorkspaceProjectStateChangeDetector.IsPartialComponentClass(document); + var result = RoslynProjectChangeDetector.IsPartialComponentClass(document); // Assert Assert.False(result); @@ -713,7 +713,7 @@ public interface IComponent {} await document.GetSemanticModelAsync(); // Act - var result = WorkspaceProjectStateChangeDetector.IsPartialComponentClass(document); + var result = RoslynProjectChangeDetector.IsPartialComponentClass(document); // Assert Assert.True(result); @@ -745,12 +745,12 @@ public interface IComponent {} await document.GetSemanticModelAsync(); // Act - var result = WorkspaceProjectStateChangeDetector.IsPartialComponentClass(document); + var result = RoslynProjectChangeDetector.IsPartialComponentClass(document); // Assert Assert.False(result); } - private WorkspaceProjectStateChangeDetector CreateDetector(IProjectWorkspaceStateGenerator generator, IProjectSnapshotManager projectManager) + private RoslynProjectChangeDetector CreateDetector(IRoslynProjectChangeProcessor generator, IProjectSnapshotManager projectManager) => new(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider, TimeSpan.FromMilliseconds(10)); } diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/TestProjectWorkspaceStateGenerator.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/TestRoslynProjectChangeProcessor.cs similarity index 95% rename from src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/TestProjectWorkspaceStateGenerator.cs rename to src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/TestRoslynProjectChangeProcessor.cs index 2cabe615d39..7dd0f677c14 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/TestProjectWorkspaceStateGenerator.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/TestRoslynProjectChangeProcessor.cs @@ -8,7 +8,7 @@ namespace Microsoft.VisualStudio.Razor.ProjectSystem; -internal class TestProjectWorkspaceStateGenerator : IProjectWorkspaceStateGenerator +internal class TestRoslynProjectChangeProcessor : IRoslynProjectChangeProcessor { private readonly List _updates = []; diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectWorkspaceStateGeneratorTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RoslynProjectChangeProcessorTest.cs similarity index 92% rename from src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectWorkspaceStateGeneratorTest.cs rename to src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RoslynProjectChangeProcessorTest.cs index 02bfb9efc75..4e3899357a4 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectWorkspaceStateGeneratorTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RoslynProjectChangeProcessorTest.cs @@ -18,7 +18,7 @@ namespace Microsoft.VisualStudio.Razor; -public class ProjectWorkspaceStateGeneratorTest : VisualStudioWorkspaceTestBase +public class RoslynProjectChangeProcessorTest : VisualStudioWorkspaceTestBase { private readonly TestTagHelperResolver _tagHelperResolver; private readonly Project _workspaceProject; @@ -26,7 +26,7 @@ public class ProjectWorkspaceStateGeneratorTest : VisualStudioWorkspaceTestBase private readonly ProjectWorkspaceState _projectWorkspaceStateWithTagHelpers; private readonly TestProjectSnapshotManager _projectManager; - public ProjectWorkspaceStateGeneratorTest(ITestOutputHelper testOutput) + public RoslynProjectChangeProcessorTest(ITestOutputHelper testOutput) : base(testOutput) { _tagHelperResolver = new TestTagHelperResolver( @@ -53,7 +53,7 @@ public ProjectWorkspaceStateGeneratorTest(ITestOutputHelper testOutput) public void Dispose_MakesUpdateNoop() { // Arrange - using var generator = new ProjectWorkspaceStateGenerator( + using var generator = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); var generatorAccessor = generator.GetTestAccessor(); @@ -72,7 +72,7 @@ public void Dispose_MakesUpdateNoop() public void Update_StartsUpdateTask() { // Arrange - using var generator = new ProjectWorkspaceStateGenerator( + using var generator = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); var generatorAccessor = generator.GetTestAccessor(); @@ -90,7 +90,7 @@ public void Update_StartsUpdateTask() public void Update_SoftCancelsIncompleteTaskForSameProject() { // Arrange - using var generator = new ProjectWorkspaceStateGenerator( + using var generator = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); var generatorAccessor = generator.GetTestAccessor(); @@ -111,7 +111,7 @@ public void Update_SoftCancelsIncompleteTaskForSameProject() public async Task Update_NullWorkspaceProject_ClearsProjectWorkspaceState() { // Arrange - using var generator = new ProjectWorkspaceStateGenerator( + using var generator = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); var generatorAccessor = generator.GetTestAccessor(); @@ -139,7 +139,7 @@ await _projectManager.UpdateAsync(updater => public async Task Update_ResolvesTagHelpersAndUpdatesWorkspaceState() { // Arrange - using var generator = new ProjectWorkspaceStateGenerator( + using var generator = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); var generatorAccessor = generator.GetTestAccessor(); diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/VsSolutionUpdatesProjectSnapshotChangeTriggerTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/VsSolutionUpdatesProjectSnapshotChangeTriggerTest.cs index b9158404c92..24533a2bb6e 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/VsSolutionUpdatesProjectSnapshotChangeTriggerTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/VsSolutionUpdatesProjectSnapshotChangeTriggerTest.cs @@ -89,7 +89,7 @@ public async Task Initialize_AttachesEventSink() using (var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger( serviceProvider, projectManager, - StrictMock.Of(), + StrictMock.Of(), _workspaceProvider, JoinableTaskContext)) { @@ -128,7 +128,7 @@ public async Task Initialize_SwitchesToMainThread() using var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger( serviceProvider, projectManager, - StrictMock.Of(), + StrictMock.Of(), _workspaceProvider, JoinableTaskContext); @@ -158,7 +158,7 @@ public async Task SolutionClosing_CancelsActiveWork() }); var serviceProvider = VsMocks.CreateServiceProvider(); - var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); + var workspaceStateGenerator = new TestRoslynProjectChangeProcessor(); var vsHierarchyMock = new StrictMock(); var vsProjectMock = vsHierarchyMock.As(); @@ -211,7 +211,7 @@ public async Task OnProjectBuiltAsync_KnownProject_EnqueuesProjectStateUpdate() }); var serviceProvider = VsMocks.CreateServiceProvider(); - var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); + var workspaceStateGenerator = new TestRoslynProjectChangeProcessor(); using var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger( serviceProvider, @@ -262,7 +262,7 @@ await projectManager.UpdateAsync(updater => new HostProject("/Some/Unknown/Path.csproj", "/Some/Unknown/obj", RazorConfiguration.Default, "Path")); }); - var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); + var workspaceStateGenerator = new TestRoslynProjectChangeProcessor(); using var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger( serviceProvider, @@ -298,7 +298,7 @@ public async Task OnProjectBuiltAsync_UnknownProject_DoesNotEnqueueUpdate() var projectManager = CreateProjectSnapshotManager(); - var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); + var workspaceStateGenerator = new TestRoslynProjectChangeProcessor(); using var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger( serviceProvider, From 39dccd9625eec67ab900affd74168ea1e7dcbe78 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Tue, 29 Oct 2024 08:47:21 +1100 Subject: [PATCH 13/14] PR Feedback --- .../RoslynProjectChangeDetector.Comparer.cs | 5 +- .../RoslynProjectChangeDetector.cs | 12 +-- .../OpenDocumentGeneratorTest.cs | 18 +++- .../RoslynProjectChangeDetectorTest.cs | 100 +++++++++--------- .../RoslynProjectChangeProcessorTest.cs | 54 +++++----- ...UpdatesProjectSnapshotChangeTriggerTest.cs | 24 ++--- 6 files changed, 113 insertions(+), 100 deletions(-) diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.Comparer.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.Comparer.cs index dfc378d2de0..d4b9d5c64d8 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.Comparer.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.Comparer.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.ProjectSystem; namespace Microsoft.VisualStudio.Razor; @@ -23,14 +22,14 @@ public bool Equals((Project?, IProjectSnapshot) x, (Project?, IProjectSnapshot) var (_, snapshotX) = x; var (_, snapshotY) = y; - return FilePathComparer.Instance.Equals(snapshotX.Key.Id, snapshotY.Key.Id); + return snapshotX.Key.Equals(snapshotY.Key); } public int GetHashCode((Project?, IProjectSnapshot) obj) { var (_, snapshot) = obj; - return FilePathComparer.Instance.GetHashCode(snapshot.Key.Id); + return snapshot.Key.GetHashCode(); } } } diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.cs index 258e6522011..33b2c551211 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/RoslynProjectChangeDetector.cs @@ -24,7 +24,7 @@ internal partial class RoslynProjectChangeDetector : IRazorStartupService, IDisp { private static readonly TimeSpan s_delay = TimeSpan.FromSeconds(1); - private readonly IRoslynProjectChangeProcessor _generator; + private readonly IRoslynProjectChangeProcessor _processor; private readonly IProjectSnapshotManager _projectManager; private readonly LanguageServerFeatureOptions _options; private readonly CodeAnalysis.Workspace _workspace; @@ -36,22 +36,22 @@ internal partial class RoslynProjectChangeDetector : IRazorStartupService, IDisp [ImportingConstructor] public RoslynProjectChangeDetector( - IRoslynProjectChangeProcessor generator, + IRoslynProjectChangeProcessor processor, IProjectSnapshotManager projectManager, LanguageServerFeatureOptions options, IWorkspaceProvider workspaceProvider) - : this(generator, projectManager, options, workspaceProvider, s_delay) + : this(processor, projectManager, options, workspaceProvider, s_delay) { } public RoslynProjectChangeDetector( - IRoslynProjectChangeProcessor generator, + IRoslynProjectChangeProcessor processor, IProjectSnapshotManager projectManager, LanguageServerFeatureOptions options, IWorkspaceProvider workspaceProvider, TimeSpan delay) { - _generator = generator; + _processor = processor; _projectManager = projectManager; _options = options; @@ -94,7 +94,7 @@ private ValueTask ProcessBatchAsync(ImmutableArray<(Project? Project, IProjectSn return default; } - _generator.EnqueueUpdate(project, projectSnapshot); + _processor.EnqueueUpdate(project, projectSnapshot); } return default; diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/OpenDocumentGeneratorTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/OpenDocumentGeneratorTest.cs index a2d8d67c4f7..f56b61fddd3 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/OpenDocumentGeneratorTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/OpenDocumentGeneratorTest.cs @@ -141,7 +141,14 @@ await projectManager.UpdateAsync(updater => updater.DocumentAdded(_hostProject1.Key, _documents[0], _documents[0].CreateEmptyTextLoader()); // Act - updater.ProjectWorkspaceStateChanged(_hostProject1.Key, ProjectWorkspaceState.Default); + var changed = _hostProject1 with + { + Configuration = _hostProject1.Configuration with + { + CSharpLanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp8 + } + }; + updater.ProjectConfigurationChanged(changed); }); // Assert @@ -164,7 +171,14 @@ await projectManager.UpdateAsync(updater => updater.DocumentOpened(_hostProject1.Key, _documents[0].FilePath, SourceText.From(string.Empty)); // Act - updater.ProjectWorkspaceStateChanged(_hostProject1.Key, ProjectWorkspaceState.Default); + var changed = _hostProject1 with + { + Configuration = _hostProject1.Configuration with + { + CSharpLanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp8 + } + }; + updater.ProjectConfigurationChanged(changed); }); // Assert diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/RoslynProjectChangeDetectorTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/RoslynProjectChangeDetectorTest.cs index 090508b92f3..9c7421c2d62 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/RoslynProjectChangeDetectorTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/RoslynProjectChangeDetectorTest.cs @@ -122,9 +122,9 @@ public RoslynProjectChangeDetectorTest(ITestOutputHelper testOutput) public async Task SolutionClosing_StopsActiveWork() { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); var workspaceChangedTask = detectorAccessor.ListenForWorkspaceChangesAsync( @@ -141,7 +141,7 @@ await projectManager.UpdateAsync(updater => await workspaceChangedTask; await detectorAccessor.WaitUntilCurrentBatchCompletesAsync(); - generator.Clear(); + processor.Clear(); // Act await projectManager.UpdateAsync(updater => @@ -154,7 +154,7 @@ await projectManager.UpdateAsync(updater => // Assert - Assert.Empty(generator.Updates); + Assert.Empty(processor.Updates); } [UITheory] @@ -164,9 +164,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentEvents_EnqueuesUpdatesForDependentProjects(WorkspaceChangeKind kind) { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); await projectManager.UpdateAsync(updater => @@ -192,10 +192,10 @@ await projectManager.UpdateAsync(updater => await detectorAccessor.WaitUntilCurrentBatchCompletesAsync(); // Assert - Assert.Equal(3, generator.Updates.Count); - Assert.Contains(generator.Updates, u => u.ProjectSnapshot.Key == _projectNumberOne.ToProjectKey()); - Assert.Contains(generator.Updates, u => u.ProjectSnapshot.Key == _projectNumberTwo.ToProjectKey()); - Assert.Contains(generator.Updates, u => u.ProjectSnapshot.Key == _projectNumberThree.ToProjectKey()); + Assert.Equal(3, processor.Updates.Count); + Assert.Contains(processor.Updates, u => u.ProjectSnapshot.Key == _projectNumberOne.ToProjectKey()); + Assert.Contains(processor.Updates, u => u.ProjectSnapshot.Key == _projectNumberTwo.ToProjectKey()); + Assert.Contains(processor.Updates, u => u.ProjectSnapshot.Key == _projectNumberThree.ToProjectKey()); } [UITheory] @@ -205,9 +205,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_ProjectEvents_EnqueuesUpdatesForDependentProjects(WorkspaceChangeKind kind) { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); await projectManager.UpdateAsync(updater => @@ -233,10 +233,10 @@ await projectManager.UpdateAsync(updater => await detectorAccessor.WaitUntilCurrentBatchCompletesAsync(); // Assert - Assert.Equal(3, generator.Updates.Count); - Assert.Contains(generator.Updates, u => u.ProjectSnapshot.Key == _projectNumberOne.ToProjectKey()); - Assert.Contains(generator.Updates, u => u.ProjectSnapshot.Key == _projectNumberTwo.ToProjectKey()); - Assert.Contains(generator.Updates, u => u.ProjectSnapshot.Key == _projectNumberThree.ToProjectKey()); + Assert.Equal(3, processor.Updates.Count); + Assert.Contains(processor.Updates, u => u.ProjectSnapshot.Key == _projectNumberOne.ToProjectKey()); + Assert.Contains(processor.Updates, u => u.ProjectSnapshot.Key == _projectNumberTwo.ToProjectKey()); + Assert.Contains(processor.Updates, u => u.ProjectSnapshot.Key == _projectNumberThree.ToProjectKey()); } [UITheory] @@ -248,9 +248,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_SolutionEvents_EnqueuesUpdatesForProjectsInSolution(WorkspaceChangeKind kind) { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); await projectManager.UpdateAsync(updater => @@ -268,7 +268,7 @@ await projectManager.UpdateAsync(updater => // Assert Assert.Collection( - generator.Updates, + processor.Updates, p => Assert.Equal(_projectNumberOne.Id, p.WorkspaceProject?.Id), p => Assert.Equal(_projectNumberTwo.Id, p.WorkspaceProject?.Id)); } @@ -282,9 +282,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_SolutionEvents_EnqueuesStateClear_EnqueuesSolutionProjectUpdates(WorkspaceChangeKind kind) { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); await projectManager.UpdateAsync(updater => @@ -309,7 +309,7 @@ await projectManager.UpdateAsync(updater => // Assert Assert.Collection( - generator.Updates, + processor.Updates, p => Assert.Equal(_projectNumberThree.Id, p.WorkspaceProject?.Id), p => Assert.Null(p.WorkspaceProject), p => Assert.Equal(_projectNumberOne.Id, p.WorkspaceProject?.Id), @@ -322,9 +322,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_ProjectChangeEvents_UpdatesProjectState_AfterDelay(WorkspaceChangeKind kind) { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); await projectManager.UpdateAsync(updater => @@ -334,7 +334,7 @@ await projectManager.UpdateAsync(updater => // Stop any existing work and clear out any updates that we might have received. detectorAccessor.CancelExistingWork(); - generator.Clear(); + processor.Clear(); // Create a listener for the workspace change we're about to send. var listenerTask = detectorAccessor.ListenForWorkspaceChangesAsync(kind); @@ -349,7 +349,7 @@ await projectManager.UpdateAsync(updater => await detectorAccessor.WaitUntilCurrentBatchCompletesAsync(); // Assert - var update = Assert.Single(generator.Updates); + var update = Assert.Single(processor.Updates); Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id); Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath); } @@ -358,9 +358,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentChanged_BackgroundVirtualCS_UpdatesProjectState_AfterDelay() { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); Workspace.TryApplyChanges(_solutionWithTwoProjects); @@ -370,7 +370,7 @@ await projectManager.UpdateAsync(updater => updater.ProjectAdded(_hostProjectOne); }); - generator.Clear(); + processor.Clear(); var solution = _solutionWithTwoProjects.WithDocumentText(_backgroundVirtualCSharpDocumentId, SourceText.From("public class Foo{}")); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.DocumentChanged, oldSolution: _solutionWithTwoProjects, newSolution: solution, projectId: _projectNumberOne.Id, _backgroundVirtualCSharpDocumentId); @@ -381,7 +381,7 @@ await projectManager.UpdateAsync(updater => await detectorAccessor.WaitUntilCurrentBatchCompletesAsync(); // Assert - var update = Assert.Single(generator.Updates); + var update = Assert.Single(processor.Updates); Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id); Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath); } @@ -390,9 +390,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentChanged_CSHTML_UpdatesProjectState_AfterDelay() { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); Workspace.TryApplyChanges(_solutionWithTwoProjects); @@ -402,7 +402,7 @@ await projectManager.UpdateAsync(updater => updater.ProjectAdded(_hostProjectOne); }); - generator.Clear(); + processor.Clear(); var solution = _solutionWithTwoProjects.WithDocumentText(_cshtmlDocumentId, SourceText.From("Hello World")); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.DocumentChanged, oldSolution: _solutionWithTwoProjects, newSolution: solution, projectId: _projectNumberOne.Id, _cshtmlDocumentId); @@ -413,7 +413,7 @@ await projectManager.UpdateAsync(updater => await detectorAccessor.WaitUntilCurrentBatchCompletesAsync(); // Assert - var update = Assert.Single(generator.Updates); + var update = Assert.Single(processor.Updates); Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id); Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath); } @@ -422,9 +422,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentChanged_Razor_UpdatesProjectState_AfterDelay() { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); Workspace.TryApplyChanges(_solutionWithTwoProjects); @@ -434,7 +434,7 @@ await projectManager.UpdateAsync(updater => updater.ProjectAdded(_hostProjectOne); }); - generator.Clear(); + processor.Clear(); var solution = _solutionWithTwoProjects.WithDocumentText(_razorDocumentId, SourceText.From("Hello World")); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.DocumentChanged, oldSolution: _solutionWithTwoProjects, newSolution: solution, projectId: _projectNumberOne.Id, _razorDocumentId); @@ -445,7 +445,7 @@ await projectManager.UpdateAsync(updater => await detectorAccessor.WaitUntilCurrentBatchCompletesAsync(); // Assert - var update = Assert.Single(generator.Updates); + var update = Assert.Single(processor.Updates); Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id); Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath); } @@ -454,9 +454,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_DocumentChanged_PartialComponent_UpdatesProjectState_AfterDelay() { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); Workspace.TryApplyChanges(_solutionWithTwoProjects); @@ -467,7 +467,7 @@ await projectManager.UpdateAsync(updater => }); await detectorAccessor.WaitUntilCurrentBatchCompletesAsync(); - generator.Clear(); + processor.Clear(); var sourceText = SourceText.From($$""" public partial class TestComponent : {{ComponentsApi.IComponent.MetadataName}} {} @@ -495,7 +495,7 @@ public interface IComponent {} await detectorAccessor.WaitUntilCurrentBatchCompletesAsync(); // Assert - var update = Assert.Single(generator.Updates); + var update = Assert.Single(processor.Updates); Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id); Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath); } @@ -504,9 +504,9 @@ public interface IComponent {} public async Task WorkspaceChanged_ProjectRemovedEvent_QueuesProjectStateRemoval() { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); await projectManager.UpdateAsync(updater => @@ -524,7 +524,7 @@ await projectManager.UpdateAsync(updater => // Assert Assert.Single( - generator.Updates, + processor.Updates, p => p.WorkspaceProject is null); } @@ -532,9 +532,9 @@ await projectManager.UpdateAsync(updater => public async Task WorkspaceChanged_ProjectAddedEvent_AddsProject() { // Arrange - var generator = new TestRoslynProjectChangeProcessor(); + var processor = new TestRoslynProjectChangeProcessor(); var projectManager = CreateProjectSnapshotManager(); - using var detector = CreateDetector(generator, projectManager); + using var detector = CreateDetector(processor, projectManager); var detectorAccessor = detector.GetTestAccessor(); await projectManager.UpdateAsync(updater => @@ -553,7 +553,7 @@ await projectManager.UpdateAsync(updater => // Assert Assert.Single( - generator.Updates, + processor.Updates, p => p.WorkspaceProject?.Id == _projectNumberThree.Id); } @@ -751,6 +751,6 @@ public interface IComponent {} Assert.False(result); } - private RoslynProjectChangeDetector CreateDetector(IRoslynProjectChangeProcessor generator, IProjectSnapshotManager projectManager) - => new(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider, TimeSpan.FromMilliseconds(10)); + private RoslynProjectChangeDetector CreateDetector(IRoslynProjectChangeProcessor processor, IProjectSnapshotManager projectManager) + => new(processor, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider, TimeSpan.FromMilliseconds(10)); } diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RoslynProjectChangeProcessorTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RoslynProjectChangeProcessorTest.cs index 4e3899357a4..315c2a5dc42 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RoslynProjectChangeProcessorTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RoslynProjectChangeProcessorTest.cs @@ -53,36 +53,36 @@ public RoslynProjectChangeProcessorTest(ITestOutputHelper testOutput) public void Dispose_MakesUpdateNoop() { // Arrange - using var generator = new RoslynProjectChangeProcessor( + using var processor = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); - var generatorAccessor = generator.GetTestAccessor(); - generatorAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); + var processorAccessor = processor.GetTestAccessor(); + processorAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); // Act - generator.Dispose(); + processor.Dispose(); - generator.EnqueueUpdate(_workspaceProject, _projectSnapshot); + processor.EnqueueUpdate(_workspaceProject, _projectSnapshot); // Assert - Assert.Empty(generatorAccessor.GetUpdates()); + Assert.Empty(processorAccessor.GetUpdates()); } [UIFact] public void Update_StartsUpdateTask() { // Arrange - using var generator = new RoslynProjectChangeProcessor( + using var processor = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); - var generatorAccessor = generator.GetTestAccessor(); - generatorAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); + var processorAccessor = processor.GetTestAccessor(); + processorAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); // Act - generator.EnqueueUpdate(_workspaceProject, _projectSnapshot); + processor.EnqueueUpdate(_workspaceProject, _projectSnapshot); // Assert - var update = Assert.Single(generatorAccessor.GetUpdates()); + var update = Assert.Single(processorAccessor.GetUpdates()); Assert.False(update.IsCompleted); } @@ -90,18 +90,18 @@ public void Update_StartsUpdateTask() public void Update_SoftCancelsIncompleteTaskForSameProject() { // Arrange - using var generator = new RoslynProjectChangeProcessor( + using var processor = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); - var generatorAccessor = generator.GetTestAccessor(); - generatorAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); + var processorAccessor = processor.GetTestAccessor(); + processorAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); - generator.EnqueueUpdate(_workspaceProject, _projectSnapshot); + processor.EnqueueUpdate(_workspaceProject, _projectSnapshot); - var initialUpdate = Assert.Single(generatorAccessor.GetUpdates()); + var initialUpdate = Assert.Single(processorAccessor.GetUpdates()); // Act - generator.EnqueueUpdate(_workspaceProject, _projectSnapshot); + processor.EnqueueUpdate(_workspaceProject, _projectSnapshot); // Assert Assert.True(initialUpdate.IsCancellationRequested); @@ -111,11 +111,11 @@ public void Update_SoftCancelsIncompleteTaskForSameProject() public async Task Update_NullWorkspaceProject_ClearsProjectWorkspaceState() { // Arrange - using var generator = new RoslynProjectChangeProcessor( + using var processor = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); - var generatorAccessor = generator.GetTestAccessor(); - generatorAccessor.NotifyBackgroundWorkCompleted = new ManualResetEventSlim(initialState: false); + var processorAccessor = processor.GetTestAccessor(); + processorAccessor.NotifyBackgroundWorkCompleted = new ManualResetEventSlim(initialState: false); await _projectManager.UpdateAsync(updater => { @@ -124,10 +124,10 @@ await _projectManager.UpdateAsync(updater => }); // Act - generator.EnqueueUpdate(workspaceProject: null, _projectSnapshot); + processor.EnqueueUpdate(workspaceProject: null, _projectSnapshot); // Jump off the UI thread so the background work can complete. - await Task.Run(() => generatorAccessor.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(3))); + await Task.Run(() => processorAccessor.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(3))); // Assert var newProjectSnapshot = _projectManager.GetLoadedProject(_projectSnapshot.Key); @@ -139,11 +139,11 @@ await _projectManager.UpdateAsync(updater => public async Task Update_ResolvesTagHelpersAndUpdatesWorkspaceState() { // Arrange - using var generator = new RoslynProjectChangeProcessor( + using var processor = new RoslynProjectChangeProcessor( _projectManager, _tagHelperResolver, LoggerFactory, NoOpTelemetryReporter.Instance); - var generatorAccessor = generator.GetTestAccessor(); - generatorAccessor.NotifyBackgroundWorkCompleted = new ManualResetEventSlim(initialState: false); + var processorAccessor = processor.GetTestAccessor(); + processorAccessor.NotifyBackgroundWorkCompleted = new ManualResetEventSlim(initialState: false); await _projectManager.UpdateAsync(updater => { @@ -151,10 +151,10 @@ await _projectManager.UpdateAsync(updater => }); // Act - generator.EnqueueUpdate(_workspaceProject, _projectSnapshot); + processor.EnqueueUpdate(_workspaceProject, _projectSnapshot); // Jump off the UI thread so the background work can complete. - await Task.Run(() => generatorAccessor.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(3))); + await Task.Run(() => processorAccessor.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(3))); // Assert var newProjectSnapshot = _projectManager.GetLoadedProject(_projectSnapshot.Key); diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/VsSolutionUpdatesProjectSnapshotChangeTriggerTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/VsSolutionUpdatesProjectSnapshotChangeTriggerTest.cs index 24533a2bb6e..d8a42d8829c 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/VsSolutionUpdatesProjectSnapshotChangeTriggerTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/VsSolutionUpdatesProjectSnapshotChangeTriggerTest.cs @@ -158,7 +158,7 @@ public async Task SolutionClosing_CancelsActiveWork() }); var serviceProvider = VsMocks.CreateServiceProvider(); - var workspaceStateGenerator = new TestRoslynProjectChangeProcessor(); + var roslynProjectChangeProcessor = new TestRoslynProjectChangeProcessor(); var vsHierarchyMock = new StrictMock(); var vsProjectMock = vsHierarchyMock.As(); @@ -169,7 +169,7 @@ public async Task SolutionClosing_CancelsActiveWork() using var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger( serviceProvider, projectManager, - workspaceStateGenerator, + roslynProjectChangeProcessor, _workspaceProvider, JoinableTaskContext); @@ -187,7 +187,7 @@ await projectManager.UpdateAsync(updater => updater.ProjectRemoved(s_someProject.Key); }); - var update = Assert.Single(workspaceStateGenerator.Updates); + var update = Assert.Single(roslynProjectChangeProcessor.Updates); Assert.NotNull(update.WorkspaceProject); Assert.Equal(update.WorkspaceProject.Id, _someWorkspaceProject.Id); Assert.Same(expectedProjectSnapshot, update.ProjectSnapshot); @@ -211,12 +211,12 @@ public async Task OnProjectBuiltAsync_KnownProject_EnqueuesProjectStateUpdate() }); var serviceProvider = VsMocks.CreateServiceProvider(); - var workspaceStateGenerator = new TestRoslynProjectChangeProcessor(); + var roslynProjectChangeProcessor = new TestRoslynProjectChangeProcessor(); using var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger( serviceProvider, projectManager, - workspaceStateGenerator, + roslynProjectChangeProcessor, _workspaceProvider, JoinableTaskContext); @@ -232,7 +232,7 @@ public async Task OnProjectBuiltAsync_KnownProject_EnqueuesProjectStateUpdate() await testAccessor.OnProjectBuiltAsync(vsHierarchyMock.Object, DisposalToken); // Assert - var update = Assert.Single(workspaceStateGenerator.Updates); + var update = Assert.Single(roslynProjectChangeProcessor.Updates); Assert.NotNull(update.WorkspaceProject); Assert.Equal(update.WorkspaceProject.Id, _someWorkspaceProject.Id); Assert.Same(expectedProjectSnapshot, update.ProjectSnapshot); @@ -262,12 +262,12 @@ await projectManager.UpdateAsync(updater => new HostProject("/Some/Unknown/Path.csproj", "/Some/Unknown/obj", RazorConfiguration.Default, "Path")); }); - var workspaceStateGenerator = new TestRoslynProjectChangeProcessor(); + var roslynProjectChangeProcessor = new TestRoslynProjectChangeProcessor(); using var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger( serviceProvider, projectManager, - workspaceStateGenerator, + roslynProjectChangeProcessor, _workspaceProvider, JoinableTaskContext); @@ -277,7 +277,7 @@ await projectManager.UpdateAsync(updater => await testAccessor.OnProjectBuiltAsync(StrictMock.Of(), DisposalToken); // Assert - Assert.Empty(workspaceStateGenerator.Updates); + Assert.Empty(roslynProjectChangeProcessor.Updates); } [UIFact] @@ -298,12 +298,12 @@ public async Task OnProjectBuiltAsync_UnknownProject_DoesNotEnqueueUpdate() var projectManager = CreateProjectSnapshotManager(); - var workspaceStateGenerator = new TestRoslynProjectChangeProcessor(); + var roslynProjectChangeProcessor = new TestRoslynProjectChangeProcessor(); using var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger( serviceProvider, projectManager, - workspaceStateGenerator, + roslynProjectChangeProcessor, _workspaceProvider, JoinableTaskContext); @@ -313,6 +313,6 @@ public async Task OnProjectBuiltAsync_UnknownProject_DoesNotEnqueueUpdate() await testAccessor.OnProjectBuiltAsync(StrictMock.Of(), DisposalToken); // Assert - Assert.Empty(workspaceStateGenerator.Updates); + Assert.Empty(roslynProjectChangeProcessor.Updates); } } From efd0d3870a48b337585163ab5a90f29d439ad2fe Mon Sep 17 00:00:00 2001 From: David Wengier Date: Tue, 29 Oct 2024 09:07:17 +1100 Subject: [PATCH 14/14] Missed one test --- .../RazorProjectServiceTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs index 504d2bd5e27..46a9609ffa8 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs @@ -65,7 +65,7 @@ await _projectManager.UpdateAsync(updater => updater.ProjectAdded(hostProject); }); - var projectWorkspaceState = ProjectWorkspaceState.Default; + var projectWorkspaceState = ProjectWorkspaceState.Create([new TagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TagHelper", "TagHelperAssembly").Build()]); // Act await _projectInfoListener.UpdatedAsync(new RazorProjectInfo(