From 58e380d38ab704f74e785866a8b64df61cb344db Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 15 Mar 2024 10:06:56 +1100 Subject: [PATCH] Remove and ban MEF in LanguageServer project --- .../Cohost/CohostDocumentContextFactory.cs | 33 ---- .../Cohost/CohostDocumentSnapshot.cs | 78 -------- .../Cohost/CohostProjectSnapshot.cs | 169 ------------------ .../Cohost/DocumentSnapshotFactory.cs | 31 ---- .../Cohost/ProjectSnapshotFactory.cs | 30 ---- .../Common/DefaultRemoteTextLoaderFactory.cs | 3 - .../DocumentColor/DocumentColorService.cs | 3 - .../DocumentContextFactory.cs | 3 - .../DocumentVersionCache.cs | 6 - ...oft.AspNetCore.Razor.LanguageServer.csproj | 6 + .../ProjectSystem/RazorProjectService.cs | 3 - .../ProjectSystem/SnapshotResolver.cs | 3 - .../DefaultLSPTagHelperTooltipFactory.cs | 3 - .../DefaultVSLSPTagHelperTooltipFactory.cs | 3 - .../AbstractCohostDelegatingEndpoint.cs | 138 -------------- .../RazorCohostRequestContextExtensions.cs | 23 --- .../source.extension.vsixmanifest | 1 - 17 files changed, 6 insertions(+), 530 deletions(-) delete mode 100644 src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostDocumentContextFactory.cs delete mode 100644 src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostDocumentSnapshot.cs delete mode 100644 src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostProjectSnapshot.cs delete mode 100644 src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/DocumentSnapshotFactory.cs delete mode 100644 src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/ProjectSnapshotFactory.cs delete mode 100644 src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/Cohost/AbstractCohostDelegatingEndpoint.cs delete mode 100644 src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/Cohost/RazorCohostRequestContextExtensions.cs diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostDocumentContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostDocumentContextFactory.cs deleted file mode 100644 index 4b0ee9390ec..00000000000 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostDocumentContextFactory.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT license. See License.txt in the project root for license information. - -using System; -using System.Composition; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost; -using Microsoft.CodeAnalysis.Razor.ProjectSystem; - -namespace Microsoft.AspNetCore.Razor.LanguageServer.Cohost; - -// NOTE: This is not a "normal" MEF export (ie, exporting an interface) purely because of a strange desire to keep API in -// RazorCohostRequestContextExtensions looking like the previous code in the non-cohost world. -[Shared] -[ExportRazorStatelessLspService(typeof(CohostDocumentContextFactory))] -[method: ImportingConstructor] -internal class CohostDocumentContextFactory(DocumentSnapshotFactory documentSnapshotFactory, IDocumentVersionCache documentVersionCache) : AbstractRazorLspService -{ - private readonly DocumentSnapshotFactory _documentSnapshotFactory = documentSnapshotFactory; - private readonly IDocumentVersionCache _documentVersionCache = documentVersionCache; - - public VersionedDocumentContext Create(Uri documentUri, TextDocument textDocument) - { - var documentSnapshot = _documentSnapshotFactory.GetOrCreate(textDocument); - - // HACK: For cohosting, we just grab the "current" version, because we know it will have been updated - // since the change handling is synchronous. In future we can just remove the whole concept of - // document versions because TextDocument is inherently versioned. - var version = _documentVersionCache.GetLatestDocumentVersion(documentSnapshot.FilePath.AssumeNotNull()); - - return new VersionedDocumentContext(documentUri, documentSnapshot, null, version); - } -} diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostDocumentSnapshot.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostDocumentSnapshot.cs deleted file mode 100644 index 2d11e2ddd8d..00000000000 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostDocumentSnapshot.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT license. See License.txt in the project root for license information. - -using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor.Language; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor.ProjectSystem; -using Microsoft.CodeAnalysis.Text; - -namespace Microsoft.AspNetCore.Razor.LanguageServer.Cohost; - -internal class CohostDocumentSnapshot(TextDocument textDocument, CohostProjectSnapshot projectSnapshot) : IDocumentSnapshot -{ - private readonly TextDocument _textDocument = textDocument; - private readonly CohostProjectSnapshot _projectSnapshot = projectSnapshot; - - private RazorCodeDocument? _codeDocument; - - public string? FileKind => FileKinds.GetFileKindFromFilePath(FilePath); - - public string? FilePath => _textDocument.FilePath; - - public string? TargetPath => _textDocument.FilePath; - - public IProjectSnapshot Project => _projectSnapshot; - - public bool SupportsOutput => true; - - public Task GetTextAsync() => _textDocument.GetTextAsync(); - - public Task GetTextVersionAsync() => _textDocument.GetTextVersionAsync(); - - public bool TryGetText([NotNullWhen(true)] out SourceText? result) => _textDocument.TryGetText(out result); - - public bool TryGetTextVersion(out VersionStamp result) => _textDocument.TryGetTextVersion(out result); - - public async Task GetGeneratedOutputAsync() - { - // TODO: We don't need to worry about locking if we get called from the didOpen/didChange LSP requests, as CLaSP - // takes care of that for us, and blocks requests until those are complete. If that doesn't end up happening, - // then a locking mechanism here would prevent concurrent compilations. - if (_codeDocument is not null) - { - return _codeDocument; - } - - // The non-cohosted DocumentSnapshot implementation uses DocumentState to get the generated output, and we could do that too - // but most of that code is optimized around caching pre-computed results when things change that don't affect the compilation. - // We can't do that here because we are using Roslyn's project snapshots, which don't contain the info that Razor needs. We could - // in future provide a side-car mechanism so we can cache things, but still take advantage of snapshots etc. but the working - // assumption for this code is that the source generator will be used, and it will do all of that, so this implementation is naive - // and simply compiles when asked, and if a new document snapshot comes in, we compile again. This is presumably worse for perf - // but since we don't expect users to ever use cohosting without source generators, it's fine for now. - - var projectEngine = _projectSnapshot.GetProjectEngine_CohostOnly(); - var tagHelpers = await _projectSnapshot.GetTagHelpersAsync(CancellationToken.None).ConfigureAwait(false); - var imports = await DocumentState.ComputedStateTracker.GetImportsAsync(this, projectEngine).ConfigureAwait(false); - _codeDocument = await DocumentState.ComputedStateTracker.GenerateCodeDocumentAsync(tagHelpers, projectEngine, this, imports).ConfigureAwait(false); - - return _codeDocument; - } - - public bool TryGetGeneratedOutput([NotNullWhen(true)] out RazorCodeDocument? result) - { - result = _codeDocument; - return result is not null; - } - - public IDocumentSnapshot WithText(SourceText text) - { - var id = _textDocument.Id; - var newDocument = _textDocument.Project.Solution.WithAdditionalDocumentText(id, text).GetAdditionalDocument(id).AssumeNotNull(); - - return new CohostDocumentSnapshot(newDocument, _projectSnapshot); - } -} diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostProjectSnapshot.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostProjectSnapshot.cs deleted file mode 100644 index 2aaac66ad45..00000000000 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/CohostProjectSnapshot.cs +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT license. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor.Language; -using Microsoft.AspNetCore.Razor.PooledObjects; -using Microsoft.AspNetCore.Razor.ProjectEngineHost; -using Microsoft.AspNetCore.Razor.ProjectSystem; -using Microsoft.AspNetCore.Razor.Telemetry; -using Microsoft.AspNetCore.Razor.Utilities; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.ProjectSystem; - -namespace Microsoft.AspNetCore.Razor.LanguageServer.Cohost; - -internal class CohostProjectSnapshot : IProjectSnapshot -{ - private readonly Project _project; - private readonly DocumentSnapshotFactory _documentSnapshotFactory; - private readonly ITelemetryReporter _telemetryReporter; - private readonly ProjectKey _projectKey; - private readonly Lazy _lazyConfiguration; - private readonly Lazy _lazyProjectEngine; - private readonly Lazy>> _importsToRelatedDocumentsLazy; - - private ImmutableArray? _tagHelpers; - - public CohostProjectSnapshot(Project project, DocumentSnapshotFactory documentSnapshotFactory, ITelemetryReporter telemetryReporter) - { - _project = project; - _documentSnapshotFactory = documentSnapshotFactory; - _telemetryReporter = telemetryReporter; - _projectKey = ProjectKey.From(_project).AssumeNotNull(); - - _lazyConfiguration = new Lazy(CreateRazorConfiguration); - _lazyProjectEngine = new Lazy(() => - { - return ProjectEngineFactories.DefaultProvider.Create( - _lazyConfiguration.Value, - rootDirectoryPath: Path.GetDirectoryName(FilePath).AssumeNotNull(), - configure: builder => - { - builder.SetRootNamespace(RootNamespace); - builder.SetCSharpLanguageVersion(CSharpLanguageVersion); - builder.SetSupportLocalizedComponentNames(); - }); - }); - - _importsToRelatedDocumentsLazy = new Lazy>>(() => - { - var importsToRelatedDocuments = ImmutableDictionary.Create>(FilePathNormalizingComparer.Instance); - foreach (var document in DocumentFilePaths) - { - var importTargetPaths = ProjectState.GetImportDocumentTargetPaths(document, FileKinds.GetFileKindFromFilePath(document), _lazyProjectEngine.Value); - importsToRelatedDocuments = ProjectState.AddToImportsToRelatedDocuments(importsToRelatedDocuments, document, importTargetPaths); - } - - return importsToRelatedDocuments; - }); - } - - public ProjectKey Key => _projectKey; - - public RazorConfiguration Configuration => throw new InvalidOperationException("Should not be called for cohosted projects."); - - public IEnumerable DocumentFilePaths - => _project.AdditionalDocuments - .Where(d => d.FilePath!.EndsWith(".razor", StringComparison.OrdinalIgnoreCase) || d.FilePath.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase)) - .Select(d => d.FilePath.AssumeNotNull()); - - public string FilePath => _project.FilePath!; - - public string IntermediateOutputPath => FilePathNormalizer.GetNormalizedDirectoryName(_project.CompilationOutputInfo.AssemblyPath); - - public string? RootNamespace => _project.DefaultNamespace ?? "ASP"; - - public string DisplayName => _project.Name; - - public VersionStamp Version => _project.Version; - - public LanguageVersion CSharpLanguageVersion => ((CSharpParseOptions)_project.ParseOptions!).LanguageVersion; - - public async ValueTask> GetTagHelpersAsync(CancellationToken cancellationToken) - { - if (_tagHelpers is null) - { - var resolver = new CompilationTagHelperResolver(_telemetryReporter); - _tagHelpers = await resolver.GetTagHelpersAsync(_project, _lazyProjectEngine.Value, cancellationToken).ConfigureAwait(false); - } - - return _tagHelpers.GetValueOrDefault(); - } - - public ProjectWorkspaceState ProjectWorkspaceState => throw new InvalidOperationException("Should not be called for cohosted projects."); - - public IDocumentSnapshot? GetDocument(string filePath) - { - var textDocument = _project.AdditionalDocuments.FirstOrDefault(d => d.FilePath == filePath); - if (textDocument is null) - { - return null; - } - - return _documentSnapshotFactory.GetOrCreate(textDocument); - } - - public RazorProjectEngine GetProjectEngine() => throw new InvalidOperationException("Should not be called for cohosted projects."); - - /// - /// NOTE: To be called only from CohostDocumentSnapshot.GetGeneratedOutputAsync(). Will be removed when that method uses the source generator directly. - /// - /// - internal RazorProjectEngine GetProjectEngine_CohostOnly() => _lazyProjectEngine.Value; - - public ImmutableArray GetRelatedDocuments(IDocumentSnapshot document) - { - var targetPath = document.TargetPath.AssumeNotNull(); - - if (!_importsToRelatedDocumentsLazy.Value.TryGetValue(targetPath, out var relatedDocuments)) - { - return ImmutableArray.Empty; - } - - using var _ = ArrayBuilderPool.GetPooledObject(out var builder); - builder.SetCapacityIfLarger(relatedDocuments.Length); - - foreach (var relatedDocumentFilePath in relatedDocuments) - { - if (GetDocument(relatedDocumentFilePath) is { } relatedDocument) - { - builder.Add(relatedDocument); - } - } - - return builder.ToImmutableArray(); - } - - public bool IsImportDocument(IDocumentSnapshot document) - { - return document.TargetPath is { } targetPath && _importsToRelatedDocumentsLazy.Value.ContainsKey(targetPath); - } - - private RazorConfiguration CreateRazorConfiguration() - { - // See RazorSourceGenerator.RazorProviders.cs - - var globalOptions = _project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GlobalOptions; - - globalOptions.TryGetValue("build_property.RazorConfiguration", out var configurationName); - - configurationName ??= "MVC-3.0"; // TODO: Source generator uses "default" here?? - - if (!globalOptions.TryGetValue("build_property.RazorLangVersion", out var razorLanguageVersionString) || - !RazorLanguageVersion.TryParse(razorLanguageVersionString, out var razorLanguageVersion)) - { - razorLanguageVersion = RazorLanguageVersion.Latest; - } - - return new(razorLanguageVersion, configurationName, Extensions: [], UseConsolidatedMvcViews: true); - } -} diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/DocumentSnapshotFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/DocumentSnapshotFactory.cs deleted file mode 100644 index 0d7c4cb7681..00000000000 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/DocumentSnapshotFactory.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT license. See License.txt in the project root for license information. - -using System; -using System.Composition; -using System.Runtime.CompilerServices; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor.ProjectSystem; - -namespace Microsoft.AspNetCore.Razor.LanguageServer.Cohost; - -[Export(typeof(DocumentSnapshotFactory)), Shared] -[method: ImportingConstructor] -internal class DocumentSnapshotFactory(Lazy projectSnapshotFactory) -{ - private static readonly ConditionalWeakTable _documentSnapshots = new(); - - private readonly Lazy _projectSnapshotFactory = projectSnapshotFactory; - - public IDocumentSnapshot GetOrCreate(TextDocument textDocument) - { - if (!_documentSnapshots.TryGetValue(textDocument, out var documentSnapshot)) - { - var projectSnapshot = _projectSnapshotFactory.Value.GetOrCreate(textDocument.Project); - documentSnapshot = new CohostDocumentSnapshot(textDocument, projectSnapshot); - _documentSnapshots.Add(textDocument, documentSnapshot); - } - - return documentSnapshot; - } -} diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/ProjectSnapshotFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/ProjectSnapshotFactory.cs deleted file mode 100644 index 7360058f3d3..00000000000 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Cohost/ProjectSnapshotFactory.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT license. See License.txt in the project root for license information. - -using System.Composition; -using System.Runtime.CompilerServices; -using Microsoft.AspNetCore.Razor.Telemetry; -using Microsoft.CodeAnalysis; - -namespace Microsoft.AspNetCore.Razor.LanguageServer.Cohost; - -[Export(typeof(ProjectSnapshotFactory)), Shared] -[method: ImportingConstructor] -internal class ProjectSnapshotFactory(DocumentSnapshotFactory documentSnapshotFactory, ITelemetryReporter telemetryReporter) -{ - private static readonly ConditionalWeakTable _projectSnapshots = new(); - - private readonly DocumentSnapshotFactory _documentSnapshotFactory = documentSnapshotFactory; - private readonly ITelemetryReporter _telemetryReporter = telemetryReporter; - - public CohostProjectSnapshot GetOrCreate(Project project) - { - if (!_projectSnapshots.TryGetValue(project, out var projectSnapshot)) - { - projectSnapshot = new CohostProjectSnapshot(project, _documentSnapshotFactory, _telemetryReporter); - _projectSnapshots.Add(project, projectSnapshot); - } - - return projectSnapshot; - } -} diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Common/DefaultRemoteTextLoaderFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Common/DefaultRemoteTextLoaderFactory.cs index 8dcebeeb225..520d2cc70a2 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Common/DefaultRemoteTextLoaderFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Common/DefaultRemoteTextLoaderFactory.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; -using System.Composition; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -12,8 +11,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common; -[Export(typeof(RemoteTextLoaderFactory)), Shared] -[method: ImportingConstructor] internal class DefaultRemoteTextLoaderFactory() : RemoteTextLoaderFactory { public override TextLoader Create(string filePath) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentColor/DocumentColorService.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentColor/DocumentColorService.cs index 0d29cb7938a..4681877c0c9 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentColor/DocumentColorService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentColor/DocumentColorService.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. -using System.Composition; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.Common; @@ -10,8 +9,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.DocumentColor; -[Export(typeof(IDocumentColorService)), Shared] -[method: ImportingConstructor] internal sealed class DocumentColorService() : IDocumentColorService { public async Task GetColorInformationAsync(IClientConnection clientConnection, DocumentColorParams request, VersionedDocumentContext? documentContext, CancellationToken cancellationToken) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs index 67fa7248060..9c603951971 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentContextFactory.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; -using System.Composition; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; @@ -16,8 +15,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer; -[Export(typeof(IDocumentContextFactory)), Shared] -[method: ImportingConstructor] internal sealed class DocumentContextFactory( IProjectSnapshotManager projectManager, ISnapshotResolver snapshotResolver, diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentVersionCache.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentVersionCache.cs index ecc9f26197e..b92fc2a926e 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentVersionCache.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DocumentVersionCache.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Composition; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.Razor; @@ -12,10 +11,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer; -// TODO: This has to be Shared for MEF to work, but this service was written assuming its lifetime was that of the language -// server, so it doesn't clean up after itself well. In the long run, this hopefully won't matter, as we can remove it -// but leaving this note here because you never know. -[Export(typeof(IDocumentVersionCache)), Shared] internal sealed partial class DocumentVersionCache : IDocumentVersionCache, IRazorStartupService { internal const int MaxDocumentTrackingCount = 20; @@ -24,7 +19,6 @@ internal sealed partial class DocumentVersionCache : IDocumentVersionCache, IRaz private readonly ReadWriterLocker _lock = new(); private readonly IProjectSnapshotManager _projectManager; - [ImportingConstructor] public DocumentVersionCache(IProjectSnapshotManager projectManager) { _projectManager = projectManager; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj index 4b2c2a691eb..413d61de44d 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj @@ -12,6 +12,12 @@ + + + + + + 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 8a63ec068f3..c9280a35517 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Immutable; -using System.Composition; using System.Diagnostics; using System.IO; using System.Linq; @@ -24,8 +23,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; -[Export(typeof(IRazorProjectService)), Shared] -[method: ImportingConstructor] internal class RazorProjectService( ProjectSnapshotManagerDispatcher dispatcher, RemoteTextLoaderFactory remoteTextLoaderFactory, 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 c1af210b963..54899d5747c 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/SnapshotResolver.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Composition; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; @@ -15,7 +14,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem; -[Export(typeof(ISnapshotResolver)), Shared] internal sealed class SnapshotResolver : ISnapshotResolver { private readonly ProjectSnapshotManagerBase _projectManager; @@ -24,7 +22,6 @@ internal sealed class SnapshotResolver : ISnapshotResolver // Internal for testing internal readonly HostProject MiscellaneousHostProject; - [ImportingConstructor] public SnapshotResolver(ProjectSnapshotManagerBase projectManager, IRazorLoggerFactory loggerFactory) { _projectManager = projectManager; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/DefaultLSPTagHelperTooltipFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/DefaultLSPTagHelperTooltipFactory.cs index b0a986ef625..4d5591efec9 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/DefaultLSPTagHelperTooltipFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/DefaultLSPTagHelperTooltipFactory.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; -using System.Composition; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; @@ -15,8 +14,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Tooltip; -[Export(typeof(LSPTagHelperTooltipFactory)), Shared] -[method: ImportingConstructor] internal class DefaultLSPTagHelperTooltipFactory(ISnapshotResolver snapshotResolver) : LSPTagHelperTooltipFactory(snapshotResolver) { public override async Task TryCreateTooltipAsync( diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/DefaultVSLSPTagHelperTooltipFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/DefaultVSLSPTagHelperTooltipFactory.cs index 26e67c8710a..45e42282d94 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/DefaultVSLSPTagHelperTooltipFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Tooltip/DefaultVSLSPTagHelperTooltipFactory.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Composition; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; @@ -18,8 +17,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Tooltip; -[Export(typeof(VSLSPTagHelperTooltipFactory)), Shared] -[method: ImportingConstructor] internal class DefaultVSLSPTagHelperTooltipFactory(ISnapshotResolver snapshotResolver) : VSLSPTagHelperTooltipFactory(snapshotResolver) { private static readonly Guid s_imageCatalogGuid = new("{ae27a6b0-e345-4288-96df-5eaf394ee369}"); diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/Cohost/AbstractCohostDelegatingEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/Cohost/AbstractCohostDelegatingEndpoint.cs deleted file mode 100644 index 8f1ac1b0e70..00000000000 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/Cohost/AbstractCohostDelegatingEndpoint.cs +++ /dev/null @@ -1,138 +0,0 @@ -// 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.AspNetCore.Razor.LanguageServer; -using Microsoft.AspNetCore.Razor.LanguageServer.Common; -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; -using Microsoft.CodeAnalysis.Razor.Workspaces.Protocol; -using Microsoft.Extensions.Logging; -using Microsoft.VisualStudio.LanguageServer.Protocol; -using Microsoft.VisualStudio.LanguageServerClient.Razor.Extensions; - -namespace Microsoft.VisualStudio.LanguageServerClient.Razor.Cohost; - -internal abstract class AbstractCohostDelegatingEndpoint : AbstractRazorCohostDocumentRequestHandler - where TRequest : ITextDocumentPositionParams -{ - private readonly IRazorDocumentMappingService _documentMappingService; - protected readonly ILogger Logger; - - protected AbstractCohostDelegatingEndpoint( - IRazorDocumentMappingService documentMappingService, - ILogger logger) - { - _documentMappingService = documentMappingService; - - Logger = logger; - } - - /// - /// The strategy to use to project the incoming caret position onto the generated C#/Html document - /// - protected virtual IDocumentPositionInfoStrategy DocumentPositionInfoStrategy { get; } = DefaultDocumentPositionInfoStrategy.Instance; - - /// - /// When , we'll try to map the cursor position to C# even when it is in a Html context, for example - /// for component attributes that are fully within a Html context, but map to a C# property write in the generated document. - /// - protected virtual bool PreferCSharpOverHtmlIfPossible { get; } = false; - - /// - /// The name of the endpoint to delegate to, from . This is the - /// custom endpoint that is sent via which returns - /// a response by delegating to C#/HTML. - /// - /// - /// An example is - /// - protected abstract string CustomMessageTarget { get; } - - protected override bool MutatesSolutionState { get; } = false; - - protected override RazorTextDocumentIdentifier? GetRazorTextDocumentIdentifier(TRequest request) - => request.TextDocument.ToRazorTextDocumentIdentifier(); - - /// - /// The delegated object to send to the - /// - protected abstract Task CreateDelegatedParamsAsync(TRequest request, RazorCohostRequestContext requestContext, DocumentPositionInfo positionInfo, CancellationToken cancellationToken); - - /// - /// If the response needs to be handled, such as for remapping positions back, override and handle here - /// - protected virtual Task HandleDelegatedResponseAsync(TResponse delegatedResponse, TRequest originalRequest, RazorCohostRequestContext requestContext, DocumentPositionInfo positionInfo, CancellationToken cancellationToken) - => Task.FromResult(delegatedResponse); - - /// - /// If the request can be handled without delegation, override this to provide a response. If a null - /// value is returned the request will be delegated to C#/HTML servers, otherwise the response - /// will be used in - /// - protected virtual Task TryHandleAsync(TRequest request, RazorCohostRequestContext requestContext, DocumentPositionInfo positionInfo, CancellationToken cancellationToken) - => Task.FromResult(default); - - /// - /// Implementation for - /// - protected override async Task HandleRequestAsync(TRequest request, RazorCohostRequestContext requestContext, CancellationToken cancellationToken) - { - var documentContext = requestContext.GetRequiredDocumentContext(); - if (documentContext is null) - { - return default; - } - - var positionInfo = await DocumentPositionInfoStrategy.TryGetPositionInfoAsync(_documentMappingService, documentContext, request.Position, Logger, cancellationToken).ConfigureAwait(false); - if (positionInfo is null) - { - return default; - } - - var response = await TryHandleAsync(request, requestContext, positionInfo, cancellationToken).ConfigureAwait(false); - if (response is not null && response is not ISumType { Value: null }) - { - return response; - } - - if (positionInfo.LanguageKind == RazorLanguageKind.Razor) - { - // We can only delegate to C# and HTML, so if we're in a Razor context and our inheritor didn't want to provide - // any response then that's all we can do. - return default; - } - else if (positionInfo.LanguageKind == RazorLanguageKind.Html && PreferCSharpOverHtmlIfPossible) - { - // Sometimes Html can actually be mapped to C#, like for example component attributes, which map to - // C# properties, even though they appear entirely in a Html context. Since remapping is pretty cheap - // it's easier to just try mapping, and see what happens, rather than checking for specific syntax nodes. - var codeDocument = await documentContext.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false); - if (_documentMappingService.TryMapToGeneratedDocumentPosition(codeDocument.GetCSharpDocument(), positionInfo.HostDocumentIndex, out Position? csharpPosition, out _)) - { - // We're just gonna pretend this mapped perfectly normally onto C#. Moving this logic to the actual position info - // calculating code is possible, but could have untold effects, so opt-in is better (for now?) - positionInfo = new DocumentPositionInfo(RazorLanguageKind.CSharp, csharpPosition, positionInfo.HostDocumentIndex); - } - } - - var delegatedParams = await CreateDelegatedParamsAsync(request, requestContext, positionInfo, cancellationToken).ConfigureAwait(false); - - if (delegatedParams is null) - { - // I guess they don't want to delegate... fine then! - return default; - } - - var delegatedResponse = await requestContext.DelegateRequestAsync(CustomMessageTarget, delegatedParams, Logger, cancellationToken).ConfigureAwait(false); - if (delegatedResponse is null) - { - return default; - } - - var remappedResponse = await HandleDelegatedResponseAsync(delegatedResponse, request, requestContext, positionInfo, cancellationToken).ConfigureAwait(false); - return remappedResponse; - } -} diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/Cohost/RazorCohostRequestContextExtensions.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/Cohost/RazorCohostRequestContextExtensions.cs deleted file mode 100644 index d2b6ede51e8..00000000000 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/Cohost/RazorCohostRequestContextExtensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT license. See License.txt in the project root for license information. - -using Microsoft.AspNetCore.Razor; -using Microsoft.AspNetCore.Razor.LanguageServer.Cohost; -using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts; -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost; -using Microsoft.CodeAnalysis.Razor.ProjectSystem; - -namespace Microsoft.VisualStudio.LanguageServerClient.Razor.Cohost; - -internal static class RazorCohostRequestContextExtensions -{ - /// - /// Simple method to allow cohosted endpoints to get a document context that is API compatible with - /// - public static VersionedDocumentContext GetRequiredDocumentContext(this RazorCohostRequestContext context) - { - var documentContextFactory = context.GetRequiredService(); - - return documentContextFactory.Create(context.Uri.AssumeNotNull(), context.TextDocument.AssumeNotNull()); - } -} diff --git a/src/Razor/src/Microsoft.VisualStudio.RazorExtension/source.extension.vsixmanifest b/src/Razor/src/Microsoft.VisualStudio.RazorExtension/source.extension.vsixmanifest index 2a8fcf74a7a..f81608a4726 100644 --- a/src/Razor/src/Microsoft.VisualStudio.RazorExtension/source.extension.vsixmanifest +++ b/src/Razor/src/Microsoft.VisualStudio.RazorExtension/source.extension.vsixmanifest @@ -47,7 +47,6 @@ -