Skip to content

Commit 0f56e69

Browse files
committed
Move down and interface-ize component search engine, and introduce IProjectCollectionResolver
1 parent 1764b62 commit 0f56e69

File tree

15 files changed

+110
-47
lines changed

15 files changed

+110
-47
lines changed

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ComponentAccessibilityCodeActionProvider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using Microsoft.AspNetCore.Razor.PooledObjects;
1717
using Microsoft.AspNetCore.Razor.Utilities;
1818
using Microsoft.CodeAnalysis.Razor;
19+
using Microsoft.CodeAnalysis.Razor.Workspaces;
1920
using Microsoft.VisualStudio.Editor.Razor;
2021
using Microsoft.VisualStudio.LanguageServer.Protocol;
2122

@@ -157,7 +158,7 @@ private static async Task AddComponentAccessFromTagAsync(RazorCodeActionContext
157158
{
158159
// if fqn contains a generic typeparam, we should strip it out. Otherwise, replacing tag name will leave generic parameters in razor code, which are illegal
159160
// e.g. <Component /> -> <Component<T> />
160-
var fullyQualifiedName = DefaultRazorComponentSearchEngine.RemoveGenericContent(tagHelperPair.Short.Name.AsMemory()).ToString();
161+
var fullyQualifiedName = RazorComponentSearchEngine.RemoveGenericContent(tagHelperPair.Short.Name.AsMemory()).ToString();
161162

162163
// If the match was case insensitive, then see if we can work out a new tag name to use as part of adding a using statement
163164
TextDocumentEdit? additionalEdit = null;

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Definition/DefinitionEndpoint.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Definition;
2929

3030
[RazorLanguageServerEndpoint(Methods.TextDocumentDefinitionName)]
3131
internal sealed class DefinitionEndpoint(
32-
RazorComponentSearchEngine componentSearchEngine,
32+
IRazorComponentSearchEngine componentSearchEngine,
3333
IRazorDocumentMappingService documentMappingService,
3434
LanguageServerFeatureOptions languageServerFeatureOptions,
3535
IClientConnection clientConnection,
3636
ILoggerFactory loggerFactory)
3737
: AbstractRazorDelegatingEndpoint<TextDocumentPositionParams, DefinitionResult?>(languageServerFeatureOptions, documentMappingService, clientConnection, loggerFactory.GetOrCreateLogger<DefinitionEndpoint>()), ICapabilitiesProvider
3838
{
39-
private readonly RazorComponentSearchEngine _componentSearchEngine = componentSearchEngine ?? throw new ArgumentNullException(nameof(componentSearchEngine));
39+
private readonly IRazorComponentSearchEngine _componentSearchEngine = componentSearchEngine ?? throw new ArgumentNullException(nameof(componentSearchEngine));
4040
private readonly IRazorDocumentMappingService _documentMappingService = documentMappingService ?? throw new ArgumentNullException(nameof(documentMappingService));
4141

4242
protected override bool PreferCSharpOverHtmlIfPossible => true;
@@ -73,7 +73,7 @@ public void ApplyCapabilities(VSInternalServerCapabilities serverCapabilities, V
7373
return default;
7474
}
7575

76-
var originComponentDocumentSnapshot = await _componentSearchEngine.TryLocateComponentAsync(originTagDescriptor).ConfigureAwait(false);
76+
var originComponentDocumentSnapshot = await _componentSearchEngine.TryLocateComponentAsync(documentContext.Snapshot, originTagDescriptor).ConfigureAwait(false);
7777
if (originComponentDocumentSnapshot is null)
7878
{
7979
Logger.LogInformation($"Origin TagHelper document snapshot is null.");

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ public static void AddDocumentManagementServices(this IServiceCollection service
226226
// Add project snapshot manager
227227
services.AddSingleton<IProjectEngineFactoryProvider, LspProjectEngineFactoryProvider>();
228228
services.AddSingleton<IProjectSnapshotManager, LspProjectSnapshotManager>();
229+
services.AddSingleton<IProjectCollectionResolver>(sp => (LspProjectSnapshotManager)sp.GetRequiredService<IProjectSnapshotManager>());
229230
}
230231

231232
public static void AddHandlerWithCapabilities<T>(this IServiceCollection services)

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/LspProjectSnapshotManager.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,22 @@
99
using Microsoft.AspNetCore.Razor.ProjectEngineHost;
1010
using Microsoft.CodeAnalysis.Razor.Logging;
1111
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
12+
using Microsoft.CodeAnalysis.Razor.Workspaces;
1213

1314
namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem;
1415

1516
internal class LspProjectSnapshotManager(
1617
IProjectEngineFactoryProvider projectEngineFactoryProvider,
1718
ILoggerFactory loggerFactory)
18-
: ProjectSnapshotManager(projectEngineFactoryProvider, loggerFactory, initializer: AddMiscFilesProject)
19+
: ProjectSnapshotManager(projectEngineFactoryProvider, loggerFactory, initializer: AddMiscFilesProject), IProjectCollectionResolver
1920
{
2021
private static void AddMiscFilesProject(Updater updater)
2122
{
2223
updater.ProjectAdded(MiscFilesHostProject.Instance);
2324
}
25+
26+
public IEnumerable<IProjectSnapshot> EnumerateProjects(IDocumentSnapshot snapshot)
27+
{
28+
return GetProjects();
29+
}
2430
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorLanguageServer.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,12 @@
2020
using Microsoft.AspNetCore.Razor.LanguageServer.LinkedEditingRange;
2121
using Microsoft.AspNetCore.Razor.LanguageServer.MapCode;
2222
using Microsoft.AspNetCore.Razor.LanguageServer.ProjectContexts;
23-
using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem;
2423
using Microsoft.AspNetCore.Razor.LanguageServer.Refactoring;
2524
using Microsoft.AspNetCore.Razor.LanguageServer.SignatureHelp;
2625
using Microsoft.AspNetCore.Razor.LanguageServer.WrapWithTag;
2726
using Microsoft.AspNetCore.Razor.Telemetry;
28-
using Microsoft.CodeAnalysis.Razor;
2927
using Microsoft.CodeAnalysis.Razor.FoldingRanges;
3028
using Microsoft.CodeAnalysis.Razor.Logging;
31-
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
3229
using Microsoft.CodeAnalysis.Razor.Workspaces;
3330
using Microsoft.CommonLanguageServerProtocol.Framework;
3431
using Microsoft.Extensions.DependencyInjection;
@@ -153,7 +150,7 @@ protected override ILspServices ConstructLspServices()
153150
}
154151

155152
// Other
156-
services.AddSingleton<RazorComponentSearchEngine, DefaultRazorComponentSearchEngine>();
153+
services.AddSingleton<IRazorComponentSearchEngine, RazorComponentSearchEngine>();
157154

158155
// Get the DefaultSession for telemetry. This is set by VS with
159156
// TelemetryService.SetDefaultSession and provides the correct

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Refactoring/RenameEndpoint.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Refactoring;
2727

2828
[RazorLanguageServerEndpoint(Methods.TextDocumentRenameName)]
2929
internal sealed class RenameEndpoint(
30-
RazorComponentSearchEngine componentSearchEngine,
31-
IProjectSnapshotManager projectManager,
30+
IRazorComponentSearchEngine componentSearchEngine,
31+
IProjectCollectionResolver projectResolver,
3232
LanguageServerFeatureOptions languageServerFeatureOptions,
3333
IRazorDocumentMappingService documentMappingService,
3434
IClientConnection clientConnection,
@@ -39,8 +39,8 @@ internal sealed class RenameEndpoint(
3939
clientConnection,
4040
loggerFactory.GetOrCreateLogger<RenameEndpoint>()), ICapabilitiesProvider
4141
{
42-
private readonly IProjectSnapshotManager _projectManager = projectManager;
43-
private readonly RazorComponentSearchEngine _componentSearchEngine = componentSearchEngine;
42+
private readonly IProjectCollectionResolver _projectResolver = projectResolver;
43+
private readonly IRazorComponentSearchEngine _componentSearchEngine = componentSearchEngine;
4444
private readonly LanguageServerFeatureOptions _languageServerFeatureOptions = languageServerFeatureOptions;
4545
private readonly IRazorDocumentMappingService _documentMappingService = documentMappingService;
4646

@@ -117,7 +117,7 @@ protected override bool IsSupported()
117117
return null;
118118
}
119119

120-
var originComponentDocumentSnapshot = await _componentSearchEngine.TryLocateComponentAsync(originTagHelpers.First()).ConfigureAwait(false);
120+
var originComponentDocumentSnapshot = await _componentSearchEngine.TryLocateComponentAsync(documentContext.Snapshot, originTagHelpers.First()).ConfigureAwait(false);
121121
if (originComponentDocumentSnapshot is null)
122122
{
123123
return null;
@@ -162,7 +162,7 @@ protected override bool IsSupported()
162162
using var documentSnapshots = new PooledArrayBuilder<IDocumentSnapshot?>();
163163
using var _ = StringHashSetPool.GetPooledObject(out var documentPaths);
164164

165-
var projects = _projectManager.GetProjects();
165+
var projects = _projectResolver.EnumerateProjects(skipDocumentContext.Snapshot);
166166

167167
foreach (var project in projects)
168168
{
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT license. See License.txt in the project root for license information.
3+
4+
using System.Collections.Generic;
5+
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
6+
7+
namespace Microsoft.CodeAnalysis.Razor.Workspaces;
8+
9+
internal interface IProjectCollectionResolver
10+
{
11+
IEnumerable<IProjectSnapshot> EnumerateProjects(IDocumentSnapshot snapshot);
12+
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorComponentSearchEngine.cs renamed to src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/IRazorComponentSearchEngine.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
using Microsoft.AspNetCore.Razor.Language;
66
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
77

8-
namespace Microsoft.AspNetCore.Razor.LanguageServer;
8+
namespace Microsoft.CodeAnalysis.Razor.Workspaces;
99

10-
internal abstract class RazorComponentSearchEngine
10+
internal interface IRazorComponentSearchEngine
1111
{
12-
public abstract Task<IDocumentSnapshot?> TryLocateComponentAsync(TagHelperDescriptor tagHelper);
12+
Task<IDocumentSnapshot?> TryLocateComponentAsync(IDocumentSnapshot contextSnapshot, TagHelperDescriptor tagHelper);
1313
}
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
using Microsoft.CodeAnalysis.Razor.Logging;
88
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
99

10-
namespace Microsoft.AspNetCore.Razor.LanguageServer;
10+
namespace Microsoft.CodeAnalysis.Razor.Workspaces;
1111

12-
internal class DefaultRazorComponentSearchEngine(
13-
IProjectSnapshotManager projectManager,
12+
internal class RazorComponentSearchEngine(
13+
IProjectCollectionResolver projectCollectionResolver,
1414
ILoggerFactory loggerFactory)
15-
: RazorComponentSearchEngine
15+
: IRazorComponentSearchEngine
1616
{
17-
private readonly IProjectSnapshotManager _projectManager = projectManager;
18-
private readonly ILogger _logger = loggerFactory.GetOrCreateLogger<DefaultRazorComponentSearchEngine>();
17+
private readonly IProjectCollectionResolver _projectResolver = projectCollectionResolver;
18+
private readonly ILogger _logger = loggerFactory.GetOrCreateLogger<RazorComponentSearchEngine>();
1919

2020
/// <summary>Search for a component in a project based on its tag name and fully qualified name.</summary>
2121
/// <remarks>
@@ -24,10 +24,11 @@ internal class DefaultRazorComponentSearchEngine(
2424
/// component is present in has the same name as the assembly its corresponding tag helper is loaded from.
2525
/// Implicitly, this method inherits any assumptions made by TrySplitNamespaceAndType.
2626
/// </remarks>
27+
/// <param name="contextSnapshot">A document snapshot that provides context to enumerate project snapshots</param>
2728
/// <param name="tagHelper">A TagHelperDescriptor to find the corresponding Razor component for.</param>
2829
/// <returns>The corresponding DocumentSnapshot if found, null otherwise.</returns>
2930
/// <exception cref="ArgumentNullException">Thrown if <paramref name="tagHelper"/> is null.</exception>
30-
public override async Task<IDocumentSnapshot?> TryLocateComponentAsync(TagHelperDescriptor tagHelper)
31+
public async Task<IDocumentSnapshot?> TryLocateComponentAsync(IDocumentSnapshot contextSnapshot, TagHelperDescriptor tagHelper)
3132
{
3233
if (tagHelper is null)
3334
{
@@ -44,7 +45,7 @@ internal class DefaultRazorComponentSearchEngine(
4445

4546
var lookupSymbolName = RemoveGenericContent(typeName.AsMemory());
4647

47-
var projects = _projectManager.GetProjects();
48+
var projects = _projectResolver.EnumerateProjects(contextSnapshot);
4849

4950
foreach (var project in projects)
5051
{
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT license. See License.txt in the project root for license information.
3+
4+
using System.Collections.Generic;
5+
using System.Composition;
6+
using System.Diagnostics;
7+
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
8+
using Microsoft.CodeAnalysis.Razor.Workspaces;
9+
10+
namespace Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
11+
12+
[Export(typeof(IProjectCollectionResolver)), Shared]
13+
[method: ImportingConstructor]
14+
internal class RemoteProjectCollectionResolver(ProjectSnapshotFactory projectSnapshotFactory) : IProjectCollectionResolver
15+
{
16+
public IEnumerable<IProjectSnapshot> EnumerateProjects(IDocumentSnapshot snapshot)
17+
{
18+
Debug.Assert(snapshot is RemoteDocumentSnapshot);
19+
20+
var projects = ((RemoteDocumentSnapshot)snapshot).TextDocument.Project.Solution.Projects;
21+
22+
foreach (var project in projects)
23+
{
24+
yield return projectSnapshotFactory.GetOrCreate(project);
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)