From abc0784e57610a0cceca63301489918015418df6 Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Thu, 27 Jun 2019 21:30:23 +1000 Subject: Fix `cargo watch` code action filtering There are two issues with the implementation of `provideCodeActions` introduced in #1439: 1. We're returning the code action based on the file its diagnostic is in; not the file the suggested fix is in. I'm not sure how often fixes are suggested cross-file but it's something we should handle. 2. We're not filtering code actions based on the passed range. The means if there is any suggestion in a file we'll show an action for every line of the file. I naively thought that VS Code would filter for us but that was wrong. Unfortunately the VS Code `CodeAction` object is very complex - it can handle edits across multiple files, run commands, etc. This makes it complex to check them for equality or see if any of their edits intersects with a specified range. To make it easier to work with suggestions this introduces a `SuggestedFix` model object and a `SuggestFixCollection` code action provider. This is a layer between the raw Rust JSON and VS Code's `CodeAction`s. I was reluctant to introduce another layer of abstraction here but my attempt to work directly with VS Code's model objects was worse. --- editors/code/src/test/vscode_diagnostics.test.ts | 182 ----------------------- 1 file changed, 182 deletions(-) delete mode 100644 editors/code/src/test/vscode_diagnostics.test.ts (limited to 'editors/code/src/test/vscode_diagnostics.test.ts') diff --git a/editors/code/src/test/vscode_diagnostics.test.ts b/editors/code/src/test/vscode_diagnostics.test.ts deleted file mode 100644 index 9c5d812fa..000000000 --- a/editors/code/src/test/vscode_diagnostics.test.ts +++ /dev/null @@ -1,182 +0,0 @@ -import * as assert from 'assert'; -import * as vscode from 'vscode'; - -import { - areCodeActionsEqual, - areDiagnosticsEqual -} from '../utils/vscode_diagnostics'; - -const uri = vscode.Uri.file('/file/1'); - -const range1 = new vscode.Range( - new vscode.Position(1, 2), - new vscode.Position(3, 4) -); - -const range2 = new vscode.Range( - new vscode.Position(5, 6), - new vscode.Position(7, 8) -); - -describe('areDiagnosticsEqual', () => { - it('should treat identical diagnostics as equal', () => { - const diagnostic1 = new vscode.Diagnostic( - range1, - 'Hello, world!', - vscode.DiagnosticSeverity.Error - ); - - const diagnostic2 = new vscode.Diagnostic( - range1, - 'Hello, world!', - vscode.DiagnosticSeverity.Error - ); - - 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, - 'Hello, world!', - vscode.DiagnosticSeverity.Error - ); - - const diagnostic2 = new vscode.Diagnostic( - range2, - 'Hello, world!', - vscode.DiagnosticSeverity.Error - ); - - assert(!areDiagnosticsEqual(diagnostic1, diagnostic2)); - }); - - it('should treat diagnostics with different messages as inequal', () => { - const diagnostic1 = new vscode.Diagnostic( - range1, - 'Hello, world!', - vscode.DiagnosticSeverity.Error - ); - - const diagnostic2 = new vscode.Diagnostic( - range1, - 'Goodbye!, world!', - vscode.DiagnosticSeverity.Error - ); - - assert(!areDiagnosticsEqual(diagnostic1, diagnostic2)); - }); - - it('should treat diagnostics with different severities as inequal', () => { - const diagnostic1 = new vscode.Diagnostic( - range1, - 'Hello, world!', - vscode.DiagnosticSeverity.Warning - ); - - const diagnostic2 = new vscode.Diagnostic( - range1, - 'Hello, world!', - vscode.DiagnosticSeverity.Error - ); - - assert(!areDiagnosticsEqual(diagnostic1, diagnostic2)); - }); -}); - -describe('areCodeActionsEqual', () => { - it('should treat identical actions as equal', () => { - const codeAction1 = new vscode.CodeAction( - 'Fix me!', - vscode.CodeActionKind.QuickFix - ); - - const codeAction2 = new vscode.CodeAction( - 'Fix me!', - vscode.CodeActionKind.QuickFix - ); - - const edit = new vscode.WorkspaceEdit(); - edit.replace(uri, range1, 'Replace with this'); - codeAction1.edit = edit; - codeAction2.edit = edit; - - assert(areCodeActionsEqual(codeAction1, codeAction2)); - }); - - it('should treat actions with different types as inequal', () => { - const codeAction1 = new vscode.CodeAction( - 'Fix me!', - vscode.CodeActionKind.Refactor - ); - - const codeAction2 = new vscode.CodeAction( - 'Fix me!', - vscode.CodeActionKind.QuickFix - ); - - const edit = new vscode.WorkspaceEdit(); - edit.replace(uri, range1, 'Replace with this'); - codeAction1.edit = edit; - codeAction2.edit = edit; - - assert(!areCodeActionsEqual(codeAction1, codeAction2)); - }); - - it('should treat actions with different titles as inequal', () => { - const codeAction1 = new vscode.CodeAction( - 'Fix me!', - vscode.CodeActionKind.Refactor - ); - - const codeAction2 = new vscode.CodeAction( - 'Do something different!', - vscode.CodeActionKind.Refactor - ); - - const edit = new vscode.WorkspaceEdit(); - edit.replace(uri, range1, 'Replace with this'); - codeAction1.edit = edit; - codeAction2.edit = edit; - - assert(!areCodeActionsEqual(codeAction1, codeAction2)); - }); - - it('should treat actions with different edits as inequal', () => { - const codeAction1 = new vscode.CodeAction( - 'Fix me!', - vscode.CodeActionKind.Refactor - ); - const edit1 = new vscode.WorkspaceEdit(); - edit1.replace(uri, range1, 'Replace with this'); - codeAction1.edit = edit1; - - const codeAction2 = new vscode.CodeAction( - 'Fix me!', - vscode.CodeActionKind.Refactor - ); - const edit2 = new vscode.WorkspaceEdit(); - edit2.replace(uri, range1, 'Replace with this other thing'); - codeAction2.edit = edit2; - - assert(!areCodeActionsEqual(codeAction1, codeAction2)); - }); -}); -- cgit v1.2.3