Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove IDocumentSnapshot.Project #9854

Closed
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class RazorCSharpFormattingBenchmark : RazorLanguageServerBenchmarkBase

private IDocumentSnapshot DocumentSnapshot { get; set; }

private IProjectSnapshot ProjectSnapshot { get; set; }

private SourceText DocumentText { get; set; }

/// <summary>
Expand All @@ -61,7 +63,7 @@ public async Task InitializeRazorCSharpFormattingAsync()
var targetPath = "/Components/Pages/Generated.razor";

DocumentUri = new Uri(_filePath);
DocumentSnapshot = GetDocumentSnapshot(projectFilePath, _filePath, targetPath);
(DocumentSnapshot, ProjectSnapshot) = GetDocumentAndProjectSnapshot(projectFilePath, _filePath, targetPath);
DocumentText = await DocumentSnapshot.GetTextAsync();
}

Expand Down Expand Up @@ -118,7 +120,7 @@ public async Task RazorCSharpFormattingAsync()
InsertSpaces = true
};

var documentContext = new VersionedDocumentContext(DocumentUri, DocumentSnapshot, projectContext: null, version: 1);
var documentContext = new VersionedDocumentContext(DocumentUri, DocumentSnapshot, ProjectSnapshot, projectContext: null, version: 1);

var edits = await RazorFormattingService.FormatAsync(documentContext, range: null, options, CancellationToken.None);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class RazorCodeActionsBenchmark : RazorLanguageServerBenchmarkBase
private Uri? DocumentUri { get; set; }
private CodeActionEndpoint? CodeActionEndpoint { get; set; }
private IDocumentSnapshot? DocumentSnapshot { get; set; }
private IProjectSnapshot? ProjectSnapshot { get; set; }
private SourceText? DocumentText { get; set; }
private Range? RazorCodeActionRange { get; set; }
private Range? CSharpCodeActionRange { get; set; }
Expand Down Expand Up @@ -75,14 +76,14 @@ public async Task SetupAsync()
var targetPath = "/Components/Pages/Generated.razor";

DocumentUri = new Uri(_filePath);
DocumentSnapshot = GetDocumentSnapshot(projectFilePath, _filePath, targetPath);
(DocumentSnapshot, ProjectSnapshot) = GetDocumentAndProjectSnapshot(projectFilePath, _filePath, targetPath);
DocumentText = await DocumentSnapshot.GetTextAsync();

RazorCodeActionRange = ToRange(razorCodeActionIndex);
CSharpCodeActionRange = ToRange(csharpCodeActionIndex);
HtmlCodeActionRange = ToRange(htmlCodeActionIndex);

var documentContext = new VersionedDocumentContext(DocumentUri, DocumentSnapshot, projectContext: null, 1);
var documentContext = new VersionedDocumentContext(DocumentUri, DocumentSnapshot, ProjectSnapshot, projectContext: null, 1);

var codeDocument = await documentContext.GetCodeDocumentAsync(CancellationToken.None);
// Need a root namespace for the Extract to Code Behind light bulb to be happy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class RazorCompletionBenchmark : RazorLanguageServerBenchmarkBase
private Uri? DocumentUri { get; set; }
private RazorCompletionEndpoint? CompletionEndpoint { get; set; }
private IDocumentSnapshot? DocumentSnapshot { get; set; }
private IProjectSnapshot? ProjectSnapshot { get; set; }
private SourceText? DocumentText { get; set; }
private Position? RazorPosition { get; set; }
private RazorRequestContext RazorRequestContext { get; set; }
Expand Down Expand Up @@ -74,12 +75,12 @@ public async Task SetupAsync()
var targetPath = "/Components/Pages/Generated.razor";

DocumentUri = new Uri(_filePath);
DocumentSnapshot = GetDocumentSnapshot(projectFilePath, _filePath, targetPath);
(DocumentSnapshot, ProjectSnapshot) = GetDocumentAndProjectSnapshot(projectFilePath, _filePath, targetPath);
DocumentText = await DocumentSnapshot.GetTextAsync();

RazorPosition = ToPosition(razorCodeActionIndex);

var documentContext = new VersionedDocumentContext(DocumentUri, DocumentSnapshot, projectContext: null, 1);
var documentContext = new VersionedDocumentContext(DocumentUri, DocumentSnapshot, ProjectSnapshot, projectContext: null, 1);
RazorRequestContext = new RazorRequestContext(documentContext, languageServer.GetLspServices(), "lsp/method", uri: null);

