From dcad07112b0fbe64006e73d5711558e825f0d7bd Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 29 May 2024 09:09:01 +0200 Subject: [PATCH 1/2] improve the dx of running the code analyzer some --- README.md | 20 ++++++-------- client/src/commands.ts | 8 ++++-- client/src/commands/code_analysis.ts | 34 ++++++++++++++++++++++- client/src/extension.ts | 41 ++++++++++++++++++---------- package.json | 5 ---- 5 files changed, 73 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 0b02131a5..a46aa1cc5 100644 --- a/README.md +++ b/README.md @@ -97,15 +97,14 @@ Even if the pre-release channel seems too experimental to you, we still suggest You'll find all ReScript specific settings under the scope `rescript.settings`. -| Setting | Description | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Prompt to Start Build | If there's no ReScript build running already in the opened project, the extension will prompt you and ask if you want to start a build automatically. You can turn off this automatic prompt via the setting `rescript.settings.askToStartBuild`. | -| ReScript Binary Path | The extension will look for the existence of a `node_modules/.bin/rescript` file and use its directory as the `binaryPath`. If it does not find it at the project root (which is where the nearest `rescript.json` resides), it goes up folders in the filesystem recursively until it either finds it (often the case in monorepos) or hits the top level. To override this lookup process, the path can be configured explicitly using the setting `rescript.settings.binaryPath` | -| ReScript Platform Path | The extension will look for the existence of a `node_modules/rescript` directory and use the subdirectory corresponding to the current platform as the `platformPath`. If it does not find it at the project root (which is where the nearest `rescript.json` resides), it goes up folders in the filesystem recursively until it either finds it (often the case in monorepos) or hits the top level. To override this lookup process, the path can be configured explicitly using the setting `rescript.settings.platformPath` | -| Inlay Hints (experimental) | This allows an editor to place annotations inline with text to display type hints. Enable using `rescript.settings.inlayHints.enable: true` | -| Code Lens (experimental) | This tells the editor to add code lenses to function definitions, showing its full type above the definition. Enable using `rescript.settings.codeLens: true` | -| Signature Help | This tells the editor to show signature help when you're writing function calls. Enable using `rescript.settings.signatureHelp.enabled: true` | -| Autostarting the Code Analyzer | The Code Analyzer needs to be started manually by default. However, you can configure the extension to start the Code Analyzer automatically via the setting `rescript.settings.autoRunCodeAnalysis`. | +| Setting | Description | +| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Prompt to Start Build | If there's no ReScript build running already in the opened project, the extension will prompt you and ask if you want to start a build automatically. You can turn off this automatic prompt via the setting `rescript.settings.askToStartBuild`. | +| ReScript Binary Path | The extension will look for the existence of a `node_modules/.bin/rescript` file and use its directory as the `binaryPath`. If it does not find it at the project root (which is where the nearest `rescript.json` resides), it goes up folders in the filesystem recursively until it either finds it (often the case in monorepos) or hits the top level. To override this lookup process, the path can be configured explicitly using the setting `rescript.settings.binaryPath` | +| ReScript Platform Path | The extension will look for the existence of a `node_modules/rescript` directory and use the subdirectory corresponding to the current platform as the `platformPath`. If it does not find it at the project root (which is where the nearest `rescript.json` resides), it goes up folders in the filesystem recursively until it either finds it (often the case in monorepos) or hits the top level. To override this lookup process, the path can be configured explicitly using the setting `rescript.settings.platformPath` | +| Inlay Hints (experimental) | This allows an editor to place annotations inline with text to display type hints. Enable using `rescript.settings.inlayHints.enable: true` | +| Code Lens (experimental) | This tells the editor to add code lenses to function definitions, showing its full type above the definition. Enable using `rescript.settings.codeLens: true` | +| Signature Help | This tells the editor to show signature help when you're writing function calls. Enable using `rescript.settings.signatureHelp.enabled: true` | **Default settings:** @@ -113,9 +112,6 @@ You'll find all ReScript specific settings under the scope `rescript.settings`. // Whether you want the extension to prompt for autostarting a ReScript build if a project is opened with no build running "rescript.settings.askToStartBuild": true, -// Automatically start ReScript's code analysis. -"rescript.settings.autoRunCodeAnalysis": false, - // Path to the directory where cross-platform ReScript binaries are. You can use it if you haven't or don't want to use the installed ReScript from node_modules in your project. "rescript.settings.binaryPath": null diff --git a/client/src/commands.ts b/client/src/commands.ts index 250e47a11..a26e07897 100644 --- a/client/src/commands.ts +++ b/client/src/commands.ts @@ -1,4 +1,4 @@ -import { DiagnosticCollection, OutputChannel } from "vscode"; +import { DiagnosticCollection, OutputChannel, StatusBarItem } from "vscode"; import { DiagnosticsResultCodeActionsMap, @@ -14,12 +14,14 @@ export const codeAnalysisWithReanalyze = ( targetDir: string | null, diagnosticsCollection: DiagnosticCollection, diagnosticsResultCodeActions: DiagnosticsResultCodeActionsMap, - outputChannel: OutputChannel + outputChannel: OutputChannel, + codeAnalysisRunningStatusBarItem: StatusBarItem ) => { runCodeAnalysisWithReanalyze( targetDir, diagnosticsCollection, diagnosticsResultCodeActions, - outputChannel + outputChannel, + codeAnalysisRunningStatusBarItem ); }; diff --git a/client/src/commands/code_analysis.ts b/client/src/commands/code_analysis.ts index fc0dffcca..322844d33 100644 --- a/client/src/commands/code_analysis.ts +++ b/client/src/commands/code_analysis.ts @@ -12,9 +12,27 @@ import { CodeActionKind, WorkspaceEdit, OutputChannel, + StatusBarItem, } from "vscode"; import { analysisProdPath, getAnalysisBinaryPath } from "../utils"; +export let statusBarItem = { + setToStopText: (codeAnalysisRunningStatusBarItem: StatusBarItem) => { + codeAnalysisRunningStatusBarItem.text = "$(debug-stop) Stop Code Analyzer"; + codeAnalysisRunningStatusBarItem.tooltip = null; + }, + setToRunningText: (codeAnalysisRunningStatusBarItem: StatusBarItem) => { + codeAnalysisRunningStatusBarItem.text = + "$(loading~spin) Running code analysis..."; + codeAnalysisRunningStatusBarItem.tooltip = null; + }, + setToFailed: (codeAnalysisRunningStatusBarItem: StatusBarItem) => { + codeAnalysisRunningStatusBarItem.text = "$(alert) Failed"; + codeAnalysisRunningStatusBarItem.tooltip = + "Something went wrong when running the code analysis."; + }, +}; + export type DiagnosticsResultCodeActionsMap = Map< string, { range: Range; codeAction: CodeAction }[] @@ -42,6 +60,7 @@ enum ClassifiedMessage { let classifyMessage = (msg: string) => { if ( msg.endsWith(" is never used") || + msg.endsWith(" is never used and could have side effects") || msg.endsWith(" has no side effects and can be removed") ) { return ClassifiedMessage.Removable; @@ -152,6 +171,12 @@ let resultsToDiagnostics = ( "" ); + codeAction.command = { + command: "rescript-vscode.clear_diagnostic", + title: "Clear diagnostic", + arguments: [diagnostic], + }; + codeAction.edit = codeActionEdit; if (diagnosticsResultCodeActions.has(item.file)) { @@ -177,7 +202,8 @@ export const runCodeAnalysisWithReanalyze = ( targetDir: string | null, diagnosticsCollection: DiagnosticCollection, diagnosticsResultCodeActions: DiagnosticsResultCodeActionsMap, - outputChannel: OutputChannel + outputChannel: OutputChannel, + codeAnalysisRunningStatusBarItem: StatusBarItem ) => { let currentDocument = window.activeTextEditor.document; let cwd = targetDir ?? path.dirname(currentDocument.uri.fsPath); @@ -188,12 +214,15 @@ export const runCodeAnalysisWithReanalyze = ( return; } + statusBarItem.setToRunningText(codeAnalysisRunningStatusBarItem); + let opts = ["reanalyze", "-json"]; let p = cp.spawn(binaryPath, opts, { cwd, }); if (p.stdout == null) { + statusBarItem.setToFailed(codeAnalysisRunningStatusBarItem); window.showErrorMessage("Something went wrong."); return; } @@ -252,6 +281,7 @@ export const runCodeAnalysisWithReanalyze = ( if (json == null) { // If reanalyze failed for some reason we'll clear the diagnostics. diagnosticsCollection.clear(); + statusBarItem.setToFailed(codeAnalysisRunningStatusBarItem); return; } @@ -272,5 +302,7 @@ export const runCodeAnalysisWithReanalyze = ( diagnosticsMap.forEach((diagnostics, filePath) => { diagnosticsCollection.set(Uri.parse(filePath), diagnostics); }); + + statusBarItem.setToStopText(codeAnalysisRunningStatusBarItem); }); }; diff --git a/client/src/extension.ts b/client/src/extension.ts index 00b60e50b..08bcfd1fa 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -12,6 +12,7 @@ import { CodeAction, WorkspaceEdit, CodeActionKind, + Diagnostic, } from "vscode"; import { @@ -23,7 +24,10 @@ import { } from "vscode-languageclient/node"; import * as customCommands from "./commands"; -import { DiagnosticsResultCodeActionsMap } from "./commands/code_analysis"; +import { + DiagnosticsResultCodeActionsMap, + statusBarItem, +} from "./commands/code_analysis"; let client: LanguageClient; @@ -150,7 +154,8 @@ export function activate(context: ExtensionContext) { inCodeAnalysisState.activatedFromDirectory, diagnosticsCollection, diagnosticsResultCodeActions, - outputChannel + outputChannel, + codeAnalysisRunningStatusBarItem ); } }) @@ -228,6 +233,21 @@ export function activate(context: ExtensionContext) { customCommands.createInterface(client); }); + commands.registerCommand( + "rescript-vscode.clear_diagnostic", + (diagnostic: Diagnostic) => { + const editor = window.activeTextEditor; + if (!editor) { + return; + } + + const document = editor.document; + const diagnostics = diagnosticsCollection.get(document.uri); + const newDiagnostics = diagnostics.filter((d) => d !== diagnostic); + diagnosticsCollection.set(document.uri, newDiagnostics); + } + ); + commands.registerCommand("rescript-vscode.open_compiled", () => { customCommands.openCompiled(client); }); @@ -272,13 +292,14 @@ export function activate(context: ExtensionContext) { codeAnalysisRunningStatusBarItem.command = "rescript-vscode.stop_code_analysis"; codeAnalysisRunningStatusBarItem.show(); - codeAnalysisRunningStatusBarItem.text = "$(debug-stop) Stop Code Analyzer"; + statusBarItem.setToStopText(codeAnalysisRunningStatusBarItem); customCommands.codeAnalysisWithReanalyze( inCodeAnalysisState.activatedFromDirectory, diagnosticsCollection, diagnosticsResultCodeActions, - outputChannel + outputChannel, + codeAnalysisRunningStatusBarItem ); }); @@ -319,7 +340,8 @@ export function activate(context: ExtensionContext) { if ( affectsConfiguration("rescript.settings.inlayHints") || affectsConfiguration("rescript.settings.codeLens") || - affectsConfiguration("rescript.settings.signatureHelp") + affectsConfiguration("rescript.settings.signatureHelp") || + affectsConfiguration("rescript.settings.incrementalTypechecking") ) { commands.executeCommand("rescript-vscode.restart_language_server"); } else { @@ -333,15 +355,6 @@ export function activate(context: ExtensionContext) { } }) ); - - // Autostart code analysis if wanted - if ( - workspace - .getConfiguration("rescript.settings") - .get("autoRunCodeAnalysis") - ) { - commands.executeCommand("rescript-vscode.start_code_analysis"); - } } export function deactivate(): Thenable | undefined { diff --git a/package.json b/package.json index cb5193430..82356a3b0 100644 --- a/package.json +++ b/package.json @@ -148,11 +148,6 @@ "default": true, "description": "Whether you want the extension to prompt for autostarting a ReScript build if a project is opened with no build running." }, - "rescript.settings.autoRunCodeAnalysis": { - "type": "boolean", - "default": false, - "description": "Automatically start ReScript's code analysis." - }, "rescript.settings.inlayHints.enable": { "type": "boolean", "default": false, From f829a24490949b98e6a7a1dc58e2df00866b2e25 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 29 May 2024 09:12:47 +0200 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22fabea6d..991d689a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ - Adjust function template snippet return. https://github.com/rescript-lang/rescript-vscode/pull/985 - Don't expand `type t` maker functions in patterns. https://github.com/rescript-lang/rescript-vscode/pull/986 - Use `loc` for identifiers to get more and better completions in certain scenarios with type parameters. https://github.com/rescript-lang/rescript-vscode/pull/993 +- Improve the DX of running the code analyzer some. https://github.com/rescript-lang/rescript-vscode/pull/995 #### :rocket: New Feature