From 500fe46e6c0df7827d56c7cd07741533422e7743 Mon Sep 17 00:00:00 2001 From: Emil Lauridsen Date: Wed, 25 Dec 2019 17:34:51 +0100 Subject: Remove cargo watch supporting code and tests from vscode extension --- editors/code/src/utils/diagnostics/SuggestedFix.ts | 67 ----- .../utils/diagnostics/SuggestedFixCollection.ts | 77 ------ editors/code/src/utils/diagnostics/rust.ts | 299 --------------------- editors/code/src/utils/diagnostics/vscode.ts | 14 - 4 files changed, 457 deletions(-) delete mode 100644 editors/code/src/utils/diagnostics/SuggestedFix.ts delete mode 100644 editors/code/src/utils/diagnostics/SuggestedFixCollection.ts delete mode 100644 editors/code/src/utils/diagnostics/rust.ts delete mode 100644 editors/code/src/utils/diagnostics/vscode.ts (limited to 'editors/code/src/utils') diff --git a/editors/code/src/utils/diagnostics/SuggestedFix.ts b/editors/code/src/utils/diagnostics/SuggestedFix.ts deleted file mode 100644 index 6e660bb61..000000000 --- a/editors/code/src/utils/diagnostics/SuggestedFix.ts +++ /dev/null @@ -1,67 +0,0 @@ -import * as vscode from 'vscode'; - -import { SuggestionApplicability } from './rust'; - -/** - * Model object for text replacements suggested by the Rust compiler - * - * This is an intermediate form between the raw `rustc` JSON and a - * `vscode.CodeAction`. It's optimised for the use-cases of - * `SuggestedFixCollection`. - */ -export default class SuggestedFix { - public readonly title: string; - public readonly location: vscode.Location; - public readonly replacement: string; - public readonly applicability: SuggestionApplicability; - - /** - * Diagnostics this suggested fix could resolve - */ - public diagnostics: vscode.Diagnostic[]; - - constructor( - title: string, - location: vscode.Location, - replacement: string, - applicability: SuggestionApplicability = SuggestionApplicability.Unspecified, - ) { - this.title = title; - this.location = location; - this.replacement = replacement; - this.applicability = applicability; - this.diagnostics = []; - } - - /** - * Determines if this suggested fix is equivalent to another instance - */ - public isEqual(other: SuggestedFix): boolean { - return ( - this.title === other.title && - this.location.range.isEqual(other.location.range) && - this.replacement === other.replacement && - this.applicability === other.applicability - ); - } - - /** - * Converts this suggested fix to a VS Code Quick Fix code action - */ - public toCodeAction(): vscode.CodeAction { - const codeAction = new vscode.CodeAction( - this.title, - vscode.CodeActionKind.QuickFix, - ); - - const edit = new vscode.WorkspaceEdit(); - edit.replace(this.location.uri, this.location.range, this.replacement); - codeAction.edit = edit; - - codeAction.isPreferred = - this.applicability === SuggestionApplicability.MachineApplicable; - - codeAction.diagnostics = [...this.diagnostics]; - return codeAction; - } -} diff --git a/editors/code/src/utils/diagnostics/SuggestedFixCollection.ts b/editors/code/src/utils/diagnostics/SuggestedFixCollection.ts deleted file mode 100644 index 57c9856cf..000000000 --- a/editors/code/src/utils/diagnostics/SuggestedFixCollection.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as vscode from 'vscode'; -import SuggestedFix from './SuggestedFix'; - -/** - * Collection of suggested fixes across multiple documents - * - * This stores `SuggestedFix` model objects and returns them via the - * `vscode.CodeActionProvider` interface. - */ -export default class SuggestedFixCollection - implements vscode.CodeActionProvider { - public static PROVIDED_CODE_ACTION_KINDS = [vscode.CodeActionKind.QuickFix]; - - /** - * Map of document URI strings to suggested fixes - */ - private suggestedFixes: Map; - - constructor() { - this.suggestedFixes = new Map(); - } - - /** - * Clears all suggested fixes across all documents - */ - public clear(): void { - this.suggestedFixes = new Map(); - } - - /** - * Adds a suggested fix for the given diagnostic - * - * Some suggested fixes will appear in multiple diagnostics. For example, - * forgetting a `mut` on a variable will suggest changing the delaration on - * every mutable usage site. If the suggested fix has already been added - * this method will instead associate the existing fix with the new - * diagnostic. - */ - public addSuggestedFixForDiagnostic( - suggestedFix: SuggestedFix, - diagnostic: vscode.Diagnostic, - ): void { - const fileUriString = suggestedFix.location.uri.toString(); - const fileSuggestions = this.suggestedFixes.get(fileUriString) || []; - - const existingSuggestion = fileSuggestions.find(s => - s.isEqual(suggestedFix), - ); - - if (existingSuggestion) { - // The existing suggestion also applies to this new diagnostic - existingSuggestion.diagnostics.push(diagnostic); - } else { - // We haven't seen this suggestion before - suggestedFix.diagnostics.push(diagnostic); - fileSuggestions.push(suggestedFix); - } - - this.suggestedFixes.set(fileUriString, fileSuggestions); - } - - /** - * Filters suggested fixes by their document and range and converts them to - * code actions - */ - public provideCodeActions( - document: vscode.TextDocument, - range: vscode.Range, - ): vscode.CodeAction[] { - const documentUriString = document.uri.toString(); - - const suggestedFixes = this.suggestedFixes.get(documentUriString); - return (suggestedFixes || []) - .filter(({ location }) => location.range.intersection(range)) - .map(suggestedEdit => suggestedEdit.toCodeAction()); - } -} diff --git a/editors/code/src/utils/diagnostics/rust.ts b/editors/code/src/utils/diagnostics/rust.ts deleted file mode 100644 index 1f0c0d3e4..000000000 --- a/editors/code/src/utils/diagnostics/rust.ts +++ /dev/null @@ -1,299 +0,0 @@ -import * as path from 'path'; -import * as vscode from 'vscode'; - -import SuggestedFix from './SuggestedFix'; - -export enum SuggestionApplicability { - MachineApplicable = 'MachineApplicable', - HasPlaceholders = 'HasPlaceholders', - MaybeIncorrect = 'MaybeIncorrect', - Unspecified = 'Unspecified', -} - -export interface RustDiagnosticSpanMacroExpansion { - span: RustDiagnosticSpan; - macro_decl_name: string; - def_site_span?: RustDiagnosticSpan; -} - -// Reference: -// https://github.com/rust-lang/rust/blob/master/src/libsyntax/json.rs -export interface RustDiagnosticSpan { - line_start: number; - line_end: number; - column_start: number; - column_end: number; - is_primary: boolean; - file_name: string; - label?: string; - expansion?: RustDiagnosticSpanMacroExpansion; - suggested_replacement?: string; - suggestion_applicability?: SuggestionApplicability; -} - -export interface RustDiagnostic { - spans: RustDiagnosticSpan[]; - rendered: string; - message: string; - level: string; - code?: { - code: string; - }; - children: RustDiagnostic[]; -} - -export interface MappedRustDiagnostic { - location: vscode.Location; - diagnostic: vscode.Diagnostic; - suggestedFixes: SuggestedFix[]; -} - -interface MappedRustChildDiagnostic { - related?: vscode.DiagnosticRelatedInformation; - suggestedFix?: SuggestedFix; - messageLine?: string; -} - -/** - * Converts a Rust level string to a VsCode severity - */ -function mapLevelToSeverity(s: string): vscode.DiagnosticSeverity { - if (s === 'error') { - return vscode.DiagnosticSeverity.Error; - } - if (s.startsWith('warn')) { - return vscode.DiagnosticSeverity.Warning; - } - return vscode.DiagnosticSeverity.Information; -} - -/** - * Check whether a file name is from macro invocation - */ -function isFromMacro(fileName: string): boolean { - return fileName.startsWith('<') && fileName.endsWith('>'); -} - -/** - * Converts a Rust macro span to a VsCode location recursively - */ -function mapMacroSpanToLocation( - spanMacro: RustDiagnosticSpanMacroExpansion, -): vscode.Location | undefined { - if (!isFromMacro(spanMacro.span.file_name)) { - return mapSpanToLocation(spanMacro.span); - } - - if (spanMacro.span.expansion) { - return mapMacroSpanToLocation(spanMacro.span.expansion); - } - - return; -} - -/** - * Converts a Rust span to a VsCode location - */ -function mapSpanToLocation(span: RustDiagnosticSpan): vscode.Location { - if (isFromMacro(span.file_name) && span.expansion) { - const macroLoc = mapMacroSpanToLocation(span.expansion); - if (macroLoc) { - return macroLoc; - } - } - - const fileName = path.join(vscode.workspace.rootPath || '', span.file_name); - const fileUri = vscode.Uri.file(fileName); - - const range = new vscode.Range( - new vscode.Position(span.line_start - 1, span.column_start - 1), - new vscode.Position(span.line_end - 1, span.column_end - 1), - ); - - return new vscode.Location(fileUri, range); -} - -/** - * Converts a secondary Rust span to a VsCode related information - * - * If the span is unlabelled this will return `undefined`. - */ -function mapSecondarySpanToRelated( - span: RustDiagnosticSpan, -): vscode.DiagnosticRelatedInformation | undefined { - if (!span.label) { - // Nothing to label this with - return; - } - - const location = mapSpanToLocation(span); - return new vscode.DiagnosticRelatedInformation(location, span.label); -} - -/** - * Determines if diagnostic is related to unused code - */ -function isUnusedOrUnnecessary(rd: RustDiagnostic): boolean { - if (!rd.code) { - return false; - } - - return [ - 'dead_code', - 'unknown_lints', - 'unreachable_code', - 'unused_attributes', - 'unused_imports', - 'unused_macros', - 'unused_variables', - ].includes(rd.code.code); -} - -/** - * Determines if diagnostic is related to deprecated code - */ -function isDeprecated(rd: RustDiagnostic): boolean { - if (!rd.code) { - return false; - } - - return ['deprecated'].includes(rd.code.code); -} - -/** - * Converts a Rust child diagnostic to a VsCode related information - * - * This can have three outcomes: - * - * 1. If this is no primary span this will return a `noteLine` - * 2. If there is a primary span with a suggested replacement it will return a - * `codeAction`. - * 3. If there is a primary span without a suggested replacement it will return - * a `related`. - */ -function mapRustChildDiagnostic(rd: RustDiagnostic): MappedRustChildDiagnostic { - const span = rd.spans.find(s => s.is_primary); - - if (!span) { - // `rustc` uses these spanless children as a way to print multi-line - // messages - return { messageLine: rd.message }; - } - - // If we have a primary span use its location, otherwise use the parent - const location = mapSpanToLocation(span); - - // We need to distinguish `null` from an empty string - if (span && typeof span.suggested_replacement === 'string') { - // Include our replacement in the title unless it's empty - const title = span.suggested_replacement - ? `${rd.message}: \`${span.suggested_replacement}\`` - : rd.message; - - return { - suggestedFix: new SuggestedFix( - title, - location, - span.suggested_replacement, - span.suggestion_applicability, - ), - }; - } else { - const related = new vscode.DiagnosticRelatedInformation( - location, - rd.message, - ); - - return { related }; - } -} - -/** - * Converts a Rust root diagnostic to VsCode form - * - * This flattens the Rust diagnostic by: - * - * 1. Creating a `vscode.Diagnostic` with the root message and primary span. - * 2. Adding any labelled secondary spans to `relatedInformation` - * 3. Categorising child diagnostics as either `SuggestedFix`es, - * `relatedInformation` or additional message lines. - * - * If the diagnostic has no primary span this will return `undefined` - */ -export function mapRustDiagnosticToVsCode( - rd: RustDiagnostic, -): MappedRustDiagnostic | undefined { - const primarySpan = rd.spans.find(s => s.is_primary); - if (!primarySpan) { - return; - } - - const location = mapSpanToLocation(primarySpan); - const secondarySpans = rd.spans.filter(s => !s.is_primary); - - const severity = mapLevelToSeverity(rd.level); - let primarySpanLabel = primarySpan.label; - - const vd = new vscode.Diagnostic(location.range, rd.message, severity); - - 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 = []; - vd.tags = []; - - for (const secondarySpan of secondarySpans) { - const related = mapSecondarySpanToRelated(secondarySpan); - if (related) { - vd.relatedInformation.push(related); - } - } - - const suggestedFixes = []; - for (const child of rd.children) { - const { related, suggestedFix, messageLine } = mapRustChildDiagnostic( - child, - ); - - if (related) { - vd.relatedInformation.push(related); - } - if (suggestedFix) { - suggestedFixes.push(suggestedFix); - } - if (messageLine) { - vd.message += `\n${messageLine}`; - - // These secondary messages usually duplicate the content of the - // primary span label. - primarySpanLabel = undefined; - } - } - - if (primarySpanLabel) { - vd.message += `\n${primarySpanLabel}`; - } - - if (isUnusedOrUnnecessary(rd)) { - vd.tags.push(vscode.DiagnosticTag.Unnecessary); - } - - if (isDeprecated(rd)) { - vd.tags.push(vscode.DiagnosticTag.Deprecated); - } - - return { - location, - diagnostic: vd, - suggestedFixes, - }; -} diff --git a/editors/code/src/utils/diagnostics/vscode.ts b/editors/code/src/utils/diagnostics/vscode.ts deleted file mode 100644 index f4a5450e2..000000000 --- a/editors/code/src/utils/diagnostics/vscode.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as vscode from 'vscode'; - -/** Compares two `vscode.Diagnostic`s for equality */ -export function areDiagnosticsEqual( - left: vscode.Diagnostic, - right: vscode.Diagnostic, -): boolean { - return ( - left.source === right.source && - left.severity === right.severity && - left.range.isEqual(right.range) && - left.message === right.message - ); -} -- cgit v1.2.3