Skip to content

Commit

Permalink
Self-versioned documents (#10747)
Browse files Browse the repository at this point in the history
A few integration tests to investigate, but the guts are here.

I'm _slightly_ worried this might cause us to recompile files more
often, but there is also the chance this fixes a bunch of bugs by
recompiling files more often :)

Commit-at-a-time review is highly recommended, as there are lots of flow
on effects of API changes
  • Loading branch information
davidwengier authored Aug 27, 2024
2 parents 0499664 + 8cebb29 commit 1ea1552
Show file tree
Hide file tree
Showing 123 changed files with 462 additions and 1,286 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public async Task RazorCSharpFormattingAsync()
InsertSpaces = true
};

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

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 @@ -83,7 +83,7 @@ public async Task SetupAsync()
CSharpCodeActionRange = DocumentText.GetZeroWidthRange(csharpCodeActionIndex);
HtmlCodeActionRange = DocumentText.GetZeroWidthRange(htmlCodeActionIndex);

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

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 @@ -79,7 +79,7 @@ public async Task SetupAsync()

RazorPosition = DocumentText.GetPosition(razorCodeActionIndex);

var documentContext = new VersionedDocumentContext(DocumentUri, DocumentSnapshot, projectContext: null, 1);
var documentContext = new DocumentContext(DocumentUri, DocumentSnapshot, projectContext: null);
RazorRequestContext = new RazorRequestContext(documentContext, RazorLanguageServerHost.GetRequiredService<ILspServices>(), "lsp/method", uri: null);
}