Position ToPosition(int index)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void Setup()
SourceText = RazorCodeDocument.Source.Text;
var documentContext = new Mock<VersionedDocumentContext>(
MockBehavior.Strict,
new object[] { It.IsAny<Uri>(), It.IsAny<IDocumentSnapshot>(), It.IsAny<VSProjectContext>(), It.IsAny<int>() });
new object[] { It.IsAny<Uri>(), It.IsAny<IDocumentSnapshot>(), It.IsAny<IProjectSnapshot>(), It.IsAny<VSProjectContext>(), It.IsAny<int>() });
documentContext
.Setup(r => r.GetCodeDocumentAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(RazorCodeDocument);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public async Task InitializeRazorCSharpFormattingAsync()

var targetPath = "/Components/Pages/Generated.razor";

DocumentSnapshot = GetDocumentSnapshot(projectFilePath, _filePath, targetPath);
(DocumentSnapshot, _) = GetDocumentAndProjectSnapshot(projectFilePath, _filePath, targetPath);

var codeDocument = await DocumentSnapshot.GetGeneratedOutputAsync();
CSharpDocument = codeDocument.GetCSharpDocument();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.

#nullable disable
Expand Down Expand Up @@ -52,7 +52,7 @@ private protected virtual LanguageServerFeatureOptions BuildFeatureOptions()

private protected NoopLogger Logger { get; }

internal IDocumentSnapshot GetDocumentSnapshot(string projectFilePath, string filePath, string targetPath)
internal (IDocumentSnapshot, IProjectSnapshot) GetDocumentAndProjectSnapshot(string projectFilePath, string filePath, string targetPath)
{
var intermediateOutputPath = Path.Combine(Path.GetDirectoryName(projectFilePath), "obj");
var hostProject = new HostProject(projectFilePath, intermediateOutputPath, RazorConfiguration.Default, rootNamespace: null);
Expand All @@ -70,7 +70,7 @@ internal IDocumentSnapshot GetDocumentSnapshot(string projectFilePath, string fi
var projectSnapshot = projectSnapshotManager.GetLoadedProject(hostProject.Key);

var documentSnapshot = projectSnapshot.GetDocument(filePath);
return documentSnapshot;
return (documentSnapshot, projectSnapshot);
}

private class NoopClientNotifierService : IClientConnection, IOnInitialized
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ public async Task InitializeRazorSemanticAsync()
TargetPath = $"/Components/Pages/{fileName}.razor";

var documentUri = new Uri(filePath);
var documentSnapshot = GetDocumentSnapshot(ProjectFilePath, filePath, TargetPath);
var (documentSnapshot, projectSnapshot) = GetDocumentAndProjectSnapshot(ProjectFilePath, filePath, TargetPath);
var version = 1;
DocumentContext = new VersionedDocumentContext(documentUri, documentSnapshot, projectContext: null, version);
DocumentContext = new VersionedDocumentContext(documentUri, documentSnapshot, projectSnapshot, projectContext: null, version);

var text = await DocumentContext.GetSourceTextAsync(CancellationToken.None).ConfigureAwait(false);
Range = new Range
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ public async Task InitializeRazorSemanticAsync()
TargetPath = "/Components/Pages/SemanticTokens.razor";

var documentUri = new Uri(filePath);
var documentSnapshot = GetDocumentSnapshot(ProjectFilePath, filePath, TargetPath);
var (documentSnapshot, projectSnapshot) = GetDocumentAndProjectSnapshot(ProjectFilePath, filePath, TargetPath);
var version = 1;
DocumentContext = new VersionedDocumentContext(documentUri, documentSnapshot, projectContext: null, version);
DocumentContext = new VersionedDocumentContext(documentUri, documentSnapshot, projectSnapshot, projectContext: null, version);

var razorOptionsMonitor = RazorLanguageServer.GetRequiredService<RazorLSPOptionsMonitor>();
var clientConnection = RazorLanguageServer.GetRequiredService<IClientConnection>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ public async Task InitializeRazorSemanticAsync()
TargetPath = "/Components/Pages/FormattingTest.razor";

var documentUri = new Uri(filePath);
var documentSnapshot = GetDocumentSnapshot(ProjectFilePath, filePath, TargetPath);
DocumentContext = new VersionedDocumentContext(documentUri, documentSnapshot, projectContext: null, version: 1);
var (documentSnapshot, projectSnapshot) = GetDocumentAndProjectSnapshot(ProjectFilePath, filePath, TargetPath);

DocumentContext = new VersionedDocumentContext(documentUri, documentSnapshot, projectSnapshot, projectContext: null, version: 1);

SemanticTokensLegend = new RazorSemanticTokensLegend(new VSInternalClientCapabilities() { SupportsVisualStudioExtensions = true });
RazorSemanticTokenService.ApplyCapabilities(new(), new VSInternalClientCapabilities() { SupportsVisualStudioExtensions = true });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ internal sealed class CodeActionEndpoint(
return null;
}

var razorCodeActionContext = await GenerateRazorCodeActionContextAsync(request, documentContext.Snapshot).ConfigureAwait(false);
var razorCodeActionContext = await GenerateRazorCodeActionContextAsync(request, documentContext.Snapshot, documentContext.Project).ConfigureAwait(false);
if (razorCodeActionContext is null)
{
return null;
Expand Down Expand Up @@ -139,7 +139,7 @@ public void ApplyCapabilities(VSInternalServerCapabilities serverCapabilities, V
}

// internal for testing
internal async Task<RazorCodeActionContext?> GenerateRazorCodeActionContextAsync(VSCodeActionParams request, IDocumentSnapshot documentSnapshot)
internal async Task<RazorCodeActionContext?> GenerateRazorCodeActionContextAsync(VSCodeActionParams request, IDocumentSnapshot documentSnapshot, IProjectSnapshot projectSnapshot)
{
var codeDocument = await documentSnapshot.GetGeneratedOutputAsync().ConfigureAwait(false);
if (codeDocument.IsUnsupported())
Expand Down Expand Up @@ -171,6 +171,7 @@ public void ApplyCapabilities(VSInternalServerCapabilities serverCapabilities, V
var context = new RazorCodeActionContext(
request,
documentSnapshot,
projectSnapshot,
codeDocument,
location.Value,
sourceText,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ private List<TagHelperPair> FindMatchingTagHelpers(RazorCodeActionContext contex
// Find all matching tag helpers
using var _ = DictionaryPool<string, TagHelperPair>.GetPooledObject(out var matching);

foreach (var tagHelper in context.DocumentSnapshot.Project.TagHelpers)
foreach (var tagHelper in context.ProjectSnapshot.TagHelpers)
{
if (SatisfiesRules(tagHelper.TagMatchingRules, tagName.AsSpan(), parentTagName.AsSpan(), attributes, out var caseInsensitiveMatch))
{
Expand All @@ -234,7 +234,7 @@ private List<TagHelperPair> FindMatchingTagHelpers(RazorCodeActionContext contex
}

// Iterate and find the fully qualified version
foreach (var tagHelper in context.DocumentSnapshot.Project.TagHelpers)
foreach (var tagHelper in context.ProjectSnapshot.TagHelpers)
{
if (matching.TryGetValue(tagHelper.Name, out var tagHelperPair))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ internal sealed class RazorCodeActionContext
public RazorCodeActionContext(
VSCodeActionParams request,
IDocumentSnapshot documentSnapshot,
IProjectSnapshot projectSnapshot,
RazorCodeDocument codeDocument,
SourceLocation location,
SourceText sourceText,
Expand All @@ -21,6 +22,7 @@ public RazorCodeActionContext(
{
Request = request ?? throw new ArgumentNullException(nameof(request));
DocumentSnapshot = documentSnapshot ?? throw new ArgumentNullException(nameof(documentSnapshot));
ProjectSnapshot = projectSnapshot ?? throw new ArgumentNullException(nameof(projectSnapshot));
CodeDocument = codeDocument ?? throw new ArgumentNullException(nameof(codeDocument));
Location = location;
SourceText = sourceText ?? throw new ArgumentNullException(nameof(sourceText));
Expand All @@ -30,6 +32,7 @@ public RazorCodeActionContext(

public VSCodeActionParams Request { get; }
public IDocumentSnapshot DocumentSnapshot { get; }
public IProjectSnapshot ProjectSnapshot { get; }
public RazorCodeDocument CodeDocument { get; }
public SourceLocation Location { get; }
public SourceText SourceText { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ public CodeDocumentReferenceHolder()
_codeDocumentCache = new();
}

public override void DocumentProcessed(RazorCodeDocument codeDocument, IDocumentSnapshot documentSnapshot)
public override void DocumentProcessed(RazorCodeDocument codeDocument, IDocumentSnapshot documentSnapshot, IProjectSnapshot projectSnapshot)
{
// We capture a reference to the code document after a document has been processed in order to ensure that
// latest document state information is readily available without re-computation. The DocumentState type
// (brains of DocumentSnapshot) will garbage collect its generated output aggressively and due to the
// nature of LSP being heavily asynchronous (multiple requests for single keystrokes) we don't want to cause
// multiple parses/regenerations across LSP requests that are all for the same document version.
var key = new DocumentKey(documentSnapshot.Project.Key, documentSnapshot.FilePath.AssumeNotNull());
var key = new DocumentKey(documentSnapshot.ProjectKey, documentSnapshot.FilePath.AssumeNotNull());
_codeDocumentCache[key] = codeDocument;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ public VersionedDocumentContext Create(Uri documentUri, TextDocument textDocumen
// document versions because TextDocument is inherently versioned.
var version = _documentVersionCache.GetLatestDocumentVersion(documentSnapshot.FilePath.AssumeNotNull());

return new VersionedDocumentContext(documentUri, documentSnapshot, null, version);
return new VersionedDocumentContext(documentUri, documentSnapshot, documentSnapshot.Project, null, version);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

namespace Microsoft.AspNetCore.Razor.LanguageServer.Cohost;

internal class CohostDocumentSnapshot(TextDocument textDocument, IProjectSnapshot projectSnapshot) : IDocumentSnapshot
internal class CohostDocumentSnapshot(TextDocument textDocument, CohostProjectSnapshot projectSnapshot) : IDocumentSnapshot
{
private readonly TextDocument _textDocument = textDocument;
private readonly IProjectSnapshot _projectSnapshot = projectSnapshot;
private readonly CohostProjectSnapshot _projectSnapshot = projectSnapshot;

private RazorCodeDocument? _codeDocument;

Expand All @@ -23,10 +23,12 @@ internal class CohostDocumentSnapshot(TextDocument textDocument, IProjectSnapsho

public string? TargetPath => _textDocument.FilePath;

public IProjectSnapshot Project => _projectSnapshot;

public bool SupportsOutput => true;

public ProjectKey ProjectKey => _projectSnapshot.Key;

internal CohostProjectSnapshot Project => _projectSnapshot;

public Task<SourceText> GetTextAsync() => _textDocument.GetTextAsync();

public Task<VersionStamp> GetTextVersionAsync() => _textDocument.GetTextVersionAsync();
Expand All @@ -53,8 +55,8 @@ public async Task<RazorCodeDocument> GetGeneratedOutputAsync()
// 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 imports = await DocumentState.ComputedStateTracker.GetImportsAsync(this).ConfigureAwait(false);
_codeDocument = await DocumentState.ComputedStateTracker.GenerateCodeDocumentAsync(Project, this, imports).ConfigureAwait(false);
var imports = await DocumentState.ComputedStateTracker.GetImportsAsync(_projectSnapshot, this).ConfigureAwait(false);
_codeDocument = await DocumentState.ComputedStateTracker.GenerateCodeDocumentAsync(_projectSnapshot, this, imports).ConfigureAwait(false);

return _codeDocument;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@
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> projectSnapshotFactory)
{
private static readonly ConditionalWeakTable<TextDocument, IDocumentSnapshot> _documentSnapshots = new();
private static readonly ConditionalWeakTable<TextDocument, CohostDocumentSnapshot> _documentSnapshots = new();

private readonly Lazy<ProjectSnapshotFactory> _projectSnapshotFactory = projectSnapshotFactory;

public IDocumentSnapshot GetOrCreate(TextDocument textDocument)
public CohostDocumentSnapshot GetOrCreate(TextDocument textDocument)
{
if (!_documentSnapshots.TryGetValue(textDocument, out var documentSnapshot))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Razor.Telemetry;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
using Microsoft.VisualStudio.Threading;

namespace Microsoft.AspNetCore.Razor.LanguageServer.Cohost;
Expand All @@ -14,13 +13,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Cohost;
[method: ImportingConstructor]
internal class ProjectSnapshotFactory(DocumentSnapshotFactory documentSnapshotFactory, ITelemetryReporter telemetryReporter, JoinableTaskContext joinableTaskContext)
{
private static readonly ConditionalWeakTable<Project, IProjectSnapshot> _projectSnapshots = new();
private static readonly ConditionalWeakTable<Project, CohostProjectSnapshot> _projectSnapshots = new();

private readonly DocumentSnapshotFactory _documentSnapshotFactory = documentSnapshotFactory;
private readonly ITelemetryReporter _telemetryReporter = telemetryReporter;
private readonly JoinableTaskContext _joinableTaskContext = joinableTaskContext;

public IProjectSnapshot GetOrCreate(Project project)
public CohostProjectSnapshot GetOrCreate(Project project)
{
if (!_projectSnapshots.TryGetValue(project, out var projectSnapshot))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(VSInternalDocumentDiagno
return null;
}

var convertedDiagnostics = RazorDiagnosticConverter.Convert(diagnostics, sourceText, documentContext.Snapshot);
var convertedDiagnostics = RazorDiagnosticConverter.Convert(diagnostics, sourceText, documentContext.Snapshot, documentContext.Project);

return
[
Expand Down
Loading