about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-19 06:58:52 +0000
committerbors <bors@rust-lang.org>2022-08-19 06:58:52 +0000
commit04c487dd516e30f3145bb792c3cbf2265e8e55b3 (patch)
tree5c8e63d7611468d98a1965da9483e8f7289f3903
parent917bd68b37de4e60e7203061a0a9c23b74d2b5c2 (diff)
parent45b7b6a60a7404d093f4afe81a0da10824cef7b8 (diff)
downloadrust-04c487dd516e30f3145bb792c3cbf2265e8e55b3.tar.gz
rust-04c487dd516e30f3145bb792c3cbf2265e8e55b3.zip
Auto merge of #13063 - Veykril:stop-flycheck, r=Veykril
Implement lsp extension for cancelling running flychecks

Fixes https://github.com/rust-lang/rust-analyzer/issues/4828
-rw-r--r--crates/flycheck/src/lib.rs26
-rw-r--r--crates/rust-analyzer/src/handlers.rs6
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs8
-rw-r--r--crates/rust-analyzer/src/main_loop.rs7
-rw-r--r--docs/dev/lsp-extensions.md2
-rw-r--r--editors/code/package.json5
-rw-r--r--editors/code/src/commands.ts6
-rw-r--r--editors/code/src/lsp_ext.ts30
-rw-r--r--editors/code/src/main.ts1
9 files changed, 69 insertions, 22 deletions
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs
index 2bebea2fbfe..c22945c81fc 100644
--- a/crates/flycheck/src/lib.rs
+++ b/crates/flycheck/src/lib.rs
@@ -77,8 +77,13 @@ impl FlycheckHandle {
     }
 
     /// Schedule a re-start of the cargo check worker.