Expand Down Expand Up @@ -146,7 +146,7 @@ public TestDelegatedCompletionListProvider(IEnumerable<DelegatedCompletionRespon
{
}

public override Task<VSInternalCompletionList?> GetCompletionListAsync(int absoluteIndex, VSInternalCompletionContext completionContext, VersionedDocumentContext documentContext, VSInternalClientCapabilities clientCapabilities, Guid correlationId, CancellationToken cancellationToken)
public override Task<VSInternalCompletionList?> GetCompletionListAsync(int absoluteIndex, VSInternalCompletionContext completionContext, DocumentContext documentContext, VSInternalClientCapabilities clientCapabilities, Guid correlationId, CancellationToken cancellationToken)
{
return Task.FromResult<VSInternalCompletionList?>(
new VSInternalCompletionList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class RazorDiagnosticsBenchmark : RazorLanguageServerBenchmarkBase
private ImmutableArray<SourceMapping> SourceMappings { get; set; }
private string? GeneratedCode { get; set; }
private object? Diagnostics { get; set; }
private VersionedDocumentContext? VersionedDocumentContext { get; set; }
private DocumentContext? DocumentContext { get; set; }
private VSInternalDocumentDiagnosticsParams? Request { get; set; }
private IEnumerable<VSInternalDiagnosticReport?>? Response { get; set; }

Expand Down Expand Up @@ -72,17 +72,17 @@ public void Setup()
RazorCodeDocument = mockRazorCodeDocument.Object;

SourceText = RazorCodeDocument.Source.Text;
var documentContext = new Mock<VersionedDocumentContext>(
var documentContext = new Mock<DocumentContext>(
MockBehavior.Strict,
new object[] { It.IsAny<Uri>(), It.IsAny<IDocumentSnapshot>(), It.IsAny<VSProjectContext>(), It.IsAny<int>() });
documentContext
.Setup(r => r.GetCodeDocumentAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(RazorCodeDocument);
documentContext.Setup(r => r.Uri).Returns(It.IsAny<Uri>());
documentContext.Setup(r => r.Version).Returns(It.IsAny<int>());
documentContext.Setup(r => r.Snapshot.Version).Returns(It.IsAny<int>());
documentContext.Setup(r => r.GetSourceTextAsync(It.IsAny<CancellationToken>())).ReturnsAsync(It.IsAny<SourceText>());
RazorRequestContext = new RazorRequestContext(documentContext.Object, null!, "lsp/method", uri: null);
VersionedDocumentContext = documentContext.Object;
DocumentContext = documentContext.Object;

var loggerFactory = EmptyLoggerFactory.Instance;
var languageServerFeatureOptions = BuildFeatureOptions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.LanguageServer;
using Microsoft.AspNetCore.Razor.LanguageServer.Semantic;
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
using Microsoft.CodeAnalysis.Razor.Logging;
Expand All @@ -28,13 +27,11 @@ public class RazorSemanticTokensBenchmark : RazorLanguageServerBenchmarkBase
{
private IRazorSemanticTokensInfoService RazorSemanticTokenService { get; set; }

private IDocumentVersionCache VersionCache { get; set; }

private Uri DocumentUri => DocumentContext.Uri;

private IDocumentSnapshot DocumentSnapshot => DocumentContext.Snapshot;

private VersionedDocumentContext DocumentContext { get; set; }
private DocumentContext DocumentContext { get; set; }

private Range Range { get; set; }

Expand Down Expand Up @@ -62,8 +59,7 @@ public async Task InitializeRazorSemanticAsync()

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

var text = await DocumentContext.GetSourceTextAsync(CancellationToken.None).ConfigureAwait(false);
Range = VsLspFactory.CreateRange(
Expand All @@ -75,9 +71,6 @@ public async Task InitializeRazorSemanticAsync()
public async Task RazorSemanticTokensRangeAsync()
{
var cancellationToken = CancellationToken.None;
var documentVersion = 1;

VersionCache.TrackDocumentVersion(DocumentSnapshot, documentVersion);

await RazorSemanticTokenService.GetSemanticTokensAsync(DocumentContext, Range.ToLinePositionSpan(), colorBackground: false, Guid.Empty, cancellationToken: cancellationToken).ConfigureAwait(false);
}
Expand All @@ -98,10 +91,7 @@ protected internal override void Builder(IServiceCollection collection)

private void EnsureServicesInitialized()
{
var capabilitiesService = new BenchmarkClientCapabilitiesService(new VSInternalClientCapabilities { SupportsVisualStudioExtensions = true });
var legend = new RazorSemanticTokensLegendService(capabilitiesService);
RazorSemanticTokenService = RazorLanguageServerHost.GetRequiredService<IRazorSemanticTokensInfoService>();
VersionCache = RazorLanguageServerHost.GetRequiredService<IDocumentVersionCache>();
}

internal class TestRazorSemanticTokensInfoService : RazorSemanticTokensInfoService
Expand All @@ -117,7 +107,7 @@ public TestRazorSemanticTokensInfoService(

// We can't get C# responses without significant amounts of extra work, so let's just shim it for now, any non-Null result is fine.
protected override Task<ImmutableArray<SemanticRange>?> GetCSharpSemanticRangesAsync(
VersionedDocumentContext documentContext,
DocumentContext documentContext,
RazorCodeDocument codeDocument,
LinePositionSpan razorRange,
bool colorBackground,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,9 @@ public class RazorSemanticTokensRangeEndpointBenchmark : RazorLanguageServerBenc

private SemanticTokensRangeEndpoint SemanticTokensRangeEndpoint { get; set; }

private IDocumentVersionCache VersionCache { get; set; }

private Uri DocumentUri => DocumentContext.Uri;

private IDocumentSnapshot DocumentSnapshot => DocumentContext.Snapshot;

private VersionedDocumentContext DocumentContext { get; set; }
private DocumentContext DocumentContext { get; set; }

private Range Range { get; set; }

Expand Down Expand Up @@ -70,8 +66,7 @@ public async Task InitializeRazorSemanticAsync()

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

var razorOptionsMonitor = RazorLanguageServerHost.GetRequiredService<RazorLSPOptionsMonitor>();
var clientCapabilitiesService = new BenchmarkClientCapabilitiesService(new VSInternalClientCapabilities() { SupportsVisualStudioExtensions = true });
Expand All @@ -83,9 +78,6 @@ public async Task InitializeRazorSemanticAsync()
start: (0, 0),
end: (text.Lines.Count - 1, text.Lines[^1].Span.Length - 1));

var documentVersion = 1;
VersionCache.TrackDocumentVersion(DocumentSnapshot, documentVersion);

RequestContext = new RazorRequestContext(DocumentContext, RazorLanguageServerHost.GetRequiredService<ILspServices>(), "lsp/method", uri: null);

var random = new Random();
Expand Down Expand Up @@ -133,7 +125,6 @@ protected internal override void Builder(IServiceCollection collection)
private void EnsureServicesInitialized()
{
RazorSemanticTokenService = RazorLanguageServerHost.GetRequiredService<IRazorSemanticTokensInfoService>();
VersionCache = RazorLanguageServerHost.GetRequiredService<IDocumentVersionCache>();
}

internal class TestCustomizableRazorSemanticTokensInfoService : RazorSemanticTokensInfoService
Expand All @@ -149,7 +140,7 @@ public TestCustomizableRazorSemanticTokensInfoService(

// We can't get C# responses without significant amounts of extra work, so let's just shim it for now, any non-Null result is fine.
protected override Task<ImmutableArray<SemanticRange>?> GetCSharpSemanticRangesAsync(
VersionedDocumentContext documentContext,
DocumentContext documentContext,
RazorCodeDocument codeDocument,
LinePositionSpan razorSpan,
bool colorBackground,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Razor.LanguageServer;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
using Microsoft.CodeAnalysis.Razor.SemanticTokens;
using Microsoft.CodeAnalysis.Text;
Expand All @@ -23,9 +22,7 @@ public class RazorSemanticTokensScrollingBenchmark : RazorLanguageServerBenchmar
{
private IRazorSemanticTokensInfoService RazorSemanticTokenService { get; set; }

private IDocumentVersionCache VersionCache { get; set; }

private VersionedDocumentContext DocumentContext { get; set; }
private DocumentContext DocumentContext { get; set; }

private Uri DocumentUri => DocumentContext.Uri;

Expand All @@ -52,7 +49,7 @@ public async Task InitializeRazorSemanticAsync()

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

var text = await DocumentSnapshot.GetTextAsync().ConfigureAwait(false);
Range = VsLspFactory.CreateRange(
Expand All @@ -66,9 +63,6 @@ public async Task InitializeRazorSemanticAsync()
public async Task RazorSemanticTokensRangeScrollingAsync()
{
var cancellationToken = CancellationToken.None;
var documentVersion = 1;

VersionCache!.TrackDocumentVersion(DocumentSnapshot, documentVersion);

var documentLineCount = Range.End.Line;

Expand Down Expand Up @@ -105,6 +99,5 @@ protected internal override void Builder(IServiceCollection collection)
private void EnsureServicesInitialized()
{
RazorSemanticTokenService = RazorLanguageServerHost.GetRequiredService<IRazorSemanticTokensInfoService>();
VersionCache = RazorLanguageServerHost.GetRequiredService<IDocumentVersionCache>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ public async override Task<CodeAction> ResolveAsync(
CodeAction codeAction,
CancellationToken cancellationToken)
{
if (!_documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier, out var documentContext))
if (!_documentContextFactory.TryCreate(csharpParams.RazorFileIdentifier, out var documentContext))
{
return codeAction;
}

var resolvedCodeAction = await ResolveCodeActionWithServerAsync(csharpParams.RazorFileIdentifier, documentContext.Version, RazorLanguageKind.CSharp, codeAction, cancellationToken).ConfigureAwait(false);
var resolvedCodeAction = await ResolveCodeActionWithServerAsync(csharpParams.RazorFileIdentifier, documentContext.Snapshot.Version, RazorLanguageKind.CSharp, codeAction, cancellationToken).ConfigureAwait(false);
if (resolvedCodeAction?.Edit?.DocumentChanges is null)
{
// Unable to resolve code action with server, return original code action
Expand Down Expand Up @@ -89,12 +89,9 @@ public async override Task<CodeAction> ResolveAsync(

cancellationToken.ThrowIfCancellationRequested();

var documentVersion = documentContext.Version;

var codeDocumentIdentifier = new OptionalVersionedTextDocumentIdentifier()
{
Uri = csharpParams.RazorFileIdentifier.Uri,
Version = documentVersion,
Uri = csharpParams.RazorFileIdentifier.Uri
};
resolvedCodeAction.Edit = new WorkspaceEdit()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ public async override Task<CodeAction> ResolveAsync(
{
cancellationToken.ThrowIfCancellationRequested();

if (!_documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier, out var documentContext))
if (!_documentContextFactory.TryCreate(csharpParams.RazorFileIdentifier, out var documentContext))
{
return codeAction;
}

var resolvedCodeAction = await ResolveCodeActionWithServerAsync(csharpParams.RazorFileIdentifier, documentContext.Version, RazorLanguageKind.CSharp, codeAction, cancellationToken).ConfigureAwait(false);
var resolvedCodeAction = await ResolveCodeActionWithServerAsync(csharpParams.RazorFileIdentifier, documentContext.Snapshot.Version, RazorLanguageKind.CSharp, codeAction, cancellationToken).ConfigureAwait(false);
if (resolvedCodeAction?.Edit?.DocumentChanges is null)
{
// Unable to resolve code action with server, return original code action
Expand Down Expand Up @@ -87,7 +87,6 @@ public async override Task<CodeAction> ResolveAsync(
var codeDocumentIdentifier = new OptionalVersionedTextDocumentIdentifier()
{
Uri = csharpParams.RazorFileIdentifier.Uri,
Version = documentContext.Version,
};
resolvedCodeAction.Edit = new WorkspaceEdit()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public void ApplyCapabilities(VSInternalServerCapabilities serverCapabilities, V
return context;
}

private async Task<ImmutableArray<RazorVSInternalCodeAction>> GetDelegatedCodeActionsAsync(VersionedDocumentContext documentContext, RazorCodeActionContext context, Guid correlationId, CancellationToken cancellationToken)
private async Task<ImmutableArray<RazorVSInternalCodeAction>> GetDelegatedCodeActionsAsync(DocumentContext documentContext, RazorCodeActionContext context, Guid correlationId, CancellationToken cancellationToken)
{
var languageKind = _documentMappingService.GetLanguageKind(context.CodeDocument, context.Location.AbsoluteIndex, rightAssociative: false);

Expand Down Expand Up @@ -256,7 +256,7 @@ private static async Task<ImmutableArray<RazorVSInternalCodeAction>> FilterCodeA
}

// Internal for testing
internal async Task<RazorVSInternalCodeAction[]> GetCodeActionsFromLanguageServerAsync(RazorLanguageKind languageKind, VersionedDocumentContext documentContext, RazorCodeActionContext context, Guid correlationId, CancellationToken cancellationToken)
internal async Task<RazorVSInternalCodeAction[]> GetCodeActionsFromLanguageServerAsync(RazorLanguageKind languageKind, DocumentContext documentContext, RazorCodeActionContext context, Guid correlationId, CancellationToken cancellationToken)
{
if (languageKind == RazorLanguageKind.CSharp)
{
Expand All @@ -282,7 +282,7 @@ internal async Task<RazorVSInternalCodeAction[]> GetCodeActionsFromLanguageServe

var delegatedParams = new DelegatedCodeActionParams()
{
HostDocumentVersion = documentContext.Version,
HostDocumentVersion = documentContext.Snapshot.Version,
CodeActionParams = context.Request,
LanguageKind = languageKind,
CorrelationId = correlationId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ public async override Task<CodeAction> ResolveAsync(
CodeAction codeAction,
CancellationToken cancellationToken)
{
if (!_documentContextFactory.TryCreateForOpenDocument(resolveParams.RazorFileIdentifier, out var documentContext))
if (!_documentContextFactory.TryCreate(resolveParams.RazorFileIdentifier, out var documentContext))
{
return codeAction;
}

var resolvedCodeAction = await ResolveCodeActionWithServerAsync(resolveParams.RazorFileIdentifier, documentContext.Version, RazorLanguageKind.Html, codeAction, cancellationToken).ConfigureAwait(false);
var resolvedCodeAction = await ResolveCodeActionWithServerAsync(resolveParams.RazorFileIdentifier, documentContext.Snapshot.Version, RazorLanguageKind.Html, codeAction, cancellationToken).ConfigureAwait(false);
if (resolvedCodeAction?.Edit?.DocumentChanges is null)
{
// Unable to resolve code action with server, return original code action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ internal sealed class GenerateMethodCodeActionResolver(
return null;
}

if (!_documentContextFactory.TryCreateForOpenDocument(actionParams.Uri, out var documentContext))
if (!_documentContextFactory.TryCreate(actionParams.Uri, out var documentContext))
{
return null;
}
Expand Down Expand Up @@ -141,7 +141,7 @@ razorClassName is null ||
private async Task<WorkspaceEdit> GenerateMethodInCodeBlockAsync(
RazorCodeDocument code,
GenerateMethodCodeActionParams actionParams,
VersionedDocumentContext documentContext,
DocumentContext documentContext,
string? razorNamespace,
string? razorClassName,
CancellationToken cancellationToken)
Expand Down Expand Up @@ -230,7 +230,7 @@ private async Task<WorkspaceEdit> GenerateMethodInCodeBlockAsync(
return new WorkspaceEdit() { DocumentChanges = new[] { razorTextDocEdit } };
}

private static async Task<string> PopulateMethodSignatureAsync(VersionedDocumentContext documentContext, GenerateMethodCodeActionParams actionParams, CancellationToken cancellationToken)
private static async Task<string> PopulateMethodSignatureAsync(DocumentContext documentContext, GenerateMethodCodeActionParams actionParams, CancellationToken cancellationToken)
{
var templateWithMethodSignature = s_generateMethodTemplate.Replace(MethodName, actionParams.MethodName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public async Task<LspColorPresentation[]> HandleRequestAsync(ColorPresentationPa

var delegatedRequest = new DelegatedColorPresentationParams
{
RequiredHostDocumentVersion = documentContext.Version,
RequiredHostDocumentVersion = documentContext.Snapshot.Version,
Color = request.Color,
Range = request.Range,
TextDocument = request.TextDocument
Expand Down
Loading

0 comments on commit 1ea1552

Please sign in to comment.