From d1529aff5e9d8a7d888702e9d9ba1cc575e1db61 Mon Sep 17 00:00:00 2001 From: Damien Rajon <145502+pyrho@users.noreply.github.com> Date: Wed, 18 Nov 2020 21:32:45 +0100 Subject: [PATCH 1/2] feat(diagnostics): ability to ignore some codes --- server/src/cli.ts | 4 +++- server/src/diagnostic-queue.ts | 11 ++++++++--- server/src/lsp-connection.ts | 12 ++++++++++-- server/src/lsp-server.spec.ts | 25 +++++++++++++++++++++++++ server/src/lsp-server.ts | 10 +++++++++- server/src/test-utils.ts | 1 + 6 files changed, 56 insertions(+), 7 deletions(-) diff --git a/server/src/cli.ts b/server/src/cli.ts index ad4232a7..007f0778 100644 --- a/server/src/cli.ts +++ b/server/src/cli.ts @@ -21,6 +21,7 @@ const program = new Command('typescript-language-server') .option('--tsserver-log-verbosity ', 'Specify a tsserver log verbosity (terse, normal, verbose). Defaults to `normal`.' + ' example: --tsserver-log-verbosity verbose') .option('--tsserver-path ', `Specify path to tsserver. example: --tsserver-path=${getTsserverExecutable()}`) + .option('--ignored-diagnostic-codes ', 'Specify a diagnostic codes to be ignored. example: --ignored-diagnostic-codes 1337 42') .parse(process.argv); if (!(program.stdio || program.socket || program.nodeIpc)) { @@ -45,5 +46,6 @@ createLspConnection({ tsserverPath: program.tsserverPath as string, tsserverLogFile: program.tsserverLogFile as string, tsserverLogVerbosity: program.tsserverLogVerbosity as string, - showMessageLevel: logLevel as lsp.MessageType + showMessageLevel: logLevel as lsp.MessageType, + ignoredDiagnosticCodes: program.ignoredDiagnosticCodes || [] as number[], }).listen(); diff --git a/server/src/diagnostic-queue.ts b/server/src/diagnostic-queue.ts index d8c9c350..6c54eee8 100644 --- a/server/src/diagnostic-queue.ts +++ b/server/src/diagnostic-queue.ts @@ -49,7 +49,8 @@ export class DiagnosticEventQueue { constructor( protected readonly publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void, protected readonly documents: LspDocuments, - protected readonly logger: Logger + protected readonly logger: Logger, + protected readonly ignoredDiagnosticCodes: number[], ) { } updateDiagnostics(kind: EventTypes, event: tsp.DiagnosticEvent): void { @@ -57,10 +58,14 @@ export class DiagnosticEventQueue { this.logger.error(`Received empty ${event.event} diagnostics.`) return; } - const { file } = event.body; + const { file, diagnostics: diagnosticsFromServer } = event.body; + + // `d.code` can be undefined + const isDiagnosticAllowed = (d: tsp.Diagnostic) => !d.code || this.ignoredDiagnosticCodes.indexOf(d.code) === -1; + const filteredDiagnostics = diagnosticsFromServer.filter(isDiagnosticAllowed); const uri = pathToUri(file, this.documents); const diagnostics = this.diagnostics.get(uri) || new FileDiagnostics(uri, this.publishDiagnostics, this.documents); - diagnostics.update(kind, event.body.diagnostics); + diagnostics.update(kind, filteredDiagnostics); this.diagnostics.set(uri, diagnostics); } } \ No newline at end of file diff --git a/server/src/lsp-connection.ts b/server/src/lsp-connection.ts index 15661679..8a36642b 100644 --- a/server/src/lsp-connection.ts +++ b/server/src/lsp-connection.ts @@ -16,7 +16,14 @@ export interface IServerOptions { tsserverPath: string; tsserverLogFile?: string; tsserverLogVerbosity?: string; - showMessageLevel: lsp.MessageType + showMessageLevel: lsp.MessageType; + + /** + * Diagnostics code to be omitted in the client response + * See https://github.com/microsoft/TypeScript/blob/master/src/compiler/diagnosticMessages.json + * for a full list of valid codes + */ + ignoredDiagnosticCodes: number[]; } export function createLspConnection(options: IServerOptions): lsp.IConnection { @@ -28,7 +35,8 @@ export function createLspConnection(options: IServerOptions): lsp.IConnection { lspClient, tsserverPath: options.tsserverPath, tsserverLogFile: options.tsserverLogFile, - tsserverLogVerbosity: options.tsserverLogVerbosity + tsserverLogVerbosity: options.tsserverLogVerbosity, + ignoredDiagnosticCodes: options.ignoredDiagnosticCodes, }); connection.onInitialize(server.initialize.bind(server)); diff --git a/server/src/lsp-server.spec.ts b/server/src/lsp-server.spec.ts index c0499aac..ec30fc0a 100644 --- a/server/src/lsp-server.spec.ts +++ b/server/src/lsp-server.spec.ts @@ -184,6 +184,31 @@ describe('diagnostics', () => { await new Promise(resolve => setTimeout(resolve, 200)); assert.equal(diagnosticsForThisTest.length, 2, JSON.stringify(diagnostics)); }).timeout(10000); + + it('code 80006 is ignored', async () => { + const doc = { + uri: uri('diagnosticsBar2.ts'), + languageId: 'typescript', + version: 1, + text: ` + function x() { + return Promise.resolve(1).then(a => a + 1); + } + const i = 1; + ` + } + server.didOpenTextDocument({ + textDocument: doc + }) + + server.requestDiagnostics(); + await server.requestDiagnostics(); + await new Promise(resolve => setTimeout(resolve, 200)); + const diagnosticsForThisFile = diagnostics.filter(d => d!.uri === doc.uri); + assert.equal(diagnosticsForThisFile.length, 1, JSON.stringify(diagnostics)); + const fileDiagnostics = diagnosticsForThisFile[0]!.diagnostics; + assert.equal(fileDiagnostics.length, 0); + }).timeout(10000); }); describe('document symbol', () => { diff --git a/server/src/lsp-server.ts b/server/src/lsp-server.ts index eabc664b..bff2ac17 100644 --- a/server/src/lsp-server.ts +++ b/server/src/lsp-server.ts @@ -45,6 +45,13 @@ export interface IServerOptions { tsserverLogFile?: string; tsserverLogVerbosity?: string; lspClient: LspClient; + + /** + * Diagnostics code to be omitted in the client response + * See https://github.com/microsoft/TypeScript/blob/master/src/compiler/diagnosticMessages.json + * for a full list of valid codes + */ + ignoredDiagnosticCodes: number[]; } export class LspServer { @@ -62,7 +69,8 @@ export class LspServer { this.diagnosticQueue = new DiagnosticEventQueue( diagnostics => this.options.lspClient.publishDiagnostics(diagnostics), this.documents, - this.logger + this.logger, + this.options.ignoredDiagnosticCodes, ); } diff --git a/server/src/test-utils.ts b/server/src/test-utils.ts index a2d18530..96d49300 100644 --- a/server/src/test-utils.ts +++ b/server/src/test-utils.ts @@ -67,6 +67,7 @@ export async function createServer(options: { applyWorkspaceEdit: () => Promise.reject(new Error('unsupported')), rename: () => Promise.reject(new Error('unsupported')) }, + ignoredDiagnosticCodes: [80006], }); await server.initialize({ From c1666a2044951ea74b40739a274ae85dcaae932c Mon Sep 17 00:00:00 2001 From: Damien Rajon <145502+pyrho@users.noreply.github.com> Date: Fri, 20 Nov 2020 16:30:02 +0100 Subject: [PATCH 2/2] fixup! feat(diagnostics): ability to ignore some codes --- server/src/lsp-server.spec.ts | 10 +++++----- server/src/test-utils.ts | 8 +++++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/server/src/lsp-server.spec.ts b/server/src/lsp-server.spec.ts index ec30fc0a..1be37578 100644 --- a/server/src/lsp-server.spec.ts +++ b/server/src/lsp-server.spec.ts @@ -185,16 +185,16 @@ describe('diagnostics', () => { assert.equal(diagnosticsForThisTest.length, 2, JSON.stringify(diagnostics)); }).timeout(10000); - it('code 80006 is ignored', async () => { + it('code 6133 (ununsed variable) is ignored', async () => { const doc = { uri: uri('diagnosticsBar2.ts'), languageId: 'typescript', version: 1, text: ` - function x() { - return Promise.resolve(1).then(a => a + 1); - } - const i = 1; + function foo() { + const x = 42; + return 1; + } ` } server.didOpenTextDocument({ diff --git a/server/src/test-utils.ts b/server/src/test-utils.ts index 96d49300..9da02786 100644 --- a/server/src/test-utils.ts +++ b/server/src/test-utils.ts @@ -42,6 +42,12 @@ export function lastPosition(document: lsp.TextDocumentItem, match: string): lsp return positionAt(document, document.text.lastIndexOf(match)); } +/** + * Creates a tsserver instance for testing. + * + * Warning: The diagnostic code `6133` ("'x' is declared but its value is never read.") is ignored + * is ignored for the purpose of testing that ignoring a code works. + */ export async function createServer(options: { rootUri: string | null tsserverLogVerbosity?: string @@ -67,7 +73,7 @@ export async function createServer(options: { applyWorkspaceEdit: () => Promise.reject(new Error('unsupported')), rename: () => Promise.reject(new Error('unsupported')) }, - ignoredDiagnosticCodes: [80006], + ignoredDiagnosticCodes: [6133], }); await server.initialize({