fix: Fix formatting requests hanging when r-a is still starting

The reason for that was that we were calculating the crate defmaps
of the file we are saving by accident causing us to get stuck waiting
on their expensive computation, while we only need the relevant crate
id.
This commit is contained in:
Lukas Wirth 2022-10-17 17:53:50 +02:00
parent 40cbeb5b3d
commit a762baca02
8 changed files with 17 additions and 24 deletions

View file

@ -482,8 +482,8 @@ impl Analysis {
} }
/// Returns crates this file belongs too. /// Returns crates this file belongs too.
pub fn crate_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> { pub fn crates_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> {
self.with_db(|db| parent_module::crate_for(db, file_id)) self.with_db(|db| parent_module::crates_for(db, file_id))
} }
/// Returns the edition of the given crate. /// Returns the edition of the given crate.

View file

@ -1,9 +1,8 @@
use hir::Semantics; use hir::Semantics;
use ide_db::{ use ide_db::{
base_db::{CrateId, FileId, FilePosition}, base_db::{CrateId, FileId, FileLoader, FilePosition},
RootDatabase, RootDatabase,
}; };
use itertools::Itertools;
use syntax::{ use syntax::{
algo::find_node_at_offset, algo::find_node_at_offset,
ast::{self, AstNode}, ast::{self, AstNode},
@ -55,9 +54,8 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
} }
/// Returns `Vec` for the same reason as `parent_module` /// Returns `Vec` for the same reason as `parent_module`
pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> { pub(crate) fn crates_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
let sema = Semantics::new(db); db.relevant_crates(file_id).iter().copied().collect()
sema.to_module_defs(file_id).map(|module| module.krate().into()).unique().collect()
} }
#[cfg(test)] #[cfg(test)]
@ -147,7 +145,7 @@ $0
mod foo; mod foo;
"#, "#,
); );
assert_eq!(analysis.crate_for(file_id).unwrap().len(), 1); assert_eq!(analysis.crates_for(file_id).unwrap().len(), 1);
} }
#[test] #[test]
@ -162,6 +160,6 @@ mod baz;
mod baz; mod baz;
"#, "#,
); );
assert_eq!(analysis.crate_for(file_id).unwrap().len(), 2); assert_eq!(analysis.crates_for(file_id).unwrap().len(), 2);
} }
} }

View file

@ -45,7 +45,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
if let Some(file_id) = file_id { if let Some(file_id) = file_id {
format_to!(buf, "\nFile info:\n"); format_to!(buf, "\nFile info:\n");
let crates = crate::parent_module::crate_for(db, file_id); let crates = crate::parent_module::crates_for(db, file_id);
if crates.is_empty() { if crates.is_empty() {
format_to!(buf, "Does not belong to any crate"); format_to!(buf, "Does not belong to any crate");
} }

View file

@ -118,11 +118,7 @@ impl CargoTargetSpec {
global_state_snapshot: &GlobalStateSnapshot, global_state_snapshot: &GlobalStateSnapshot,
file_id: FileId, file_id: FileId,
) -> Result<Option<CargoTargetSpec>> { ) -> Result<Option<CargoTargetSpec>> {
let crate_id = match &*global_state_snapshot.analysis.crate_for(file_id)? { let (cargo_ws, target) = match global_state_snapshot.cargo_target_for_file_id(file_id) {
&[crate_id, ..] => crate_id,
_ => return Ok(None),
};
let (cargo_ws, target) = match global_state_snapshot.cargo_target_for_crate_root(crate_id) {
Some(it) => it, Some(it) => it,
None => return Ok(None), None => return Ok(None),
}; };

View file

@ -52,7 +52,7 @@ impl<'a> RequestDispatcher<'a> {
let _pctx = stdx::panic_context::enter(panic_context); let _pctx = stdx::panic_context::enter(panic_context);
f(self.global_state, params) f(self.global_state, params)
}; };
if let Ok(response) = result_to_response::<R>(req.id.clone(), result) { if let Ok(response) = result_to_response::<R>(req.id, result) {
self.global_state.respond(response); self.global_state.respond(response);
} }
@ -80,7 +80,7 @@ impl<'a> RequestDispatcher<'a> {
f(global_state_snapshot, params) f(global_state_snapshot, params)
}); });
if let Ok(response) = thread_result_to_response::<R>(req.id.clone(), result) { if let Ok(response) = thread_result_to_response::<R>(req.id, result) {
self.global_state.respond(response); self.global_state.respond(response);
} }

