From d806782d9ce69c73556f1871b71856e228e48edd Mon Sep 17 00:00:00 2001 From: Lyu Jason Date: Sun, 28 Jun 2020 11:37:43 +0800 Subject: [PATCH 1/3] update all opened document diagnostics on save --- .../src/lib/DiagnosticsManager.ts | 27 +++++++++++++++++ .../src/lib/documents/DocumentManager.ts | 19 ++++++++++++ .../plugins/typescript/LSAndTSDocResolver.ts | 1 + packages/language-server/src/server.ts | 29 ++++++++++++++----- 4 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 packages/language-server/src/lib/DiagnosticsManager.ts diff --git a/packages/language-server/src/lib/DiagnosticsManager.ts b/packages/language-server/src/lib/DiagnosticsManager.ts new file mode 100644 index 000000000..c1c4ce12f --- /dev/null +++ b/packages/language-server/src/lib/DiagnosticsManager.ts @@ -0,0 +1,27 @@ +import { IConnection, TextDocumentIdentifier, Diagnostic } from 'vscode-languageserver'; +import { DocumentManager, Document } from './documents'; + +export type SendDiagnostics = IConnection['sendDiagnostics']; +export type GetDiagnostics = (doc: TextDocumentIdentifier) => Thenable; + +export class DiagnosticsManager { + constructor( + private sendDiagnostics: SendDiagnostics, + private docManager: DocumentManager, + private getDiagnostics: GetDiagnostics + ) { } + + updateAll() { + this.docManager.getAllOpenedByClient().forEach((doc) => { + this.update(doc[1]); + }); + } + + async update(document: Document) { + const diagnostics = await this.getDiagnostics({ uri: document.getURL() }); + this.sendDiagnostics({ + uri: document.getURL(), + diagnostics, + }); + } +} diff --git a/packages/language-server/src/lib/documents/DocumentManager.ts b/packages/language-server/src/lib/documents/DocumentManager.ts index 5d1224728..2df877daf 100644 --- a/packages/language-server/src/lib/documents/DocumentManager.ts +++ b/packages/language-server/src/lib/documents/DocumentManager.ts @@ -13,6 +13,7 @@ export type DocumentEvent = 'documentOpen' | 'documentChange' | 'documentClose'; */ export class DocumentManager { private emitter = new EventEmitter(); + private openedByServer = new Set(); public documents: Map = new Map(); public locked = new Set(); public deleteCandidates = new Set(); @@ -20,6 +21,7 @@ export class DocumentManager { constructor(private createDocument: (textDocument: TextDocumentItem) => Document) {} openDocument(textDocument: TextDocumentItem): Document { + console.log(textDocument.uri); let document: Document; if (this.documents.has(textDocument.uri)) { document = this.documents.get(textDocument.uri)!; @@ -39,14 +41,29 @@ export class DocumentManager { this.locked.add(uri); } + markAsOpenedByServer(uri: string): void { + this.openedByServer.add(uri); + } + + unmarkOpenedByServer(uri: string): void { + this.openedByServer.delete(uri); + } + + getAllOpenedByClient() { + return Array.from(this.documents.entries()) + .filter((doc) => !this.openedByServer.has(doc[0])); + } + releaseDocument(uri: string): void { this.locked.delete(uri); + this.openedByServer.delete(uri); if (this.deleteCandidates.has(uri)) { this.deleteCandidates.delete(uri); this.closeDocument(uri); } } + closeDocument(uri: string) { const document = this.documents.get(uri); if (!document) { @@ -61,6 +78,8 @@ export class DocumentManager { } else { this.deleteCandidates.add(uri); } + + this.openedByServer.delete(uri); } updateDocument( diff --git a/packages/language-server/src/plugins/typescript/LSAndTSDocResolver.ts b/packages/language-server/src/plugins/typescript/LSAndTSDocResolver.ts index eee4f5fef..ae5a2cd53 100644 --- a/packages/language-server/src/plugins/typescript/LSAndTSDocResolver.ts +++ b/packages/language-server/src/plugins/typescript/LSAndTSDocResolver.ts @@ -40,6 +40,7 @@ export class LSAndTSDocResolver { version: 0, }); this.docManager.lockDocument(uri); + this.docManager.markAsOpenedByServer(uri); return document; }; diff --git a/packages/language-server/src/server.ts b/packages/language-server/src/server.ts index 4396eda86..60bddbd4e 100644 --- a/packages/language-server/src/server.ts +++ b/packages/language-server/src/server.ts @@ -26,6 +26,7 @@ import _ from 'lodash'; import { LSConfigManager } from './ls-config'; import { urlToPath } from './utils'; import { Logger } from './logger'; +import { DiagnosticsManager } from './lib/DiagnosticsManager'; namespace TagCloseRequest { export const type: RequestType< @@ -99,6 +100,9 @@ export function startServer(options?: LSOptions) { textDocumentSync: { openClose: true, change: TextDocumentSyncKind.Incremental, + save: { + includeText: false + }, }, hoverProvider: true, completionProvider: { @@ -162,6 +166,7 @@ export function startServer(options?: LSOptions) { renameProvider: evt.capabilities.textDocument?.rename?.prepareSupport ? { prepareProvider: true } : true, + }, }; }); @@ -175,7 +180,11 @@ export function startServer(options?: LSOptions) { pluginHost.updateConfig(settings.svelte?.plugin); }); - connection.onDidOpenTextDocument((evt) => docManager.openDocument(evt.textDocument)); + connection.onDidOpenTextDocument((evt) => { + docManager.openDocument(evt.textDocument); + docManager.unmarkOpenedByServer(evt.textDocument.uri); + }); + connection.onDidCloseTextDocument((evt) => docManager.closeDocument(evt.textDocument.uri)); connection.onDidChangeTextDocument((evt) => docManager.updateDocument(evt.textDocument, evt.contentChanges), @@ -219,6 +228,13 @@ export function startServer(options?: LSOptions) { return pluginHost.resolveCompletion(data, completionItem); }); + + const diagnosticsManager = new DiagnosticsManager( + connection.sendDiagnostics, + docManager, + pluginHost.getDiagnostics.bind(pluginHost) + ); + connection.onDidChangeWatchedFiles((para) => { for (const change of para.changes) { const filename = urlToPath(change.uri); @@ -226,17 +242,14 @@ export function startServer(options?: LSOptions) { pluginHost.onWatchFileChanges(filename, change.type); } } + + diagnosticsManager.updateAll(); }); + connection.onDidSaveTextDocument(() => diagnosticsManager.updateAll()); docManager.on( 'documentChange', - _.debounce(async (document: Document) => { - const diagnostics = await pluginHost.getDiagnostics({ uri: document.getURL() }); - connection!.sendDiagnostics({ - uri: document.getURL(), - diagnostics, - }); - }, 500), + _.debounce(async (document: Document) => diagnosticsManager.update(document), 500), ); // The language server protocol does not have a specific "did rename/move files" event, From a7fe030cc6b21a6562380650a0a35152d39322aa Mon Sep 17 00:00:00 2001 From: Lyu Jason Date: Sun, 28 Jun 2020 19:58:08 +0800 Subject: [PATCH 2/3] change to track those opened in client --- .../src/lib/documents/DocumentManager.ts | 16 ++++++---------- .../src/plugins/typescript/LSAndTSDocResolver.ts | 1 - packages/language-server/src/server.ts | 2 +- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/packages/language-server/src/lib/documents/DocumentManager.ts b/packages/language-server/src/lib/documents/DocumentManager.ts index 2df877daf..9dd0cf303 100644 --- a/packages/language-server/src/lib/documents/DocumentManager.ts +++ b/packages/language-server/src/lib/documents/DocumentManager.ts @@ -13,7 +13,7 @@ export type DocumentEvent = 'documentOpen' | 'documentChange' | 'documentClose'; */ export class DocumentManager { private emitter = new EventEmitter(); - private openedByServer = new Set(); + private openedInClient = new Set(); public documents: Map = new Map(); public locked = new Set(); public deleteCandidates = new Set(); @@ -41,22 +41,18 @@ export class DocumentManager { this.locked.add(uri); } - markAsOpenedByServer(uri: string): void { - this.openedByServer.add(uri); - } - - unmarkOpenedByServer(uri: string): void { - this.openedByServer.delete(uri); + markAsOpenedInClient(uri: string): void { + this.openedInClient.add(uri); } getAllOpenedByClient() { return Array.from(this.documents.entries()) - .filter((doc) => !this.openedByServer.has(doc[0])); + .filter((doc) => this.openedInClient.has(doc[0])); } releaseDocument(uri: string): void { this.locked.delete(uri); - this.openedByServer.delete(uri); + this.openedInClient.delete(uri); if (this.deleteCandidates.has(uri)) { this.deleteCandidates.delete(uri); this.closeDocument(uri); @@ -79,7 +75,7 @@ export class DocumentManager { this.deleteCandidates.add(uri); } - this.openedByServer.delete(uri); + this.openedInClient.delete(uri); } updateDocument( diff --git a/packages/language-server/src/plugins/typescript/LSAndTSDocResolver.ts b/packages/language-server/src/plugins/typescript/LSAndTSDocResolver.ts index ae5a2cd53..eee4f5fef 100644 --- a/packages/language-server/src/plugins/typescript/LSAndTSDocResolver.ts +++ b/packages/language-server/src/plugins/typescript/LSAndTSDocResolver.ts @@ -40,7 +40,6 @@ export class LSAndTSDocResolver { version: 0, }); this.docManager.lockDocument(uri); - this.docManager.markAsOpenedByServer(uri); return document; }; diff --git a/packages/language-server/src/server.ts b/packages/language-server/src/server.ts index 60bddbd4e..030b59dd2 100644 --- a/packages/language-server/src/server.ts +++ b/packages/language-server/src/server.ts @@ -182,7 +182,7 @@ export function startServer(options?: LSOptions) { connection.onDidOpenTextDocument((evt) => { docManager.openDocument(evt.textDocument); - docManager.unmarkOpenedByServer(evt.textDocument.uri); + docManager.markAsOpenedInClient(evt.textDocument.uri); }); connection.onDidCloseTextDocument((evt) => docManager.closeDocument(evt.textDocument.uri)); From 13023f6112ea2661ad105727ea845d3cda5e8e0f Mon Sep 17 00:00:00 2001 From: Lyu Jason Date: Sun, 28 Jun 2020 19:59:38 +0800 Subject: [PATCH 3/3] cleanup --- packages/language-server/src/lib/documents/DocumentManager.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/language-server/src/lib/documents/DocumentManager.ts b/packages/language-server/src/lib/documents/DocumentManager.ts index 9dd0cf303..db421b44f 100644 --- a/packages/language-server/src/lib/documents/DocumentManager.ts +++ b/packages/language-server/src/lib/documents/DocumentManager.ts @@ -21,7 +21,6 @@ export class DocumentManager { constructor(private createDocument: (textDocument: TextDocumentItem) => Document) {} openDocument(textDocument: TextDocumentItem): Document { - console.log(textDocument.uri); let document: Document; if (this.documents.has(textDocument.uri)) { document = this.documents.get(textDocument.uri)!;