From a8a1bc4b15b75e5702cb1ce1d4c5ab3153dbe3c9 Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Thu, 27 Jun 2019 08:47:36 +1000 Subject: Extract lint scopes from `cargo watch` Currently all of our VS Code diagnostics are given the source of `rustc`. However, if you have something like `cargo-watch.command` set to `clippy` it will also watch for Clippy lints. The `rustc` source is a bit misleading in that case. Fortunately, Rust's tool lints (RFC 2103) line up perfectly with VS Code's concept of `source`. This checks for lints scoped to a given tool and then splits them in to a `source` and tool-specific `code`. --- editors/code/src/test/rust_diagnostics.test.ts | 9 +++++---- editors/code/src/test/vscode_diagnostics.test.ts | 18 ++++++++++++++++++ editors/code/src/utils/rust_diagnostics.ts | 14 ++++++++++++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/editors/code/src/test/rust_diagnostics.test.ts b/editors/code/src/test/rust_diagnostics.test.ts index 5eb064b97..f27c58fe2 100644 --- a/editors/code/src/test/rust_diagnostics.test.ts +++ b/editors/code/src/test/rust_diagnostics.test.ts @@ -37,6 +37,7 @@ describe('mapRustDiagnosticToVsCode', () => { diagnostic.severity, vscode.DiagnosticSeverity.Error ); + assert.strictEqual(diagnostic.source, 'rustc'); assert.strictEqual( diagnostic.message, [ @@ -72,6 +73,7 @@ describe('mapRustDiagnosticToVsCode', () => { ].join('\n') ); assert.strictEqual(diagnostic.code, 'unused_variables'); + assert.strictEqual(diagnostic.source, 'rustc'); assert.deepStrictEqual(diagnostic.tags, [ vscode.DiagnosticTag.Unnecessary ]); @@ -101,6 +103,7 @@ describe('mapRustDiagnosticToVsCode', () => { 'this function takes 2 parameters but 3 parameters were supplied' ); assert.strictEqual(diagnostic.code, 'E0061'); + assert.strictEqual(diagnostic.source, 'rustc'); assert.strictEqual(diagnostic.tags, undefined); // One related information for the original definition @@ -125,6 +128,7 @@ describe('mapRustDiagnosticToVsCode', () => { diagnostic.severity, vscode.DiagnosticSeverity.Warning ); + assert.strictEqual(diagnostic.source, 'clippy'); assert.strictEqual( diagnostic.message, [ @@ -133,10 +137,7 @@ describe('mapRustDiagnosticToVsCode', () => { 'for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref' ].join('\n') ); - assert.strictEqual( - diagnostic.code, - 'clippy::trivially_copy_pass_by_ref' - ); + assert.strictEqual(diagnostic.code, 'trivially_copy_pass_by_ref'); assert.strictEqual(diagnostic.tags, undefined); // One related information for the lint definition diff --git a/editors/code/src/test/vscode_diagnostics.test.ts b/editors/code/src/test/vscode_diagnostics.test.ts index ca4345626..9c5d812fa 100644 --- a/editors/code/src/test/vscode_diagnostics.test.ts +++ b/editors/code/src/test/vscode_diagnostics.test.ts @@ -35,6 +35,24 @@ describe('areDiagnosticsEqual', () => { assert(areDiagnosticsEqual(diagnostic1, diagnostic2)); }); + it('should treat diagnostics with different sources as inequal', () => { + const diagnostic1 = new vscode.Diagnostic( + range1, + 'Hello, world!', + vscode.DiagnosticSeverity.Error + ); + diagnostic1.source = 'rustc'; + + const diagnostic2 = new vscode.Diagnostic( + range1, + 'Hello, world!', + vscode.DiagnosticSeverity.Error + ); + diagnostic2.source = 'clippy'; + + assert(!areDiagnosticsEqual(diagnostic1, diagnostic2)); + }); + it('should treat diagnostics with different ranges as inequal', () => { const diagnostic1 = new vscode.Diagnostic( range1, diff --git a/editors/code/src/utils/rust_diagnostics.ts b/editors/code/src/utils/rust_diagnostics.ts index ed049c95e..3c524cb37 100644 --- a/editors/code/src/utils/rust_diagnostics.ts +++ b/editors/code/src/utils/rust_diagnostics.ts @@ -187,8 +187,18 @@ export function mapRustDiagnosticToVsCode( const vd = new vscode.Diagnostic(location.range, rd.message, severity); - vd.source = 'rustc'; - vd.code = rd.code ? rd.code.code : undefined; + let source = 'rustc'; + let code = rd.code && rd.code.code; + if (code) { + // See if this is an RFC #2103 scoped lint (e.g. from Clippy) + const scopedCode = code.split('::'); + if (scopedCode.length === 2) { + [source, code] = scopedCode; + } + } + + vd.source = source; + vd.code = code; vd.relatedInformation = []; for (const secondarySpan of secondarySpans) { -- cgit v1.2.3