Skip to content

Commit

Permalink
Merged PR 468200: Tell Roslyn to initialize Razor only when the user …
Browse files Browse the repository at this point in the history
…needs to

Allows the extension to be in charge of when the Roslyn does its work to initialize Razor.

The Roslyn side of this, which handles the notification, is https://dnceng.visualstudio.com/internal/_git/dotnet-roslyn/pullrequest/30922

Also related is dotnet/razor#8639
  • Loading branch information
davidwengier committed May 4, 2023
2 parents 7fb0321 + d8ab636 commit 3fca197
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
8 changes: 8 additions & 0 deletions src/lsptoolshost/roslynLanguageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export class RoslynLanguageServer {
public static readonly roslynPullDiagnosticCommand: string = 'roslyn.pullDiagnosticRazorCSharp';
public static readonly provideCodeActionsCommand: string = 'roslyn.provideCodeActions';
public static readonly resolveCodeActionCommand: string = 'roslyn.resolveCodeAction';
public static readonly razorInitializeCommand: string = 'razor.initialize';

// These are notifications we will get from the LSP server and will forward to the Razor extension.
private static readonly provideRazorDynamicFileInfoMethodName: string = 'razor/provideDynamicFileInfo';
Expand Down Expand Up @@ -386,6 +387,13 @@ export class RoslynLanguageServer {
vscode.commands.registerCommand(RoslynLanguageServer.resolveCodeActionCommand, async (request: CodeAction) => {
return await this.sendRequest(CodeActionResolveRequest.type, request, CancellationToken.None);
});

// Roslyn is responsible for producing a json file containing information for Razor, that comes from the compilation for
// a project. We want to defer this work until necessary, so this command is called by the Razor document manager to tell
// us when they need us to initialize the Razor things.
vscode.commands.registerCommand(RoslynLanguageServer.razorInitializeCommand, () => {
client.sendNotification("razor/initialize", { });
});
}

private getServerFileName() {
Expand Down
24 changes: 18 additions & 6 deletions src/razor/src/Document/RazorDocumentManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { createDocument } from './RazorDocumentFactory';

export class RazorDocumentManager implements IRazorDocumentManager {
public roslynActivated = false;
public razorDocumentGenerationInitialized = false;

private readonly razorDocuments: { [hostDocumentPath: string]: IRazorDocument } = {};
private readonly openRazorDocuments = new Set<string>();
Expand Down Expand Up @@ -56,8 +57,6 @@ export class RazorDocumentManager implements IRazorDocumentManager {
public async getDocument(uri: vscode.Uri) {
const document = this._getDocument(uri);

await this.ensureDocumentAndProjectedDocumentsOpen(document);

return document;
}

Expand Down Expand Up @@ -111,7 +110,7 @@ export class RazorDocumentManager implements IRazorDocumentManager {
continue;
}

this.openDocument(textDocument.uri);
await this.openDocument(textDocument.uri);
}
}

Expand All @@ -122,12 +121,12 @@ export class RazorDocumentManager implements IRazorDocumentManager {
async (uri: vscode.Uri) => this.addDocument(uri));
const didDeleteRegistration = watcher.onDidDelete(
async (uri: vscode.Uri) => this.removeDocument(uri));
const didOpenRegistration = vscode.workspace.onDidOpenTextDocument(document => {
const didOpenRegistration = vscode.workspace.onDidOpenTextDocument(async document => {
if (document.languageId !== RazorLanguage.id) {
return;
}

this.openDocument(document.uri);
await this.openDocument(document.uri);
});
const didCloseRegistration = vscode.workspace.onDidCloseTextDocument(document => {
if (document.languageId !== RazorLanguage.id) {
Expand Down Expand Up @@ -165,7 +164,20 @@ export class RazorDocumentManager implements IRazorDocumentManager {
return document;
}

private openDocument(uri: vscode.Uri) {
private async openDocument(uri: vscode.Uri) {
// On first open of a Razor document, we kick off the generation of all razor documents so that
// components are discovered correctly. If we do this early, when we initialize everything, we
// just spend a lot of time generating documents and json files that might not be needed.
// If we wait for each individual document to be opened by the user, then locally defined components
// don't work, which is a poor experience. This is the compromise.
if (!this.razorDocumentGenerationInitialized) {
this.razorDocumentGenerationInitialized = true;
vscode.commands.executeCommand(RoslynLanguageServer.razorInitializeCommand);
for (const document of this.documents) {
await this.ensureDocumentAndProjectedDocumentsOpen(document);
}
}

const document = this._getDocument(uri);

this.notifyDocumentChange(document, RazorDocumentChangeKind.opened);
Expand Down

0 comments on commit 3fca197

Please sign in to comment.