View file

@ -8,7 +8,7 @@ use std::{sync::Arc, time::Instant};
use crossbeam_channel::{unbounded, Receiver, Sender}; use crossbeam_channel::{unbounded, Receiver, Sender};
use flycheck::FlycheckHandle; use flycheck::FlycheckHandle;
use ide::{Analysis, AnalysisHost, Cancellable, Change, FileId}; use ide::{Analysis, AnalysisHost, Cancellable, Change, FileId};
use ide_db::base_db::{CrateId, FileLoader, SourceDatabase}; use ide_db::base_db::{FileLoader, SourceDatabase};
use lsp_types::{SemanticTokens, Url}; use lsp_types::{SemanticTokens, Url};
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use proc_macro_api::ProcMacroServer; use proc_macro_api::ProcMacroServer;
@ -398,11 +398,10 @@ impl GlobalStateSnapshot {
url_from_abs_path(path) url_from_abs_path(path)
} }
pub(crate) fn cargo_target_for_crate_root( pub(crate) fn cargo_target_for_file_id(
&self, &self,
crate_id: CrateId, file_id: FileId,
) -> Option<(&CargoWorkspace, Target)> { ) -> Option<(&CargoWorkspace, Target)> {
let file_id = self.analysis.crate_root(crate_id).ok()?;
let path = self.vfs.read().0.file_path(file_id); let path = self.vfs.read().0.file_path(file_id);
let path = path.as_path()?; let path = path.as_path()?;
self.workspaces.iter().find_map(|ws| match ws { self.workspaces.iter().find_map(|ws| match ws {

View file

@ -658,7 +658,7 @@ pub(crate) fn handle_parent_module(
// check if invoked at the crate root // check if invoked at the crate root
let file_id = from_proto::file_id(&snap, &params.text_document.uri)?; let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
let crate_id = match snap.analysis.crate_for(file_id)?.first() { let crate_id = match snap.analysis.crates_for(file_id)?.first() {
Some(&crate_id) => crate_id, Some(&crate_id) => crate_id,
None => return Ok(None), None => return Ok(None),
}; };
@ -1782,7 +1782,7 @@ fn run_rustfmt(
) -> Result<Option<Vec<lsp_types::TextEdit>>> { ) -> Result<Option<Vec<lsp_types::TextEdit>>> {
let file_id = from_proto::file_id(snap, &text_document.uri)?; let file_id = from_proto::file_id(snap, &text_document.uri)?;
let file = snap.analysis.file_text(file_id)?; let file = snap.analysis.file_text(file_id)?;
let crate_ids = snap.analysis.crate_for(file_id)?; let crate_ids = snap.analysis.crates_for(file_id)?;
let line_index = snap.file_line_index(file_id)?; let line_index = snap.file_line_index(file_id)?;

View file

@ -767,7 +767,7 @@ impl GlobalState {
let analysis = this.analysis_host.analysis(); let analysis = this.analysis_host.analysis();
// Crates containing or depending on the saved file // Crates containing or depending on the saved file
let crate_ids: Vec<_> = analysis let crate_ids: Vec<_> = analysis
.crate_for(file_id)? .crates_for(file_id)?
.into_iter() .into_iter()
.flat_map(|id| { .flat_map(|id| {
this.analysis_host this.analysis_host