-    pub fn update(&self) {
-        self.sender.send(Restart).unwrap();
+    pub fn restart(&self) {
+        self.sender.send(Restart::Yes).unwrap();
+    }
+
+    /// Stop this cargo check worker.
+    pub fn cancel(&self) {
+        self.sender.send(Restart::No).unwrap();
     }
 
     pub fn id(&self) -> usize {
@@ -122,7 +127,10 @@ pub enum Progress {
     DidCancel,
 }
 
-struct Restart;
+enum Restart {
+    Yes,
+    No,
+}
 
 struct FlycheckActor {
     id: usize,
@@ -149,6 +157,7 @@ impl FlycheckActor {
         config: FlycheckConfig,
         workspace_root: AbsPathBuf,
     ) -> FlycheckActor {
+        tracing::info!(%id, ?workspace_root, "Spawning flycheck");
         FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
     }
     fn progress(&self, progress: Progress) {
@@ -164,10 +173,13 @@ impl FlycheckActor {
     fn run(mut self, inbox: Receiver<Restart>) {
         while let Some(event) = self.next_event(&inbox) {
             match event {
-                Event::Restart(Restart) => {
+                Event::Restart(Restart::No) => {
+                    self.cancel_check_process();
+                }
+                Event::Restart(Restart::Yes) => {
                     // Cancel the previously spawned process
                     self.cancel_check_process();
-                    while let Ok(Restart) = inbox.recv_timeout(Duration::from_millis(50)) {}
+                    while let Ok(_) = inbox.recv_timeout(Duration::from_millis(50)) {}
 
                     let command = self.check_command();
                     tracing::debug!(?command, "will restart flycheck");
@@ -223,6 +235,10 @@ impl FlycheckActor {
 
     fn cancel_check_process(&mut self) {
         if let Some(cargo_handle) = self.cargo_handle.take() {
+            tracing::debug!(
+                command = ?self.check_command(),
+                "did  cancel flycheck"
+            );
             cargo_handle.cancel();
             self.progress(Progress::DidCancel);
         }
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 6337d49c240..fdb3205b0a9 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -51,6 +51,12 @@ pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<
     Ok(())
 }
 
+pub(crate) fn handle_cancel_flycheck(state: &mut GlobalState, _: ()) -> Result<()> {
+    let _p = profile::span("handle_stop_flycheck");
+    state.flycheck.iter().for_each(|flycheck| flycheck.cancel());
+    Ok(())
+}
+
 pub(crate) fn handle_analyzer_status(
     snap: GlobalStateSnapshot,
     params: lsp_ext::AnalyzerStatusParams,
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index 5f0e108624b..e61c8b643d2 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -129,6 +129,14 @@ pub struct ExpandedMacro {
     pub expansion: String,
 }
 
+pub enum CancelFlycheck {}
+
+impl Request for CancelFlycheck {
+    type Params = ();
+    type Result = ();
+    const METHOD: &'static str = "rust-analyzer/cancelFlycheck";
+}
+
 pub enum MatchingBrace {}
 
 impl Request for MatchingBrace {
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 77419998249..f187547019a 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -288,7 +288,7 @@ impl GlobalState {
 
             if became_quiescent {
                 // Project has loaded properly, kick off initial flycheck
-                self.flycheck.iter().for_each(FlycheckHandle::update);
+                self.flycheck.iter().for_each(FlycheckHandle::restart);
                 if self.config.prefill_caches() {
                     self.prime_caches_queue.request_op("became quiescent".to_string());
                 }
@@ -590,6 +590,7 @@ impl GlobalState {
             .on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)
             .on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)
             .on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)
+            .on_sync_mut::<lsp_ext::CancelFlycheck>(handlers::handle_cancel_flycheck)
             .on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)
             .on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter)
             .on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)
@@ -779,7 +780,7 @@ impl GlobalState {
                             for (id, _) in workspace_ids.clone() {
                                 if id == flycheck.id() {
                                     updated = true;
-                                    flycheck.update();
+                                    flycheck.restart();
                                     continue;
                                 }
                             }
@@ -798,7 +799,7 @@ impl GlobalState {
                 // No specific flycheck was triggered, so let's trigger all of them.
                 if !updated {
                     for flycheck in &this.flycheck {
-                        flycheck.update();
+                        flycheck.restart();
                     }
                 }
                 Ok(())
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 5040643d34a..6d2c7d7b063 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
 <!---
-lsp_ext.rs hash: 2a188defec26cc7c
+lsp_ext.rs hash: 7b710095d773b978
 
 If you need to change the above hash to make the test pass, please check if you
 need to adjust this doc as well and ping this issue:
diff --git a/editors/code/package.json b/editors/code/package.json
index 0714b356fe0..2e38c057302 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -235,6 +235,11 @@
                 "command": "rust-analyzer.moveItemDown",
                 "title": "Move item down",
                 "category": "rust-analyzer"
+            },
+            {
+                "command": "rust-analyzer.cancelFlycheck",
+                "title": "Cancel running flychecks",
+                "category": "rust-analyzer"
             }
         ],
         "keybindings": [
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 12f666401fd..a21b304bbda 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -817,6 +817,12 @@ export function openDocs(ctx: Ctx): Cmd {
     };
 }
 
+export function cancelFlycheck(ctx: Ctx): Cmd {
+    return async () => {
+        await ctx.client.sendRequest(ra.cancelFlycheck);
+    };
+}
+
 export function resolveCodeAction(ctx: Ctx): Cmd {
     const client = ctx.client;
     return async (params: lc.CodeAction) => {
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index f80af78a74a..875261c48a6 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -75,6 +75,23 @@ export const expandMacro = new lc.RequestType<ExpandMacroParams, ExpandedMacro |
     "rust-analyzer/expandMacro"
 );
 
+export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, TestInfo[], void>(
+    "rust-analyzer/relatedTests"
+);
+
+export const cancelFlycheck = new lc.RequestType0<void, void>("rust-analyzer/cancelFlycheck");
+
+// Experimental extensions
+
+export interface SsrParams {
+    query: string;
+    parseOnly: boolean;
+    textDocument: lc.TextDocumentIdentifier;
+    position: lc.Position;
+    selections: readonly lc.Range[];
+}
+export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>("experimental/ssr");
+
 export interface MatchingBraceParams {
     textDocument: lc.TextDocumentIdentifier;
     positions: lc.Position[];
@@ -127,19 +144,6 @@ export interface TestInfo {
     runnable: Runnable;
 }
 
-export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, TestInfo[], void>(
-    "rust-analyzer/relatedTests"
-);
-
-export interface SsrParams {
-    query: string;
-    parseOnly: boolean;
-    textDocument: lc.TextDocumentIdentifier;
-    position: lc.Position;
-    selections: readonly lc.Range[];
-}
-export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>("experimental/ssr");
-
 export interface CommandLink extends lc.Command {
     /**
      * A tooltip for the command, when represented in the UI.
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index d78b711a47a..a9847dd2a65 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -163,6 +163,7 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
     ctx.registerCommand("peekTests", commands.peekTests);
     ctx.registerCommand("moveItemUp", commands.moveItemUp);
     ctx.registerCommand("moveItemDown", commands.moveItemDown);
+    ctx.registerCommand("cancelFlycheck", commands.cancelFlycheck);
 
     defaultOnEnter.dispose();
     ctx.registerCommand("onEnter", commands.onEnter);