From b95e00f8db481c3fc1250eb7e9143497a4b3378a Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 26 Apr 2024 11:08:11 -0700 Subject: [PATCH 01/16] Add misc project when server is initialized This change updates SnapshotResolver with an InitializeAsync method that is called when the LSP "initialized" endpoint is handled. When initialized, the SnapshotResolver adds the misc project to the ProjectSnapshotManager. Tests have been updated to call InitializeAsync whenever a SnapshotResolver is created. --- .../Hover/HoverService.TestAccessor.cs | 25 +++ .../Hover/HoverService.cs | 22 +-- .../ProjectSystem/ISnapshotResolver.cs | 2 + .../ProjectSystem/SnapshotResolver.cs | 10 ++ .../RazorInitializedEndpoint.cs | 4 + .../DefaultLSPTagHelperTooltipFactoryTest.cs | 13 +- ...DefaultVSLSPTagHelperTooltipFactoryTest.cs | 21 ++- ...egacyRazorCompletionResolveEndpointTest.cs | 22 +-- .../RazorCompletionItemResolverTest.cs | 23 +-- .../TagHelperTooltipFactoryBaseTest.cs | 5 + .../DefaultRazorComponentSearchEngineTest.cs | 1 + .../DocumentContextFactoryTest.cs | 35 ++-- ...extDocumentUriPresentationEndpointTests.cs | 92 ++++++----- .../Hover/HoverServiceTest.cs | 149 ++++++++++-------- .../RazorProjectServiceTest.cs | 17 +- .../Refactoring/RenameEndpointTest.cs | 3 +- .../SnapshotResolverTest.cs | 16 +- .../TestSnapshotResolver.cs | 3 + 18 files changed, 296 insertions(+), 167 deletions(-) create mode 100644 src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hover/HoverService.TestAccessor.cs diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hover/HoverService.TestAccessor.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hover/HoverService.TestAccessor.cs new file mode 100644 index 00000000000..c78299255ad --- /dev/null +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hover/HoverService.TestAccessor.cs @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.VisualStudio.LanguageServer.Protocol; + +namespace Microsoft.AspNetCore.Razor.LanguageServer.Hover; + +internal sealed partial class HoverService +{ + internal TestAccessor GetTestAccessor() => new(this); + + internal sealed class TestAccessor(HoverService instance) + { + public Task GetHoverInfoAsync( + string documentFilePath, + RazorCodeDocument codeDocument, + SourceLocation location, + VSInternalClientCapabilities clientCapabilities, + CancellationToken cancellationToken) + => instance.GetHoverInfoAsync(documentFilePath, codeDocument, location, clientCapabilities, cancellationToken); + } +} diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hover/HoverService.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hover/HoverService.cs index 06df30ce42d..28cefc408c1 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hover/HoverService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hover/HoverService.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Hover; -internal sealed class HoverService( +internal sealed partial class HoverService( LSPTagHelperTooltipFactory lspTagHelperTooltipFactory, VSLSPTagHelperTooltipFactory vsLspTagHelperTooltipFactory, IRazorDocumentMappingService mappingService, @@ -94,15 +94,13 @@ internal sealed class HoverService( return response; } - public TestAccessor GetTestAccessor() => new(this); - - public async Task GetHoverInfoAsync(string documentFilePath, RazorCodeDocument codeDocument, SourceLocation location, VSInternalClientCapabilities clientCapabilities, CancellationToken cancellationToken) + private async Task GetHoverInfoAsync( + string documentFilePath, + RazorCodeDocument codeDocument, + SourceLocation location, + VSInternalClientCapabilities clientCapabilities, + CancellationToken cancellationToken) { - if (codeDocument is null) - { - throw new ArgumentNullException(nameof(codeDocument)); - } - var syntaxTree = codeDocument.GetSyntaxTree(); var owner = syntaxTree.Root.FindInnermostNode(location.AbsoluteIndex); @@ -350,10 +348,4 @@ private static VisualStudioMarkupKind GetHoverContentFormat(ClientCapabilities c var hoverKind = hoverContentFormat?.Contains(VisualStudioMarkupKind.Markdown) == true ? VisualStudioMarkupKind.Markdown : VisualStudioMarkupKind.PlainText; return hoverKind; } - - public class TestAccessor(HoverService service) - { - public Task GetHoverInfoAsync(string documentFilePath, RazorCodeDocument codeDocument, SourceLocation location, VSInternalClientCapabilities clientCapabilities, CancellationToken cancellationToken) - => service.GetHoverInfoAsync(documentFilePath, codeDocument, location, clientCapabilities, cancellationToken); - } } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs index b03ef8bb809..9c72a9ffbb9 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs @@ -10,6 +10,8 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; internal interface ISnapshotResolver { + Task InitializeAsync(CancellationToken cancellationToken); + /// /// Finds all the projects where the document path starts with the path of the folder that contains the project file. /// diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs index 5f5b9584841..c478d6ce6bf 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs @@ -33,6 +33,16 @@ public SnapshotResolver(IProjectSnapshotManager projectManager, ILoggerFactory l MiscellaneousHostProject = new HostProject(normalizedPath, normalizedPath, FallbackRazorConfiguration.Latest, rootNamespace: null, "Miscellaneous Files"); } + public Task InitializeAsync(CancellationToken cancellationToken) + { + // This is called when the language server is initialized. + + return _projectManager.UpdateAsync( + (updater, miscHostProject) => updater.ProjectAdded(miscHostProject), + state: MiscellaneousHostProject, + cancellationToken); + } + /// public ImmutableArray FindPotentialProjects(string documentFilePath) { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs index 8bfa172f064..8dae020e548 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts; +using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CommonLanguageServerProtocol.Framework; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -20,6 +21,9 @@ public async Task HandleNotificationAsync(InitializedParams request, RazorReques var onStartedItems = requestContext.LspServices.GetRequiredServices(); var capabilitiesService = requestContext.GetRequiredService(); + var snapshotResolver = requestContext.LspServices.GetRequiredService(); + await snapshotResolver.InitializeAsync(cancellationToken).ConfigureAwait(false); + var fileChangeDetectorManager = requestContext.LspServices.GetRequiredService(); await fileChangeDetectorManager.InitializedAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultLSPTagHelperTooltipFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultLSPTagHelperTooltipFactoryTest.cs index 44a5019366a..d3e9d38e904 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultLSPTagHelperTooltipFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultLSPTagHelperTooltipFactoryTest.cs @@ -67,6 +67,7 @@ public async Task TryCreateTooltip_Markup_NoAssociatedTagHelperDescriptions_Retu { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundElementDescription.Empty; @@ -82,6 +83,7 @@ public async Task TryCreateTooltip_Markup_Element_SingleAssociatedTagHelper_Retu { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -104,6 +106,7 @@ public async Task TryCreateTooltip_Markup_Element_PlainText_NoBold() { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -123,10 +126,11 @@ public async Task TryCreateTooltip_Markup_Element_PlainText_NoBold() } [Fact] - public void TryCreateTooltip_Markup_Attribute_PlainText_NoBold() + public async Task TryCreateTooltip_Markup_Attribute_PlainText_NoBold() { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { @@ -154,6 +158,7 @@ public async Task TryCreateTooltip_Markup_Element_MultipleAssociatedTagHelpers_R { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -178,10 +183,11 @@ public async Task TryCreateTooltip_Markup_Element_MultipleAssociatedTagHelpers_R } [Fact] - public void TryCreateTooltip_Markup_Attribute_SingleAssociatedAttribute_ReturnsTrue() + public async Task TryCreateTooltip_Markup_Attribute_SingleAssociatedAttribute_ReturnsTrue() { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { @@ -205,10 +211,11 @@ public void TryCreateTooltip_Markup_Attribute_SingleAssociatedAttribute_ReturnsT } [Fact] - public void TryCreateTooltip_Markup_Attribute_MultipleAssociatedAttributes_ReturnsTrue() + public async Task TryCreateTooltip_Markup_Attribute_MultipleAssociatedAttributes_ReturnsTrue() { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultVSLSPTagHelperTooltipFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultVSLSPTagHelperTooltipFactoryTest.cs index 4cc132fddcc..7375f0287e4 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultVSLSPTagHelperTooltipFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultVSLSPTagHelperTooltipFactoryTest.cs @@ -171,6 +171,7 @@ public async Task TryCreateTooltip_ClassifiedTextElement_NoAssociatedTagHelperDe { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundElementDescription.Empty; @@ -186,6 +187,7 @@ public async Task TryCreateTooltip_ClassifiedTextElement_Element_SingleAssociate { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -227,6 +229,7 @@ public async Task TryCreateTooltip_ClassifiedTextElement_Element_NamespaceContai { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -267,6 +270,7 @@ public async Task TryCreateTooltip_ClassifiedTextElement_Element_MultipleAssocia { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -317,10 +321,11 @@ public async Task TryCreateTooltip_ClassifiedTextElement_Element_MultipleAssocia } [Fact] - public void TryCreateTooltip_ClassifiedTextElement_NoAssociatedAttributeDescriptions_ReturnsFalse() + public async Task TryCreateTooltip_ClassifiedTextElement_NoAssociatedAttributeDescriptions_ReturnsFalse() { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundAttributeDescription.Empty; @@ -333,10 +338,11 @@ public void TryCreateTooltip_ClassifiedTextElement_NoAssociatedAttributeDescript } [Fact] - public void TryCreateTooltip_ClassifiedTextElement_Attribute_SingleAssociatedAttribute_ReturnsTrue_NestedTypes() + public async Task TryCreateTooltip_ClassifiedTextElement_Attribute_SingleAssociatedAttribute_ReturnsTrue_NestedTypes() { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { @@ -382,10 +388,11 @@ public void TryCreateTooltip_ClassifiedTextElement_Attribute_SingleAssociatedAtt } [Fact] - public void TryCreateTooltip_ClassifiedTextElement_Attribute_MultipleAssociatedAttributes_ReturnsTrue() + public async Task TryCreateTooltip_ClassifiedTextElement_Attribute_MultipleAssociatedAttributes_ReturnsTrue() { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { @@ -461,6 +468,7 @@ public async Task TryCreateTooltip_ContainerElement_NoAssociatedTagHelperDescrip { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundElementDescription.Empty; @@ -476,6 +484,7 @@ public async Task TryCreateTooltip_ContainerElement_Attribute_MultipleAssociated { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -556,10 +565,11 @@ public async Task TryCreateTooltip_ContainerElement_Attribute_MultipleAssociated } [Fact] - public void TryCreateTooltip_ContainerElement_NoAssociatedAttributeDescriptions_ReturnsFalse() + public async Task TryCreateTooltip_ContainerElement_NoAssociatedAttributeDescriptions_ReturnsFalse() { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundAttributeDescription.Empty; @@ -572,10 +582,11 @@ public void TryCreateTooltip_ContainerElement_NoAssociatedAttributeDescriptions_ } [Fact] - public void TryCreateTooltip_ContainerElement_Attribute_MultipleAssociatedAttributes_ReturnsTrue() + public async Task TryCreateTooltip_ContainerElement_Attribute_MultipleAssociatedAttributes_ReturnsTrue() { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/LegacyRazorCompletionResolveEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/LegacyRazorCompletionResolveEndpointTest.cs index b8eb3739233..85d0266c529 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/LegacyRazorCompletionResolveEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/LegacyRazorCompletionResolveEndpointTest.cs @@ -20,18 +20,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion; -public class LegacyRazorCompletionResolveEndpointTest : LanguageServerTestBase +public class LegacyRazorCompletionResolveEndpointTest(ITestOutputHelper testOutput) : LanguageServerTestBase(testOutput) { - private readonly LSPTagHelperTooltipFactory _lspTagHelperTooltipFactory; - private readonly VSLSPTagHelperTooltipFactory _vsLspTagHelperTooltipFactory; - private readonly CompletionListCache _completionListCache; - private readonly VSInternalCompletionSetting _completionCapability; - private readonly VSInternalClientCapabilities _defaultClientCapability; - - public LegacyRazorCompletionResolveEndpointTest(ITestOutputHelper testOutput) - : base(testOutput) + private LSPTagHelperTooltipFactory _lspTagHelperTooltipFactory; + private VSLSPTagHelperTooltipFactory _vsLspTagHelperTooltipFactory; + private CompletionListCache _completionListCache; + private VSInternalCompletionSetting _completionCapability; + private VSInternalClientCapabilities _defaultClientCapability; + + protected async override Task InitializeAsync() { var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); _lspTagHelperTooltipFactory = new Mock(MockBehavior.Strict, snapshotResolver).Object; _vsLspTagHelperTooltipFactory = new Mock(MockBehavior.Strict, snapshotResolver).Object; _completionListCache = new CompletionListCache(); @@ -97,6 +97,7 @@ public async Task Handle_Resolve_DirectiveAttributeCompletion_ReturnsCompletionI { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var lspDescriptionFactory = new Mock(MockBehavior.Strict, snapshotResolver); var markdown = new MarkupContent { @@ -126,6 +127,7 @@ public async Task Handle_Resolve_DirectiveAttributeParameterCompletion_ReturnsCo { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new Mock(MockBehavior.Strict, snapshotResolver); var markdown = new MarkupContent { @@ -155,6 +157,7 @@ public async Task Handle_Resolve_TagHelperElementCompletion_ReturnsCompletionIte { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var lspDescriptionFactory = new Mock(MockBehavior.Strict, snapshotResolver); var markdown = new MarkupContent { @@ -184,6 +187,7 @@ public async Task Handle_Resolve_TagHelperAttribute_ReturnsCompletionItemWithDoc { // Arrange var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var lspDescriptionFactory = new Mock(MockBehavior.Strict, snapshotResolver); var markdown = new MarkupContent { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionItemResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionItemResolverTest.cs index 4e09d07a1b3..8b27149e518 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionItemResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionItemResolverTest.cs @@ -17,20 +17,21 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion; -public class RazorCompletionItemResolverTest : LanguageServerTestBase +public class RazorCompletionItemResolverTest(ITestOutputHelper testOutput) : LanguageServerTestBase(testOutput) { - private readonly LSPTagHelperTooltipFactory _lspTagHelperTooltipFactory; - private readonly VSLSPTagHelperTooltipFactory _vsLspTagHelperTooltipFactory; - private readonly VSInternalCompletionSetting _completionCapability; - private readonly VSInternalClientCapabilities _defaultClientCapability; - private readonly VSInternalClientCapabilities _vsClientCapability; - private readonly AggregateBoundAttributeDescription _attributeDescription; - private readonly AggregateBoundElementDescription _elementDescription; - - public RazorCompletionItemResolverTest(ITestOutputHelper testOutput) - : base(testOutput) + private LSPTagHelperTooltipFactory _lspTagHelperTooltipFactory; + private VSLSPTagHelperTooltipFactory _vsLspTagHelperTooltipFactory; + private VSInternalCompletionSetting _completionCapability; + private VSInternalClientCapabilities _defaultClientCapability; + private VSInternalClientCapabilities _vsClientCapability; + private AggregateBoundAttributeDescription _attributeDescription; + private AggregateBoundElementDescription _elementDescription; + + protected async override Task InitializeAsync() { var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); + _lspTagHelperTooltipFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); _vsLspTagHelperTooltipFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); _completionCapability = new VSInternalCompletionSetting() diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/TagHelperTooltipFactoryBaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/TagHelperTooltipFactoryBaseTest.cs index eaa0b62a696..d6ca8799bb7 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/TagHelperTooltipFactoryBaseTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/TagHelperTooltipFactoryBaseTest.cs @@ -346,6 +346,7 @@ public void TryExtractSummary_NoXml_ReturnsTrue() public async Task GetAvailableProjects_NoProjects_ReturnsNull() { var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync("file.razor", "MyTagHelper", CancellationToken.None); @@ -370,6 +371,7 @@ public async Task GetAvailableProjects_OneProject_ReturnsNull() var project = TestProjectSnapshot.Create(projectFilePath, documentFilePaths: [razorFilePath], projectWorkspaceState); var snapshotResolver = new TestSnapshotResolver(razorFilePath, project); + await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync(razorFilePath, tagHelperTypeName, CancellationToken.None); @@ -407,6 +409,7 @@ public async Task GetAvailableProjects_AvailableInAllProjects_ReturnsNull() projectWorkspaceState); var snapshotResolver = new TestSnapshotResolver(razorFilePath, project1, project2); + await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync(razorFilePath, tagHelperTypeName, CancellationToken.None); @@ -446,6 +449,7 @@ public async Task GetAvailableProjects_NotAvailableInAllProjects_ReturnsText() displayName: "project2"); var snapshotResolver = new TestSnapshotResolver(razorFilePath, project1, project2); + await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync(razorFilePath, tagHelperTypeName, CancellationToken.None); @@ -482,6 +486,7 @@ public async Task GetAvailableProjects_NotAvailableInAnyProject_ReturnsText() displayName: "project2"); var snapshotResolver = new TestSnapshotResolver(razorFilePath, project1, project2); + await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync(razorFilePath, "MyTagHelper", CancellationToken.None); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs index 7bcf0743ab0..901b582c4cf 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs @@ -47,6 +47,7 @@ protected override async Task InitializeAsync() _projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(_projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); var documentVersionCache = new DocumentVersionCache(_projectManager); var remoteTextLoaderFactoryMock = new StrictMock(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs index 22e6aa37894..1afbcc244d1 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs @@ -40,7 +40,10 @@ public async Task TryCreateAsync_CanNotResolveDocument_ReturnsNull() var filePath = FilePathNormalizer.Normalize(Path.Combine(s_baseDirectory, "file.cshtml")); var uri = new Uri(filePath); - var factory = new DocumentContextFactory(_projectManager, new TestDocumentResolver(), _documentVersionCache, LoggerFactory); + var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); + + var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act var documentContext = await factory.TryCreateAsync(uri, DisposalToken); @@ -56,7 +59,10 @@ public async Task TryCreateForOpenDocumentAsync_CanNotResolveDocument_ReturnsNul var filePath = FilePathNormalizer.Normalize(Path.Combine(s_baseDirectory, "file.cshtml")); var uri = new Uri(filePath); - var factory = new DocumentContextFactory(_projectManager, new TestDocumentResolver(), _documentVersionCache, LoggerFactory); + var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); + + var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act var documentContext = await factory.TryCreateForOpenDocumentAsync(uri, DisposalToken); @@ -73,8 +79,9 @@ public async Task TryCreateForOpenDocumentAsync_CanNotResolveVersion_ReturnsNull var uri = new Uri(filePath); var documentSnapshot = TestDocumentSnapshot.Create(filePath); - var documentResolver = new TestDocumentResolver(documentSnapshot); - var factory = new DocumentContextFactory(_projectManager, documentResolver, _documentVersionCache, LoggerFactory); + var snapshotResolver = new TestSnapshotResolver(documentSnapshot); + await snapshotResolver.InitializeAsync(DisposalToken); + var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act var documentContext = await factory.TryCreateForOpenDocumentAsync(uri, DisposalToken); @@ -93,8 +100,9 @@ public async Task TryCreateAsync_ResolvesContent() var documentSnapshot = TestDocumentSnapshot.Create(filePath); var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(string.Empty, documentSnapshot.FilePath)); documentSnapshot.With(codeDocument); - var documentResolver = new TestDocumentResolver(documentSnapshot); - var factory = new DocumentContextFactory(_projectManager, documentResolver, _documentVersionCache, LoggerFactory); + var snapshotResolver = new TestSnapshotResolver(documentSnapshot); + await snapshotResolver.InitializeAsync(DisposalToken); + var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act var documentContext = await factory.TryCreateAsync(uri, DisposalToken); @@ -117,8 +125,9 @@ public async Task TryCreateAsync_WithProjectContext_Resolves() var documentSnapshot = TestDocumentSnapshot.Create(filePath); var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(string.Empty, documentSnapshot.FilePath)); documentSnapshot.With(codeDocument); - var documentResolver = new TestDocumentResolver(documentSnapshot); - var factory = new DocumentContextFactory(_projectManager, documentResolver, _documentVersionCache, LoggerFactory); + var snapshotResolver = new TestSnapshotResolver(documentSnapshot); + await snapshotResolver.InitializeAsync(DisposalToken); + var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); var hostProject = new HostProject(projectFilePath, intermediateOutputPath, RazorConfiguration.Default, rootNamespace: null); var hostDocument = new HostDocument(filePath, "file.cshtml"); @@ -180,9 +189,10 @@ public async Task TryCreateForOpenDocumentAsync_ResolvesContent() var documentSnapshot = TestDocumentSnapshot.Create(filePath); var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(string.Empty, documentSnapshot.FilePath)); documentSnapshot.With(codeDocument); - var documentResolver = new TestDocumentResolver(documentSnapshot); + var snapshotResolver = new TestSnapshotResolver(documentSnapshot); + await snapshotResolver.InitializeAsync(DisposalToken); _documentVersionCache.TrackDocumentVersion(documentSnapshot, version: 1337); - var factory = new DocumentContextFactory(_projectManager, documentResolver, _documentVersionCache, LoggerFactory); + var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act var documentContext = await factory.TryCreateForOpenDocumentAsync(uri, DisposalToken); @@ -194,10 +204,13 @@ public async Task TryCreateForOpenDocumentAsync_ResolvesContent() Assert.Same(documentSnapshot, documentContext.Snapshot); } - private class TestDocumentResolver(IDocumentSnapshot? documentSnapshot = null) : ISnapshotResolver + private sealed class TestSnapshotResolver(IDocumentSnapshot? documentSnapshot = null) : ISnapshotResolver { private readonly IDocumentSnapshot? _documentSnapshot = documentSnapshot; + public Task InitializeAsync(CancellationToken cancellationToken) + => Task.CompletedTask; + public ImmutableArray FindPotentialProjects(string documentFilePath) => throw new NotImplementedException(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs index 62f4cebf3cc..6e48c9a7c23 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs @@ -29,10 +29,14 @@ public class TextDocumentUriPresentationEndpointTests(ITestOutputHelper testOutp public async Task Handle_SimpleComponent_ReturnsResult() { // Arrange - var manager = CreateProjectSnapshotManager(); - var project = await manager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); - await manager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); - await manager.CreateAndAddDocumentAsync(project, "c:/path/MyTagHelper.razor"); + var projectManager = CreateProjectSnapshotManager(); + + var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); + + var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); + await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); + await projectManager.CreateAndAddDocumentAsync(project, "c:/path/MyTagHelper.razor"); var documentMappingService = Mock.Of( s => s.GetLanguageKind(It.IsAny(), It.IsAny(), It.IsAny()) == RazorLanguageKind.Html, MockBehavior.Strict); @@ -42,17 +46,16 @@ public async Task Handle_SimpleComponent_ReturnsResult() builder.SetMetadata(TypeNameIdentifier("MyTagHelper"), TypeNamespace("TestRootNamespace")); var tagHelperDescriptor = builder.Build(); - await manager.UpdateAsync(updater => updater.ProjectWorkspaceStateChanged(project.Key, ProjectWorkspaceState.Create([tagHelperDescriptor]))); + await projectManager.UpdateAsync(updater => updater.ProjectWorkspaceStateChanged(project.Key, ProjectWorkspaceState.Create([tagHelperDescriptor]))); var razorFilePath = "c:/path/index.razor"; var uri = new Uri(razorFilePath); - var snapshotResolver = new SnapshotResolver(manager, LoggerFactory); - var documentVersionCache = new DocumentVersionCache(manager); - await manager.UpdateAsync(updater => updater.DocumentOpened(project.Key, razorFilePath, SourceText.From("
"))); - var documentSnapshot = manager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); + var documentVersionCache = new DocumentVersionCache(projectManager); + await projectManager.UpdateAsync(updater => updater.DocumentOpened(project.Key, razorFilePath, SourceText.From("
"))); + var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); - var documentContextFactory = new DocumentContextFactory(manager, snapshotResolver, documentVersionCache, LoggerFactory); + var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, null, DisposalToken); var clientConnection = new Mock(MockBehavior.Strict); @@ -91,10 +94,14 @@ public async Task Handle_SimpleComponent_ReturnsResult() public async Task Handle_SimpleComponentWithChildFile_ReturnsResult() { // Arrange - var manager = CreateProjectSnapshotManager(); - var project = await manager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); - await manager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); - await manager.CreateAndAddDocumentAsync(project, "c:/path/MyTagHelper.razor"); + var projectManager = CreateProjectSnapshotManager(); + + var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); + + var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); + await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); + await projectManager.CreateAndAddDocumentAsync(project, "c:/path/MyTagHelper.razor"); var documentMappingService = Mock.Of( s => s.GetLanguageKind(It.IsAny(), It.IsAny(), It.IsAny()) == RazorLanguageKind.Html, MockBehavior.Strict); @@ -104,17 +111,16 @@ public async Task Handle_SimpleComponentWithChildFile_ReturnsResult() builder.SetMetadata(TypeNameIdentifier("MyTagHelper"), TypeNamespace("TestRootNamespace")); var tagHelperDescriptor = builder.Build(); - await manager.UpdateAsync(updater => updater.ProjectWorkspaceStateChanged(project.Key, ProjectWorkspaceState.Create([tagHelperDescriptor]))); + await projectManager.UpdateAsync(updater => updater.ProjectWorkspaceStateChanged(project.Key, ProjectWorkspaceState.Create([tagHelperDescriptor]))); var razorFilePath = "c:/path/index.razor"; var uri = new Uri(razorFilePath); - var snapshotResolver = new SnapshotResolver(manager, LoggerFactory); - var documentVersionCache = new DocumentVersionCache(manager); - await manager.UpdateAsync(updater => updater.DocumentOpened(project.Key, razorFilePath, SourceText.From("
"))); - var documentSnapshot = manager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); + var documentVersionCache = new DocumentVersionCache(projectManager); + await projectManager.UpdateAsync(updater => updater.DocumentOpened(project.Key, razorFilePath, SourceText.From("
"))); + var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); - var documentContextFactory = new DocumentContextFactory(manager, snapshotResolver, documentVersionCache, LoggerFactory); + var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, null, DisposalToken); var clientConnection = new Mock(MockBehavior.Strict); @@ -158,10 +164,14 @@ public async Task Handle_SimpleComponentWithChildFile_ReturnsResult() public async Task Handle_ComponentWithRequiredAttribute_ReturnsResult() { // Arrange - var manager = CreateProjectSnapshotManager(); - var project = await manager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); - await manager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); - await manager.CreateAndAddDocumentAsync(project, "c:/path/fetchdata.razor"); + var projectManager = CreateProjectSnapshotManager(); + + var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); + + var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); + await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); + await projectManager.CreateAndAddDocumentAsync(project, "c:/path/fetchdata.razor"); var documentMappingService = Mock.Of( s => s.GetLanguageKind(It.IsAny(), It.IsAny(), It.IsAny()) == RazorLanguageKind.Html, MockBehavior.Strict); @@ -177,17 +187,16 @@ public async Task Handle_ComponentWithRequiredAttribute_ReturnsResult() builder.BindAttribute(b => b.Name = "MyNonRequiredAttribute"); var tagHelperDescriptor = builder.Build(); - await manager.UpdateAsync(updater => updater.ProjectWorkspaceStateChanged(project.Key, ProjectWorkspaceState.Create([tagHelperDescriptor]))); + await projectManager.UpdateAsync(updater => updater.ProjectWorkspaceStateChanged(project.Key, ProjectWorkspaceState.Create([tagHelperDescriptor]))); var razorFilePath = "c:/path/index.razor"; var uri = new Uri(razorFilePath); - var snapshotResolver = new SnapshotResolver(manager, LoggerFactory); - var documentVersionCache = new DocumentVersionCache(manager); - await manager.UpdateAsync(updater => updater.DocumentOpened(project.Key, razorFilePath, SourceText.From("
"))); - var documentSnapshot = manager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); + var documentVersionCache = new DocumentVersionCache(projectManager); + await projectManager.UpdateAsync(updater => updater.DocumentOpened(project.Key, razorFilePath, SourceText.From("
"))); + var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); - var documentContextFactory = new DocumentContextFactory(manager, snapshotResolver, documentVersionCache, LoggerFactory); + var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, null, DisposalToken); var clientConnection = new Mock(MockBehavior.Strict); @@ -387,10 +396,14 @@ public async Task Handle_NotComponent_ReturnsNull() public async Task Handle_ComponentWithNestedFiles_ReturnsResult() { // Arrange - var manager = CreateProjectSnapshotManager(); - var project = await manager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); - await manager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); - await manager.CreateAndAddDocumentAsync(project, "c:/path/fetchdata.razor"); + var projectManager = CreateProjectSnapshotManager(); + + var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); + + var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); + await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); + await projectManager.CreateAndAddDocumentAsync(project, "c:/path/fetchdata.razor"); var documentMappingService = Mock.Of( s => s.GetLanguageKind(It.IsAny(), It.IsAny(), It.IsAny()) == RazorLanguageKind.Html, MockBehavior.Strict); @@ -401,17 +414,16 @@ public async Task Handle_ComponentWithNestedFiles_ReturnsResult() builder.SetMetadata(TypeNameIdentifier("FetchData"), TypeNamespace("TestRootNamespace")); var tagHelperDescriptor = builder.Build(); - await manager.UpdateAsync(updater => updater.ProjectWorkspaceStateChanged(project.Key, ProjectWorkspaceState.Create([tagHelperDescriptor]))); + await projectManager.UpdateAsync(updater => updater.ProjectWorkspaceStateChanged(project.Key, ProjectWorkspaceState.Create([tagHelperDescriptor]))); var razorFilePath = "c:/path/index.razor"; var uri = new Uri(razorFilePath); - var snapshotResolver = new SnapshotResolver(manager, LoggerFactory); - var documentVersionCache = new DocumentVersionCache(manager); - await manager.UpdateAsync(updater => updater.DocumentOpened(project.Key, razorFilePath, SourceText.From("
"))); - var documentSnapshot = manager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); + var documentVersionCache = new DocumentVersionCache(projectManager); + await projectManager.UpdateAsync(updater => updater.DocumentOpened(project.Key, razorFilePath, SourceText.From("
"))); + var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); - var documentContextFactory = new DocumentContextFactory(manager, snapshotResolver, documentVersionCache, LoggerFactory); + var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, null, DisposalToken); var clientConnection = new Mock(MockBehavior.Strict); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Hover/HoverServiceTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Hover/HoverServiceTest.cs index 13def471594..f71a7eebaea 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Hover/HoverServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Hover/HoverServiceTest.cs @@ -64,11 +64,12 @@ public async Task GetHoverInfo_TagHelper_Element() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Contains("**Test1TagHelper**", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -93,11 +94,12 @@ public async Task GetHoverInfo_TagHelper_Element_WithParent() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Contains("**SomeChild**", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -122,11 +124,12 @@ public async Task GetHoverInfo_TagHelper_Attribute_WithParent() TestFileMarkupParser.GetPositionAndSpan(txt, out txt, out var cursorPosition, out var span); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Contains("**Attribute**", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -145,11 +148,12 @@ public async Task GetHoverInfo_TagHelper_Element_EndTag() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Contains("**Test1TagHelper**", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -172,11 +176,12 @@ public async Task GetHoverInfo_TagHelper_Attribute() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Contains("**BoolVal**", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -200,12 +205,13 @@ public async Task GetHoverInfo_TagHelper_AttributeTrailingEdge() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var edgeLocation = cursorPosition; var location = new SourceLocation(edgeLocation, 0, edgeLocation); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Contains("**BoolVal**", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -229,11 +235,12 @@ public async Task GetHoverInfo_TagHelper_AttributeValue_ReturnsNull() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Null(hover); @@ -250,11 +257,12 @@ public async Task GetHoverInfo_TagHelper_AfterAttributeEquals_ReturnsNull() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Null(hover); @@ -271,11 +279,12 @@ public async Task GetHoverInfo_TagHelper_AttributeEnd_ReturnsNull() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Null(hover); @@ -292,11 +301,12 @@ public async Task GetHoverInfo_TagHelper_MinimizedAttribute() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Contains("**BoolVal**", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -324,11 +334,12 @@ public void Increment(){ TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, "text.razor", DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.NotNull(hover); @@ -352,11 +363,12 @@ public async Task GetHoverInfo_TagHelper_MalformedElement() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Contains("**Test1TagHelper**", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -379,11 +391,12 @@ public async Task GetHoverInfo_TagHelper_MalformedAttribute() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Contains("**BoolVal**", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -407,11 +420,12 @@ public async Task GetHoverInfo_HTML_MarkupElement() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreateMarkDownCapabilities(), DisposalToken); // Assert Assert.Null(hover); @@ -429,11 +443,12 @@ public async Task GetHoverInfo_TagHelper_PlainTextElement() var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), DisposalToken); // Assert Assert.Contains("Test1TagHelper", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -458,11 +473,12 @@ public async Task GetHoverInfo_TagHelper_PlainTextElement_EndTag() var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), DisposalToken); // Assert Assert.Contains("Test1TagHelper", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -486,11 +502,12 @@ public async Task GetHoverInfo_TagHelper_TextComponent() var codeDocument = CreateCodeDocument(txt, isRazorFile: true, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.razor", codeDocument, location, CreatePlainTextCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.razor", codeDocument, location, CreatePlainTextCapabilities(), DisposalToken); // Assert Assert.Contains("Text", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -516,11 +533,12 @@ public async Task GetHoverInfo_TagHelper_TextComponent_NestedInHtml() var codeDocument = CreateCodeDocument(txt, isRazorFile: true, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.razor", codeDocument, location, CreatePlainTextCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.razor", codeDocument, location, CreatePlainTextCapabilities(), DisposalToken); // Assert Assert.Contains("Text", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -547,11 +565,12 @@ public async Task GetHoverInfo_TagHelper_TextComponent_NestedInCSharp() var codeDocument = CreateCodeDocument(txt, isRazorFile: true, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.razor", codeDocument, location, CreatePlainTextCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.razor", codeDocument, location, CreatePlainTextCapabilities(), DisposalToken); // Assert Assert.Null(hover); @@ -573,11 +592,12 @@ public async Task GetHoverInfo_TagHelper_TextComponent_NestedInCSharpAndText() var codeDocument = CreateCodeDocument(txt, isRazorFile: true, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.razor", codeDocument, location, CreatePlainTextCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.razor", codeDocument, location, CreatePlainTextCapabilities(), DisposalToken); // Assert Assert.Contains("Text", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -602,11 +622,12 @@ public async Task GetHoverInfo_TagHelper_PlainTextAttribute() var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), DisposalToken); // Assert Assert.Contains("BoolVal", ((MarkupContent)hover.Contents).Value, StringComparison.Ordinal); @@ -632,11 +653,12 @@ public async Task GetHoverInfo_HTML_PlainTextElement() var codeDocument = CreateCodeDocument(txt, isRazorFile: false); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), DisposalToken); // Assert Assert.Null(hover); @@ -654,11 +676,13 @@ public async Task GetHoverInfo_HTML_PlainTextAttribute() var codeDocument = CreateCodeDocument(txt, isRazorFile: false); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); + var location = new SourceLocation(cursorPosition, -1, -1); // Act - var hover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), CancellationToken.None); + var hover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, CreatePlainTextCapabilities(), DisposalToken); // Assert Assert.Null(hover); @@ -675,13 +699,14 @@ public async Task GetHoverInfo_TagHelper_Element_VSClient_ReturnVSHover() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); var clientCapabilities = CreateMarkDownCapabilities(); clientCapabilities.SupportsVisualStudioExtensions = true; // Act - var vsHover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, clientCapabilities, CancellationToken.None); + var vsHover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, clientCapabilities, DisposalToken); // Assert Assert.False(vsHover.Contents.Value.TryGetFourth(out var _)); @@ -718,13 +743,15 @@ public async Task GetHoverInfo_TagHelper_Attribute_VSClient_ReturnVSHover() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = GetHoverTestAccessor(); + + var service = await GetHoverServiceAsync(); + var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); var clientCapabilities = CreateMarkDownCapabilities(); clientCapabilities.SupportsVisualStudioExtensions = true; // Act - var vsHover = await service.GetHoverInfoAsync("file.cshtml", codeDocument, location, clientCapabilities, CancellationToken.None); + var vsHover = await serviceAccessor.GetHoverInfoAsync("file.cshtml", codeDocument, location, clientCapabilities, DisposalToken); // Assert Assert.False(vsHover.Contents.Value.TryGetFourth(out var _)); @@ -783,7 +810,7 @@ public async Task Handle_Hover_SingleServer_CallsDelegatedLanguageServer() c => c.TryMapToGeneratedDocumentPosition(It.IsAny(), It.IsAny(), out projectedPosition, out projectedIndex)) .Returns(true); - var endpoint = CreateEndpoint(languageServerFeatureOptions, documentMappingServiceMock.Object, clientConnectionMock.Object); + var endpoint = await CreateEndpointAsync(languageServerFeatureOptions, documentMappingServiceMock.Object, clientConnectionMock.Object); var request = new TextDocumentPositionParams { @@ -932,10 +959,10 @@ private async Task GetResultFromSingleServerEndpointAsync(strin var languageServer = new HoverLanguageServer(csharpServer, csharpDocumentUri, DisposalToken); var documentMappingService = new RazorDocumentMappingService(FilePathService, documentContextFactory, LoggerFactory); - var hoverService = GetHoverService(documentMappingService); + var service = await GetHoverServiceAsync(documentMappingService); var endpoint = new HoverEndpoint( - hoverService, + service, languageServerFeatureOptions, documentMappingService, languageServer, @@ -985,12 +1012,11 @@ public void Increment(){ return documentContext; } - private HoverEndpoint CreateEndpoint( + private async Task CreateEndpointAsync( LanguageServerFeatureOptions languageServerFeatureOptions = null, IRazorDocumentMappingService documentMappingService = null, IClientConnection clientConnection = null) { - languageServerFeatureOptions ??= Mock.Of(options => options.SupportsFileManipulation == true && options.SingleServerSupport == false, MockBehavior.Strict); var documentMappingServiceMock = new Mock(MockBehavior.Strict); @@ -1001,8 +1027,10 @@ private HoverEndpoint CreateEndpoint( clientConnection ??= Mock.Of(MockBehavior.Strict); + var service = await GetHoverServiceAsync(); + var endpoint = new HoverEndpoint( - GetHoverService(), + service, languageServerFeatureOptions, documentMappingService, clientConnection, @@ -1011,15 +1039,10 @@ private HoverEndpoint CreateEndpoint( return endpoint; } - private HoverService.TestAccessor GetHoverTestAccessor() - { - var service = GetHoverService(); - return service.GetTestAccessor(); - } - - private HoverService GetHoverService(IRazorDocumentMappingService mappingService = null) + private async Task GetHoverServiceAsync(IRazorDocumentMappingService mappingService = null) { var snapshotResolver = new TestSnapshotResolver(); + await snapshotResolver.InitializeAsync(DisposalToken); var lspTagHelperTooltipFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var vsLspTagHelperTooltipFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); 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 2a029d5c23f..e35a702939f 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs @@ -24,20 +24,23 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer; -public class RazorProjectServiceTest : LanguageServerTestBase +public class RazorProjectServiceTest(ITestOutputHelper testOutput) : LanguageServerTestBase(testOutput) { private static readonly SourceText s_emptyText = SourceText.From(""); - private readonly TestProjectSnapshotManager _projectManager; - private readonly SnapshotResolver _snapshotResolver; - private readonly DocumentVersionCache _documentVersionCache; - private readonly RazorProjectService _projectService; + // Each of these is initialized by InitializeAsync() below. +#nullable disable + private TestProjectSnapshotManager _projectManager; + private SnapshotResolver _snapshotResolver; + private DocumentVersionCache _documentVersionCache; + private RazorProjectService _projectService; +#nullable enable - public RazorProjectServiceTest(ITestOutputHelper testOutput) - : base(testOutput) + protected override async Task InitializeAsync() { _projectManager = CreateProjectSnapshotManager(); _snapshotResolver = new SnapshotResolver(_projectManager, LoggerFactory); + await _snapshotResolver.InitializeAsync(DisposalToken); _documentVersionCache = new DocumentVersionCache(_projectManager); var remoteTextLoaderFactoryMock = new StrictMock(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs index 45ec426d786..801bb4c374d 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs @@ -612,8 +612,9 @@ public async Task Handle_Rename_SingleServer_DoesNotDelegateForRazor() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - var documentVersionCache = new DocumentVersionCache(projectManager); + await snapshotResolver.InitializeAsync(DisposalToken); + var documentVersionCache = new DocumentVersionCache(projectManager); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); var remoteTextLoaderFactoryMock = new StrictMock(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs index 2514ee67059..cf500cb526d 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs @@ -39,6 +39,7 @@ public async Task TryResolveDocumentInAnyProject_AsksMiscellaneousProjectForDocu var normalizedFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); await projectManager.UpdateAsync(async updater => { @@ -65,6 +66,7 @@ public async Task TryResolveDocumentInAnyProject_AsksPotentialParentProjectForDo var documentFilePath = @"C:\path\to\document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); // Act var document = await snapshotResolver.ResolveDocumentInAnyProjectAsync(documentFilePath, DisposalToken); @@ -80,6 +82,7 @@ public async Task TryResolveAllProjects_NoProjects_ReturnsFalse() var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); // Act var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); @@ -95,6 +98,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectDoesNotContainDo var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); @@ -111,6 +115,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectContainsDocument // Arrange var documentFilePath = Path.Combine(TempDirectory.Instance.DirectoryPath, "document.cshtml"); var snapshotResolver = await CreateSnapshotResolverAsync(documentFilePath, addToMiscellaneous: true); + await snapshotResolver.InitializeAsync(DisposalToken); // Act var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); @@ -127,6 +132,7 @@ public async Task TryResolveAllProjects_UnrelatedProject_ReturnsFalse() var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); await projectManager.UpdateAsync(updater => { @@ -147,6 +153,9 @@ public async Task TryResolveAllProjects_OwnerProjectWithOthers_ReturnsTrue() var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); + var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); + var expectedProject = await projectManager.UpdateAsync(updater => { var expectedProject = updater.CreateAndAddProject("C:/path/to/project.csproj"); @@ -156,8 +165,6 @@ public async Task TryResolveAllProjects_OwnerProjectWithOthers_ReturnsTrue() return expectedProject; }); - var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - // Act var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); @@ -175,6 +182,7 @@ public async Task TryResolveAllProjects_MiscellaneousOwnerProjectWithOthers_Retu var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); var miscProject = await projectManager.UpdateAsync(async updater => { @@ -200,6 +208,7 @@ public async Task TryResolveAllProjects_OwnerProjectDifferentCasing_ReturnsTrue( var documentFilePath = "c:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); var ownerProject = await projectManager.UpdateAsync(updater => { @@ -223,6 +232,7 @@ public async Task GetMiscellaneousProject_ProjectLoaded_ReturnsExistingProject() // Arrange var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); // Act var project = await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); @@ -238,6 +248,7 @@ public async Task GetMiscellaneousProject_ProjectNotLoaded_CreatesProjectAndRetu // Arrange var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); // Act var project = await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); @@ -253,6 +264,7 @@ private async Task CreateSnapshotResolverAsync(string filePath var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); + await snapshotResolver.InitializeAsync(DisposalToken); if (addToMiscellaneous) { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs index 9fd89db8c79..0ce97cd4251 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs @@ -27,6 +27,9 @@ public TestSnapshotResolver(string filePath, params IProjectSnapshot[] projects) _projects = [.. projects]; } + public Task InitializeAsync(CancellationToken cancellationToken) + => Task.CompletedTask; + public ImmutableArray FindPotentialProjects(string documentFilePath) => documentFilePath == _filePath ? _projects From 56356efb019bb9d2307fae4a9b697b20743c5b49 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 26 Apr 2024 11:17:42 -0700 Subject: [PATCH 02/16] Make ISnapshotResolver.GetMiscellaneousProject synchronous Now that the misc project is guaranteed to be in the project snapshot manager, the operation to retrieve the misc project can be made synchronous. --- .../DocumentContextFactory.cs | 2 +- .../ProjectSystem/ISnapshotResolver.cs | 2 +- .../ISnapshotResolverExtensions.cs | 2 +- .../ProjectSystem/RazorProjectService.cs | 12 ++++---- .../ProjectSystem/SnapshotResolver.cs | 18 ++---------- .../DocumentContextFactoryTest.cs | 2 +- .../RazorProjectServiceTest.cs | 28 ++++++++----------- .../SnapshotResolverTest.cs | 20 ++++++------- .../TestSnapshotResolver.cs | 4 +-- 9 files changed, 36 insertions(+), 54 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs index 54d0da1837c..e60ab87e649 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs @@ -106,7 +106,7 @@ internal sealed class DocumentContextFactory( // Couldn't find the document in a real project. Maybe the language server doesn't yet know about the project // that the IDE is asking us about. In that case, we might have the document in our misc files project, and we'll // move it to the real project when/if we find out about it. - var miscellaneousProject = await _snapshotResolver.GetMiscellaneousProjectAsync(cancellationToken).ConfigureAwait(false); + var miscellaneousProject = _snapshotResolver.GetMiscellaneousProject(); var normalizedDocumentPath = FilePathNormalizer.Normalize(filePath); if (miscellaneousProject.GetDocument(normalizedDocumentPath) is { } miscDocument) { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs index 9c72a9ffbb9..8d4ebb26d09 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs @@ -17,7 +17,7 @@ internal interface ISnapshotResolver /// ImmutableArray FindPotentialProjects(string documentFilePath); - Task GetMiscellaneousProjectAsync(CancellationToken cancellationToken); + IProjectSnapshot GetMiscellaneousProject(); /// /// Finds a for the given document path that is contained within any project, and returns the first diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs index 9aa33c0de9c..0d97b60af32 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs @@ -30,7 +30,7 @@ public static async Task> TryResolveAllProjects } var normalizedDocumentPath = FilePathNormalizer.Normalize(documentFilePath); - var miscProject = await snapshotResolver.GetMiscellaneousProjectAsync(cancellationToken).ConfigureAwait(false); + var miscProject = snapshotResolver.GetMiscellaneousProject(); if (miscProject.GetDocument(normalizedDocumentPath) is not null) { projects.Add(miscProject); 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 c725852e10c..f90e13736f2 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -66,7 +66,7 @@ private async Task AddDocumentNeedsLocksAsync(string filePath, CancellationToken if (!added) { - var miscFilesProject = await _snapshotResolver.GetMiscellaneousProjectAsync(cancellationToken).ConfigureAwait(false); + var miscFilesProject = _snapshotResolver.GetMiscellaneousProject(); await AddDocumentToProjectAsync(miscFilesProject, textDocumentPath, cancellationToken).ConfigureAwait(false); } @@ -203,7 +203,7 @@ await ActOnDocumentInMultipleProjectsAsync(filePath, async (projectSnapshot, tex if (_projectManager.IsDocumentOpen(textDocumentPath)) { _logger.LogInformation($"Moving document '{textDocumentPath}' from project '{projectSnapshot.Key}' to misc files because it is open."); - var miscellaneousProject = await _snapshotResolver.GetMiscellaneousProjectAsync(cancellationToken).ConfigureAwait(false); + var miscellaneousProject = _snapshotResolver.GetMiscellaneousProject(); if (projectSnapshot != miscellaneousProject) { await MoveDocumentAsync(textDocumentPath, projectSnapshot, miscellaneousProject, cancellationToken).ConfigureAwait(false); @@ -261,7 +261,7 @@ private async Task ActOnDocumentInMultipleProjectsAsync( var projects = await _snapshotResolver.TryResolveAllProjectsAsync(textDocumentPath, cancellationToken).ConfigureAwait(false); if (projects.IsEmpty) { - var miscFilesProject = await _snapshotResolver.GetMiscellaneousProjectAsync(cancellationToken).ConfigureAwait(false); + var miscFilesProject = _snapshotResolver.GetMiscellaneousProject(); projects = [miscFilesProject]; } @@ -373,7 +373,7 @@ private async Task UpdateProjectDocumentsAsync(ImmutableArray EnsureFullPath(document.FilePath, projectDirectory), FilePathComparer.Instance); - var miscellaneousProject = await _snapshotResolver.GetMiscellaneousProjectAsync(cancellationToken).ConfigureAwait(false); + var miscellaneousProject = _snapshotResolver.GetMiscellaneousProject(); // "Remove" any unnecessary documents by putting them into the misc project foreach (var documentFilePath in project.DocumentFilePaths) @@ -433,7 +433,7 @@ await _projectManager } project = _projectManager.GetLoadedProject(project.Key); - miscellaneousProject = await _snapshotResolver.GetMiscellaneousProjectAsync(cancellationToken).ConfigureAwait(false); + miscellaneousProject = _snapshotResolver.GetMiscellaneousProject(); // Add (or migrate from misc) any new documents foreach (var documentKvp in documentMap) @@ -508,7 +508,7 @@ private static string EnsureFullPath(string filePath, string projectDirectory) private async Task TryMigrateMiscellaneousDocumentsToProjectAsync(CancellationToken cancellationToken) { - var miscellaneousProject = await _snapshotResolver.GetMiscellaneousProjectAsync(cancellationToken).ConfigureAwait(false); + var miscellaneousProject = _snapshotResolver.GetMiscellaneousProject(); foreach (var documentFilePath in miscellaneousProject.DocumentFilePaths) { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs index c478d6ce6bf..a33419eeabd 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs @@ -73,21 +73,9 @@ public ImmutableArray FindPotentialProjects(string documentFil return projects.DrainToImmutable(); } - public async Task GetMiscellaneousProjectAsync(CancellationToken cancellationToken) + public IProjectSnapshot GetMiscellaneousProject() { - if (!_projectManager.TryGetLoadedProject(MiscellaneousHostProject.Key, out var miscellaneousProject)) - { - await _projectManager - .UpdateAsync( - static (updater, miscHostProject) => updater.ProjectAdded(miscHostProject), - state: MiscellaneousHostProject, - cancellationToken) - .ConfigureAwait(false); - - miscellaneousProject = _projectManager.GetLoadedProject(MiscellaneousHostProject.Key); - } - - return miscellaneousProject; + return _projectManager.GetLoadedProject(MiscellaneousHostProject.Key); } public async Task ResolveDocumentInAnyProjectAsync(string documentFilePath, CancellationToken cancellationToken) @@ -112,7 +100,7 @@ await _projectManager } _logger.LogTrace($"Looking for {documentFilePath} in miscellaneous project."); - var miscellaneousProject = await GetMiscellaneousProjectAsync(cancellationToken).ConfigureAwait(false); + var miscellaneousProject = GetMiscellaneousProject(); if (miscellaneousProject.GetDocument(normalizedDocumentPath) is { } miscDocument) { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs index 1afbcc244d1..ab2c2b131e4 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs @@ -214,7 +214,7 @@ public Task InitializeAsync(CancellationToken cancellationToken) public ImmutableArray FindPotentialProjects(string documentFilePath) => throw new NotImplementedException(); - public Task GetMiscellaneousProjectAsync(CancellationToken cancellationToken) + public IProjectSnapshot GetMiscellaneousProject() => throw new NotImplementedException(); public Task ResolveDocumentInAnyProjectAsync(string documentFilePath, CancellationToken cancellationToken) 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 e35a702939f..b54c9e417d9 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs @@ -155,7 +155,7 @@ public async Task UpdateProject_MovesDocumentsFromMisc() var hostProject = new HostProject("C:/path/to/project.csproj", "C:/path/to/obj", RazorConfiguration.Default, "TestRootNamespace"); var hostDocument = new HostDocument("C:/path/to/file.cshtml", "file.cshtml", FileKinds.Legacy); - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); await _projectManager.UpdateAsync(updater => { @@ -192,7 +192,7 @@ public async Task UpdateProject_MovesExistingDocumentToMisc() var hostProject = new HostProject("C:/path/to/project.csproj", "C:/path/to/obj", RazorConfiguration.Default, "TestRootNamespace"); var hostDocument = new HostDocument("C:/path/to/file.cshtml", "file.cshtml", FileKinds.Legacy); - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); var project = await _projectManager.UpdateAsync(updater => { @@ -231,10 +231,6 @@ public async Task UpdateProject_KnownDocuments() var hostProject = new HostProject("path/to/project.csproj", "path/to/obj", RazorConfiguration.Default, "TestRootNamespace"); var document = new HostDocument("path/to/file.cshtml", "file.cshtml", FileKinds.Legacy); - // Note: We acquire the miscellaneous project here to avoid a spurious 'ProjectAdded' - // notification when it would get created by UpdateProject(...) below. - _ = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); - await _projectManager.UpdateAsync(updater => { updater.ProjectAdded(hostProject); @@ -505,7 +501,7 @@ public async Task CloseDocument_ClosesDocumentInMiscellaneousProject() await _projectService.AddDocumentAsync(DocumentFilePath, DisposalToken); await _projectService.OpenDocumentAsync(DocumentFilePath, s_emptyText, version: 42, DisposalToken); - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); Assert.True(_projectManager.IsDocumentOpen(DocumentFilePath)); @@ -592,7 +588,7 @@ public async Task OpenDocument_OpensAlreadyAddedDocumentInMiscellaneousProject() await _projectService.AddDocumentAsync(DocumentFilePath, DisposalToken); - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); Assert.False(_projectManager.IsDocumentOpen(DocumentFilePath)); @@ -643,7 +639,7 @@ public async Task AddDocument_NoopsIfDocumentIsAlreadyAdded() await _projectService.AddDocumentAsync(DocumentFilePath, DisposalToken); - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); using var listener = _projectManager.ListenToNotifications(); @@ -686,7 +682,7 @@ public async Task AddDocument_AddsDocumentToMiscellaneousProject() // Arrange const string DocumentFilePath = "document.cshtml"; - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); using var listener = _projectManager.ListenToNotifications(); @@ -774,7 +770,7 @@ public async Task RemoveOpenDocument_RemovesDocumentFromOwnerProject_MovesToMisc await _projectService.OpenDocumentAsync(DocumentFilePath, s_emptyText, version: 42, DisposalToken); var ownerProject = _projectManager.GetLoadedProject(ownerProjectKey); - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); Assert.True(_projectManager.IsDocumentOpen(DocumentFilePath)); @@ -799,7 +795,7 @@ public async Task RemoveDocument_RemovesDocumentFromMiscellaneousProject() await _projectService.AddDocumentAsync(DocumentFilePath, DisposalToken); - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); Assert.False(_projectManager.IsDocumentOpen(DocumentFilePath)); @@ -842,7 +838,7 @@ public async Task RemoveDocument_NoopsIfMiscellaneousProjectDoesNotContainDocume // Arrange const string DocumentFilePath = "document.cshtml"; - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); Assert.False(_projectManager.IsDocumentOpen(DocumentFilePath)); @@ -929,7 +925,7 @@ public async Task UpdateDocument_ChangesDocumentInMiscProject() await _projectService.AddDocumentAsync(DocumentFilePath, DisposalToken); await _projectService.OpenDocumentAsync(DocumentFilePath, s_emptyText, version: 42, DisposalToken); - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); Assert.True(_projectManager.IsDocumentOpen(DocumentFilePath)); @@ -1042,7 +1038,7 @@ public async Task AddProject_DoesNotMigrateMiscellaneousDocumentIfNewProjectNotA const string DocumentFilePath1 = "C:/path/to/document1.cshtml"; const string DocumentFilePath2 = "C:/path/to/document2.cshtml"; - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); await _projectManager.UpdateAsync(updater => { @@ -1072,7 +1068,7 @@ public async Task AddProject_MigratesMiscellaneousDocumentsToNewOwnerProject() const string DocumentFilePath1 = "C:/path/to/document1.cshtml"; const string DocumentFilePath2 = "C:/path/to/document2.cshtml"; - var miscProject = await _snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = _snapshotResolver.GetMiscellaneousProject(); await _projectManager.UpdateAsync(updater => { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs index cf500cb526d..71e8c58b9ab 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs @@ -41,9 +41,9 @@ public async Task TryResolveDocumentInAnyProject_AsksMiscellaneousProjectForDocu var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); await snapshotResolver.InitializeAsync(DisposalToken); - await projectManager.UpdateAsync(async updater => + await projectManager.UpdateAsync(updater => { - var miscProject = await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = snapshotResolver.GetMiscellaneousProject(); var hostProject = new HostProject(miscProject.FilePath, miscProject.IntermediateOutputPath, FallbackRazorConfiguration.Latest, miscProject.RootNamespace); updater.DocumentAdded( hostProject.Key, @@ -100,8 +100,6 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectDoesNotContainDo var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); await snapshotResolver.InitializeAsync(DisposalToken); - await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); - // Act var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); @@ -121,7 +119,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectContainsDocument var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); // Assert - var miscFilesProject = await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscFilesProject = snapshotResolver.GetMiscellaneousProject(); Assert.Single(projects, miscFilesProject); } @@ -184,9 +182,9 @@ public async Task TryResolveAllProjects_MiscellaneousOwnerProjectWithOthers_Retu var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); await snapshotResolver.InitializeAsync(DisposalToken); - var miscProject = await projectManager.UpdateAsync(async updater => + var miscProject = await projectManager.UpdateAsync(updater => { - var miscProject = (ProjectSnapshot)await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = (ProjectSnapshot)snapshotResolver.GetMiscellaneousProject(); updater.CreateAndAddDocument(miscProject, documentFilePath); updater.CreateAndAddProject("C:/path/to/project.csproj"); @@ -235,7 +233,7 @@ public async Task GetMiscellaneousProject_ProjectLoaded_ReturnsExistingProject() await snapshotResolver.InitializeAsync(DisposalToken); // Act - var project = await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var project = snapshotResolver.GetMiscellaneousProject(); var inManager = projectManager.GetLoadedProject(snapshotResolver.MiscellaneousHostProject.Key); // Assert @@ -251,7 +249,7 @@ public async Task GetMiscellaneousProject_ProjectNotLoaded_CreatesProjectAndRetu await snapshotResolver.InitializeAsync(DisposalToken); // Act - var project = await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var project = snapshotResolver.GetMiscellaneousProject(); // Assert Assert.Single(projectManager.GetProjects()); @@ -268,9 +266,9 @@ private async Task CreateSnapshotResolverAsync(string filePath if (addToMiscellaneous) { - await projectManager.UpdateAsync(async updater => + await projectManager.UpdateAsync(updater => { - var miscProject = (ProjectSnapshot)await snapshotResolver.GetMiscellaneousProjectAsync(DisposalToken); + var miscProject = (ProjectSnapshot)snapshotResolver.GetMiscellaneousProject(); updater.CreateAndAddDocument(miscProject, filePath); }); } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs index 0ce97cd4251..0804dbd1230 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs @@ -35,8 +35,8 @@ public ImmutableArray FindPotentialProjects(string documentFil ? _projects : []; - public Task GetMiscellaneousProjectAsync(CancellationToken cancellationToken) - => Task.FromResult(_miscProject); + public IProjectSnapshot GetMiscellaneousProject() + => _miscProject; public Task ResolveDocumentInAnyProjectAsync(string documentFilePath, CancellationToken cancellationToken) => Task.FromResult(null); From 8b6e05bb7b05f83f45df22145bfdea544df455fc Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 26 Apr 2024 11:23:33 -0700 Subject: [PATCH 03/16] Make ISnapshotResolver.TryResolveAllProjects synchronous This extension method no longer has awaits and can be made synchronous. In addition, the cancellation token can be removed. --- .../ProjectSystem/ISnapshotResolverExtensions.cs | 5 ++--- .../ProjectSystem/RazorProjectService.cs | 2 +- .../Tooltip/TagHelperTooltipFactoryBase.cs | 2 +- .../SnapshotResolverTest.cs | 14 +++++++------- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs index 0d97b60af32..cae7fc343e9 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs @@ -12,10 +12,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; internal static class ISnapshotResolverExtensions { - public static async Task> TryResolveAllProjectsAsync( + public static ImmutableArray TryResolveAllProjects( this ISnapshotResolver snapshotResolver, - string documentFilePath, - CancellationToken cancellationToken) + string documentFilePath) { var potentialProjects = snapshotResolver.FindPotentialProjects(documentFilePath); 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 f90e13736f2..c647461df79 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -258,7 +258,7 @@ private async Task ActOnDocumentInMultipleProjectsAsync( CancellationToken cancellationToken) { var textDocumentPath = FilePathNormalizer.Normalize(filePath); - var projects = await _snapshotResolver.TryResolveAllProjectsAsync(textDocumentPath, cancellationToken).ConfigureAwait(false); + var projects = _snapshotResolver.TryResolveAllProjects(textDocumentPath); if (projects.IsEmpty) { var miscFilesProject = _snapshotResolver.GetMiscellaneousProject(); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/TagHelperTooltipFactoryBase.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/TagHelperTooltipFactoryBase.cs index b80184a1bb8..521a76f8c5e 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/TagHelperTooltipFactoryBase.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/TagHelperTooltipFactoryBase.cs @@ -31,7 +31,7 @@ protected TagHelperTooltipFactoryBase(ISnapshotResolver snapshotResolver) internal async Task GetProjectAvailabilityAsync(string documentFilePath, string tagHelperTypeName, CancellationToken cancellationToken) { - var projectSnapshots = await _snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, cancellationToken).ConfigureAwait(false); + var projectSnapshots = _snapshotResolver.TryResolveAllProjects(documentFilePath); if (projectSnapshots.IsEmpty) { return null; diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs index 71e8c58b9ab..3604771f495 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs @@ -85,7 +85,7 @@ public async Task TryResolveAllProjects_NoProjects_ReturnsFalse() await snapshotResolver.InitializeAsync(DisposalToken); // Act - var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); + var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); // Assert Assert.Empty(projects); @@ -101,7 +101,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectDoesNotContainDo await snapshotResolver.InitializeAsync(DisposalToken); // Act - var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); + var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); // Assert Assert.Empty(projects); @@ -116,7 +116,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectContainsDocument await snapshotResolver.InitializeAsync(DisposalToken); // Act - var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); + var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); // Assert var miscFilesProject = snapshotResolver.GetMiscellaneousProject(); @@ -138,7 +138,7 @@ await projectManager.UpdateAsync(updater => }); // Act - var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); + var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); // Assert Assert.Empty(projects); @@ -164,7 +164,7 @@ public async Task TryResolveAllProjects_OwnerProjectWithOthers_ReturnsTrue() }); // Act - var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); + var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); // Assert var project = Assert.Single(projects); @@ -192,7 +192,7 @@ public async Task TryResolveAllProjects_MiscellaneousOwnerProjectWithOthers_Retu }); // Act - var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); + var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); // Assert var project = Assert.Single(projects); @@ -217,7 +217,7 @@ public async Task TryResolveAllProjects_OwnerProjectDifferentCasing_ReturnsTrue( }); // Act - var projects = await snapshotResolver.TryResolveAllProjectsAsync(documentFilePath, DisposalToken); + var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); // Assert var project = Assert.Single(projects); From e027f2e5e970b44dd2638e2c99687a3b12194061 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 26 Apr 2024 11:35:48 -0700 Subject: [PATCH 04/16] Make ISnapshotResolver.ResolveDocumentInAnyProject synchronous --- .../DocumentContextFactory.cs | 4 +--- .../ProjectSystem/ISnapshotResolver.cs | 2 +- .../ProjectSystem/RazorProjectService.cs | 4 +--- .../ProjectSystem/SnapshotResolver.cs | 2 +- .../DocumentContextFactoryTest.cs | 6 +++--- .../SnapshotResolverTest.cs | 6 +++--- .../TestSnapshotResolver.cs | 4 ++-- 7 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs index e60ab87e649..f33182006c8 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs @@ -92,9 +92,7 @@ internal sealed class DocumentContextFactory( { if (projectContext is null) { - return await _snapshotResolver - .ResolveDocumentInAnyProjectAsync(filePath, cancellationToken) - .ConfigureAwait(false); + return _snapshotResolver.ResolveDocumentInAnyProject(filePath); } if (_projectManager.TryGetLoadedProject(projectContext.ToProjectKey(), out var project) && diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs index 8d4ebb26d09..4ba0d3e7a27 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs @@ -23,5 +23,5 @@ internal interface ISnapshotResolver /// Finds a for the given document path that is contained within any project, and returns the first /// one found if it does. This method should be avoided where possible, and the overload that takes a should be used instead /// - Task ResolveDocumentInAnyProjectAsync(string documentFilePath, CancellationToken cancellationToken); + IDocumentSnapshot? ResolveDocumentInAnyProject(string documentFilePath); } 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 c647461df79..257f30ab02f 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -123,9 +123,7 @@ public async Task OpenDocumentAsync(string filePath, SourceText sourceText, int // We are okay to use the non-project-key overload of TryResolveDocument here because we really are just checking if the document // has been added to _any_ project. AddDocument will take care of adding to all of the necessary ones, and then below we ensure // we process them all too - var document = await _snapshotResolver - .ResolveDocumentInAnyProjectAsync(textDocumentPath, cancellationToken) - .ConfigureAwait(false); + var document = _snapshotResolver.ResolveDocumentInAnyProject(textDocumentPath); if (document is null) { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs index a33419eeabd..e1f3292dd97 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs @@ -78,7 +78,7 @@ public IProjectSnapshot GetMiscellaneousProject() return _projectManager.GetLoadedProject(MiscellaneousHostProject.Key); } - public async Task ResolveDocumentInAnyProjectAsync(string documentFilePath, CancellationToken cancellationToken) + public IDocumentSnapshot? ResolveDocumentInAnyProject(string documentFilePath) { _logger.LogTrace($"Looking for {documentFilePath}."); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs index ab2c2b131e4..44c2241fc21 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs @@ -217,9 +217,9 @@ public ImmutableArray FindPotentialProjects(string documentFil public IProjectSnapshot GetMiscellaneousProject() => throw new NotImplementedException(); - public Task ResolveDocumentInAnyProjectAsync(string documentFilePath, CancellationToken cancellationToken) + public IDocumentSnapshot? ResolveDocumentInAnyProject(string documentFilePath) => documentFilePath == _documentSnapshot?.FilePath - ? Task.FromResult(_documentSnapshot) - : Task.FromResult(null); + ? _documentSnapshot + : null; } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs index 3604771f495..8e31b99b373 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs @@ -24,7 +24,7 @@ public async Task TryResolveDocumentInAnyProject_AsksPotentialParentProjectForDo var snapshotResolver = await CreateSnapshotResolverAsync(normalizedFilePath); // Act - var document = await snapshotResolver.ResolveDocumentInAnyProjectAsync(documentFilePath, DisposalToken); + var document = snapshotResolver.ResolveDocumentInAnyProject(documentFilePath); // Assert Assert.NotNull(document); @@ -52,7 +52,7 @@ await projectManager.UpdateAsync(updater => }); // Act - var document = await snapshotResolver.ResolveDocumentInAnyProjectAsync(documentFilePath, DisposalToken); + var document = snapshotResolver.ResolveDocumentInAnyProject(documentFilePath); // Assert Assert.NotNull(document); @@ -69,7 +69,7 @@ public async Task TryResolveDocumentInAnyProject_AsksPotentialParentProjectForDo await snapshotResolver.InitializeAsync(DisposalToken); // Act - var document = await snapshotResolver.ResolveDocumentInAnyProjectAsync(documentFilePath, DisposalToken); + var document = snapshotResolver.ResolveDocumentInAnyProject(documentFilePath); // Assert Assert.Null(document); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs index 0804dbd1230..866ca72e5a7 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs @@ -38,6 +38,6 @@ public ImmutableArray FindPotentialProjects(string documentFil public IProjectSnapshot GetMiscellaneousProject() => _miscProject; - public Task ResolveDocumentInAnyProjectAsync(string documentFilePath, CancellationToken cancellationToken) - => Task.FromResult(null); + public IDocumentSnapshot? ResolveDocumentInAnyProject(string documentFilePath) + => null; } From a198c29a1218c3bb32445e8601e74b7876430466 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 26 Apr 2024 13:16:12 -0700 Subject: [PATCH 05/16] Make IDocumentContextFactory synchronous Now that ISnapshotResolver is synchronous, there's no reason for IDocumentContextFactory to be synchronous. --- .../CSharp/DefaultCSharpCodeActionResolver.cs | 2 +- ...mattedRemappingCSharpCodeActionResolver.cs | 2 +- .../Html/DefaultHtmlCodeActionResolver.cs | 2 +- .../Razor/AddUsingsCodeActionResolver.cs | 2 +- .../CreateComponentCodeActionResolver.cs | 2 +- .../ExtractToCodeBehindCodeActionResolver.cs | 2 +- .../Razor/GenerateMethodCodeActionResolver.cs | 2 +- .../DelegatedCompletionItemResolver.cs | 2 +- .../Diagnostics/RazorDiagnosticsPublisher.cs | 5 +-- .../DocumentContextFactory.cs | 42 ++++++++++++------- .../TextDocumentUriPresentationEndpoint.cs | 2 +- .../MapCode/MapCodeEndpoint.cs | 4 +- .../RazorRequestContextFactory.cs | 4 +- .../AbstractRazorDocumentMappingService.cs | 6 +-- .../ProjectSystem/IDocumentContextFactory.cs | 4 +- .../IDocumentContextFactoryExtensions.cs | 26 ++++++------ .../ProjectSystem/DocumentContextFactory.cs | 4 +- .../OnAutoInsertEndpointTest.NetFx.cs | 2 +- .../CodeActionEndToEndTest.NetFx.cs | 6 +-- .../Html/DefaultHtmlCodeActionResolverTest.cs | 2 +- .../ValidateBreakpointRangeEndpointTest.cs | 2 +- .../DefinitionEndpointDelegationTest.cs | 2 +- .../DocumentContextFactoryTest.cs | 14 +++---- ...extDocumentUriPresentationEndpointTests.cs | 8 ++-- .../DocumentSymbolEndpointTest.cs | 2 +- .../FindAllReferencesEndpointTest.cs | 2 +- .../Folding/FoldingEndpointTest.cs | 2 +- .../DocumentOnTypeFormattingEndpointTest.cs | 2 +- .../ImplementationEndpointTest.cs | 2 +- .../InlayHints/InlayHintEndpointTest.cs | 2 +- .../MapCode/MapCodeTest.cs | 2 +- .../ProjectContextsEndpointTest.cs | 2 +- .../RenameEndpointDelegationTest.cs | 2 +- .../Refactoring/RenameEndpointTest.cs | 26 ++++++------ .../Semantic/SemanticTokensTest.cs | 4 +- .../SignatureHelpEndpointTest.cs | 2 +- .../WrapWithTag/WrapWithTagEndpointTests.cs | 6 +-- .../TestDocumentContextFactory.cs | 12 +++--- 38 files changed, 110 insertions(+), 107 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/DefaultCSharpCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/DefaultCSharpCodeActionResolver.cs index b8f32f31676..0538ace062a 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/DefaultCSharpCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/DefaultCSharpCodeActionResolver.cs @@ -73,7 +73,7 @@ public async override Task ResolveAsync( throw new ArgumentNullException(nameof(codeAction)); } - var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(csharpParams.RazorFileIdentifier, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier); if (documentContext is null) { return codeAction; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/UnformattedRemappingCSharpCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/UnformattedRemappingCSharpCodeActionResolver.cs index 4b820125d30..1289713ff0b 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/UnformattedRemappingCSharpCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/UnformattedRemappingCSharpCodeActionResolver.cs @@ -54,7 +54,7 @@ public async override Task ResolveAsync( cancellationToken.ThrowIfCancellationRequested(); - var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(csharpParams.RazorFileIdentifier, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier); if (documentContext is null) { return codeAction; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Html/DefaultHtmlCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Html/DefaultHtmlCodeActionResolver.cs index bab5000610b..59f4420eb72 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Html/DefaultHtmlCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Html/DefaultHtmlCodeActionResolver.cs @@ -55,7 +55,7 @@ public async override Task ResolveAsync( throw new ArgumentNullException(nameof(codeAction)); } - var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(resolveParams.RazorFileIdentifier, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreateForOpenDocument(resolveParams.RazorFileIdentifier); if (documentContext is null) { return codeAction; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/AddUsingsCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/AddUsingsCodeActionResolver.cs index 794862b98e7..879953b5a00 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/AddUsingsCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/AddUsingsCodeActionResolver.cs @@ -45,7 +45,7 @@ public AddUsingsCodeActionResolver(IDocumentContextFactory documentContextFactor return null; } - var documentContext = await _documentContextFactory.TryCreateAsync(actionParams.Uri, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreate(actionParams.Uri); if (documentContext is null) { return null; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/CreateComponentCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/CreateComponentCodeActionResolver.cs index 54b7a4053ac..420e2839e41 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/CreateComponentCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/CreateComponentCodeActionResolver.cs @@ -43,7 +43,7 @@ public CreateComponentCodeActionResolver(IDocumentContextFactory documentContext return null; } - var documentContext = await _documentContextFactory.TryCreateAsync(actionParams.Uri, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreate(actionParams.Uri); if (documentContext is null) { return null; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToCodeBehindCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToCodeBehindCodeActionResolver.cs index db43048de89..eff9809f42b 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToCodeBehindCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToCodeBehindCodeActionResolver.cs @@ -60,7 +60,7 @@ public ExtractToCodeBehindCodeActionResolver( var path = FilePathNormalizer.Normalize(actionParams.Uri.GetAbsoluteOrUNCPath()); - var documentContext = await _documentContextFactory.TryCreateAsync(actionParams.Uri, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreate(actionParams.Uri); if (documentContext is null) { return null; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/GenerateMethodCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/GenerateMethodCodeActionResolver.cs index abc3f072032..7a66254716f 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/GenerateMethodCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/GenerateMethodCodeActionResolver.cs @@ -72,7 +72,7 @@ public GenerateMethodCodeActionResolver( return null; } - var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(actionParams.Uri, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreateForOpenDocument(actionParams.Uri); if (documentContext is null) { return null; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionItemResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionItemResolver.cs index 68474333fa7..2a82ae9beda 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionItemResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionItemResolver.cs @@ -100,7 +100,7 @@ private async Task PostProcessCompletionItemAsync( } var identifier = context.OriginalRequestParams.Identifier.TextDocumentIdentifier; - var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(identifier, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreateForOpenDocument(identifier); if (documentContext is null) { return resolvedCompletionItem; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorDiagnosticsPublisher.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorDiagnosticsPublisher.cs index 29e4eb9a631..24347cc3c59 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorDiagnosticsPublisher.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorDiagnosticsPublisher.cs @@ -183,9 +183,8 @@ .. csharpDiagnostics ?? [] delegatedResponse.Value.TryGetFirst(out var fullDiagnostics) && fullDiagnostics.Items is not null) { - var documentContext = await _documentContextFactory.Value - .TryCreateAsync(delegatedParams.TextDocument.Uri, projectContext: null, token) - .ConfigureAwait(false); + var documentContext = _documentContextFactory.Value + .TryCreate(delegatedParams.TextDocument.Uri, projectContext: null); if (documentContext is not null) { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs index f33182006c8..4a0463201cc 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; @@ -27,12 +28,11 @@ internal sealed class DocumentContextFactory( private readonly IDocumentVersionCache _documentVersionCache = documentVersionCache; private readonly ILogger _logger = loggerFactory.GetOrCreateLogger(); - public async Task TryCreateAsync(Uri documentUri, VSProjectContext? projectContext, bool versioned, CancellationToken cancellationToken) + public DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) { var filePath = documentUri.GetAbsoluteOrUNCPath(); - var documentAndVersion = await TryGetDocumentAndVersionAsync(filePath, projectContext, versioned, cancellationToken).ConfigureAwait(false); - if (documentAndVersion is null) + if (!TryGetDocumentAndVersion(filePath, projectContext, versioned, out var documentAndVersion)) { // Stale request or misbehaving client, see above comment. return null; @@ -59,20 +59,24 @@ internal sealed class DocumentContextFactory( return new DocumentContext(documentUri, documentSnapshot, projectContext); } - private async Task TryGetDocumentAndVersionAsync(string filePath, VSProjectContext? projectContext, bool versioned, CancellationToken cancellationToken) + private bool TryGetDocumentAndVersion( + string filePath, + VSProjectContext? projectContext, + bool versioned, + [NotNullWhen(true)] out DocumentSnapshotAndVersion? documentAndVersion) { - var documentSnapshot = await TryResolveDocumentAsync(filePath, projectContext, cancellationToken).ConfigureAwait(false); - - if (documentSnapshot is not null) + if (TryResolveDocument(filePath, projectContext, out var documentSnapshot)) { if (!versioned) { - return new DocumentSnapshotAndVersion(documentSnapshot, Version: null); + documentAndVersion = new DocumentSnapshotAndVersion(documentSnapshot, Version: null); + return true; } if (_documentVersionCache.TryGetDocumentVersion(documentSnapshot, out var version)) { - return new DocumentSnapshotAndVersion(documentSnapshot, version.Value); + documentAndVersion = new DocumentSnapshotAndVersion(documentSnapshot, version.Value); + return true; } _logger.LogWarning($"Tried to create context for document {filePath} and project {projectContext?.Id} and a document was found, but version didn't match."); @@ -85,20 +89,26 @@ internal sealed class DocumentContextFactory( // version cache has evicted the entry // 2. Client is misbehaving and sending requests for a document that we've never seen before. _logger.LogWarning($"Tried to create context for document {filePath} and project {projectContext?.Id} which was not found."); - return null; + documentAndVersion = null; + return false; } - private async Task TryResolveDocumentAsync(string filePath, VSProjectContext? projectContext, CancellationToken cancellationToken) + private bool TryResolveDocument( + string filePath, + VSProjectContext? projectContext, + [NotNullWhen(true)] out IDocumentSnapshot? documentSnapshot) { if (projectContext is null) { - return _snapshotResolver.ResolveDocumentInAnyProject(filePath); + documentSnapshot = _snapshotResolver.ResolveDocumentInAnyProject(filePath); + return documentSnapshot is not null; } if (_projectManager.TryGetLoadedProject(projectContext.ToProjectKey(), out var project) && project.GetDocument(filePath) is { } document) { - return document; + documentSnapshot = document; + return true; } // Couldn't find the document in a real project. Maybe the language server doesn't yet know about the project @@ -109,10 +119,12 @@ internal sealed class DocumentContextFactory( if (miscellaneousProject.GetDocument(normalizedDocumentPath) is { } miscDocument) { _logger.LogDebug($"Found document {filePath} in the misc files project, but was asked for project context {projectContext.Id}"); - return miscDocument; + documentSnapshot = miscDocument; + return true; } - return null; + documentSnapshot = null; + return false; } private record DocumentSnapshotAndVersion(IDocumentSnapshot Snapshot, int? Version); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentPresentation/TextDocumentUriPresentationEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentPresentation/TextDocumentUriPresentationEndpoint.cs index fae8cab2f25..9e3e13ead68 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentPresentation/TextDocumentUriPresentationEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentPresentation/TextDocumentUriPresentationEndpoint.cs @@ -116,7 +116,7 @@ protected override IRazorPresentationParams CreateRazorRequestParameters(UriPres { Logger.LogInformation($"Trying to find document info for dropped uri {uri}."); - var documentContext = await _documentContextFactory.TryCreateAsync(uri, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreate(uri); if (documentContext is null) { Logger.LogInformation($"Failed to find document for component {uri}."); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs index ab765a35cff..1381364d2ec 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs @@ -85,7 +85,7 @@ public void ApplyCapabilities(VSInternalServerCapabilities serverCapabilities, V continue; } - var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(mapping.TextDocument.Uri, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreateForOpenDocument(mapping.TextDocument.Uri); if (documentContext is null) { continue; @@ -356,7 +356,7 @@ private async Task GetCSharpFocusLocationsAsync(Location[][] focus continue; } - var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(potentialLocation.Uri, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreateForOpenDocument(potentialLocation.Uri); if (documentContext is null) { continue; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs index 850c3c8c486..a2bb4b809ca 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs @@ -35,7 +35,7 @@ public override async Task CreateRequestContextAsync uriHandler) { @@ -43,7 +43,7 @@ public override async Task CreateRequestContextAsync RemapWorkspaceEditAsync(WorkspaceEdit workspace return (generatedDocumentUri, generatedDocumentRange); } - var documentContext = await _documentContextFactory.TryCreateAsync(razorDocumentUri, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreate(razorDocumentUri); if (documentContext is null) { return (generatedDocumentUri, generatedDocumentRange); @@ -809,7 +809,7 @@ private async Task RemapVersionedDocumentEditsAsync(TextDocu } var razorDocumentUri = _documentFilePathService.GetRazorDocumentUri(generatedDocumentUri); - var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(razorDocumentUri, entry.TextDocument.GetProjectContext(), cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreateForOpenDocument(razorDocumentUri, entry.TextDocument.GetProjectContext()); if (documentContext is null) { continue; @@ -853,7 +853,7 @@ private async Task> RemapDocumentEditsAsync(Dicti continue; } - var documentContext = await _documentContextFactory.TryCreateAsync(uri, cancellationToken).ConfigureAwait(false); + var documentContext = _documentContextFactory.TryCreate(uri); if (documentContext is null) { continue; diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactory.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactory.cs index 0981b00ea84..973d9f734ed 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactory.cs @@ -2,13 +2,11 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; -using System.Threading; -using System.Threading.Tasks; using Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.CodeAnalysis.Razor.ProjectSystem; internal interface IDocumentContextFactory { - Task TryCreateAsync(Uri documentUri, VSProjectContext? projectContext, bool versioned, CancellationToken cancellationToken); + DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned); } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactoryExtensions.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactoryExtensions.cs index 767efcbec5d..e825c027521 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactoryExtensions.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactoryExtensions.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; -using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -11,21 +9,21 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem; internal static class IDocumentContextFactoryExtensions { - public static Task TryCreateAsync(this IDocumentContextFactory service, TextDocumentIdentifier documentIdentifier, CancellationToken cancellationToken) - => service.TryCreateAsync(documentIdentifier.Uri, documentIdentifier.GetProjectContext(), versioned: false, cancellationToken); + public static DocumentContext? TryCreate(this IDocumentContextFactory service, TextDocumentIdentifier documentIdentifier) + => service.TryCreate(documentIdentifier.Uri, documentIdentifier.GetProjectContext(), versioned: false); - public static Task TryCreateAsync(this IDocumentContextFactory service, Uri documentUri, CancellationToken cancellationToken) - => service.TryCreateAsync(documentUri, projectContext: null, versioned: false, cancellationToken); + public static DocumentContext? TryCreate(this IDocumentContextFactory service, Uri documentUri) + => service.TryCreate(documentUri, projectContext: null, versioned: false); - public static Task TryCreateAsync(this IDocumentContextFactory service, Uri documentUri, VSProjectContext? projectContext, CancellationToken cancellationToken) - => service.TryCreateAsync(documentUri, projectContext, versioned: false, cancellationToken); + public static DocumentContext? TryCreate(this IDocumentContextFactory service, Uri documentUri, VSProjectContext? projectContext) + => service.TryCreate(documentUri, projectContext, versioned: false); - public static async Task TryCreateForOpenDocumentAsync(this IDocumentContextFactory service, Uri documentUri, CancellationToken cancellationToken) - => (VersionedDocumentContext?)await service.TryCreateAsync(documentUri, projectContext: null, versioned: true, cancellationToken).ConfigureAwait(false); + public static VersionedDocumentContext? TryCreateForOpenDocument(this IDocumentContextFactory service, Uri documentUri) + => (VersionedDocumentContext?)service.TryCreate(documentUri, projectContext: null, versioned: true); - public static async Task TryCreateForOpenDocumentAsync(this IDocumentContextFactory service, TextDocumentIdentifier documentIdentifier, CancellationToken cancellationToken) - => (VersionedDocumentContext?)await service.TryCreateAsync(documentIdentifier.Uri, documentIdentifier.GetProjectContext(), versioned: true, cancellationToken).ConfigureAwait(false); + public static VersionedDocumentContext? TryCreateForOpenDocument(this IDocumentContextFactory service, TextDocumentIdentifier documentIdentifier) + => (VersionedDocumentContext?)service.TryCreate(documentIdentifier.Uri, documentIdentifier.GetProjectContext(), versioned: true); - public static async Task TryCreateForOpenDocumentAsync(this IDocumentContextFactory service, Uri documentUri, VSProjectContext? projectContext, CancellationToken cancellationToken) - => (VersionedDocumentContext?)await service.TryCreateAsync(documentUri, projectContext, versioned: true, cancellationToken).ConfigureAwait(false); + public static VersionedDocumentContext? TryCreateForOpenDocument(this IDocumentContextFactory service, Uri documentUri, VSProjectContext? projectContext) + => (VersionedDocumentContext?)service.TryCreate(documentUri, projectContext, versioned: true); } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/DocumentContextFactory.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/DocumentContextFactory.cs index ffd381e2d60..cd8f2ae3adb 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/DocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/DocumentContextFactory.cs @@ -3,8 +3,6 @@ using System; using System.Composition; -using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -13,7 +11,7 @@ namespace Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; [Export(typeof(IDocumentContextFactory)), Shared] internal class DocumentContextFactory : IDocumentContextFactory { - public Task TryCreateAsync(Uri documentUri, VSProjectContext? projectContext, bool versioned, CancellationToken cancellationToken) + public DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) { throw new NotSupportedException("OOP doesn't support this yet, because we don't have a way to pass in the right solution snapshot to use"); } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/AutoInsert/OnAutoInsertEndpointTest.NetFx.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/AutoInsert/OnAutoInsertEndpointTest.NetFx.cs index 8cd0e91648e..80c082a802d 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/AutoInsert/OnAutoInsertEndpointTest.NetFx.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/AutoInsert/OnAutoInsertEndpointTest.NetFx.cs @@ -383,7 +383,7 @@ private async Task VerifyCSharpOnAutoInsertAsync(string input, string expected, InsertSpaces = true }, }; - var documentContext = await DocumentContextFactory.TryCreateForOpenDocumentAsync(@params.TextDocument, DisposalToken); + var documentContext = DocumentContextFactory.TryCreateForOpenDocument(@params.TextDocument); var requestContext = await CreateOnAutoInsertRequestContextAsync(documentContext); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CodeActionEndToEndTest.NetFx.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CodeActionEndToEndTest.NetFx.cs index 0149e9a1554..e11d9dccc49 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CodeActionEndToEndTest.NetFx.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CodeActionEndToEndTest.NetFx.cs @@ -1255,18 +1255,18 @@ public GenerateMethodResolverDocumentContextFactory } } - public override Task TryCreateAsync(Uri documentUri, VSProjectContext? projectContext, bool versioned, CancellationToken cancellationToken) + public override DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) { if (FilePath is null || CodeDocument is null) { - return Task.FromResult(null); + return null; } var projectWorkspaceState = ProjectWorkspaceState.Create(_tagHelperDescriptors.ToImmutableArray()); var testDocumentSnapshot = TestDocumentSnapshot.Create(FilePath, CodeDocument.GetSourceText().ToString(), CodeAnalysis.VersionStamp.Default, projectWorkspaceState); testDocumentSnapshot.With(CodeDocument); - return Task.FromResult(CreateDocumentContext(new Uri(FilePath), testDocumentSnapshot)); + return CreateDocumentContext(new Uri(FilePath), testDocumentSnapshot); } private static List CreateTagHelperDescriptors() diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Html/DefaultHtmlCodeActionResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Html/DefaultHtmlCodeActionResolverTest.cs index 8b054675166..abe355839a7 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Html/DefaultHtmlCodeActionResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Html/DefaultHtmlCodeActionResolverTest.cs @@ -33,7 +33,7 @@ public async Task ResolveAsync_RemapsAndFixesEdits() var documentPath = "c:/Test.razor"; var documentUri = new Uri(documentPath); var documentContextFactory = CreateDocumentContextFactory(documentUri, contents); - var context = await documentContextFactory.TryCreateAsync(documentUri, DisposalToken); + var context = documentContextFactory.TryCreate(documentUri); Assert.NotNull(context); var sourceText = await context.GetSourceTextAsync(DisposalToken); var remappedEdit = new WorkspaceEdit diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Debugging/ValidateBreakpointRangeEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Debugging/ValidateBreakpointRangeEndpointTest.cs index 66d9084adf9..afe5697c3ed 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Debugging/ValidateBreakpointRangeEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Debugging/ValidateBreakpointRangeEndpointTest.cs @@ -152,7 +152,7 @@ private async Task VerifyBreakpointRangeAsync(string input) Range = breakpointSpan.ToRange(codeDocument.GetSourceText()) }; - var documentContext = await DocumentContextFactory.TryCreateForOpenDocumentAsync(request.TextDocument, DisposalToken); + var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); Assert.NotNull(documentContext); var requestContext = CreateValidateBreakpointRangeRequestContext(documentContext); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Definition/DefinitionEndpointDelegationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Definition/DefinitionEndpointDelegationTest.cs index ceec91b2fe6..fe09f9f1f38 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Definition/DefinitionEndpointDelegationTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Definition/DefinitionEndpointDelegationTest.cs @@ -239,7 +239,7 @@ await projectManager.UpdateAsync(updater => var searchEngine = new DefaultRazorComponentSearchEngine(projectManager, LoggerFactory); var razorUri = new Uri(razorFilePath); - var documentContext = await DocumentContextFactory.TryCreateForOpenDocumentAsync(razorUri, DisposalToken); + var documentContext = DocumentContextFactory.TryCreateForOpenDocument(razorUri); var requestContext = CreateRazorRequestContext(documentContext); var endpoint = new DefinitionEndpoint(searchEngine, DocumentMappingService, LanguageServerFeatureOptions, languageServer, LoggerFactory); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs index 44c2241fc21..332cf86a97a 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs @@ -46,7 +46,7 @@ public async Task TryCreateAsync_CanNotResolveDocument_ReturnsNull() var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = await factory.TryCreateAsync(uri, DisposalToken); + var documentContext = factory.TryCreate(uri); // Assert Assert.Null(documentContext); @@ -65,7 +65,7 @@ public async Task TryCreateForOpenDocumentAsync_CanNotResolveDocument_ReturnsNul var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = await factory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = factory.TryCreateForOpenDocument(uri); // Assert Assert.Null(documentContext); @@ -84,7 +84,7 @@ public async Task TryCreateForOpenDocumentAsync_CanNotResolveVersion_ReturnsNull var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = await factory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = factory.TryCreateForOpenDocument(uri); // Assert Assert.Null(documentContext); @@ -105,7 +105,7 @@ public async Task TryCreateAsync_ResolvesContent() var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = await factory.TryCreateAsync(uri, DisposalToken); + var documentContext = factory.TryCreate(uri); // Assert Assert.NotNull(documentContext); @@ -139,7 +139,7 @@ await _projectManager.UpdateAsync(updater => }); // Act - var documentContext = await factory.TryCreateAsync(uri, new VisualStudio.LanguageServer.Protocol.VSProjectContext { Id = hostProject.Key.Id }, DisposalToken); + var documentContext = factory.TryCreate(uri, new VisualStudio.LanguageServer.Protocol.VSProjectContext { Id = hostProject.Key.Id }); // Assert Assert.NotNull(documentContext); @@ -171,7 +171,7 @@ await _projectManager.UpdateAsync(updater => }); // Act - var documentContext = await factory.TryCreateAsync(uri, new VisualStudio.LanguageServer.Protocol.VSProjectContext { Id = hostProject.Key.Id }, DisposalToken); + var documentContext = factory.TryCreate(uri, new VisualStudio.LanguageServer.Protocol.VSProjectContext { Id = hostProject.Key.Id }); // Assert Assert.NotNull(documentContext); @@ -195,7 +195,7 @@ public async Task TryCreateForOpenDocumentAsync_ResolvesContent() var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = await factory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = factory.TryCreateForOpenDocument(uri); // Assert Assert.NotNull(documentContext); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs index 6e48c9a7c23..219ead40280 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs @@ -56,7 +56,7 @@ public async Task Handle_SimpleComponent_ReturnsResult() var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, null, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri, null); var clientConnection = new Mock(MockBehavior.Strict); @@ -121,7 +121,7 @@ public async Task Handle_SimpleComponentWithChildFile_ReturnsResult() var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, null, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri, null); var clientConnection = new Mock(MockBehavior.Strict); @@ -197,7 +197,7 @@ public async Task Handle_ComponentWithRequiredAttribute_ReturnsResult() var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, null, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri, null); var clientConnection = new Mock(MockBehavior.Strict); @@ -424,7 +424,7 @@ public async Task Handle_ComponentWithNestedFiles_ReturnsResult() var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, null, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri, null); var clientConnection = new Mock(MockBehavior.Strict); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentSymbols/DocumentSymbolEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentSymbols/DocumentSymbolEndpointTest.cs index 606d15227ac..330094e771c 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentSymbols/DocumentSymbolEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentSymbols/DocumentSymbolEndpointTest.cs @@ -89,7 +89,7 @@ private async Task VerifyDocumentSymbolsAsync(string input) } } }; - var documentContext = await DocumentContextFactory.TryCreateForOpenDocumentAsync(request.TextDocument, DisposalToken); + var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/FindReferences/FindAllReferencesEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/FindReferences/FindAllReferencesEndpointTest.cs index bd2c914f1f0..a573b837542 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/FindReferences/FindAllReferencesEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/FindReferences/FindAllReferencesEndpointTest.cs @@ -76,7 +76,7 @@ private async Task VerifyCSharpFindAllReferencesAsyncAsync(string input) }, Position = new Position(line, offset) }; - var documentContext = await DocumentContextFactory.TryCreateForOpenDocumentAsync(request.TextDocument, DisposalToken); + var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Folding/FoldingEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Folding/FoldingEndpointTest.cs index b3f99666f9d..98fc454f6ab 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Folding/FoldingEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Folding/FoldingEndpointTest.cs @@ -117,7 +117,7 @@ private async Task VerifyRazorFoldsAsync(string input, string? filePath = null) } } }; - var documentContext = await DocumentContextFactory.TryCreateForOpenDocumentAsync(request.TextDocument, DisposalToken); + var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs index ce3cffc65cb..b50ce3a2f5a 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs @@ -207,7 +207,7 @@ public async Task Handle_OnTypeFormatting_UnexpectedTriggerCharacter_ReturnsNull Position = new Position(2, 11), Options = new FormattingOptions { InsertSpaces = true, TabSize = 4 } }; - var documentContext = await documentResolver.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentResolver.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext!); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Implementation/ImplementationEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Implementation/ImplementationEndpointTest.cs index c67b98cbf47..44e12871a03 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Implementation/ImplementationEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Implementation/ImplementationEndpointTest.cs @@ -107,7 +107,7 @@ private async Task VerifyCSharpGoToImplementationAsync(string input) }, Position = new Position(line, offset) }; - var documentContext = await DocumentContextFactory.TryCreateForOpenDocumentAsync(request.TextDocument, DisposalToken); + var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/InlayHints/InlayHintEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/InlayHints/InlayHintEndpointTest.cs index 1ab01e11bc5..d3567565840 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/InlayHints/InlayHintEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/InlayHints/InlayHintEndpointTest.cs @@ -112,7 +112,7 @@ private async Task VerifyInlayHintsAsync(string input, Dictionary Position = new Position(line, offset), NewName = newName }; - var documentContext = await DocumentContextFactory.TryCreateForOpenDocumentAsync(request.TextDocument, DisposalToken); + var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs index 801bb4c374d..2add96d36aa 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs @@ -121,7 +121,7 @@ public async Task Handle_Rename_FileManipulationNotSupported_ReturnsNull() NewName = "Component5" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -144,7 +144,7 @@ public async Task Handle_Rename_WithNamespaceDirective() NewName = "Component5" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -185,7 +185,7 @@ public async Task Handle_Rename_OnComponentParameter_ReturnsNull() NewName = "Test2" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -208,7 +208,7 @@ public async Task Handle_Rename_OnOpeningBrace_ReturnsNull() NewName = "Test2" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -231,7 +231,7 @@ public async Task Handle_Rename_OnComponentNameLeadingEdge_ReturnsResult() NewName = "Test2" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -254,7 +254,7 @@ public async Task Handle_Rename_OnComponentName_ReturnsResult() NewName = "Test2" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -277,7 +277,7 @@ public async Task Handle_Rename_OnComponentNameTrailingEdge_ReturnsResult() NewName = "Test2" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -300,7 +300,7 @@ public async Task Handle_Rename_ComponentInSameFile() NewName = "Component5" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -386,7 +386,7 @@ public async Task Handle_Rename_FullyQualifiedAndNot() NewName = "Component5" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -432,7 +432,7 @@ public async Task Handle_Rename_MultipleFileUsages() NewName = "Component5" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -485,7 +485,7 @@ public async Task Handle_Rename_DifferentDirectories() NewName = "TestComponent" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -550,7 +550,7 @@ public async Task Handle_Rename_SingleServer_CallsDelegatedLanguageServer() NewName = "Test2" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -584,7 +584,7 @@ public async Task Handle_Rename_SingleServer_DoesNotDelegateForRazor() NewName = "Test2" }; - var documentContext = await documentContextFactory.TryCreateForOpenDocumentAsync(request.TextDocument.Uri, DisposalToken); + var documentContext = documentContextFactory.TryCreateForOpenDocument(request.TextDocument.Uri); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/SemanticTokensTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/SemanticTokensTest.cs index 0c8146e0aa8..a566c7effe0 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/SemanticTokensTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/SemanticTokensTest.cs @@ -1201,9 +1201,9 @@ private static string GetFileRepresentationOfTokens(SourceText sourceText, int[] private class TestDocumentContextFactory(VersionedDocumentContext? documentContext = null) : IDocumentContextFactory { - public Task TryCreateAsync(Uri documentUri, VSProjectContext? projectContext, bool versioned, CancellationToken cancellationToken) + public DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) { - return Task.FromResult(documentContext); + return documentContext; } } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SignatureHelp/SignatureHelpEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SignatureHelp/SignatureHelpEndpointTest.cs index f9b96f44947..a04ee0e851e 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SignatureHelp/SignatureHelpEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SignatureHelp/SignatureHelpEndpointTest.cs @@ -115,7 +115,7 @@ private async Task VerifySignatureHelpWithContextAndOptionsAsync(string input, R Context = signatureHelpContext }; - var documentContext = await DocumentContextFactory.TryCreateForOpenDocumentAsync(request.TextDocument, DisposalToken); + var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); var requestContext = CreateRazorRequestContext(documentContext); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/WrapWithTag/WrapWithTagEndpointTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/WrapWithTag/WrapWithTagEndpointTests.cs index 6dc791c3481..ea1aaa2c47d 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/WrapWithTag/WrapWithTagEndpointTests.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/WrapWithTag/WrapWithTagEndpointTests.cs @@ -270,7 +270,7 @@ public async Task CleanUpTextEdits_NoTilde() var uri = new Uri("file://path.razor"); var factory = CreateDocumentContextFactory(uri, input); - var context = await factory.TryCreateAsync(uri, DisposalToken); + var context = factory.TryCreate(uri); Assert.NotNull(context); var inputSourceText = await context!.GetSourceTextAsync(DisposalToken); @@ -320,7 +320,7 @@ public async Task CleanUpTextEdits_BadEditWithTilde() var uri = new Uri("file://path.razor"); var factory = CreateDocumentContextFactory(uri, input); - var context = await factory.TryCreateAsync(uri, DisposalToken); + var context = factory.TryCreate(uri); Assert.NotNull(context); var inputSourceText = await context!.GetSourceTextAsync(DisposalToken); @@ -371,7 +371,7 @@ public async Task CleanUpTextEdits_GoodEditWithTilde() var uri = new Uri("file://path.razor"); var factory = CreateDocumentContextFactory(uri, input); - var context = await factory.TryCreateAsync(uri, DisposalToken); + var context = factory.TryCreate(uri); Assert.NotNull(context); var inputSourceText = await context!.GetSourceTextAsync(DisposalToken); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/TestDocumentContextFactory.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/TestDocumentContextFactory.cs index 995d5a95b43..66427228c74 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/TestDocumentContextFactory.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/TestDocumentContextFactory.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; -using System.Threading; -using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -27,23 +25,23 @@ public TestDocumentContextFactory(string filePath, RazorCodeDocument codeDocumen _version = version; } - public virtual Task TryCreateAsync(Uri documentUri, VSProjectContext? projectContext, bool versioned, CancellationToken cancellationToken) + public virtual DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) { if (FilePath is null || CodeDocument is null) { - return Task.FromResult(null); + return null; } if (versioned) { if (_version is null) { - return Task.FromResult(null); + return null; } - return Task.FromResult(TestDocumentContext.From(FilePath, CodeDocument, _version.Value)); + return TestDocumentContext.From(FilePath, CodeDocument, _version.Value); } - return Task.FromResult(TestDocumentContext.From(FilePath, CodeDocument)); + return TestDocumentContext.From(FilePath, CodeDocument); } } From 654c7148d81393339fc6f938bbb00a0fee08944b Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 26 Apr 2024 13:17:28 -0700 Subject: [PATCH 06/16] Remove async from RazorRequestContextFactory.CreateRequestContextAsync This method now runs synchronously. --- .../RazorRequestContextFactory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs index a2bb4b809ca..b7b63ede8ed 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs @@ -17,7 +17,7 @@ internal class RazorRequestContextFactory(ILspServices lspServices) : AbstractRe { private readonly ILspServices _lspServices = lspServices; - public override async Task CreateRequestContextAsync(IQueueItem queueItem, IMethodHandler methodHandler, TRequestParams @params, CancellationToken cancellationToken) + public override Task CreateRequestContextAsync(IQueueItem queueItem, IMethodHandler methodHandler, TRequestParams @params, CancellationToken cancellationToken) { var logger = _lspServices.GetRequiredService().GetOrCreateLogger(); @@ -58,6 +58,6 @@ public override async Task CreateRequestContextAsync Date: Fri, 26 Apr 2024 13:54:19 -0700 Subject: [PATCH 07/16] Make RazorProjectService operations atomic The RazorProjectService APIs (e.g. AddDocumentAsync, UpdateProjectAsync, etc.) were chunked into multiple tasks and awaits. That means that other updates to the ProjectSnapshotManager could be interleaved with them. This change ensures that the operations are atomic (as far as the ProjectSnapshotManager is concerned) by running each within a call to ProjectSnapshotManager.UpdateAsync(...). Because of other changes to make CPU-bound async work synchronous the operations themselves can be made synchronous. --- .../ProjectSystem/RazorProjectService.cs | 458 ++++++++---------- 1 file changed, 191 insertions(+), 267 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 257f30ab02f..1b625fb8fe0 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -29,7 +29,7 @@ internal class RazorProjectService( IDocumentVersionCache documentVersionCache, IProjectSnapshotManager projectManager, ILoggerFactory loggerFactory) - : IRazorProjectService, IDisposable + : IRazorProjectService { private readonly IProjectSnapshotManager _projectManager = projectManager; private readonly RemoteTextLoaderFactory _remoteTextLoaderFactory = remoteTextLoaderFactory; @@ -37,23 +37,15 @@ internal class RazorProjectService( private readonly IDocumentVersionCache _documentVersionCache = documentVersionCache; private readonly ILogger _logger = loggerFactory.GetOrCreateLogger(); - // This lock is used to ensure that the public entry points to the project service, - // i.e. AddDocumentAsync, OpenDocumentAsync, etc., cannot interleave. - private readonly AsyncSemaphore _gate = new(initialCount: 1); - - public void Dispose() - { - _gate.Dispose(); - } - - public async Task AddDocumentAsync(string filePath, CancellationToken cancellationToken) + public Task AddDocumentAsync(string filePath, CancellationToken cancellationToken) { - using var _ = await _gate.EnterAsync(cancellationToken).ConfigureAwait(false); - - await AddDocumentNeedsLocksAsync(filePath, cancellationToken).ConfigureAwait(false); + return _projectManager.UpdateAsync( + updater: AddDocumentCore, + state: filePath, + cancellationToken); } - private async Task AddDocumentNeedsLocksAsync(string filePath, CancellationToken cancellationToken) + private void AddDocumentCore(ProjectSnapshotManager.Updater updater, string filePath) { var textDocumentPath = FilePathNormalizer.Normalize(filePath); @@ -61,16 +53,16 @@ private async Task AddDocumentNeedsLocksAsync(string filePath, CancellationToken foreach (var projectSnapshot in _snapshotResolver.FindPotentialProjects(textDocumentPath)) { added = true; - await AddDocumentToProjectAsync(projectSnapshot, textDocumentPath, cancellationToken).ConfigureAwait(false); + AddDocumentToProject(updater, projectSnapshot, textDocumentPath); } if (!added) { var miscFilesProject = _snapshotResolver.GetMiscellaneousProject(); - await AddDocumentToProjectAsync(miscFilesProject, textDocumentPath, cancellationToken).ConfigureAwait(false); + AddDocumentToProject(updater, miscFilesProject, textDocumentPath); } - async Task AddDocumentToProjectAsync(IProjectSnapshot projectSnapshot, string textDocumentPath, CancellationToken cancellationToken) + void AddDocumentToProject(ProjectSnapshotManager.Updater updater, IProjectSnapshot projectSnapshot, string textDocumentPath) { if (projectSnapshot.GetDocument(FilePathNormalizer.Normalize(textDocumentPath)) is not null) { @@ -95,12 +87,7 @@ async Task AddDocumentToProjectAsync(IProjectSnapshot projectSnapshot, string te _logger.LogInformation($"Adding document '{filePath}' to project '{projectSnapshot.Key}'."); - await _projectManager - .UpdateAsync( - static (updater, state) => updater.DocumentAdded(state.key, state.hostDocument, state.textLoader), - state: (key: projectSnapshot.Key, hostDocument, textLoader), - cancellationToken) - .ConfigureAwait(false); + updater.DocumentAdded(projectSnapshot.Key, hostDocument, textLoader); // Adding a document to a project could also happen because a target was added to a project, or we're moving a document // from Misc Project to a real one, and means the newly added document could actually already be open. @@ -109,151 +96,137 @@ await _projectManager _projectManager.TryGetLoadedProject(projectSnapshot.Key, out var project) && project.GetDocument(textDocumentPath) is { } document) { - _ = document.GetGeneratedOutputAsync(); + document.GetGeneratedOutputAsync().Forget(); } } } - public async Task OpenDocumentAsync(string filePath, SourceText sourceText, int version, CancellationToken cancellationToken) + public Task OpenDocumentAsync(string filePath, SourceText sourceText, int version, CancellationToken cancellationToken) { - using var _ = await _gate.EnterAsync(cancellationToken).ConfigureAwait(false); - - var textDocumentPath = FilePathNormalizer.Normalize(filePath); - - // We are okay to use the non-project-key overload of TryResolveDocument here because we really are just checking if the document - // has been added to _any_ project. AddDocument will take care of adding to all of the necessary ones, and then below we ensure - // we process them all too - var document = _snapshotResolver.ResolveDocumentInAnyProject(textDocumentPath); + return _projectManager.UpdateAsync( + updater => + { + var textDocumentPath = FilePathNormalizer.Normalize(filePath); - if (document is null) - { - // Document hasn't been added. This usually occurs when VSCode trumps all other initialization - // processes and pre-initializes already open documents. - await AddDocumentNeedsLocksAsync(filePath, cancellationToken).ConfigureAwait(false); - } + // We are okay to use the non-project-key overload of TryResolveDocument here because we really are just checking if the document + // has been added to _any_ project. AddDocument will take care of adding to all of the necessary ones, and then below we ensure + // we process them all too + var document = _snapshotResolver.ResolveDocumentInAnyProject(textDocumentPath); - await ActOnDocumentInMultipleProjectsAsync( - filePath, - async (projectSnapshot, textDocumentPath, cancellationToken) => - { - _logger.LogInformation($"Opening document '{textDocumentPath}' in project '{projectSnapshot.Key}'."); - - await _projectManager - .UpdateAsync( - static (updater, state) => updater.DocumentOpened(state.key, state.textDocumentPath, state.sourceText), - state: (key: projectSnapshot.Key, textDocumentPath, sourceText), - cancellationToken) - .ConfigureAwait(false); - }, - cancellationToken).ConfigureAwait(false); + if (document is null) + { + // Document hasn't been added. This usually occurs when VSCode trumps all other initialization + // processes and pre-initializes already open documents. + AddDocumentCore(updater, filePath); + } - // Use a separate loop, as the above call modified out projects, so we have to make sure we're operating on the latest snapshot - await ActOnDocumentInMultipleProjectsAsync( - filePath, - (projectSnapshot, textDocumentPath, cancellationToken) => - { - TrackDocumentVersion(projectSnapshot, textDocumentPath, version, startGenerating: true); - return Task.CompletedTask; + ActOnDocumentInMultipleProjects( + filePath, + (projectSnapshot, textDocumentPath) => + { + _logger.LogInformation($"Opening document '{textDocumentPath}' in project '{projectSnapshot.Key}'."); + updater.DocumentOpened(projectSnapshot.Key, textDocumentPath, sourceText); + }); + + // Use a separate loop, as the above call modified out projects, so we have to make sure we're operating on the latest snapshot + ActOnDocumentInMultipleProjects( + filePath, + (projectSnapshot, textDocumentPath) => + { + TrackDocumentVersion(projectSnapshot, textDocumentPath, version, startGenerating: true); + }); }, - cancellationToken).ConfigureAwait(false); + cancellationToken); } - public async Task CloseDocumentAsync(string filePath, CancellationToken cancellationToken) + public Task CloseDocumentAsync(string filePath, CancellationToken cancellationToken) { - using var _ = await _gate.EnterAsync(cancellationToken).ConfigureAwait(false); - - await ActOnDocumentInMultipleProjectsAsync( - filePath, - (projectSnapshot, textDocumentPath, cancellationToken) => + return _projectManager.UpdateAsync( + updater => { - var textLoader = _remoteTextLoaderFactory.Create(filePath); - _logger.LogInformation($"Closing document '{textDocumentPath}' in project '{projectSnapshot.Key}'."); + ActOnDocumentInMultipleProjects( + filePath, + (projectSnapshot, textDocumentPath) => + { + var textLoader = _remoteTextLoaderFactory.Create(filePath); + _logger.LogInformation($"Closing document '{textDocumentPath}' in project '{projectSnapshot.Key}'."); - return _projectManager.UpdateAsync( - static (updater, state) => updater.DocumentClosed(state.key, state.textDocumentPath, state.textLoader), - state: (key: projectSnapshot.Key, textDocumentPath, textLoader), - cancellationToken); + updater.DocumentClosed(projectSnapshot.Key, textDocumentPath, textLoader); + }); }, - cancellationToken).ConfigureAwait(false); + cancellationToken); } - public async Task RemoveDocumentAsync(string filePath, CancellationToken cancellationToken) + public Task RemoveDocumentAsync(string filePath, CancellationToken cancellationToken) { - using var _ = await _gate.EnterAsync(cancellationToken).ConfigureAwait(false); - - await ActOnDocumentInMultipleProjectsAsync(filePath, async (projectSnapshot, textDocumentPath, cancellationToken) => - { - if (!projectSnapshot.DocumentFilePaths.Contains(textDocumentPath, FilePathComparer.Instance)) - { - _logger.LogInformation($"Containing project is not tracking document '{textDocumentPath}'"); - return; - } - - if (projectSnapshot.GetDocument(textDocumentPath) is not DocumentSnapshot documentSnapshot) - { - _logger.LogError($"Containing project does not contain document '{textDocumentPath}'"); - return; - } - - // If the document is open, we can't remove it, because we could still get a request for it, and that - // request would fail. Instead we move it to the miscellaneous project, just like if we got notified of - // a remove via the project.razor.bin - if (_projectManager.IsDocumentOpen(textDocumentPath)) - { - _logger.LogInformation($"Moving document '{textDocumentPath}' from project '{projectSnapshot.Key}' to misc files because it is open."); - var miscellaneousProject = _snapshotResolver.GetMiscellaneousProject(); - if (projectSnapshot != miscellaneousProject) - { - await MoveDocumentAsync(textDocumentPath, projectSnapshot, miscellaneousProject, cancellationToken).ConfigureAwait(false); - } - } - else + return _projectManager.UpdateAsync( + updater => { - _logger.LogInformation($"Removing document '{textDocumentPath}' from project '{projectSnapshot.Key}'."); - - await _projectManager - .UpdateAsync( - static (updater, state) => updater.DocumentRemoved(state.Key, state.HostDocument), - state: (projectSnapshot.Key, documentSnapshot.State.HostDocument), - cancellationToken) - .ConfigureAwait(false); - } - }, - cancellationToken).ConfigureAwait(false); + ActOnDocumentInMultipleProjects( + filePath, + (projectSnapshot, textDocumentPath) => + { + if (!projectSnapshot.DocumentFilePaths.Contains(textDocumentPath, FilePathComparer.Instance)) + { + _logger.LogInformation($"Containing project is not tracking document '{textDocumentPath}'"); + return; + } + + if (projectSnapshot.GetDocument(textDocumentPath) is not DocumentSnapshot documentSnapshot) + { + _logger.LogError($"Containing project does not contain document '{textDocumentPath}'"); + return; + } + + // If the document is open, we can't remove it, because we could still get a request for it, and that + // request would fail. Instead we move it to the miscellaneous project, just like if we got notified of + // a remove via the project.razor.bin + if (_projectManager.IsDocumentOpen(textDocumentPath)) + { + _logger.LogInformation($"Moving document '{textDocumentPath}' from project '{projectSnapshot.Key}' to misc files because it is open."); + var miscellaneousProject = _snapshotResolver.GetMiscellaneousProject(); + if (projectSnapshot != miscellaneousProject) + { + MoveDocument(updater, textDocumentPath, fromProject: projectSnapshot, toProject: miscellaneousProject); + } + } + else + { + _logger.LogInformation($"Removing document '{textDocumentPath}' from project '{projectSnapshot.Key}'."); + + updater.DocumentRemoved(projectSnapshot.Key, documentSnapshot.State.HostDocument); + } + }); + }, + cancellationToken); } - public async Task UpdateDocumentAsync(string filePath, SourceText sourceText, int version, CancellationToken cancellationToken) + public Task UpdateDocumentAsync(string filePath, SourceText sourceText, int version, CancellationToken cancellationToken) { - using var _ = await _gate.EnterAsync(cancellationToken).ConfigureAwait(false); - - await ActOnDocumentInMultipleProjectsAsync( - filePath, - (project, textDocumentPath, cancellationToken) => + return _projectManager.UpdateAsync( + updater => { - _logger.LogTrace($"Updating document '{textDocumentPath}' in {project.Key}."); + ActOnDocumentInMultipleProjects( + filePath, + (project, textDocumentPath) => + { + _logger.LogTrace($"Updating document '{textDocumentPath}' in {project.Key}."); - return _projectManager.UpdateAsync( - static (updater, state) => updater.DocumentChanged(state.key, state.textDocumentPath, state.sourceText), - state: (key: project.Key, textDocumentPath, sourceText), - cancellationToken); - }, - cancellationToken).ConfigureAwait(false); + updater.DocumentChanged(project.Key, textDocumentPath, sourceText); + }); - // Use a separate loop, as the above call modified out projects, so we have to make sure we're operating on the latest snapshot - await ActOnDocumentInMultipleProjectsAsync( - filePath, - (projectSnapshot, textDocumentPath, cancellationToken) => - { - TrackDocumentVersion(projectSnapshot, textDocumentPath, version, startGenerating: false); - return Task.CompletedTask; + // Use a separate loop, as the above call modified out projects, so we have to make sure we're operating on the latest snapshot + ActOnDocumentInMultipleProjects( + filePath, + (projectSnapshot, textDocumentPath) => + { + TrackDocumentVersion(projectSnapshot, textDocumentPath, version, startGenerating: false); + }); }, - cancellationToken).ConfigureAwait(false); + cancellationToken); } - private async Task ActOnDocumentInMultipleProjectsAsync( - string filePath, - Func func, - CancellationToken cancellationToken) + private void ActOnDocumentInMultipleProjects(string filePath, Action action) { var textDocumentPath = FilePathNormalizer.Normalize(filePath); var projects = _snapshotResolver.TryResolveAllProjects(textDocumentPath); @@ -265,11 +238,11 @@ private async Task ActOnDocumentInMultipleProjectsAsync( foreach (var project in projects) { - await func(project, textDocumentPath, cancellationToken).ConfigureAwait(false); + action(project, textDocumentPath); } } - public async Task AddProjectAsync( + public Task AddProjectAsync( string filePath, string intermediateOutputPath, RazorConfiguration? configuration, @@ -277,28 +250,26 @@ public async Task AddProjectAsync( string? displayName, CancellationToken cancellationToken) { - using var _ = await _gate.EnterAsync(cancellationToken).ConfigureAwait(false); - - var normalizedPath = FilePathNormalizer.Normalize(filePath); - var hostProject = new HostProject( - normalizedPath, intermediateOutputPath, configuration ?? FallbackRazorConfiguration.Latest, rootNamespace, displayName); + return _projectManager.UpdateAsync( + updater => + { + var normalizedPath = FilePathNormalizer.Normalize(filePath); + var hostProject = new HostProject( + normalizedPath, intermediateOutputPath, configuration ?? FallbackRazorConfiguration.Latest, rootNamespace, displayName); - // ProjectAdded will no-op if the project already exists - await _projectManager - .UpdateAsync( - static (updater, hostProject) => updater.ProjectAdded(hostProject), - state: hostProject, - cancellationToken) - .ConfigureAwait(false); + // ProjectAdded will no-op if the project already exists + updater.ProjectAdded(hostProject); - _logger.LogInformation($"Added project '{filePath}' with key {hostProject.Key} to project system."); + _logger.LogInformation($"Added project '{filePath}' with key {hostProject.Key} to project system."); - await TryMigrateMiscellaneousDocumentsToProjectAsync(cancellationToken).ConfigureAwait(false); + TryMigrateMiscellaneousDocumentsToProject(updater); - return hostProject.Key; + return hostProject.Key; + }, + cancellationToken); } - public async Task UpdateProjectAsync( + public Task UpdateProjectAsync( ProjectKey projectKey, RazorConfiguration? configuration, string? rootNamespace, @@ -307,63 +278,59 @@ public async Task UpdateProjectAsync( ImmutableArray documents, CancellationToken cancellationToken) { - using var _ = await _gate.EnterAsync(cancellationToken).ConfigureAwait(false); + return _projectManager.UpdateAsync( + updater => + { + if (!_projectManager.TryGetLoadedProject(projectKey, out var project)) + { + // Never tracked the project to begin with, noop. + _logger.LogInformation($"Failed to update untracked project '{projectKey}'."); + return; + } - if (!_projectManager.TryGetLoadedProject(projectKey, out var project)) - { - // Never tracked the project to begin with, noop. - _logger.LogInformation($"Failed to update untracked project '{projectKey}'."); - return; - } + UpdateProjectDocuments(updater, documents, project.Key); - await UpdateProjectDocumentsAsync(documents, project.Key, cancellationToken).ConfigureAwait(false); + if (!projectWorkspaceState.Equals(ProjectWorkspaceState.Default)) + { + _logger.LogInformation($"Updating project '{project.Key}' TagHelpers ({projectWorkspaceState.TagHelpers.Length}) and C# Language Version ({projectWorkspaceState.CSharpLanguageVersion})."); + } - if (!projectWorkspaceState.Equals(ProjectWorkspaceState.Default)) - { - _logger.LogInformation($"Updating project '{project.Key}' TagHelpers ({projectWorkspaceState.TagHelpers.Length}) and C# Language Version ({projectWorkspaceState.CSharpLanguageVersion})."); - } + updater.ProjectWorkspaceStateChanged(project.Key, projectWorkspaceState); - await _projectManager - .UpdateAsync( - static (updater, state) => updater.ProjectWorkspaceStateChanged(state.key, state.projectWorkspaceState), - state: (key: project.Key, projectWorkspaceState), - cancellationToken) - .ConfigureAwait(false); - - var currentConfiguration = project.Configuration; - var currentRootNamespace = project.RootNamespace; - if (currentConfiguration.ConfigurationName == configuration?.ConfigurationName && - currentRootNamespace == rootNamespace) - { - _logger.LogTrace($"Updating project '{project.Key}'. The project is already using configuration '{configuration.ConfigurationName}' and root namespace '{rootNamespace}'."); - return; - } + var currentConfiguration = project.Configuration; + var currentRootNamespace = project.RootNamespace; + if (currentConfiguration.ConfigurationName == configuration?.ConfigurationName && + currentRootNamespace == rootNamespace) + { + _logger.LogTrace($"Updating project '{project.Key}'. The project is already using configuration '{configuration.ConfigurationName}' and root namespace '{rootNamespace}'."); + return; + } - if (configuration is null) - { - configuration = FallbackRazorConfiguration.Latest; - _logger.LogInformation($"Updating project '{project.Key}' to use the latest configuration ('{configuration.ConfigurationName}')'."); - } - else if (currentConfiguration.ConfigurationName != configuration.ConfigurationName) - { - _logger.LogInformation($"Updating project '{project.Key}' to Razor configuration '{configuration.ConfigurationName}' with language version '{configuration.LanguageVersion}'."); - } + if (configuration is null) + { + configuration = FallbackRazorConfiguration.Latest; + _logger.LogInformation($"Updating project '{project.Key}' to use the latest configuration ('{configuration.ConfigurationName}')'."); + } + else if (currentConfiguration.ConfigurationName != configuration.ConfigurationName) + { + _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}'."); - } + if (currentRootNamespace != rootNamespace) + { + _logger.LogInformation($"Updating project '{project.Key}''s root namespace to '{rootNamespace}'."); + } - var hostProject = new HostProject(project.FilePath, project.IntermediateOutputPath, configuration, rootNamespace, displayName); - await _projectManager - .UpdateAsync( - static (updater, hostProject) => updater.ProjectConfigurationChanged(hostProject), - state: hostProject, - cancellationToken) - .ConfigureAwait(false); + var hostProject = new HostProject(project.FilePath, project.IntermediateOutputPath, configuration, rootNamespace, displayName); + updater.ProjectConfigurationChanged(hostProject); + }, + cancellationToken); } - private async Task UpdateProjectDocumentsAsync(ImmutableArray documents, ProjectKey projectKey, CancellationToken cancellationToken) + private void UpdateProjectDocuments( + ProjectSnapshotManager.Updater updater, + ImmutableArray documents, + ProjectKey projectKey) { _logger.LogDebug($"UpdateProjectDocuments for {projectKey} with {documents.Length} documents: {string.Join(", ", documents.Select(d => d.FilePath))}"); @@ -384,7 +351,7 @@ private async Task UpdateProjectDocumentsAsync(ImmutableArray - { - updater.DocumentRemoved(state.currentProjectKey, state.currentHostDocument); - updater.DocumentAdded(state.currentProjectKey, state.newHostDocument, state.remoteTextLoader); - }, - state: (currentProjectKey, currentHostDocument, newHostDocument, remoteTextLoader), - cancellationToken) - .ConfigureAwait(false); + updater.DocumentRemoved(currentProjectKey, currentHostDocument); + updater.DocumentAdded(currentProjectKey, newHostDocument, remoteTextLoader); } project = _projectManager.GetLoadedProject(project.Key); @@ -445,7 +404,7 @@ await _projectManager if (miscellaneousProject.DocumentFilePaths.Contains(documentFilePath, FilePathComparer.Instance)) { - await MoveDocumentAsync(documentFilePath, miscellaneousProject, project, cancellationToken).ConfigureAwait(false); + MoveDocument(updater, documentFilePath, fromProject: miscellaneousProject, toProject: project); } else { @@ -455,24 +414,23 @@ await _projectManager _logger.LogInformation($"Adding new document '{documentFilePath}' to project '{currentProjectKey}'."); - await _projectManager - .UpdateAsync( - static (updater, state) => updater.DocumentAdded(state.currentProjectKey, state.newHostDocument, state.remoteTextLoader), - state: (currentProjectKey, newHostDocument, remoteTextLoader), - cancellationToken) - .ConfigureAwait(false); + updater.DocumentAdded(currentProjectKey, newHostDocument, remoteTextLoader); } } } - private Task MoveDocumentAsync(string documentFilePath, IProjectSnapshot fromProject, IProjectSnapshot toProject, CancellationToken cancellationToken) + private void MoveDocument( + ProjectSnapshotManager.Updater updater, + string documentFilePath, + IProjectSnapshot fromProject, + IProjectSnapshot toProject) { Debug.Assert(fromProject.DocumentFilePaths.Contains(documentFilePath, FilePathComparer.Instance)); Debug.Assert(!toProject.DocumentFilePaths.Contains(documentFilePath, FilePathComparer.Instance)); if (fromProject.GetDocument(documentFilePath) is not DocumentSnapshot documentSnapshot) { - return Task.CompletedTask; + return; } var currentHostDocument = documentSnapshot.State.HostDocument; @@ -482,14 +440,8 @@ private Task MoveDocumentAsync(string documentFilePath, IProjectSnapshot fromPro _logger.LogInformation($"Moving '{documentFilePath}' from the '{fromProject.Key}' project to '{toProject.Key}' project."); - return _projectManager.UpdateAsync( - static (updater, state) => - { - updater.DocumentRemoved(state.fromProject.Key, state.currentHostDocument); - updater.DocumentAdded(state.toProject.Key, state.newHostDocument, state.textLoader); - }, - state: (fromProject, currentHostDocument, toProject, newHostDocument, textLoader), - cancellationToken); + updater.DocumentRemoved(fromProject.Key, currentHostDocument); + updater.DocumentAdded(toProject.Key, newHostDocument, textLoader); } private static string EnsureFullPath(string filePath, string projectDirectory) @@ -504,7 +456,7 @@ private static string EnsureFullPath(string filePath, string projectDirectory) return normalizedFilePath; } - private async Task TryMigrateMiscellaneousDocumentsToProjectAsync(CancellationToken cancellationToken) + private void TryMigrateMiscellaneousDocumentsToProject(ProjectSnapshotManager.Updater updater) { var miscellaneousProject = _snapshotResolver.GetMiscellaneousProject(); @@ -524,12 +476,7 @@ private async Task TryMigrateMiscellaneousDocumentsToProjectAsync(CancellationTo // Remove from miscellaneous project var defaultMiscProject = miscellaneousProject; - await _projectManager - .UpdateAsync( - static (updater, state) => updater.DocumentRemoved(state.Key, state.HostDocument), - state: (defaultMiscProject.Key, documentSnapshot.State.HostDocument), - cancellationToken) - .ConfigureAwait(false); + updater.DocumentRemoved(defaultMiscProject.Key, documentSnapshot.State.HostDocument); // Add to new project @@ -538,12 +485,7 @@ await _projectManager var newHostDocument = new HostDocument(documentSnapshot.FilePath, documentSnapshot.TargetPath); _logger.LogInformation($"Migrating '{documentFilePath}' from the '{miscellaneousProject.Key}' project to '{projectSnapshot.Key}' project."); - await _projectManager - .UpdateAsync( - static (updater, state) => updater.DocumentAdded(state.key, state.newHostDocument, state.textLoader), - state: (key: defaultProject.Key, newHostDocument, textLoader), - cancellationToken) - .ConfigureAwait(false); + updater.DocumentAdded(defaultProject.Key, newHostDocument, textLoader); } } @@ -559,25 +501,7 @@ private void TrackDocumentVersion(IProjectSnapshot projectSnapshot, string textD if (startGenerating) { // Start generating the C# for the document so it can immediately be ready for incoming requests. - _ = documentSnapshot.GetGeneratedOutputAsync(); - } - } - - private class DelegatingTextLoader : TextLoader - { - private readonly IDocumentSnapshot _fromDocument; - public DelegatingTextLoader(IDocumentSnapshot fromDocument) - { - _fromDocument = fromDocument ?? throw new ArgumentNullException(nameof(fromDocument)); - } - public override async Task LoadTextAndVersionAsync( - LoadTextOptions options, - CancellationToken cancellationToken) - { - var sourceText = await _fromDocument.GetTextAsync().ConfigureAwait(false); - var version = await _fromDocument.GetTextVersionAsync().ConfigureAwait(false); - var textAndVersion = TextAndVersion.Create(sourceText, version.GetNewerVersion()); - return textAndVersion; + documentSnapshot.GetGeneratedOutputAsync().Forget(); } } } From 91b1f876dcc6c9946d3c2799bd7c225272a4aff6 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 26 Apr 2024 14:00:26 -0700 Subject: [PATCH 08/16] Convert ResolveDocumentInAnyProject to Try* method --- .../DocumentContextFactory.cs | 3 +-- .../ProjectSystem/ISnapshotResolver.cs | 3 ++- .../ProjectSystem/RazorProjectService.cs | 4 +--- .../ProjectSystem/SnapshotResolver.cs | 19 +++++++++---------- .../DocumentContextFactoryTest.cs | 16 ++++++++++++---- .../SnapshotResolverTest.cs | 8 +++----- .../TestSnapshotResolver.cs | 8 ++++++-- 7 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs index 4a0463201cc..d42d9947761 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs @@ -100,8 +100,7 @@ private bool TryResolveDocument( { if (projectContext is null) { - documentSnapshot = _snapshotResolver.ResolveDocumentInAnyProject(filePath); - return documentSnapshot is not null; + return _snapshotResolver.TryResolveDocumentInAnyProject(filePath, out documentSnapshot); } if (_projectManager.TryGetLoadedProject(projectContext.ToProjectKey(), out var project) && diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs index 4ba0d3e7a27..e29d45c4320 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Razor.ProjectSystem; @@ -23,5 +24,5 @@ internal interface ISnapshotResolver /// Finds a for the given document path that is contained within any project, and returns the first /// one found if it does. This method should be avoided where possible, and the overload that takes a should be used instead /// - IDocumentSnapshot? ResolveDocumentInAnyProject(string documentFilePath); + bool TryResolveDocumentInAnyProject(string documentFilePath, [NotNullWhen(true)] out IDocumentSnapshot? document); } 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 1b625fb8fe0..cb83af882a4 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -111,9 +111,7 @@ public Task OpenDocumentAsync(string filePath, SourceText sourceText, int versio // We are okay to use the non-project-key overload of TryResolveDocument here because we really are just checking if the document // has been added to _any_ project. AddDocument will take care of adding to all of the necessary ones, and then below we ensure // we process them all too - var document = _snapshotResolver.ResolveDocumentInAnyProject(textDocumentPath); - - if (document is null) + if (!_snapshotResolver.TryResolveDocumentInAnyProject(textDocumentPath, out var document)) { // Document hasn't been added. This usually occurs when VSCode trumps all other initialization // processes and pre-initializes already open documents. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs index e1f3292dd97..c6c98254db6 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Threading; @@ -78,24 +79,20 @@ public IProjectSnapshot GetMiscellaneousProject() return _projectManager.GetLoadedProject(MiscellaneousHostProject.Key); } - public IDocumentSnapshot? ResolveDocumentInAnyProject(string documentFilePath) + public bool TryResolveDocumentInAnyProject(string documentFilePath, [NotNullWhen(true)] out IDocumentSnapshot? document) { _logger.LogTrace($"Looking for {documentFilePath}."); - if (documentFilePath is null) - { - throw new ArgumentNullException(nameof(documentFilePath)); - } - var normalizedDocumentPath = FilePathNormalizer.Normalize(documentFilePath); var potentialProjects = FindPotentialProjects(documentFilePath); foreach (var project in potentialProjects) { - if (project.GetDocument(normalizedDocumentPath) is { } document) + if (project.GetDocument(normalizedDocumentPath) is { } projectDocument) { _logger.LogTrace($"Found {documentFilePath} in {project.FilePath}"); - return document; + document = projectDocument; + return true; } } @@ -105,11 +102,13 @@ public IProjectSnapshot GetMiscellaneousProject() if (miscellaneousProject.GetDocument(normalizedDocumentPath) is { } miscDocument) { _logger.LogTrace($"Found {documentFilePath} in miscellaneous project."); - return miscDocument; + document = miscDocument; + return true; } _logger.LogTrace($"{documentFilePath} not found in {string.Join(", ", _projectManager.GetProjects().SelectMany(p => p.DocumentFilePaths))}"); - return null; + document = null; + return false; } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs index 332cf86a97a..9fdb394e6ad 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -217,9 +218,16 @@ public ImmutableArray FindPotentialProjects(string documentFil public IProjectSnapshot GetMiscellaneousProject() => throw new NotImplementedException(); - public IDocumentSnapshot? ResolveDocumentInAnyProject(string documentFilePath) - => documentFilePath == _documentSnapshot?.FilePath - ? _documentSnapshot - : null; + public bool TryResolveDocumentInAnyProject(string documentFilePath, [NotNullWhen(true)] out IDocumentSnapshot? document) + { + if (documentFilePath == _documentSnapshot?.FilePath) + { + document = _documentSnapshot; + return true; + } + + document = null; + return false; + } } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs index 8e31b99b373..55edd63a57b 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs @@ -24,10 +24,9 @@ public async Task TryResolveDocumentInAnyProject_AsksPotentialParentProjectForDo var snapshotResolver = await CreateSnapshotResolverAsync(normalizedFilePath); // Act - var document = snapshotResolver.ResolveDocumentInAnyProject(documentFilePath); + Assert.True(snapshotResolver.TryResolveDocumentInAnyProject(documentFilePath, out var document)); // Assert - Assert.NotNull(document); Assert.Equal(normalizedFilePath, document.FilePath); } @@ -52,10 +51,9 @@ await projectManager.UpdateAsync(updater => }); // Act - var document = snapshotResolver.ResolveDocumentInAnyProject(documentFilePath); + Assert.True(snapshotResolver.TryResolveDocumentInAnyProject(documentFilePath, out var document)); // Assert - Assert.NotNull(document); Assert.Equal(normalizedFilePath, document.FilePath); } @@ -69,7 +67,7 @@ public async Task TryResolveDocumentInAnyProject_AsksPotentialParentProjectForDo await snapshotResolver.InitializeAsync(DisposalToken); // Act - var document = snapshotResolver.ResolveDocumentInAnyProject(documentFilePath); + Assert.False(snapshotResolver.TryResolveDocumentInAnyProject(documentFilePath, out var document)); // Assert Assert.Null(document); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs index 866ca72e5a7..2febc09dacb 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; @@ -38,6 +39,9 @@ public ImmutableArray FindPotentialProjects(string documentFil public IProjectSnapshot GetMiscellaneousProject() => _miscProject; - public IDocumentSnapshot? ResolveDocumentInAnyProject(string documentFilePath) - => null; + public bool TryResolveDocumentInAnyProject(string documentFilePath, [NotNullWhen(true)] out IDocumentSnapshot? document) + { + document = null; + return false; + } } From 27f8be95e115869bbda47567116613d5455f9f0b Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 26 Apr 2024 14:11:01 -0700 Subject: [PATCH 09/16] Remove unneeded ArgumentNullException --- .../ProjectSystem/SnapshotResolver.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs index c6c98254db6..e0bfe8bebea 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs @@ -47,11 +47,6 @@ public Task InitializeAsync(CancellationToken cancellationToken) /// public ImmutableArray FindPotentialProjects(string documentFilePath) { - if (documentFilePath is null) - { - throw new ArgumentNullException(nameof(documentFilePath)); - } - var normalizedDocumentPath = FilePathNormalizer.Normalize(documentFilePath); using var projects = new PooledArrayBuilder(); From 1d7c262550a8fbcd0f0fc5d443022e9b003e491b Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 29 Apr 2024 09:20:15 -0700 Subject: [PATCH 10/16] Make IOnInitialized a bit more general purpose --- .../LanguageServer/RazorLanguageServerBenchmarkBase.cs | 2 +- .../ClientConnection.cs | 3 ++- .../IOnInitialized.cs | 3 ++- .../RazorConfigurationEndpoint.cs | 7 ++++++- .../RazorInitializedEndpoint.cs | 3 +-- 5 files changed, 12 insertions(+), 6 deletions(-) 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 e91930e3f92..50d6d8246f3 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs @@ -87,7 +87,7 @@ await projectManager.UpdateAsync( private class NoopClientNotifierService : IClientConnection, IOnInitialized { - public Task OnInitializedAsync(VSInternalClientCapabilities clientCapabilities, CancellationToken cancellationToken) + public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { return Task.CompletedTask; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs index 56f18aad58b..0a3c90a7b8f 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.Hosting; +using Microsoft.CommonLanguageServerProtocol.Framework; using Microsoft.VisualStudio.LanguageServer.Protocol; using StreamJsonRpc; @@ -47,7 +48,7 @@ public async Task SendNotificationAsync(string method, CancellationToken cancell /// /// Fires when the language server is set to "Started". /// - public Task OnInitializedAsync(VSInternalClientCapabilities clientCapabilities, CancellationToken cancellationToken) + public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { _initializedCompletionSource.TrySetResult(true); return Task.CompletedTask; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs index 2dee615eea3..0dfd09f719d 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs @@ -3,11 +3,12 @@ using System.Threading; using System.Threading.Tasks; +using Microsoft.CommonLanguageServerProtocol.Framework; using Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.AspNetCore.Razor.LanguageServer; internal interface IOnInitialized { - Task OnInitializedAsync(VSInternalClientCapabilities clientCapabilities, CancellationToken cancellationToken); + Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs index b0f8a5b46ff..57e8793dd49 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs @@ -6,6 +6,8 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts; using Microsoft.CodeAnalysis.Razor.Logging; +using Microsoft.CodeAnalysis.Razor.Protocol; +using Microsoft.CommonLanguageServerProtocol.Framework; using Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.AspNetCore.Razor.LanguageServer; @@ -25,8 +27,11 @@ public async Task HandleNotificationAsync(DidChangeConfigurationParams request, await _optionsMonitor.UpdateAsync(cancellationToken).ConfigureAwait(false); } - public async Task OnInitializedAsync(VSInternalClientCapabilities clientCapabilities, CancellationToken cancellationToken) + public async Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { + var capabilitiesService = services.GetRequiredService(); + var clientCapabilities = capabilitiesService.ClientCapabilities; + if (clientCapabilities.Workspace?.Configuration == true) { await _optionsMonitor.UpdateAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs index 8dae020e548..ab80a332ef0 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs @@ -19,7 +19,6 @@ internal class RazorInitializedEndpoint : INotificationHandler(); - var capabilitiesService = requestContext.GetRequiredService(); var snapshotResolver = requestContext.LspServices.GetRequiredService(); await snapshotResolver.InitializeAsync(cancellationToken).ConfigureAwait(false); @@ -29,7 +28,7 @@ public async Task HandleNotificationAsync(InitializedParams request, RazorReques foreach (var onStartedItem in onStartedItems) { - await onStartedItem.OnInitializedAsync(capabilitiesService.ClientCapabilities, cancellationToken).ConfigureAwait(false); + await onStartedItem.OnInitializedAsync(requestContext.LspServices, cancellationToken).ConfigureAwait(false); } } } From e3594cdd70a1f92f71d2ffa9164f1327e1b9f302 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 29 Apr 2024 10:07:52 -0700 Subject: [PATCH 11/16] Make SnapshotResolver implement IOnInitialized --- .../IServiceCollectionExtensions.cs | 5 +- .../ProjectSystem/ISnapshotResolver.cs | 2 - .../ProjectSystem/SnapshotResolver.cs | 5 +- .../RazorInitializedEndpoint.cs | 3 - .../DefaultLSPTagHelperTooltipFactoryTest.cs | 13 +--- ...DefaultVSLSPTagHelperTooltipFactoryTest.cs | 21 ++----- ...egacyRazorCompletionResolveEndpointTest.cs | 24 +++---- .../RazorCompletionItemResolverTest.cs | 28 ++++----- .../TagHelperTooltipFactoryBaseTest.cs | 5 -- .../DefaultRazorComponentSearchEngineTest.cs | 3 +- .../DocumentContextFactoryTest.cs | 20 ++---- ...extDocumentUriPresentationEndpointTests.cs | 10 +-- .../Hover/HoverServiceTest.cs | 63 +++++++++---------- .../RazorProjectServiceTest.cs | 3 +- .../Refactoring/RenameEndpointTest.cs | 3 +- .../SnapshotResolverTest.cs | 26 ++++---- .../TestSnapshotResolver.cs | 5 -- 17 files changed, 100 insertions(+), 139 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs index d8deed9d358..c406305de47 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs @@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Extensions; internal static class IServiceCollectionExtensions { - public static void AddLifeCycleServices(this IServiceCollection services, RazorLanguageServer razorLanguageServer, ClientConnection serverManager, ILspServerActivationTracker? lspServerActivationTracker) + public static void AddLifeCycleServices(this IServiceCollection services, RazorLanguageServer razorLanguageServer, ClientConnection clientConnection, ILspServerActivationTracker? lspServerActivationTracker) { services.AddHandler(); services.AddHandler(); @@ -51,7 +51,7 @@ public static void AddLifeCycleServices(this IServiceCollection services, RazorL services.AddSingleton(); - services.AddSingleton(serverManager); + services.AddSingleton(clientConnection); } public static void AddFormattingServices(this IServiceCollection services) @@ -207,6 +207,7 @@ public static void AddDocumentManagementServices(this IServiceCollection service services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(sp => (SnapshotResolver)sp.GetRequiredService()); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs index e29d45c4320..6d60ea43698 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolver.cs @@ -11,8 +11,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; internal interface ISnapshotResolver { - Task InitializeAsync(CancellationToken cancellationToken); - /// /// Finds all the projects where the document path starts with the path of the folder that contains the project file. /// diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs index e0bfe8bebea..d5a86495af5 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs @@ -13,10 +13,11 @@ using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.ProjectSystem; +using Microsoft.CommonLanguageServerProtocol.Framework; namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; -internal sealed class SnapshotResolver : ISnapshotResolver +internal sealed class SnapshotResolver : ISnapshotResolver, IOnInitialized { private readonly IProjectSnapshotManager _projectManager; private readonly ILogger _logger; @@ -34,7 +35,7 @@ public SnapshotResolver(IProjectSnapshotManager projectManager, ILoggerFactory l MiscellaneousHostProject = new HostProject(normalizedPath, normalizedPath, FallbackRazorConfiguration.Latest, rootNamespace: null, "Miscellaneous Files"); } - public Task InitializeAsync(CancellationToken cancellationToken) + public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { // This is called when the language server is initialized. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs index ab80a332ef0..c2ade7352dc 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs @@ -20,9 +20,6 @@ public async Task HandleNotificationAsync(InitializedParams request, RazorReques { var onStartedItems = requestContext.LspServices.GetRequiredServices(); - var snapshotResolver = requestContext.LspServices.GetRequiredService(); - await snapshotResolver.InitializeAsync(cancellationToken).ConfigureAwait(false); - var fileChangeDetectorManager = requestContext.LspServices.GetRequiredService(); await fileChangeDetectorManager.InitializedAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultLSPTagHelperTooltipFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultLSPTagHelperTooltipFactoryTest.cs index d3e9d38e904..44a5019366a 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultLSPTagHelperTooltipFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultLSPTagHelperTooltipFactoryTest.cs @@ -67,7 +67,6 @@ public async Task TryCreateTooltip_Markup_NoAssociatedTagHelperDescriptions_Retu { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundElementDescription.Empty; @@ -83,7 +82,6 @@ public async Task TryCreateTooltip_Markup_Element_SingleAssociatedTagHelper_Retu { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -106,7 +104,6 @@ public async Task TryCreateTooltip_Markup_Element_PlainText_NoBold() { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -126,11 +123,10 @@ public async Task TryCreateTooltip_Markup_Element_PlainText_NoBold() } [Fact] - public async Task TryCreateTooltip_Markup_Attribute_PlainText_NoBold() + public void TryCreateTooltip_Markup_Attribute_PlainText_NoBold() { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { @@ -158,7 +154,6 @@ public async Task TryCreateTooltip_Markup_Element_MultipleAssociatedTagHelpers_R { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -183,11 +178,10 @@ public async Task TryCreateTooltip_Markup_Element_MultipleAssociatedTagHelpers_R } [Fact] - public async Task TryCreateTooltip_Markup_Attribute_SingleAssociatedAttribute_ReturnsTrue() + public void TryCreateTooltip_Markup_Attribute_SingleAssociatedAttribute_ReturnsTrue() { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { @@ -211,11 +205,10 @@ public async Task TryCreateTooltip_Markup_Attribute_SingleAssociatedAttribute_Re } [Fact] - public async Task TryCreateTooltip_Markup_Attribute_MultipleAssociatedAttributes_ReturnsTrue() + public void TryCreateTooltip_Markup_Attribute_MultipleAssociatedAttributes_ReturnsTrue() { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultVSLSPTagHelperTooltipFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultVSLSPTagHelperTooltipFactoryTest.cs index 7375f0287e4..4cc132fddcc 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultVSLSPTagHelperTooltipFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/DefaultVSLSPTagHelperTooltipFactoryTest.cs @@ -171,7 +171,6 @@ public async Task TryCreateTooltip_ClassifiedTextElement_NoAssociatedTagHelperDe { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundElementDescription.Empty; @@ -187,7 +186,6 @@ public async Task TryCreateTooltip_ClassifiedTextElement_Element_SingleAssociate { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -229,7 +227,6 @@ public async Task TryCreateTooltip_ClassifiedTextElement_Element_NamespaceContai { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -270,7 +267,6 @@ public async Task TryCreateTooltip_ClassifiedTextElement_Element_MultipleAssocia { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -321,11 +317,10 @@ public async Task TryCreateTooltip_ClassifiedTextElement_Element_MultipleAssocia } [Fact] - public async Task TryCreateTooltip_ClassifiedTextElement_NoAssociatedAttributeDescriptions_ReturnsFalse() + public void TryCreateTooltip_ClassifiedTextElement_NoAssociatedAttributeDescriptions_ReturnsFalse() { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundAttributeDescription.Empty; @@ -338,11 +333,10 @@ public async Task TryCreateTooltip_ClassifiedTextElement_NoAssociatedAttributeDe } [Fact] - public async Task TryCreateTooltip_ClassifiedTextElement_Attribute_SingleAssociatedAttribute_ReturnsTrue_NestedTypes() + public void TryCreateTooltip_ClassifiedTextElement_Attribute_SingleAssociatedAttribute_ReturnsTrue_NestedTypes() { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { @@ -388,11 +382,10 @@ public async Task TryCreateTooltip_ClassifiedTextElement_Attribute_SingleAssocia } [Fact] - public async Task TryCreateTooltip_ClassifiedTextElement_Attribute_MultipleAssociatedAttributes_ReturnsTrue() + public void TryCreateTooltip_ClassifiedTextElement_Attribute_MultipleAssociatedAttributes_ReturnsTrue() { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { @@ -468,7 +461,6 @@ public async Task TryCreateTooltip_ContainerElement_NoAssociatedTagHelperDescrip { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundElementDescription.Empty; @@ -484,7 +476,6 @@ public async Task TryCreateTooltip_ContainerElement_Attribute_MultipleAssociated { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedTagHelperInfos = new[] { @@ -565,11 +556,10 @@ public async Task TryCreateTooltip_ContainerElement_Attribute_MultipleAssociated } [Fact] - public async Task TryCreateTooltip_ContainerElement_NoAssociatedAttributeDescriptions_ReturnsFalse() + public void TryCreateTooltip_ContainerElement_NoAssociatedAttributeDescriptions_ReturnsFalse() { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var elementDescription = AggregateBoundAttributeDescription.Empty; @@ -582,11 +572,10 @@ public async Task TryCreateTooltip_ContainerElement_NoAssociatedAttributeDescrip } [Fact] - public async Task TryCreateTooltip_ContainerElement_Attribute_MultipleAssociatedAttributes_ReturnsTrue() + public void TryCreateTooltip_ContainerElement_Attribute_MultipleAssociatedAttributes_ReturnsTrue() { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); var associatedAttributeDescriptions = new[] { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/LegacyRazorCompletionResolveEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/LegacyRazorCompletionResolveEndpointTest.cs index 85d0266c529..e6c15dd2da7 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/LegacyRazorCompletionResolveEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/LegacyRazorCompletionResolveEndpointTest.cs @@ -20,18 +20,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion; -public class LegacyRazorCompletionResolveEndpointTest(ITestOutputHelper testOutput) : LanguageServerTestBase(testOutput) +public class LegacyRazorCompletionResolveEndpointTest : LanguageServerTestBase { - private LSPTagHelperTooltipFactory _lspTagHelperTooltipFactory; - private VSLSPTagHelperTooltipFactory _vsLspTagHelperTooltipFactory; - private CompletionListCache _completionListCache; - private VSInternalCompletionSetting _completionCapability; - private VSInternalClientCapabilities _defaultClientCapability; - - protected async override Task InitializeAsync() + private readonly LSPTagHelperTooltipFactory _lspTagHelperTooltipFactory; + private readonly VSLSPTagHelperTooltipFactory _vsLspTagHelperTooltipFactory; + private readonly CompletionListCache _completionListCache; + private readonly VSInternalCompletionSetting _completionCapability; + private readonly VSInternalClientCapabilities _defaultClientCapability; + + public LegacyRazorCompletionResolveEndpointTest(ITestOutputHelper testOutput) + : base(testOutput) { var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); _lspTagHelperTooltipFactory = new Mock(MockBehavior.Strict, snapshotResolver).Object; _vsLspTagHelperTooltipFactory = new Mock(MockBehavior.Strict, snapshotResolver).Object; _completionListCache = new CompletionListCache(); @@ -39,7 +39,7 @@ protected async override Task InitializeAsync() { CompletionItem = new CompletionItemSetting() { - DocumentationFormat = new[] { MarkupKind.PlainText, MarkupKind.Markdown }, + DocumentationFormat = [MarkupKind.PlainText, MarkupKind.Markdown], } }; @@ -97,7 +97,6 @@ public async Task Handle_Resolve_DirectiveAttributeCompletion_ReturnsCompletionI { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var lspDescriptionFactory = new Mock(MockBehavior.Strict, snapshotResolver); var markdown = new MarkupContent { @@ -127,7 +126,6 @@ public async Task Handle_Resolve_DirectiveAttributeParameterCompletion_ReturnsCo { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var descriptionFactory = new Mock(MockBehavior.Strict, snapshotResolver); var markdown = new MarkupContent { @@ -157,7 +155,6 @@ public async Task Handle_Resolve_TagHelperElementCompletion_ReturnsCompletionIte { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var lspDescriptionFactory = new Mock(MockBehavior.Strict, snapshotResolver); var markdown = new MarkupContent { @@ -187,7 +184,6 @@ public async Task Handle_Resolve_TagHelperAttribute_ReturnsCompletionItemWithDoc { // Arrange var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var lspDescriptionFactory = new Mock(MockBehavior.Strict, snapshotResolver); var markdown = new MarkupContent { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionItemResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionItemResolverTest.cs index 8b27149e518..52095bcc787 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionItemResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionItemResolverTest.cs @@ -17,20 +17,20 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion; -public class RazorCompletionItemResolverTest(ITestOutputHelper testOutput) : LanguageServerTestBase(testOutput) +public class RazorCompletionItemResolverTest : LanguageServerTestBase { - private LSPTagHelperTooltipFactory _lspTagHelperTooltipFactory; - private VSLSPTagHelperTooltipFactory _vsLspTagHelperTooltipFactory; - private VSInternalCompletionSetting _completionCapability; - private VSInternalClientCapabilities _defaultClientCapability; - private VSInternalClientCapabilities _vsClientCapability; - private AggregateBoundAttributeDescription _attributeDescription; - private AggregateBoundElementDescription _elementDescription; - - protected async override Task InitializeAsync() + private readonly LSPTagHelperTooltipFactory _lspTagHelperTooltipFactory; + private readonly VSLSPTagHelperTooltipFactory _vsLspTagHelperTooltipFactory; + private readonly VSInternalCompletionSetting _completionCapability; + private readonly VSInternalClientCapabilities _defaultClientCapability; + private readonly VSInternalClientCapabilities _vsClientCapability; + private readonly AggregateBoundAttributeDescription _attributeDescription; + private readonly AggregateBoundElementDescription _elementDescription; + + public RazorCompletionItemResolverTest(ITestOutputHelper testOutput) + : base(testOutput) { var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); _lspTagHelperTooltipFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); _vsLspTagHelperTooltipFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); @@ -38,7 +38,7 @@ protected async override Task InitializeAsync() { CompletionItem = new CompletionItemSetting() { - DocumentationFormat = new[] { MarkupKind.PlainText, MarkupKind.Markdown }, + DocumentationFormat = [MarkupKind.PlainText, MarkupKind.Markdown], } }; @@ -60,9 +60,9 @@ protected async override Task InitializeAsync() }; var attributeDescriptionInfo = new BoundAttributeDescriptionInfo("System.DateTime", "System.DateTime", "DateTime", "Returns the time."); - _attributeDescription = new AggregateBoundAttributeDescription(ImmutableArray.Create(attributeDescriptionInfo)); + _attributeDescription = new AggregateBoundAttributeDescription([attributeDescriptionInfo]); var elementDescriptionInfo = new BoundElementDescriptionInfo("System.SomeTagHelper", "This is some TagHelper."); - _elementDescription = new AggregateBoundElementDescription(ImmutableArray.Create(elementDescriptionInfo)); + _elementDescription = new AggregateBoundElementDescription([elementDescriptionInfo]); } [Fact] diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/TagHelperTooltipFactoryBaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/TagHelperTooltipFactoryBaseTest.cs index d6ca8799bb7..eaa0b62a696 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/TagHelperTooltipFactoryBaseTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/TagHelperTooltipFactoryBaseTest.cs @@ -346,7 +346,6 @@ public void TryExtractSummary_NoXml_ReturnsTrue() public async Task GetAvailableProjects_NoProjects_ReturnsNull() { var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync("file.razor", "MyTagHelper", CancellationToken.None); @@ -371,7 +370,6 @@ public async Task GetAvailableProjects_OneProject_ReturnsNull() var project = TestProjectSnapshot.Create(projectFilePath, documentFilePaths: [razorFilePath], projectWorkspaceState); var snapshotResolver = new TestSnapshotResolver(razorFilePath, project); - await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync(razorFilePath, tagHelperTypeName, CancellationToken.None); @@ -409,7 +407,6 @@ public async Task GetAvailableProjects_AvailableInAllProjects_ReturnsNull() projectWorkspaceState); var snapshotResolver = new TestSnapshotResolver(razorFilePath, project1, project2); - await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync(razorFilePath, tagHelperTypeName, CancellationToken.None); @@ -449,7 +446,6 @@ public async Task GetAvailableProjects_NotAvailableInAllProjects_ReturnsText() displayName: "project2"); var snapshotResolver = new TestSnapshotResolver(razorFilePath, project1, project2); - await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync(razorFilePath, tagHelperTypeName, CancellationToken.None); @@ -486,7 +482,6 @@ public async Task GetAvailableProjects_NotAvailableInAnyProject_ReturnsText() displayName: "project2"); var snapshotResolver = new TestSnapshotResolver(razorFilePath, project1, project2); - await snapshotResolver.InitializeAsync(DisposalToken); var service = new TestTagHelperToolTipFactory(snapshotResolver); var availability = await service.GetProjectAvailabilityAsync(razorFilePath, "MyTagHelper", CancellationToken.None); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs index 901b582c4cf..5f2491651f9 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Razor.Test.Common.ProjectSystem; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; +using Microsoft.CommonLanguageServerProtocol.Framework; using Moq; using Xunit; using Xunit.Abstractions; @@ -47,7 +48,7 @@ protected override async Task InitializeAsync() _projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(_projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var documentVersionCache = new DocumentVersionCache(_projectManager); var remoteTextLoaderFactoryMock = new StrictMock(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs index 9fdb394e6ad..c6c07d573fa 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs @@ -5,7 +5,6 @@ using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; @@ -35,14 +34,13 @@ public DocumentContextFactoryTest(ITestOutputHelper testOutput) } [Fact] - public async Task TryCreateAsync_CanNotResolveDocument_ReturnsNull() + public void TryCreateAsync_CanNotResolveDocument_ReturnsNull() { // Arrange var filePath = FilePathNormalizer.Normalize(Path.Combine(s_baseDirectory, "file.cshtml")); var uri = new Uri(filePath); var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); @@ -54,14 +52,13 @@ public async Task TryCreateAsync_CanNotResolveDocument_ReturnsNull() } [Fact] - public async Task TryCreateForOpenDocumentAsync_CanNotResolveDocument_ReturnsNull() + public void TryCreateForOpenDocumentAsync_CanNotResolveDocument_ReturnsNull() { // Arrange var filePath = FilePathNormalizer.Normalize(Path.Combine(s_baseDirectory, "file.cshtml")); var uri = new Uri(filePath); var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); @@ -73,7 +70,7 @@ public async Task TryCreateForOpenDocumentAsync_CanNotResolveDocument_ReturnsNul } [Fact] - public async Task TryCreateForOpenDocumentAsync_CanNotResolveVersion_ReturnsNull() + public void TryCreateForOpenDocumentAsync_CanNotResolveVersion_ReturnsNull() { // Arrange var filePath = FilePathNormalizer.Normalize(Path.Combine(s_baseDirectory, "file.cshtml")); @@ -81,7 +78,6 @@ public async Task TryCreateForOpenDocumentAsync_CanNotResolveVersion_ReturnsNull var documentSnapshot = TestDocumentSnapshot.Create(filePath); var snapshotResolver = new TestSnapshotResolver(documentSnapshot); - await snapshotResolver.InitializeAsync(DisposalToken); var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act @@ -92,7 +88,7 @@ public async Task TryCreateForOpenDocumentAsync_CanNotResolveVersion_ReturnsNull } [Fact] - public async Task TryCreateAsync_ResolvesContent() + public void TryCreateAsync_ResolvesContent() { // Arrange var filePath = FilePathNormalizer.Normalize(Path.Combine(s_baseDirectory, "file.cshtml")); @@ -102,7 +98,6 @@ public async Task TryCreateAsync_ResolvesContent() var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(string.Empty, documentSnapshot.FilePath)); documentSnapshot.With(codeDocument); var snapshotResolver = new TestSnapshotResolver(documentSnapshot); - await snapshotResolver.InitializeAsync(DisposalToken); var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act @@ -127,7 +122,6 @@ public async Task TryCreateAsync_WithProjectContext_Resolves() var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(string.Empty, documentSnapshot.FilePath)); documentSnapshot.With(codeDocument); var snapshotResolver = new TestSnapshotResolver(documentSnapshot); - await snapshotResolver.InitializeAsync(DisposalToken); var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); var hostProject = new HostProject(projectFilePath, intermediateOutputPath, RazorConfiguration.Default, rootNamespace: null); @@ -181,7 +175,7 @@ await _projectManager.UpdateAsync(updater => } [Fact] - public async Task TryCreateForOpenDocumentAsync_ResolvesContent() + public void TryCreateForOpenDocumentAsync_ResolvesContent() { // Arrange var filePath = FilePathNormalizer.Normalize(Path.Combine(s_baseDirectory, "file.cshtml")); @@ -191,7 +185,6 @@ public async Task TryCreateForOpenDocumentAsync_ResolvesContent() var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(string.Empty, documentSnapshot.FilePath)); documentSnapshot.With(codeDocument); var snapshotResolver = new TestSnapshotResolver(documentSnapshot); - await snapshotResolver.InitializeAsync(DisposalToken); _documentVersionCache.TrackDocumentVersion(documentSnapshot, version: 1337); var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); @@ -209,9 +202,6 @@ private sealed class TestSnapshotResolver(IDocumentSnapshot? documentSnapshot = { private readonly IDocumentSnapshot? _documentSnapshot = documentSnapshot; - public Task InitializeAsync(CancellationToken cancellationToken) - => Task.CompletedTask; - public ImmutableArray FindPotentialProjects(string documentFilePath) => throw new NotImplementedException(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs index 219ead40280..12a7678ed24 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Razor.LanguageServer.Hosting; using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; using Microsoft.AspNetCore.Razor.ProjectSystem; +using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer; using Microsoft.AspNetCore.Razor.Test.Common.ProjectSystem; using Microsoft.CodeAnalysis.Razor.DocumentMapping; @@ -15,6 +16,7 @@ using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Protocol.DocumentPresentation; using Microsoft.CodeAnalysis.Text; +using Microsoft.CommonLanguageServerProtocol.Framework; using Microsoft.VisualStudio.LanguageServer.Protocol; using Moq; using Xunit; @@ -32,7 +34,7 @@ public async Task Handle_SimpleComponent_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); @@ -97,7 +99,7 @@ public async Task Handle_SimpleComponentWithChildFile_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); @@ -167,7 +169,7 @@ public async Task Handle_ComponentWithRequiredAttribute_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); @@ -399,7 +401,7 @@ public async Task Handle_ComponentWithNestedFiles_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Hover/HoverServiceTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Hover/HoverServiceTest.cs index f71a7eebaea..80a01f5734e 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Hover/HoverServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Hover/HoverServiceTest.cs @@ -48,7 +48,7 @@ private static VSInternalClientCapabilities CreateCapabilities(MarkupKind markup { Hover = new() { - ContentFormat = new[] { markupKind }, + ContentFormat = [markupKind], } } }; @@ -64,7 +64,7 @@ public async Task GetHoverInfo_TagHelper_Element() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -94,7 +94,7 @@ public async Task GetHoverInfo_TagHelper_Element_WithParent() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -124,7 +124,7 @@ public async Task GetHoverInfo_TagHelper_Attribute_WithParent() TestFileMarkupParser.GetPositionAndSpan(txt, out txt, out var cursorPosition, out var span); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -148,7 +148,7 @@ public async Task GetHoverInfo_TagHelper_Element_EndTag() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -176,7 +176,7 @@ public async Task GetHoverInfo_TagHelper_Attribute() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -205,7 +205,7 @@ public async Task GetHoverInfo_TagHelper_AttributeTrailingEdge() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var edgeLocation = cursorPosition; var location = new SourceLocation(edgeLocation, 0, edgeLocation); @@ -235,7 +235,7 @@ public async Task GetHoverInfo_TagHelper_AttributeValue_ReturnsNull() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -257,7 +257,7 @@ public async Task GetHoverInfo_TagHelper_AfterAttributeEquals_ReturnsNull() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -279,7 +279,7 @@ public async Task GetHoverInfo_TagHelper_AttributeEnd_ReturnsNull() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -301,7 +301,7 @@ public async Task GetHoverInfo_TagHelper_MinimizedAttribute() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -334,7 +334,7 @@ public void Increment(){ TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, "text.razor", DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -363,7 +363,7 @@ public async Task GetHoverInfo_TagHelper_MalformedElement() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -391,7 +391,7 @@ public async Task GetHoverInfo_TagHelper_MalformedAttribute() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -420,7 +420,7 @@ public async Task GetHoverInfo_HTML_MarkupElement() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -443,7 +443,7 @@ public async Task GetHoverInfo_TagHelper_PlainTextElement() var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -473,7 +473,7 @@ public async Task GetHoverInfo_TagHelper_PlainTextElement_EndTag() var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -502,7 +502,7 @@ public async Task GetHoverInfo_TagHelper_TextComponent() var codeDocument = CreateCodeDocument(txt, isRazorFile: true, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -533,7 +533,7 @@ public async Task GetHoverInfo_TagHelper_TextComponent_NestedInHtml() var codeDocument = CreateCodeDocument(txt, isRazorFile: true, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -565,7 +565,7 @@ public async Task GetHoverInfo_TagHelper_TextComponent_NestedInCSharp() var codeDocument = CreateCodeDocument(txt, isRazorFile: true, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -592,7 +592,7 @@ public async Task GetHoverInfo_TagHelper_TextComponent_NestedInCSharpAndText() var codeDocument = CreateCodeDocument(txt, isRazorFile: true, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -622,7 +622,7 @@ public async Task GetHoverInfo_TagHelper_PlainTextAttribute() var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -653,7 +653,7 @@ public async Task GetHoverInfo_HTML_PlainTextElement() var codeDocument = CreateCodeDocument(txt, isRazorFile: false); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -676,7 +676,7 @@ public async Task GetHoverInfo_HTML_PlainTextAttribute() var codeDocument = CreateCodeDocument(txt, isRazorFile: false); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); @@ -699,7 +699,7 @@ public async Task GetHoverInfo_TagHelper_Element_VSClient_ReturnVSHover() TestFileMarkupParser.GetPosition(txt, out txt, out var cursorPosition); var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); var clientCapabilities = CreateMarkDownCapabilities(); @@ -744,7 +744,7 @@ public async Task GetHoverInfo_TagHelper_Attribute_VSClient_ReturnVSHover() var codeDocument = CreateCodeDocument(txt, isRazorFile: false, DefaultTagHelpers); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var serviceAccessor = service.GetTestAccessor(); var location = new SourceLocation(cursorPosition, -1, -1); var clientCapabilities = CreateMarkDownCapabilities(); @@ -810,7 +810,7 @@ public async Task Handle_Hover_SingleServer_CallsDelegatedLanguageServer() c => c.TryMapToGeneratedDocumentPosition(It.IsAny(), It.IsAny(), out projectedPosition, out projectedIndex)) .Returns(true); - var endpoint = await CreateEndpointAsync(languageServerFeatureOptions, documentMappingServiceMock.Object, clientConnectionMock.Object); + var endpoint = CreateEndpoint(languageServerFeatureOptions, documentMappingServiceMock.Object, clientConnectionMock.Object); var request = new TextDocumentPositionParams { @@ -959,7 +959,7 @@ private async Task GetResultFromSingleServerEndpointAsync(strin var languageServer = new HoverLanguageServer(csharpServer, csharpDocumentUri, DisposalToken); var documentMappingService = new RazorDocumentMappingService(FilePathService, documentContextFactory, LoggerFactory); - var service = await GetHoverServiceAsync(documentMappingService); + var service = GetHoverService(documentMappingService); var endpoint = new HoverEndpoint( service, @@ -1012,7 +1012,7 @@ public void Increment(){ return documentContext; } - private async Task CreateEndpointAsync( + private HoverEndpoint CreateEndpoint( LanguageServerFeatureOptions languageServerFeatureOptions = null, IRazorDocumentMappingService documentMappingService = null, IClientConnection clientConnection = null) @@ -1027,7 +1027,7 @@ private async Task CreateEndpointAsync( clientConnection ??= Mock.Of(MockBehavior.Strict); - var service = await GetHoverServiceAsync(); + var service = GetHoverService(); var endpoint = new HoverEndpoint( service, @@ -1039,10 +1039,9 @@ private async Task CreateEndpointAsync( return endpoint; } - private async Task GetHoverServiceAsync(IRazorDocumentMappingService mappingService = null) + private HoverService GetHoverService(IRazorDocumentMappingService mappingService = null) { var snapshotResolver = new TestSnapshotResolver(); - await snapshotResolver.InitializeAsync(DisposalToken); var lspTagHelperTooltipFactory = new DefaultLSPTagHelperTooltipFactory(snapshotResolver); var vsLspTagHelperTooltipFactory = new DefaultVSLSPTagHelperTooltipFactory(snapshotResolver); 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 b54c9e417d9..1216ebf0b2e 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; +using Microsoft.CommonLanguageServerProtocol.Framework; using Moq; using Xunit; using Xunit.Abstractions; @@ -40,7 +41,7 @@ protected override async Task InitializeAsync() { _projectManager = CreateProjectSnapshotManager(); _snapshotResolver = new SnapshotResolver(_projectManager, LoggerFactory); - await _snapshotResolver.InitializeAsync(DisposalToken); + await _snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); _documentVersionCache = new DocumentVersionCache(_projectManager); var remoteTextLoaderFactoryMock = new StrictMock(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs index 2add96d36aa..af4fbdcf3ae 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs @@ -24,6 +24,7 @@ using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Text; +using Microsoft.CommonLanguageServerProtocol.Framework; using Microsoft.VisualStudio.LanguageServer.Protocol; using Moq; using Xunit; @@ -612,7 +613,7 @@ public async Task Handle_Rename_SingleServer_DoesNotDelegateForRazor() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var documentVersionCache = new DocumentVersionCache(projectManager); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs index 55edd63a57b..03fca0e9934 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs @@ -4,10 +4,12 @@ using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; +using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer; using Microsoft.AspNetCore.Razor.Test.Common.ProjectSystem; using Microsoft.AspNetCore.Razor.Utilities; using Microsoft.CodeAnalysis.Razor.ProjectSystem; +using Microsoft.CommonLanguageServerProtocol.Framework; using Xunit; using Xunit.Abstractions; @@ -38,7 +40,7 @@ public async Task TryResolveDocumentInAnyProject_AsksMiscellaneousProjectForDocu var normalizedFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); await projectManager.UpdateAsync(updater => { @@ -64,7 +66,7 @@ public async Task TryResolveDocumentInAnyProject_AsksPotentialParentProjectForDo var documentFilePath = @"C:\path\to\document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act Assert.False(snapshotResolver.TryResolveDocumentInAnyProject(documentFilePath, out var document)); @@ -80,7 +82,7 @@ public async Task TryResolveAllProjects_NoProjects_ReturnsFalse() var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); @@ -96,7 +98,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectDoesNotContainDo var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); @@ -111,7 +113,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectContainsDocument // Arrange var documentFilePath = Path.Combine(TempDirectory.Instance.DirectoryPath, "document.cshtml"); var snapshotResolver = await CreateSnapshotResolverAsync(documentFilePath, addToMiscellaneous: true); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); @@ -128,7 +130,7 @@ public async Task TryResolveAllProjects_UnrelatedProject_ReturnsFalse() var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); await projectManager.UpdateAsync(updater => { @@ -150,7 +152,7 @@ public async Task TryResolveAllProjects_OwnerProjectWithOthers_ReturnsTrue() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var expectedProject = await projectManager.UpdateAsync(updater => { @@ -178,7 +180,7 @@ public async Task TryResolveAllProjects_MiscellaneousOwnerProjectWithOthers_Retu var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var miscProject = await projectManager.UpdateAsync(updater => { @@ -204,7 +206,7 @@ public async Task TryResolveAllProjects_OwnerProjectDifferentCasing_ReturnsTrue( var documentFilePath = "c:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var ownerProject = await projectManager.UpdateAsync(updater => { @@ -228,7 +230,7 @@ public async Task GetMiscellaneousProject_ProjectLoaded_ReturnsExistingProject() // Arrange var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act var project = snapshotResolver.GetMiscellaneousProject(); @@ -244,7 +246,7 @@ public async Task GetMiscellaneousProject_ProjectNotLoaded_CreatesProjectAndRetu // Arrange var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act var project = snapshotResolver.GetMiscellaneousProject(); @@ -260,7 +262,7 @@ private async Task CreateSnapshotResolverAsync(string filePath var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); if (addToMiscellaneous) { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs index 2febc09dacb..5d385dd4301 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/TestSnapshotResolver.cs @@ -3,8 +3,6 @@ using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; using Microsoft.AspNetCore.Razor.Test.Common.ProjectSystem; using Microsoft.CodeAnalysis.Razor.ProjectSystem; @@ -28,9 +26,6 @@ public TestSnapshotResolver(string filePath, params IProjectSnapshot[] projects) _projects = [.. projects]; } - public Task InitializeAsync(CancellationToken cancellationToken) - => Task.CompletedTask; - public ImmutableArray FindPotentialProjects(string documentFilePath) => documentFilePath == _filePath ? _projects From 6ef629c8ae6a695d8e58973f8557bb9531d68100 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 29 Apr 2024 10:15:34 -0700 Subject: [PATCH 12/16] Make RazorFileChangeDetectorManager implement IOnInitialized --- .../Extensions/IServiceCollectionExtensions.cs | 1 + .../RazorFileChangeDetectorManager.cs | 5 +++-- .../RazorInitializedEndpoint.cs | 3 --- .../RazorFileChangeDetectorManagerTest.cs | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs index c406305de47..5d19745938e 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs @@ -212,6 +212,7 @@ public static void AddDocumentManagementServices(this IServiceCollection service services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(sp => sp.GetRequiredService()); if (featureOptions.UseProjectConfigurationEndpoint) { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs index 34656bef655..17b727855b6 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs @@ -7,19 +7,20 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CommonLanguageServerProtocol.Framework; namespace Microsoft.AspNetCore.Razor.LanguageServer; internal class RazorFileChangeDetectorManager( WorkspaceDirectoryPathResolver workspaceDirectoryPathResolver, - IEnumerable fileChangeDetectors) : IDisposable + IEnumerable fileChangeDetectors) : IOnInitialized, IDisposable { private readonly WorkspaceDirectoryPathResolver _workspaceDirectoryPathResolver = workspaceDirectoryPathResolver; private readonly ImmutableArray _fileChangeDetectors = fileChangeDetectors.ToImmutableArray(); private readonly object _disposeLock = new(); private bool _disposed; - public async Task InitializedAsync(CancellationToken cancellationToken) + public async Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { // Initialized request, this occurs once the server and client have agreed on what sort of features they both support. It only happens once. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs index c2ade7352dc..277533d056c 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs @@ -20,9 +20,6 @@ public async Task HandleNotificationAsync(InitializedParams request, RazorReques { var onStartedItems = requestContext.LspServices.GetRequiredServices(); - var fileChangeDetectorManager = requestContext.LspServices.GetRequiredService(); - await fileChangeDetectorManager.InitializedAsync(cancellationToken).ConfigureAwait(false); - foreach (var onStartedItem in onStartedItems) { await onStartedItem.OnInitializedAsync(requestContext.LspServices, cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs index ae207259fbc..91f017f679a 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs @@ -60,7 +60,7 @@ public async Task InitializedAsync_StartsFileChangeDetectors() using (var detectorManager = new RazorFileChangeDetectorManager(workspaceDirectoryPathResolver, [detectorMock1.Object, detectorMock2.Object])) { // Act - await detectorManager.InitializedAsync(DisposalToken); + await detectorManager.OnInitializedAsync(StrictMock.Of(), DisposalToken); } // Assert @@ -98,7 +98,7 @@ public async Task InitializedAsync_Disposed_ReStopsFileChangeDetectors() using var detectorManager = new RazorFileChangeDetectorManager(workspaceDirectoryPathResolver, [detectorMock.Object]); // Act - var initializeTask = detectorManager.InitializedAsync(DisposalToken); + var initializeTask = detectorManager.OnInitializedAsync(StrictMock.Of(), DisposalToken); detectorManager.Dispose(); // Unblock the detector start From 0b4c78b869d76071e73baa661ec324aad2d02dac Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 29 Apr 2024 10:17:05 -0700 Subject: [PATCH 13/16] Renamed OnInitializedAsync to InitializeAsync --- .../RazorLanguageServerBenchmarkBase.cs | 2 +- .../ClientConnection.cs | 2 +- .../IOnInitialized.cs | 2 +- .../ProjectSystem/SnapshotResolver.cs | 2 +- .../RazorConfigurationEndpoint.cs | 2 +- .../RazorFileChangeDetectorManager.cs | 2 +- .../RazorInitializedEndpoint.cs | 2 +- .../DefaultRazorComponentSearchEngineTest.cs | 2 +- ...extDocumentUriPresentationEndpointTests.cs | 8 +++---- .../RazorFileChangeDetectorManagerTest.cs | 4 ++-- .../RazorProjectServiceTest.cs | 2 +- .../Refactoring/RenameEndpointTest.cs | 2 +- .../SnapshotResolverTest.cs | 24 +++++++++---------- 13 files changed, 28 insertions(+), 28 deletions(-) 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 50d6d8246f3..046e7fcd9f3 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs @@ -87,7 +87,7 @@ await projectManager.UpdateAsync( private class NoopClientNotifierService : IClientConnection, IOnInitialized { - public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) + public Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) { return Task.CompletedTask; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs index 0a3c90a7b8f..4f187bebae2 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs @@ -48,7 +48,7 @@ public async Task SendNotificationAsync(string method, CancellationToken cancell /// /// Fires when the language server is set to "Started". /// - public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) + public Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) { _initializedCompletionSource.TrySetResult(true); return Task.CompletedTask; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs index 0dfd09f719d..c4a96df9cfd 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs @@ -10,5 +10,5 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer; internal interface IOnInitialized { - Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken); + Task InitializeAsync(ILspServices services, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs index d5a86495af5..e7debc3328e 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs @@ -35,7 +35,7 @@ public SnapshotResolver(IProjectSnapshotManager projectManager, ILoggerFactory l MiscellaneousHostProject = new HostProject(normalizedPath, normalizedPath, FallbackRazorConfiguration.Latest, rootNamespace: null, "Miscellaneous Files"); } - public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) + public Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) { // This is called when the language server is initialized. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs index 57e8793dd49..ec50e8436ee 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs @@ -27,7 +27,7 @@ public async Task HandleNotificationAsync(DidChangeConfigurationParams request, await _optionsMonitor.UpdateAsync(cancellationToken).ConfigureAwait(false); } - public async Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) + public async Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) { var capabilitiesService = services.GetRequiredService(); var clientCapabilities = capabilitiesService.ClientCapabilities; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs index 17b727855b6..d5f7894eaa7 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs @@ -20,7 +20,7 @@ internal class RazorFileChangeDetectorManager( private readonly object _disposeLock = new(); private bool _disposed; - public async Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) + public async Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) { // Initialized request, this occurs once the server and client have agreed on what sort of features they both support. It only happens once. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs index 277533d056c..7a204c94677 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs @@ -22,7 +22,7 @@ public async Task HandleNotificationAsync(InitializedParams request, RazorReques foreach (var onStartedItem in onStartedItems) { - await onStartedItem.OnInitializedAsync(requestContext.LspServices, cancellationToken).ConfigureAwait(false); + await onStartedItem.InitializeAsync(requestContext.LspServices, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs index 5f2491651f9..653feacfdac 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs @@ -48,7 +48,7 @@ protected override async Task InitializeAsync() _projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(_projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); var documentVersionCache = new DocumentVersionCache(_projectManager); var remoteTextLoaderFactoryMock = new StrictMock(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs index 12a7678ed24..7750f1278cc 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs @@ -34,7 +34,7 @@ public async Task Handle_SimpleComponent_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); @@ -99,7 +99,7 @@ public async Task Handle_SimpleComponentWithChildFile_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); @@ -169,7 +169,7 @@ public async Task Handle_ComponentWithRequiredAttribute_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); @@ -401,7 +401,7 @@ public async Task Handle_ComponentWithNestedFiles_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs index 91f017f679a..1d74ee1fdad 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs @@ -60,7 +60,7 @@ public async Task InitializedAsync_StartsFileChangeDetectors() using (var detectorManager = new RazorFileChangeDetectorManager(workspaceDirectoryPathResolver, [detectorMock1.Object, detectorMock2.Object])) { // Act - await detectorManager.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await detectorManager.InitializeAsync(StrictMock.Of(), DisposalToken); } // Assert @@ -98,7 +98,7 @@ public async Task InitializedAsync_Disposed_ReStopsFileChangeDetectors() using var detectorManager = new RazorFileChangeDetectorManager(workspaceDirectoryPathResolver, [detectorMock.Object]); // Act - var initializeTask = detectorManager.OnInitializedAsync(StrictMock.Of(), DisposalToken); + var initializeTask = detectorManager.InitializeAsync(StrictMock.Of(), DisposalToken); detectorManager.Dispose(); // Unblock the detector start 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 1216ebf0b2e..0bd59a7b828 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs @@ -41,7 +41,7 @@ protected override async Task InitializeAsync() { _projectManager = CreateProjectSnapshotManager(); _snapshotResolver = new SnapshotResolver(_projectManager, LoggerFactory); - await _snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await _snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); _documentVersionCache = new DocumentVersionCache(_projectManager); var remoteTextLoaderFactoryMock = new StrictMock(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs index af4fbdcf3ae..7895732e57d 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs @@ -613,7 +613,7 @@ public async Task Handle_Rename_SingleServer_DoesNotDelegateForRazor() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); var documentVersionCache = new DocumentVersionCache(projectManager); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs index 03fca0e9934..100910509a0 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs @@ -40,7 +40,7 @@ public async Task TryResolveDocumentInAnyProject_AsksMiscellaneousProjectForDocu var normalizedFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); await projectManager.UpdateAsync(updater => { @@ -66,7 +66,7 @@ public async Task TryResolveDocumentInAnyProject_AsksPotentialParentProjectForDo var documentFilePath = @"C:\path\to\document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); // Act Assert.False(snapshotResolver.TryResolveDocumentInAnyProject(documentFilePath, out var document)); @@ -82,7 +82,7 @@ public async Task TryResolveAllProjects_NoProjects_ReturnsFalse() var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); // Act var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); @@ -98,7 +98,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectDoesNotContainDo var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); // Act var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); @@ -113,7 +113,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectContainsDocument // Arrange var documentFilePath = Path.Combine(TempDirectory.Instance.DirectoryPath, "document.cshtml"); var snapshotResolver = await CreateSnapshotResolverAsync(documentFilePath, addToMiscellaneous: true); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); // Act var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); @@ -130,7 +130,7 @@ public async Task TryResolveAllProjects_UnrelatedProject_ReturnsFalse() var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); await projectManager.UpdateAsync(updater => { @@ -152,7 +152,7 @@ public async Task TryResolveAllProjects_OwnerProjectWithOthers_ReturnsTrue() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); var expectedProject = await projectManager.UpdateAsync(updater => { @@ -180,7 +180,7 @@ public async Task TryResolveAllProjects_MiscellaneousOwnerProjectWithOthers_Retu var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); var miscProject = await projectManager.UpdateAsync(updater => { @@ -206,7 +206,7 @@ public async Task TryResolveAllProjects_OwnerProjectDifferentCasing_ReturnsTrue( var documentFilePath = "c:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); var ownerProject = await projectManager.UpdateAsync(updater => { @@ -230,7 +230,7 @@ public async Task GetMiscellaneousProject_ProjectLoaded_ReturnsExistingProject() // Arrange var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); // Act var project = snapshotResolver.GetMiscellaneousProject(); @@ -246,7 +246,7 @@ public async Task GetMiscellaneousProject_ProjectNotLoaded_CreatesProjectAndRetu // Arrange var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); // Act var project = snapshotResolver.GetMiscellaneousProject(); @@ -262,7 +262,7 @@ private async Task CreateSnapshotResolverAsync(string filePath var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); if (addToMiscellaneous) { From 313b8c682a73ca9fea6eadd0672b2bf96c6bb6cd Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 29 Apr 2024 10:28:45 -0700 Subject: [PATCH 14/16] Improve signature of TryResolveAllProjects --- .../ISnapshotResolverExtensions.cs | 14 ++++++----- .../ProjectSystem/RazorProjectService.cs | 3 +-- .../Tooltip/TagHelperTooltipFactoryBase.cs | 3 +-- .../SnapshotResolverTest.cs | 23 ++++++------------- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs index cae7fc343e9..f297cb7f8a2 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/ISnapshotResolverExtensions.cs @@ -12,19 +12,20 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; internal static class ISnapshotResolverExtensions { - public static ImmutableArray TryResolveAllProjects( + public static bool TryResolveAllProjects( this ISnapshotResolver snapshotResolver, - string documentFilePath) + string documentFilePath, + out ImmutableArray projects) { var potentialProjects = snapshotResolver.FindPotentialProjects(documentFilePath); - using var projects = new PooledArrayBuilder(capacity: potentialProjects.Length); + using var builder = new PooledArrayBuilder(capacity: potentialProjects.Length); foreach (var project in potentialProjects) { if (project.GetDocument(documentFilePath) is not null) { - projects.Add(project); + builder.Add(project); } } @@ -32,9 +33,10 @@ public static ImmutableArray TryResolveAllProjects( var miscProject = snapshotResolver.GetMiscellaneousProject(); if (miscProject.GetDocument(normalizedDocumentPath) is not null) { - projects.Add(miscProject); + builder.Add(miscProject); } - return projects.DrainToImmutable(); + projects = builder.DrainToImmutable(); + return projects.Length > 0; } } 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 cb83af882a4..a5319903b6f 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -227,8 +227,7 @@ public Task UpdateDocumentAsync(string filePath, SourceText sourceText, int vers private void ActOnDocumentInMultipleProjects(string filePath, Action action) { var textDocumentPath = FilePathNormalizer.Normalize(filePath); - var projects = _snapshotResolver.TryResolveAllProjects(textDocumentPath); - if (projects.IsEmpty) + if (!_snapshotResolver.TryResolveAllProjects(textDocumentPath, out var projects)) { var miscFilesProject = _snapshotResolver.GetMiscellaneousProject(); projects = [miscFilesProject]; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/TagHelperTooltipFactoryBase.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/TagHelperTooltipFactoryBase.cs index 521a76f8c5e..8f4484da6b9 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/TagHelperTooltipFactoryBase.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/TagHelperTooltipFactoryBase.cs @@ -31,8 +31,7 @@ protected TagHelperTooltipFactoryBase(ISnapshotResolver snapshotResolver) internal async Task GetProjectAvailabilityAsync(string documentFilePath, string tagHelperTypeName, CancellationToken cancellationToken) { - var projectSnapshots = _snapshotResolver.TryResolveAllProjects(documentFilePath); - if (projectSnapshots.IsEmpty) + if (!_snapshotResolver.TryResolveAllProjects(documentFilePath, out var projectSnapshots)) { return null; } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs index 100910509a0..009b19c0aa5 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs @@ -85,10 +85,7 @@ public async Task TryResolveAllProjects_NoProjects_ReturnsFalse() await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); // Act - var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); - - // Assert - Assert.Empty(projects); + Assert.False(snapshotResolver.TryResolveAllProjects(documentFilePath, out _)); } [Fact] @@ -101,10 +98,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectDoesNotContainDo await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); // Act - var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); - - // Assert - Assert.Empty(projects); + Assert.False(snapshotResolver.TryResolveAllProjects(documentFilePath, out _)); } [Fact] @@ -116,7 +110,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectContainsDocument await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); // Act - var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); + Assert.True(snapshotResolver.TryResolveAllProjects(documentFilePath, out var projects)); // Assert var miscFilesProject = snapshotResolver.GetMiscellaneousProject(); @@ -138,10 +132,7 @@ await projectManager.UpdateAsync(updater => }); // Act - var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); - - // Assert - Assert.Empty(projects); + Assert.False(snapshotResolver.TryResolveAllProjects(documentFilePath, out _)); } [Fact] @@ -164,7 +155,7 @@ public async Task TryResolveAllProjects_OwnerProjectWithOthers_ReturnsTrue() }); // Act - var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); + Assert.True(snapshotResolver.TryResolveAllProjects(documentFilePath, out var projects)); // Assert var project = Assert.Single(projects); @@ -192,7 +183,7 @@ public async Task TryResolveAllProjects_MiscellaneousOwnerProjectWithOthers_Retu }); // Act - var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); + Assert.True(snapshotResolver.TryResolveAllProjects(documentFilePath, out var projects)); // Assert var project = Assert.Single(projects); @@ -217,7 +208,7 @@ public async Task TryResolveAllProjects_OwnerProjectDifferentCasing_ReturnsTrue( }); // Act - var projects = snapshotResolver.TryResolveAllProjects(documentFilePath); + Assert.True(snapshotResolver.TryResolveAllProjects(documentFilePath, out var projects)); // Assert var project = Assert.Single(projects); From c9efa48ac318f1746fe7c4ff5cf4844cf4076ff2 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 29 Apr 2024 11:27:27 -0700 Subject: [PATCH 15/16] Improve signatures of TryCreate methods --- .../CSharp/DefaultCSharpCodeActionResolver.cs | 3 +- ...mattedRemappingCSharpCodeActionResolver.cs | 3 +- .../Html/DefaultHtmlCodeActionResolver.cs | 3 +- .../Razor/AddUsingsCodeActionResolver.cs | 3 +- .../CreateComponentCodeActionResolver.cs | 3 +- .../ExtractToCodeBehindCodeActionResolver.cs | 3 +- .../Razor/GenerateMethodCodeActionResolver.cs | 3 +- .../DelegatedCompletionItemResolver.cs | 3 +- .../Diagnostics/RazorDiagnosticsPublisher.cs | 5 +- .../DocumentContextFactory.cs | 21 ++++-- .../TextDocumentUriPresentationEndpoint.cs | 3 +- .../MapCode/MapCodeEndpoint.cs | 6 +- .../RazorRequestContextFactory.cs | 4 +- .../AbstractRazorDocumentMappingService.cs | 10 ++- .../ProjectSystem/IDocumentContextFactory.cs | 7 +- .../IDocumentContextFactoryExtensions.cs | 72 +++++++++++++++---- .../ProjectSystem/DocumentContextFactory.cs | 7 +- .../OnAutoInsertEndpointTest.NetFx.cs | 2 +- .../CodeActionEndToEndTest.NetFx.cs | 14 ++-- .../Html/DefaultHtmlCodeActionResolverTest.cs | 3 +- .../ValidateBreakpointRangeEndpointTest.cs | 3 +- .../DefinitionEndpointDelegationTest.cs | 2 +- .../DocumentContextFactoryTest.cs | 28 +++----- ...extDocumentUriPresentationEndpointTests.cs | 9 +-- .../DocumentSymbolEndpointTest.cs | 2 +- .../FindAllReferencesEndpointTest.cs | 2 +- .../Folding/FoldingEndpointTest.cs | 2 +- .../DocumentOnTypeFormattingEndpointTest.cs | 8 +-- .../ImplementationEndpointTest.cs | 2 +- .../InlayHints/InlayHintEndpointTest.cs | 2 +- .../MapCode/MapCodeTest.cs | 2 +- .../ProjectContextsEndpointTest.cs | 2 +- .../RenameEndpointDelegationTest.cs | 2 +- .../Refactoring/RenameEndpointTest.cs | 26 +++---- .../Semantic/SemanticTokensTest.cs | 10 ++- .../SignatureHelpEndpointTest.cs | 2 +- .../WrapWithTag/WrapWithTagEndpointTests.cs | 9 +-- .../TestDocumentContextFactory.cs | 19 +++-- 38 files changed, 183 insertions(+), 127 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/DefaultCSharpCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/DefaultCSharpCodeActionResolver.cs index 0538ace062a..692c9525d0a 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/DefaultCSharpCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/DefaultCSharpCodeActionResolver.cs @@ -73,8 +73,7 @@ public async override Task ResolveAsync( throw new ArgumentNullException(nameof(codeAction)); } - var documentContext = _documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier); - if (documentContext is null) + if (!_documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier, out var documentContext)) { return codeAction; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/UnformattedRemappingCSharpCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/UnformattedRemappingCSharpCodeActionResolver.cs index 1289713ff0b..a7f33f3d93c 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/UnformattedRemappingCSharpCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/UnformattedRemappingCSharpCodeActionResolver.cs @@ -54,8 +54,7 @@ public async override Task ResolveAsync( cancellationToken.ThrowIfCancellationRequested(); - var documentContext = _documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier); - if (documentContext is null) + if (!_documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier, out var documentContext)) { return codeAction; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Html/DefaultHtmlCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Html/DefaultHtmlCodeActionResolver.cs index 59f4420eb72..8aaaefadca0 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Html/DefaultHtmlCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Html/DefaultHtmlCodeActionResolver.cs @@ -55,8 +55,7 @@ public async override Task ResolveAsync( throw new ArgumentNullException(nameof(codeAction)); } - var documentContext = _documentContextFactory.TryCreateForOpenDocument(resolveParams.RazorFileIdentifier); - if (documentContext is null) + if (!_documentContextFactory.TryCreateForOpenDocument(resolveParams.RazorFileIdentifier, out var documentContext)) { return codeAction; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/AddUsingsCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/AddUsingsCodeActionResolver.cs index 879953b5a00..3fb397f010c 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/AddUsingsCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/AddUsingsCodeActionResolver.cs @@ -45,8 +45,7 @@ public AddUsingsCodeActionResolver(IDocumentContextFactory documentContextFactor return null; } - var documentContext = _documentContextFactory.TryCreate(actionParams.Uri); - if (documentContext is null) + if (!_documentContextFactory.TryCreate(actionParams.Uri, out var documentContext)) { return null; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/CreateComponentCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/CreateComponentCodeActionResolver.cs index 420e2839e41..a69358b3a76 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/CreateComponentCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/CreateComponentCodeActionResolver.cs @@ -43,8 +43,7 @@ public CreateComponentCodeActionResolver(IDocumentContextFactory documentContext return null; } - var documentContext = _documentContextFactory.TryCreate(actionParams.Uri); - if (documentContext is null) + if (!_documentContextFactory.TryCreate(actionParams.Uri, out var documentContext)) { return null; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToCodeBehindCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToCodeBehindCodeActionResolver.cs index eff9809f42b..4bd8554f543 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToCodeBehindCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToCodeBehindCodeActionResolver.cs @@ -60,8 +60,7 @@ public ExtractToCodeBehindCodeActionResolver( var path = FilePathNormalizer.Normalize(actionParams.Uri.GetAbsoluteOrUNCPath()); - var documentContext = _documentContextFactory.TryCreate(actionParams.Uri); - if (documentContext is null) + if (!_documentContextFactory.TryCreate(actionParams.Uri, out var documentContext)) { return null; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/GenerateMethodCodeActionResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/GenerateMethodCodeActionResolver.cs index 7a66254716f..20e130b4f10 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/GenerateMethodCodeActionResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/GenerateMethodCodeActionResolver.cs @@ -72,8 +72,7 @@ public GenerateMethodCodeActionResolver( return null; } - var documentContext = _documentContextFactory.TryCreateForOpenDocument(actionParams.Uri); - if (documentContext is null) + if (!_documentContextFactory.TryCreateForOpenDocument(actionParams.Uri, out var documentContext)) { return null; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionItemResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionItemResolver.cs index 2a82ae9beda..bc422f283b0 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionItemResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionItemResolver.cs @@ -100,8 +100,7 @@ private async Task PostProcessCompletionItemAsync( } var identifier = context.OriginalRequestParams.Identifier.TextDocumentIdentifier; - var documentContext = _documentContextFactory.TryCreateForOpenDocument(identifier); - if (documentContext is null) + if (!_documentContextFactory.TryCreateForOpenDocument(identifier, out var documentContext)) { return resolvedCompletionItem; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorDiagnosticsPublisher.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorDiagnosticsPublisher.cs index 24347cc3c59..bd92d5ed7de 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorDiagnosticsPublisher.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorDiagnosticsPublisher.cs @@ -183,10 +183,7 @@ .. csharpDiagnostics ?? [] delegatedResponse.Value.TryGetFirst(out var fullDiagnostics) && fullDiagnostics.Items is not null) { - var documentContext = _documentContextFactory.Value - .TryCreate(delegatedParams.TextDocument.Uri, projectContext: null); - - if (documentContext is not null) + if (_documentContextFactory.Value.TryCreate(delegatedParams.TextDocument.Uri, projectContext: null, out var documentContext)) { return await _translateDiagnosticsService.Value .TranslateAsync(RazorLanguageKind.CSharp, fullDiagnostics.Items, documentContext, token) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs index d42d9947761..3748910b451 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs @@ -28,21 +28,27 @@ internal sealed class DocumentContextFactory( private readonly IDocumentVersionCache _documentVersionCache = documentVersionCache; private readonly ILogger _logger = loggerFactory.GetOrCreateLogger(); - public DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) + public bool TryCreate( + Uri documentUri, + VSProjectContext? projectContext, + bool versioned, + [NotNullWhen(true)] out DocumentContext? context) { var filePath = documentUri.GetAbsoluteOrUNCPath(); if (!TryGetDocumentAndVersion(filePath, projectContext, versioned, out var documentAndVersion)) { // Stale request or misbehaving client, see above comment. - return null; + context = null; + return false; } var (documentSnapshot, version) = documentAndVersion; if (documentSnapshot is null) { Debug.Fail($"Document snapshot should never be null here for '{filePath}'. This indicates that our acquisition of documents / versions did not behave as expected."); - return null; + context = null; + return false; } if (versioned) @@ -50,13 +56,16 @@ internal sealed class DocumentContextFactory( // If we were asked for a versioned document, but have no version info, then we didn't find the document if (version is null) { - return null; + context = null; + return false; } - return new VersionedDocumentContext(documentUri, documentSnapshot, projectContext, version.Value); + context = new VersionedDocumentContext(documentUri, documentSnapshot, projectContext, version.Value); + return true; } - return new DocumentContext(documentUri, documentSnapshot, projectContext); + context = new DocumentContext(documentUri, documentSnapshot, projectContext); + return true; } private bool TryGetDocumentAndVersion( diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentPresentation/TextDocumentUriPresentationEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentPresentation/TextDocumentUriPresentationEndpoint.cs index 9e3e13ead68..be769456b92 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentPresentation/TextDocumentUriPresentationEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentPresentation/TextDocumentUriPresentationEndpoint.cs @@ -116,8 +116,7 @@ protected override IRazorPresentationParams CreateRazorRequestParameters(UriPres { Logger.LogInformation($"Trying to find document info for dropped uri {uri}."); - var documentContext = _documentContextFactory.TryCreate(uri); - if (documentContext is null) + if (!_documentContextFactory.TryCreate(uri, out var documentContext)) { Logger.LogInformation($"Failed to find document for component {uri}."); return null; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs index 1381364d2ec..6c6fa42d602 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs @@ -85,8 +85,7 @@ public void ApplyCapabilities(VSInternalServerCapabilities serverCapabilities, V continue; } - var documentContext = _documentContextFactory.TryCreateForOpenDocument(mapping.TextDocument.Uri); - if (documentContext is null) + if (!_documentContextFactory.TryCreateForOpenDocument(mapping.TextDocument.Uri, out var documentContext)) { continue; } @@ -356,8 +355,7 @@ private async Task GetCSharpFocusLocationsAsync(Location[][] focus continue; } - var documentContext = _documentContextFactory.TryCreateForOpenDocument(potentialLocation.Uri); - if (documentContext is null) + if (!_documentContextFactory.TryCreateForOpenDocument(potentialLocation.Uri, out var documentContext)) { continue; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs index b7b63ede8ed..3383b82b7cb 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorRequestContextFactory.cs @@ -35,7 +35,7 @@ public override Task CreateRequestContextAsync uriHandler) { @@ -43,7 +43,7 @@ public override Task CreateRequestContextAsync RemapWorkspaceEditAsync(WorkspaceEdit workspace return (generatedDocumentUri, generatedDocumentRange); } - var documentContext = _documentContextFactory.TryCreate(razorDocumentUri); - if (documentContext is null) + if (!_documentContextFactory.TryCreate(razorDocumentUri, out var documentContext)) { return (generatedDocumentUri, generatedDocumentRange); } @@ -809,8 +808,8 @@ private async Task RemapVersionedDocumentEditsAsync(TextDocu } var razorDocumentUri = _documentFilePathService.GetRazorDocumentUri(generatedDocumentUri); - var documentContext = _documentContextFactory.TryCreateForOpenDocument(razorDocumentUri, entry.TextDocument.GetProjectContext()); - if (documentContext is null) + + if (!_documentContextFactory.TryCreateForOpenDocument(razorDocumentUri, entry.TextDocument.GetProjectContext(), out var documentContext)) { continue; } @@ -853,8 +852,7 @@ private async Task> RemapDocumentEditsAsync(Dicti continue; } - var documentContext = _documentContextFactory.TryCreate(uri); - if (documentContext is null) + if (!_documentContextFactory.TryCreate(uri, out var documentContext)) { continue; } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactory.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactory.cs index 973d9f734ed..6eb544326ec 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactory.cs @@ -2,11 +2,16 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.CodeAnalysis.Razor.ProjectSystem; internal interface IDocumentContextFactory { - DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned); + bool TryCreate( + Uri documentUri, + VSProjectContext? projectContext, + bool versioned, + [NotNullWhen(true)] out DocumentContext? context); } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactoryExtensions.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactoryExtensions.cs index e825c027521..2264ce4399e 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactoryExtensions.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentContextFactoryExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -9,21 +10,68 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem; internal static class IDocumentContextFactoryExtensions { - public static DocumentContext? TryCreate(this IDocumentContextFactory service, TextDocumentIdentifier documentIdentifier) - => service.TryCreate(documentIdentifier.Uri, documentIdentifier.GetProjectContext(), versioned: false); + public static bool TryCreate( + this IDocumentContextFactory service, + TextDocumentIdentifier documentIdentifier, + [NotNullWhen(true)] out DocumentContext? context) + => service.TryCreate(documentIdentifier.Uri, documentIdentifier.GetProjectContext(), versioned: false, out context); - public static DocumentContext? TryCreate(this IDocumentContextFactory service, Uri documentUri) - => service.TryCreate(documentUri, projectContext: null, versioned: false); + public static bool TryCreate( + this IDocumentContextFactory service, + Uri documentUri, + [NotNullWhen(true)] out DocumentContext? context) + => service.TryCreate(documentUri, projectContext: null, versioned: false, out context); - public static DocumentContext? TryCreate(this IDocumentContextFactory service, Uri documentUri, VSProjectContext? projectContext) - => service.TryCreate(documentUri, projectContext, versioned: false); + public static bool TryCreate( + this IDocumentContextFactory service, + Uri documentUri, + VSProjectContext? projectContext, + [NotNullWhen(true)] out DocumentContext? context) + => service.TryCreate(documentUri, projectContext, versioned: false, out context); - public static VersionedDocumentContext? TryCreateForOpenDocument(this IDocumentContextFactory service, Uri documentUri) - => (VersionedDocumentContext?)service.TryCreate(documentUri, projectContext: null, versioned: true); + public static bool TryCreateForOpenDocument( + this IDocumentContextFactory service, + Uri documentUri, + [NotNullWhen(true)] out VersionedDocumentContext? context) + { + if (service.TryCreate(documentUri, projectContext: null, versioned: true, out var documentContext)) + { + context = (VersionedDocumentContext)documentContext; + return true; + } - public static VersionedDocumentContext? TryCreateForOpenDocument(this IDocumentContextFactory service, TextDocumentIdentifier documentIdentifier) - => (VersionedDocumentContext?)service.TryCreate(documentIdentifier.Uri, documentIdentifier.GetProjectContext(), versioned: true); + context = null; + return false; + } - public static VersionedDocumentContext? TryCreateForOpenDocument(this IDocumentContextFactory service, Uri documentUri, VSProjectContext? projectContext) - => (VersionedDocumentContext?)service.TryCreate(documentUri, projectContext, versioned: true); + public static bool TryCreateForOpenDocument( + this IDocumentContextFactory service, + TextDocumentIdentifier documentIdentifier, + [NotNullWhen(true)] out VersionedDocumentContext? context) + { + if (service.TryCreate(documentIdentifier.Uri, documentIdentifier.GetProjectContext(), versioned: true, out var documentContext)) + { + context = (VersionedDocumentContext)documentContext; + return true; + } + + context = null; + return false; + } + + public static bool TryCreateForOpenDocument( + this IDocumentContextFactory service, + Uri documentUri, + VSProjectContext? projectContext, + [NotNullWhen(true)] out VersionedDocumentContext? context) + { + if (service.TryCreate(documentUri, projectContext, versioned: true, out var documentContext)) + { + context = (VersionedDocumentContext)documentContext; + return true; + } + + context = null; + return false; + } } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/DocumentContextFactory.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/DocumentContextFactory.cs index cd8f2ae3adb..a23e018bcd1 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/DocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/DocumentContextFactory.cs @@ -3,6 +3,7 @@ using System; using System.Composition; +using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -11,7 +12,11 @@ namespace Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; [Export(typeof(IDocumentContextFactory)), Shared] internal class DocumentContextFactory : IDocumentContextFactory { - public DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) + public bool TryCreate( + Uri documentUri, + VSProjectContext? projectContext, + bool versioned, + [NotNullWhen(true)] out DocumentContext? context) { throw new NotSupportedException("OOP doesn't support this yet, because we don't have a way to pass in the right solution snapshot to use"); } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/AutoInsert/OnAutoInsertEndpointTest.NetFx.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/AutoInsert/OnAutoInsertEndpointTest.NetFx.cs index 80c082a802d..7fea7b3970c 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/AutoInsert/OnAutoInsertEndpointTest.NetFx.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/AutoInsert/OnAutoInsertEndpointTest.NetFx.cs @@ -383,7 +383,7 @@ private async Task VerifyCSharpOnAutoInsertAsync(string input, string expected, InsertSpaces = true }, }; - var documentContext = DocumentContextFactory.TryCreateForOpenDocument(@params.TextDocument); + Assert.True(DocumentContextFactory.TryCreateForOpenDocument(@params.TextDocument, out var documentContext)); var requestContext = await CreateOnAutoInsertRequestContextAsync(documentContext); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CodeActionEndToEndTest.NetFx.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CodeActionEndToEndTest.NetFx.cs index e11d9dccc49..2134812aa35 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CodeActionEndToEndTest.NetFx.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CodeActionEndToEndTest.NetFx.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Threading; @@ -1247,7 +1248,6 @@ public GenerateMethodResolverDocumentContextFactory int? version = null) : base(filePath, codeDocument, version) { - _tagHelperDescriptors = CreateTagHelperDescriptors(); if (tagHelpers is not null) { @@ -1255,18 +1255,24 @@ public GenerateMethodResolverDocumentContextFactory } } - public override DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) + public override bool TryCreate( + Uri documentUri, + VSProjectContext? projectContext, + bool versioned, + [NotNullWhen(true)] out DocumentContext? context) { if (FilePath is null || CodeDocument is null) { - return null; + context = null; + return false; } var projectWorkspaceState = ProjectWorkspaceState.Create(_tagHelperDescriptors.ToImmutableArray()); var testDocumentSnapshot = TestDocumentSnapshot.Create(FilePath, CodeDocument.GetSourceText().ToString(), CodeAnalysis.VersionStamp.Default, projectWorkspaceState); testDocumentSnapshot.With(CodeDocument); - return CreateDocumentContext(new Uri(FilePath), testDocumentSnapshot); + context = CreateDocumentContext(new Uri(FilePath), testDocumentSnapshot); + return true; } private static List CreateTagHelperDescriptors() diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Html/DefaultHtmlCodeActionResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Html/DefaultHtmlCodeActionResolverTest.cs index abe355839a7..a95e8a3e73b 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Html/DefaultHtmlCodeActionResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Html/DefaultHtmlCodeActionResolverTest.cs @@ -33,8 +33,7 @@ public async Task ResolveAsync_RemapsAndFixesEdits() var documentPath = "c:/Test.razor"; var documentUri = new Uri(documentPath); var documentContextFactory = CreateDocumentContextFactory(documentUri, contents); - var context = documentContextFactory.TryCreate(documentUri); - Assert.NotNull(context); + Assert.True(documentContextFactory.TryCreate(documentUri, out var context)); var sourceText = await context.GetSourceTextAsync(DisposalToken); var remappedEdit = new WorkspaceEdit { diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Debugging/ValidateBreakpointRangeEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Debugging/ValidateBreakpointRangeEndpointTest.cs index afe5697c3ed..1c60c66ddec 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Debugging/ValidateBreakpointRangeEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Debugging/ValidateBreakpointRangeEndpointTest.cs @@ -152,8 +152,7 @@ private async Task VerifyBreakpointRangeAsync(string input) Range = breakpointSpan.ToRange(codeDocument.GetSourceText()) }; - var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); - Assert.NotNull(documentContext); + Assert.True(DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument, out var documentContext)); var requestContext = CreateValidateBreakpointRangeRequestContext(documentContext); return await endpoint.HandleRequestAsync(request, requestContext, DisposalToken); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Definition/DefinitionEndpointDelegationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Definition/DefinitionEndpointDelegationTest.cs index fe09f9f1f38..80ab00ce291 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Definition/DefinitionEndpointDelegationTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Definition/DefinitionEndpointDelegationTest.cs @@ -239,7 +239,7 @@ await projectManager.UpdateAsync(updater => var searchEngine = new DefaultRazorComponentSearchEngine(projectManager, LoggerFactory); var razorUri = new Uri(razorFilePath); - var documentContext = DocumentContextFactory.TryCreateForOpenDocument(razorUri); + Assert.True(DocumentContextFactory.TryCreateForOpenDocument(razorUri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); var endpoint = new DefinitionEndpoint(searchEngine, DocumentMappingService, LanguageServerFeatureOptions, languageServer, LoggerFactory); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs index c6c07d573fa..89ee041a418 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentContextFactoryTest.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Razor.Test.Common.ProjectSystem; using Microsoft.AspNetCore.Razor.Utilities; using Microsoft.CodeAnalysis.Razor.ProjectSystem; +using Microsoft.VisualStudio.Copilot; using Moq; using Xunit; using Xunit.Abstractions; @@ -45,10 +46,7 @@ public void TryCreateAsync_CanNotResolveDocument_ReturnsNull() var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = factory.TryCreate(uri); - - // Assert - Assert.Null(documentContext); + Assert.False(factory.TryCreate(uri, out _)); } [Fact] @@ -63,10 +61,7 @@ public void TryCreateForOpenDocumentAsync_CanNotResolveDocument_ReturnsNull() var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = factory.TryCreateForOpenDocument(uri); - - // Assert - Assert.Null(documentContext); + Assert.False(factory.TryCreateForOpenDocument(uri, out _)); } [Fact] @@ -81,10 +76,7 @@ public void TryCreateForOpenDocumentAsync_CanNotResolveVersion_ReturnsNull() var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = factory.TryCreateForOpenDocument(uri); - - // Assert - Assert.Null(documentContext); + Assert.False(factory.TryCreateForOpenDocument(uri, out _)); } [Fact] @@ -101,10 +93,9 @@ public void TryCreateAsync_ResolvesContent() var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = factory.TryCreate(uri); + Assert.True(factory.TryCreate(uri, out var documentContext)); // Assert - Assert.NotNull(documentContext); Assert.Equal(uri, documentContext.Uri); Assert.Same(documentSnapshot, documentContext.Snapshot); } @@ -134,10 +125,9 @@ await _projectManager.UpdateAsync(updater => }); // Act - var documentContext = factory.TryCreate(uri, new VisualStudio.LanguageServer.Protocol.VSProjectContext { Id = hostProject.Key.Id }); + Assert.True(factory.TryCreate(uri, new VisualStudio.LanguageServer.Protocol.VSProjectContext { Id = hostProject.Key.Id }, out var documentContext)); // Assert - Assert.NotNull(documentContext); Assert.Equal(uri, documentContext.Uri); } @@ -166,10 +156,9 @@ await _projectManager.UpdateAsync(updater => }); // Act - var documentContext = factory.TryCreate(uri, new VisualStudio.LanguageServer.Protocol.VSProjectContext { Id = hostProject.Key.Id }); + Assert.True(factory.TryCreate(uri, new VisualStudio.LanguageServer.Protocol.VSProjectContext { Id = hostProject.Key.Id }, out var documentContext)); // Assert - Assert.NotNull(documentContext); Assert.Equal(uri, documentContext.Uri); documentResolverMock.Verify(); } @@ -189,10 +178,9 @@ public void TryCreateForOpenDocumentAsync_ResolvesContent() var factory = new DocumentContextFactory(_projectManager, snapshotResolver, _documentVersionCache, LoggerFactory); // Act - var documentContext = factory.TryCreateForOpenDocument(uri); + Assert.True(factory.TryCreateForOpenDocument(uri, out var documentContext)); // Assert - Assert.NotNull(documentContext); Assert.Equal(1337, documentContext.Version); Assert.Equal(uri, documentContext.Uri); Assert.Same(documentSnapshot, documentContext.Snapshot); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs index 7750f1278cc..6e4874fb0ee 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.Razor.Protocol.DocumentPresentation; using Microsoft.CodeAnalysis.Text; using Microsoft.CommonLanguageServerProtocol.Framework; +using Microsoft.VisualStudio.Copilot; using Microsoft.VisualStudio.LanguageServer.Protocol; using Moq; using Xunit; @@ -58,7 +59,7 @@ public async Task Handle_SimpleComponent_ReturnsResult() var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri, null); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, null, out var documentContext)); var clientConnection = new Mock(MockBehavior.Strict); @@ -123,7 +124,7 @@ public async Task Handle_SimpleComponentWithChildFile_ReturnsResult() var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri, null); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, null, out var documentContext)); var clientConnection = new Mock(MockBehavior.Strict); @@ -199,7 +200,7 @@ public async Task Handle_ComponentWithRequiredAttribute_ReturnsResult() var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri, null); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, null, out var documentContext)); var clientConnection = new Mock(MockBehavior.Strict); @@ -426,7 +427,7 @@ public async Task Handle_ComponentWithNestedFiles_ReturnsResult() var documentSnapshot = projectManager.GetLoadedProject(project.Key).GetDocument(razorFilePath).AssumeNotNull(); documentVersionCache.TrackDocumentVersion(documentSnapshot, 1); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri, null); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, null, out var documentContext)); var clientConnection = new Mock(MockBehavior.Strict); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentSymbols/DocumentSymbolEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentSymbols/DocumentSymbolEndpointTest.cs index 330094e771c..af789583a46 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentSymbols/DocumentSymbolEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentSymbols/DocumentSymbolEndpointTest.cs @@ -89,7 +89,7 @@ private async Task VerifyDocumentSymbolsAsync(string input) } } }; - var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); + Assert.True(DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/FindReferences/FindAllReferencesEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/FindReferences/FindAllReferencesEndpointTest.cs index a573b837542..a4cd1f10529 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/FindReferences/FindAllReferencesEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/FindReferences/FindAllReferencesEndpointTest.cs @@ -76,7 +76,7 @@ private async Task VerifyCSharpFindAllReferencesAsyncAsync(string input) }, Position = new Position(line, offset) }; - var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); + Assert.True(DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Folding/FoldingEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Folding/FoldingEndpointTest.cs index 98fc454f6ab..e5733d3ebcb 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Folding/FoldingEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Folding/FoldingEndpointTest.cs @@ -117,7 +117,7 @@ private async Task VerifyRazorFoldsAsync(string input, string? filePath = null) } } }; - var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); + Assert.True(DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs index b50ce3a2f5a..a6cc0b4b1c6 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs @@ -193,9 +193,9 @@ public async Task Handle_OnTypeFormatting_UnexpectedTriggerCharacter_ReturnsNull var codeDocument = CreateCodeDocument(content, sourceMappings); var uri = new Uri("file://path/test.razor"); - var documentResolver = CreateDocumentContextFactory(uri, codeDocument); + var documentContextFactory = CreateDocumentContextFactory(uri, codeDocument); var formattingService = new DummyRazorFormattingService(); - var documentMappingService = new RazorDocumentMappingService(FilePathService, documentResolver, LoggerFactory); + var documentMappingService = new RazorDocumentMappingService(FilePathService, documentContextFactory, LoggerFactory); var optionsMonitor = GetOptionsMonitor(enableFormatting: true); var endpoint = new DocumentOnTypeFormattingEndpoint( @@ -207,8 +207,8 @@ public async Task Handle_OnTypeFormatting_UnexpectedTriggerCharacter_ReturnsNull Position = new Position(2, 11), Options = new FormattingOptions { InsertSpaces = true, TabSize = 4 } }; - var documentContext = documentResolver.TryCreateForOpenDocument(uri); - var requestContext = CreateRazorRequestContext(documentContext!); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); + var requestContext = CreateRazorRequestContext(documentContext); // Act var result = await endpoint.HandleRequestAsync(@params, requestContext, DisposalToken); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Implementation/ImplementationEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Implementation/ImplementationEndpointTest.cs index 44e12871a03..556b54a9dbf 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Implementation/ImplementationEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Implementation/ImplementationEndpointTest.cs @@ -107,7 +107,7 @@ private async Task VerifyCSharpGoToImplementationAsync(string input) }, Position = new Position(line, offset) }; - var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); + Assert.True(DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/InlayHints/InlayHintEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/InlayHints/InlayHintEndpointTest.cs index d3567565840..3dc9e041f34 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/InlayHints/InlayHintEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/InlayHints/InlayHintEndpointTest.cs @@ -112,7 +112,7 @@ private async Task VerifyInlayHintsAsync(string input, Dictionary Position = new Position(line, offset), NewName = newName }; - var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); + Assert.True(DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs index 7895732e57d..421eb965173 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs @@ -122,7 +122,7 @@ public async Task Handle_Rename_FileManipulationNotSupported_ReturnsNull() NewName = "Component5" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -145,7 +145,7 @@ public async Task Handle_Rename_WithNamespaceDirective() NewName = "Component5" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -186,7 +186,7 @@ public async Task Handle_Rename_OnComponentParameter_ReturnsNull() NewName = "Test2" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -209,7 +209,7 @@ public async Task Handle_Rename_OnOpeningBrace_ReturnsNull() NewName = "Test2" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -232,7 +232,7 @@ public async Task Handle_Rename_OnComponentNameLeadingEdge_ReturnsResult() NewName = "Test2" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -255,7 +255,7 @@ public async Task Handle_Rename_OnComponentName_ReturnsResult() NewName = "Test2" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -278,7 +278,7 @@ public async Task Handle_Rename_OnComponentNameTrailingEdge_ReturnsResult() NewName = "Test2" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -301,7 +301,7 @@ public async Task Handle_Rename_ComponentInSameFile() NewName = "Component5" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -387,7 +387,7 @@ public async Task Handle_Rename_FullyQualifiedAndNot() NewName = "Component5" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -433,7 +433,7 @@ public async Task Handle_Rename_MultipleFileUsages() NewName = "Component5" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -486,7 +486,7 @@ public async Task Handle_Rename_DifferentDirectories() NewName = "TestComponent" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -551,7 +551,7 @@ public async Task Handle_Rename_SingleServer_CallsDelegatedLanguageServer() NewName = "Test2" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act @@ -585,7 +585,7 @@ public async Task Handle_Rename_SingleServer_DoesNotDelegateForRazor() NewName = "Test2" }; - var documentContext = documentContextFactory.TryCreateForOpenDocument(request.TextDocument.Uri); + Assert.True(documentContextFactory.TryCreateForOpenDocument(request.TextDocument.Uri, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); // Act diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/SemanticTokensTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/SemanticTokensTest.cs index a566c7effe0..fe2d02b11ce 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/SemanticTokensTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/SemanticTokensTest.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; @@ -1201,9 +1202,14 @@ private static string GetFileRepresentationOfTokens(SourceText sourceText, int[] private class TestDocumentContextFactory(VersionedDocumentContext? documentContext = null) : IDocumentContextFactory { - public DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) + public bool TryCreate( + Uri documentUri, + VSProjectContext? projectContext, + bool versioned, + [NotNullWhen(true)] out DocumentContext? context) { - return documentContext; + context = documentContext; + return context is not null; } } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SignatureHelp/SignatureHelpEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SignatureHelp/SignatureHelpEndpointTest.cs index a04ee0e851e..e1d816083a6 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SignatureHelp/SignatureHelpEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SignatureHelp/SignatureHelpEndpointTest.cs @@ -115,7 +115,7 @@ private async Task VerifySignatureHelpWithContextAndOptionsAsync(string input, R Context = signatureHelpContext }; - var documentContext = DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument); + Assert.True(DocumentContextFactory.TryCreateForOpenDocument(request.TextDocument, out var documentContext)); var requestContext = CreateRazorRequestContext(documentContext); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/WrapWithTag/WrapWithTagEndpointTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/WrapWithTag/WrapWithTagEndpointTests.cs index ea1aaa2c47d..d7b3adbaac6 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/WrapWithTag/WrapWithTagEndpointTests.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/WrapWithTag/WrapWithTagEndpointTests.cs @@ -270,8 +270,7 @@ public async Task CleanUpTextEdits_NoTilde() var uri = new Uri("file://path.razor"); var factory = CreateDocumentContextFactory(uri, input); - var context = factory.TryCreate(uri); - Assert.NotNull(context); + Assert.True(factory.TryCreate(uri, out var context)); var inputSourceText = await context!.GetSourceTextAsync(DisposalToken); var computedEdits = new TextEdit[] @@ -320,8 +319,7 @@ public async Task CleanUpTextEdits_BadEditWithTilde() var uri = new Uri("file://path.razor"); var factory = CreateDocumentContextFactory(uri, input); - var context = factory.TryCreate(uri); - Assert.NotNull(context); + Assert.True(factory.TryCreate(uri, out var context)); var inputSourceText = await context!.GetSourceTextAsync(DisposalToken); var computedEdits = new TextEdit[] @@ -371,8 +369,7 @@ public async Task CleanUpTextEdits_GoodEditWithTilde() var uri = new Uri("file://path.razor"); var factory = CreateDocumentContextFactory(uri, input); - var context = factory.TryCreate(uri); - Assert.NotNull(context); + Assert.True(factory.TryCreate(uri, out var context)); var inputSourceText = await context!.GetSourceTextAsync(DisposalToken); var computedEdits = new TextEdit[] diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/TestDocumentContextFactory.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/TestDocumentContextFactory.cs index 66427228c74..591df7ed021 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/TestDocumentContextFactory.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/TestDocumentContextFactory.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Razor.Language; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -25,23 +26,31 @@ public TestDocumentContextFactory(string filePath, RazorCodeDocument codeDocumen _version = version; } - public virtual DocumentContext? TryCreate(Uri documentUri, VSProjectContext? projectContext, bool versioned) + public virtual bool TryCreate( + Uri documentUri, + VSProjectContext? projectContext, + bool versioned, + [NotNullWhen(true)] out DocumentContext? context) { if (FilePath is null || CodeDocument is null) { - return null; + context = null; + return false; } if (versioned) { if (_version is null) { - return null; + context = null; + return false; } - return TestDocumentContext.From(FilePath, CodeDocument, _version.Value); + context = TestDocumentContext.From(FilePath, CodeDocument, _version.Value); + return true; } - return TestDocumentContext.From(FilePath, CodeDocument); + context = TestDocumentContext.From(FilePath, CodeDocument); + return true; } } From 00b1ea3e32e0c7011797de4836874b90199b843c Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 29 Apr 2024 13:13:43 -0700 Subject: [PATCH 16/16] Rename method back to OnInitializedAsync --- .../RazorLanguageServerBenchmarkBase.cs | 2 +- .../ClientConnection.cs | 2 +- .../IOnInitialized.cs | 2 +- .../ProjectSystem/SnapshotResolver.cs | 2 +- .../RazorConfigurationEndpoint.cs | 2 +- .../RazorFileChangeDetectorManager.cs | 2 +- .../RazorInitializedEndpoint.cs | 2 +- .../DefaultRazorComponentSearchEngineTest.cs | 2 +- ...extDocumentUriPresentationEndpointTests.cs | 8 +++---- .../RazorFileChangeDetectorManagerTest.cs | 4 ++-- .../RazorProjectServiceTest.cs | 2 +- .../Refactoring/RenameEndpointTest.cs | 2 +- .../SnapshotResolverTest.cs | 24 +++++++++---------- 13 files changed, 28 insertions(+), 28 deletions(-) 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 046e7fcd9f3..50d6d8246f3 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs @@ -87,7 +87,7 @@ await projectManager.UpdateAsync( private class NoopClientNotifierService : IClientConnection, IOnInitialized { - public Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) + public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { return Task.CompletedTask; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs index 4f187bebae2..0a3c90a7b8f 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs @@ -48,7 +48,7 @@ public async Task SendNotificationAsync(string method, CancellationToken cancell /// /// Fires when the language server is set to "Started". /// - public Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) + public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { _initializedCompletionSource.TrySetResult(true); return Task.CompletedTask; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs index c4a96df9cfd..0dfd09f719d 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IOnInitialized.cs @@ -10,5 +10,5 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer; internal interface IOnInitialized { - Task InitializeAsync(ILspServices services, CancellationToken cancellationToken); + Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs index e7debc3328e..d5a86495af5 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs @@ -35,7 +35,7 @@ public SnapshotResolver(IProjectSnapshotManager projectManager, ILoggerFactory l MiscellaneousHostProject = new HostProject(normalizedPath, normalizedPath, FallbackRazorConfiguration.Latest, rootNamespace: null, "Miscellaneous Files"); } - public Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) + public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { // This is called when the language server is initialized. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs index ec50e8436ee..57e8793dd49 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationEndpoint.cs @@ -27,7 +27,7 @@ public async Task HandleNotificationAsync(DidChangeConfigurationParams request, await _optionsMonitor.UpdateAsync(cancellationToken).ConfigureAwait(false); } - public async Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) + public async Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { var capabilitiesService = services.GetRequiredService(); var clientCapabilities = capabilitiesService.ClientCapabilities; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs index d5f7894eaa7..17b727855b6 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorFileChangeDetectorManager.cs @@ -20,7 +20,7 @@ internal class RazorFileChangeDetectorManager( private readonly object _disposeLock = new(); private bool _disposed; - public async Task InitializeAsync(ILspServices services, CancellationToken cancellationToken) + public async Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken) { // Initialized request, this occurs once the server and client have agreed on what sort of features they both support. It only happens once. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs index 7a204c94677..277533d056c 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorInitializedEndpoint.cs @@ -22,7 +22,7 @@ public async Task HandleNotificationAsync(InitializedParams request, RazorReques foreach (var onStartedItem in onStartedItems) { - await onStartedItem.InitializeAsync(requestContext.LspServices, cancellationToken).ConfigureAwait(false); + await onStartedItem.OnInitializedAsync(requestContext.LspServices, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs index 653feacfdac..5f2491651f9 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DefaultRazorComponentSearchEngineTest.cs @@ -48,7 +48,7 @@ protected override async Task InitializeAsync() _projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(_projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var documentVersionCache = new DocumentVersionCache(_projectManager); var remoteTextLoaderFactoryMock = new StrictMock(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs index 6e4874fb0ee..657627b5d28 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/DocumentPresentation/TextDocumentUriPresentationEndpointTests.cs @@ -35,7 +35,7 @@ public async Task Handle_SimpleComponent_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); @@ -100,7 +100,7 @@ public async Task Handle_SimpleComponentWithChildFile_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); @@ -170,7 +170,7 @@ public async Task Handle_ComponentWithRequiredAttribute_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); @@ -402,7 +402,7 @@ public async Task Handle_ComponentWithNestedFiles_ReturnsResult() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var project = await projectManager.UpdateAsync(updater => updater.CreateAndAddProject("c:/path/project.csproj")); await projectManager.CreateAndAddDocumentAsync(project, "c:/path/index.razor"); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs index 1d74ee1fdad..91f017f679a 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorFileChangeDetectorManagerTest.cs @@ -60,7 +60,7 @@ public async Task InitializedAsync_StartsFileChangeDetectors() using (var detectorManager = new RazorFileChangeDetectorManager(workspaceDirectoryPathResolver, [detectorMock1.Object, detectorMock2.Object])) { // Act - await detectorManager.InitializeAsync(StrictMock.Of(), DisposalToken); + await detectorManager.OnInitializedAsync(StrictMock.Of(), DisposalToken); } // Assert @@ -98,7 +98,7 @@ public async Task InitializedAsync_Disposed_ReStopsFileChangeDetectors() using var detectorManager = new RazorFileChangeDetectorManager(workspaceDirectoryPathResolver, [detectorMock.Object]); // Act - var initializeTask = detectorManager.InitializeAsync(StrictMock.Of(), DisposalToken); + var initializeTask = detectorManager.OnInitializedAsync(StrictMock.Of(), DisposalToken); detectorManager.Dispose(); // Unblock the detector start 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 0bd59a7b828..1216ebf0b2e 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorProjectServiceTest.cs @@ -41,7 +41,7 @@ protected override async Task InitializeAsync() { _projectManager = CreateProjectSnapshotManager(); _snapshotResolver = new SnapshotResolver(_projectManager, LoggerFactory); - await _snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await _snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); _documentVersionCache = new DocumentVersionCache(_projectManager); var remoteTextLoaderFactoryMock = new StrictMock(); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs index 421eb965173..23f638c183d 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Refactoring/RenameEndpointTest.cs @@ -613,7 +613,7 @@ public async Task Handle_Rename_SingleServer_DoesNotDelegateForRazor() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var documentVersionCache = new DocumentVersionCache(projectManager); var documentContextFactory = new DocumentContextFactory(projectManager, snapshotResolver, documentVersionCache, LoggerFactory); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs index 009b19c0aa5..4bf6690db04 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/SnapshotResolverTest.cs @@ -40,7 +40,7 @@ public async Task TryResolveDocumentInAnyProject_AsksMiscellaneousProjectForDocu var normalizedFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); await projectManager.UpdateAsync(updater => { @@ -66,7 +66,7 @@ public async Task TryResolveDocumentInAnyProject_AsksPotentialParentProjectForDo var documentFilePath = @"C:\path\to\document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act Assert.False(snapshotResolver.TryResolveDocumentInAnyProject(documentFilePath, out var document)); @@ -82,7 +82,7 @@ public async Task TryResolveAllProjects_NoProjects_ReturnsFalse() var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act Assert.False(snapshotResolver.TryResolveAllProjects(documentFilePath, out _)); @@ -95,7 +95,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectDoesNotContainDo var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act Assert.False(snapshotResolver.TryResolveAllProjects(documentFilePath, out _)); @@ -107,7 +107,7 @@ public async Task TryResolveAllProjects_OnlyMiscellaneousProjectContainsDocument // Arrange var documentFilePath = Path.Combine(TempDirectory.Instance.DirectoryPath, "document.cshtml"); var snapshotResolver = await CreateSnapshotResolverAsync(documentFilePath, addToMiscellaneous: true); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act Assert.True(snapshotResolver.TryResolveAllProjects(documentFilePath, out var projects)); @@ -124,7 +124,7 @@ public async Task TryResolveAllProjects_UnrelatedProject_ReturnsFalse() var documentFilePath = "C:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); await projectManager.UpdateAsync(updater => { @@ -143,7 +143,7 @@ public async Task TryResolveAllProjects_OwnerProjectWithOthers_ReturnsTrue() var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var expectedProject = await projectManager.UpdateAsync(updater => { @@ -171,7 +171,7 @@ public async Task TryResolveAllProjects_MiscellaneousOwnerProjectWithOthers_Retu var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var miscProject = await projectManager.UpdateAsync(updater => { @@ -197,7 +197,7 @@ public async Task TryResolveAllProjects_OwnerProjectDifferentCasing_ReturnsTrue( var documentFilePath = "c:/path/to/document.cshtml"; var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); var ownerProject = await projectManager.UpdateAsync(updater => { @@ -221,7 +221,7 @@ public async Task GetMiscellaneousProject_ProjectLoaded_ReturnsExistingProject() // Arrange var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act var project = snapshotResolver.GetMiscellaneousProject(); @@ -237,7 +237,7 @@ public async Task GetMiscellaneousProject_ProjectNotLoaded_CreatesProjectAndRetu // Arrange var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); // Act var project = snapshotResolver.GetMiscellaneousProject(); @@ -253,7 +253,7 @@ private async Task CreateSnapshotResolverAsync(string filePath var projectManager = CreateProjectSnapshotManager(); var snapshotResolver = new SnapshotResolver(projectManager, LoggerFactory); - await snapshotResolver.InitializeAsync(StrictMock.Of(), DisposalToken); + await snapshotResolver.OnInitializedAsync(StrictMock.Of(), DisposalToken); if (addToMiscellaneous) {