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

[LSP] Modify semanticTokens isFinalized logic #60484

Merged
merged 14 commits into from
Apr 5, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,13 @@ static SemanticTokensHelpers()

// If the full compilation is not yet available, we'll try getting a partial one. It may contain inaccurate
// results but will speed up how quickly we can respond to the client's request.
var frozenDocument = document.WithFrozenPartialSemantics(cancellationToken);
var semanticModel = await frozenDocument.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var isFinalized = document.Project.TryGetCompilation(out var compilation) && compilation == semanticModel.Compilation;
document = frozenDocument;
document = document.WithFrozenPartialSemantics(cancellationToken);

// Razor uses isFinalized to determine whether to cache tokens. IsFullyLoaded may not contain the fully finalized
// tokens, but we should be able to remove it altogether once Roslyn implements workspace/semanticTokens/refresh:
// https://github.com/dotnet/roslyn/issues/60441
var workspaceStatusService = document.Project.Solution.Workspace.Services.GetRequiredService<IWorkspaceStatusService>();
var isFinalized = await workspaceStatusService.IsFullyLoadedAsync(cancellationToken).ConfigureAwait(false);
allisonchou marked this conversation as resolved.
Show resolved Hide resolved

var classifiedSpans = await GetClassifiedSpansForDocumentAsync(
document, textSpan, options, includeSyntacticClassifications, cancellationToken).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ public SemanticTokensRangeHandler(IGlobalOptionService globalOptions)

var options = _globalOptions.GetClassificationOptions(context.Document.Project.Language);

// If the project's compilation isn't yet available, kick off a task in the background to
// hopefully make it available faster since we'll need it later to compute tokens.
if (!context.Document.Project.TryGetCompilation(out _))
{
_ = context.Document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is supposed to be handled by BackgroundCompiler and CompilationAvailableTaggerEventSource. Is there a reason we want it here separately?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was an issue in Razor where document.Project.TryGetCompilation(out var _) was returning false even after ~5 mins of waiting. We thought kicking off a separate task at the beginning might solve this problem and allow compilation to return sooner.

cc @CyrusNajmabadi is this the correct way to handle things?


// The results from the range handler should not be cached since we don't want to cache
// partial token results. In addition, a range request is only ever called with a whole
// document request, so caching range results is unnecessary since the whole document
Expand Down