aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-09-08 07:48:45 +0100
committerAleksey Kladov <[email protected]>2019-09-09 10:32:16 +0100
commitef2b84ddf119c950272c5f1eb321f3f9e90bedd4 (patch)
treed746c95cef14b27f67f1e5fd32d289e6d20b4d57
parent734a43e95afc97773c234956a95b78caed88f2a3 (diff)
introduce hir debugging infra
This is to make debugging rust-analyzer easier. The idea is that `dbg!(krate.debug(db))` will print the actual, fuzzy crate name, instead of precise ID. Debug printing infra is a separate thing, to make sure that the actual hir doesn't have access to global information. Do not use `.debug` for `log::` logging: debugging executes queries, and might introduce unneded dependencies to the crate graph
-rw-r--r--Cargo.lock1
-rw-r--r--crates/ra_db/src/input.rs16
-rw-r--r--crates/ra_hir/src/db.rs3
-rw-r--r--crates/ra_hir/src/debug.rs64
-rw-r--r--crates/ra_hir/src/lib.rs1
-rw-r--r--crates/ra_hir/src/mock.rs25
-rw-r--r--crates/ra_ide_api/src/change.rs15
-rw-r--r--crates/ra_ide_api/src/db.rs31
-rw-r--r--crates/ra_lsp_server/Cargo.toml1
-rw-r--r--crates/ra_lsp_server/src/world.rs7
-rw-r--r--crates/ra_project_model/src/lib.rs20
11 files changed, 166 insertions, 18 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f93f11a82..ceb26961e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1060,6 +1060,7 @@ dependencies = [
1060 "lsp-server 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1060 "lsp-server 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1061 "lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)", 1061 "lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)",
1062 "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1062 "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
1063 "ra_db 0.1.0",
1063 "ra_ide_api 0.1.0", 1064 "ra_ide_api 0.1.0",
1064 "ra_prof 0.1.0", 1065 "ra_prof 0.1.0",
1065 "ra_project_model 0.1.0", 1066 "ra_project_model 0.1.0",
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index d1ee3c036..a1ace61b6 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -82,6 +82,12 @@ pub struct CyclicDependencies;
82#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 82#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
83pub struct CrateId(pub u32); 83pub struct CrateId(pub u32);
84 84
85impl CrateId {
86 pub fn shift(self, amount: u32) -> CrateId {
87 CrateId(self.0 + amount)
88 }
89}
90
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 91#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
86pub enum Edition { 92pub enum Edition {
87 Edition2018, 93 Edition2018,
@@ -178,15 +184,19 @@ impl CrateGraph {
178 184
179 /// Extends this crate graph by adding a complete disjoint second crate 185 /// Extends this crate graph by adding a complete disjoint second crate
180 /// graph. 186 /// graph.
181 pub fn extend(&mut self, other: CrateGraph) { 187 ///
188 /// The ids of the crates in the `other` graph are shifted by the return
189 /// amount.
190 pub fn extend(&mut self, other: CrateGraph) -> u32 {
182 let start = self.arena.len() as u32; 191 let start = self.arena.len() as u32;
183 self.arena.extend(other.arena.into_iter().map(|(id, mut data)| { 192 self.arena.extend(other.arena.into_iter().map(|(id, mut data)| {
184 let new_id = CrateId(id.0 + start); 193 let new_id = id.shift(start);
185 for dep in &mut data.dependencies { 194 for dep in &mut data.dependencies {
186 dep.crate_id = CrateId(dep.crate_id.0 + start); 195 dep.crate_id = dep.crate_id.shift(start);
187 } 196 }
188 (new_id, data) 197 (new_id, data)
189 })); 198 }));
199 start
190 } 200 }
191 201
192 fn dfs_find(&self, target: CrateId, from: CrateId, visited: &mut FxHashSet<CrateId>) -> bool { 202 fn dfs_find(&self, target: CrateId, from: CrateId, visited: &mut FxHashSet<CrateId>) -> bool {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 7b7974f5b..f7f124904 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -5,6 +5,7 @@ use ra_syntax::{ast, Parse, SmolStr, SyntaxNode};
5 5
6use crate::{ 6use crate::{
7 adt::{EnumData, StructData}, 7 adt::{EnumData, StructData},
8 debug::HirDebugDatabase,
8 generics::{GenericDef, GenericParams}, 9 generics::{GenericDef, GenericParams},
9 ids, 10 ids,
10 impl_block::{ImplBlock, ImplSourceMap, ModuleImplBlocks}, 11 impl_block::{ImplBlock, ImplSourceMap, ModuleImplBlocks},
@@ -83,7 +84,7 @@ pub trait AstDatabase: InternDatabase {
83// This database uses `AstDatabase` internally, 84// This database uses `AstDatabase` internally,
84#[salsa::query_group(DefDatabaseStorage)] 85#[salsa::query_group(DefDatabaseStorage)]
85#[salsa::requires(AstDatabase)] 86#[salsa::requires(AstDatabase)]
86pub trait DefDatabase: InternDatabase { 87pub trait DefDatabase: InternDatabase + HirDebugDatabase {
87 #[salsa::invoke(crate::adt::StructData::struct_data_query)] 88 #[salsa::invoke(crate::adt::StructData::struct_data_query)]
88 fn struct_data(&self, s: Struct) -> Arc<StructData>; 89 fn struct_data(&self, s: Struct) -> Arc<StructData>;
89 90
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs
new file mode 100644
index 000000000..5a835741d
--- /dev/null
+++ b/crates/ra_hir/src/debug.rs
@@ -0,0 +1,64 @@
1use std::{cell::Cell, fmt};
2
3use ra_db::{CrateId, FileId};
4
5use crate::{db::HirDatabase, Crate, Module, Name};
6
7impl Crate {
8 pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ {
9 debug_fn(move |fmt| db.debug_crate(self, fmt))
10 }
11}
12
13impl Module {
14 pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ {
15 debug_fn(move |fmt| db.debug_module(self, fmt))
16 }
17}
18
19pub trait HirDebugHelper: HirDatabase {
20 fn crate_name(&self, _krate: CrateId) -> Option<String> {
21 None
22 }
23 fn file_path(&self, _file_id: FileId) -> Option<String> {
24 None
25 }
26}
27
28pub trait HirDebugDatabase {
29 fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
30 fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
31}
32
33impl<DB: HirDebugHelper> HirDebugDatabase for DB {
34 fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
35 let mut builder = fmt.debug_tuple("Crate");
36 match self.crate_name(krate.crate_id) {
37 Some(name) => builder.field(&name),
38 None => builder.field(&krate.crate_id),
39 }
40 .finish()
41 }
42
43 fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
44 let file_id = module.definition_source(self).file_id.original_file(self);
45 let path = self.file_path(file_id);
46 fmt.debug_struct("Module")
47 .field("name", &module.name(self).unwrap_or_else(Name::missing))
48 .field("path", &path.unwrap_or_else(|| "N/A".to_string()))
49 .finish()
50 }
51}
52
53fn debug_fn(f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug {
54 struct DebugFn<F>(Cell<Option<F>>);
55
56 impl<F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result> fmt::Debug for DebugFn<F> {
57 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
58 let f = self.0.take().unwrap();
59 f(fmt)
60 }
61 }
62
63 DebugFn(Cell::new(Some(f)))
64}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 7c2a68992..24ee84f86 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -20,6 +20,7 @@ macro_rules! impl_froms {
20} 20}
21 21
22mod either; 22mod either;
23pub mod debug;
23 24
24pub mod db; 25pub mod db;
25#[macro_use] 26#[macro_use]
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index 972f0ece5..8dcea5071 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -2,13 +2,14 @@ use std::{panic, sync::Arc};
2 2
3use parking_lot::Mutex; 3use parking_lot::Mutex;
4use ra_db::{ 4use ra_db::{
5 salsa, CrateGraph, Edition, FileId, FilePosition, SourceDatabase, SourceRoot, SourceRootId, 5 salsa, CrateGraph, CrateId, Edition, FileId, FilePosition, SourceDatabase, SourceRoot,
6 SourceRootId,
6}; 7};
7use relative_path::RelativePathBuf; 8use relative_path::RelativePathBuf;
8use rustc_hash::FxHashMap; 9use rustc_hash::FxHashMap;
9use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; 10use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER};
10 11
11use crate::{db, diagnostics::DiagnosticSink}; 12use crate::{db, debug::HirDebugHelper, diagnostics::DiagnosticSink};
12 13
13pub const WORKSPACE: SourceRootId = SourceRootId(0); 14pub const WORKSPACE: SourceRootId = SourceRootId(0);
14 15
@@ -24,10 +25,22 @@ pub struct MockDatabase {
24 events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, 25 events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>,
25 runtime: salsa::Runtime<MockDatabase>, 26 runtime: salsa::Runtime<MockDatabase>,
26 files: FxHashMap<String, FileId>, 27 files: FxHashMap<String, FileId>,
28 crate_names: Arc<FxHashMap<CrateId, String>>,
29 file_paths: Arc<FxHashMap<FileId, String>>,
27} 30}
28 31
29impl panic::RefUnwindSafe for MockDatabase {} 32impl panic::RefUnwindSafe for MockDatabase {}
30 33
34impl HirDebugHelper for MockDatabase {
35 fn crate_name(&self, krate: CrateId) -> Option<String> {
36 self.crate_names.get(&krate).cloned()
37 }
38
39 fn file_path(&self, file_id: FileId) -> Option<String> {
40 self.file_paths.get(&file_id).cloned()
41 }
42}
43
31impl MockDatabase { 44impl MockDatabase {
32 pub fn with_files(fixture: &str) -> MockDatabase { 45 pub fn with_files(fixture: &str) -> MockDatabase {
33 let (db, position) = MockDatabase::from_fixture(fixture); 46 let (db, position) = MockDatabase::from_fixture(fixture);
@@ -62,6 +75,7 @@ impl MockDatabase {
62 for (crate_name, (crate_root, edition, _)) in graph.0.iter() { 75 for (crate_name, (crate_root, edition, _)) in graph.0.iter() {
63 let crate_root = self.file_id_of(&crate_root); 76 let crate_root = self.file_id_of(&crate_root);
64 let crate_id = crate_graph.add_crate_root(crate_root, *edition); 77 let crate_id = crate_graph.add_crate_root(crate_root, *edition);
78 Arc::make_mut(&mut self.crate_names).insert(crate_id, crate_name.clone());
65 ids.insert(crate_name, crate_id); 79 ids.insert(crate_name, crate_id);
66 } 80 }
67 for (crate_name, (_, _, deps)) in graph.0.iter() { 81 for (crate_name, (_, _, deps)) in graph.0.iter() {
@@ -151,8 +165,11 @@ impl MockDatabase {
151 let is_crate_root = rel_path == "lib.rs" || rel_path == "/main.rs"; 165 let is_crate_root = rel_path == "lib.rs" || rel_path == "/main.rs";
152 166
153 let file_id = FileId(self.files.len() as u32); 167 let file_id = FileId(self.files.len() as u32);
168
154 let prev = self.files.insert(path.to_string(), file_id); 169 let prev = self.files.insert(path.to_string(), file_id);
155 assert!(prev.is_none(), "duplicate files in the text fixture"); 170 assert!(prev.is_none(), "duplicate files in the text fixture");
171 Arc::make_mut(&mut self.file_paths).insert(file_id, path.to_string());
172
156 let text = Arc::new(text.to_string()); 173 let text = Arc::new(text.to_string());
157 self.set_file_text(file_id, text); 174 self.set_file_text(file_id, text);
158 self.set_file_relative_path(file_id, rel_path.clone()); 175 self.set_file_relative_path(file_id, rel_path.clone());
@@ -200,6 +217,8 @@ impl Default for MockDatabase {
200 events: Default::default(), 217 events: Default::default(),
201 runtime: salsa::Runtime::default(), 218 runtime: salsa::Runtime::default(),
202 files: FxHashMap::default(), 219 files: FxHashMap::default(),
220 crate_names: Default::default(),
221 file_paths: Default::default(),
203 }; 222 };
204 db.set_crate_graph(Default::default()); 223 db.set_crate_graph(Default::default());
205 db 224 db
@@ -213,6 +232,8 @@ impl salsa::ParallelDatabase for MockDatabase {
213 runtime: self.runtime.snapshot(self), 232 runtime: self.runtime.snapshot(self),
214 // only the root database can be used to get file_id by path. 233 // only the root database can be used to get file_id by path.
215 files: FxHashMap::default(), 234 files: FxHashMap::default(),
235 file_paths: Arc::clone(&self.file_paths),
236 crate_names: Arc::clone(&self.crate_names),
216 }) 237 })
217 } 238 }
218} 239}
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs
index 89631935a..0d52f5ffb 100644
--- a/crates/ra_ide_api/src/change.rs
+++ b/crates/ra_ide_api/src/change.rs
@@ -2,7 +2,7 @@ use std::{fmt, sync::Arc, time};
2 2
3use ra_db::{ 3use ra_db::{
4 salsa::{Database, Durability, SweepStrategy}, 4 salsa::{Database, Durability, SweepStrategy},
5 CrateGraph, FileId, SourceDatabase, SourceRoot, SourceRootId, 5 CrateGraph, CrateId, FileId, SourceDatabase, SourceRoot, SourceRootId,
6}; 6};
7use ra_prof::{memory_usage, profile, Bytes}; 7use ra_prof::{memory_usage, profile, Bytes};
8use ra_syntax::SourceFile; 8use ra_syntax::SourceFile;
@@ -11,7 +11,7 @@ use relative_path::RelativePathBuf;
11use rustc_hash::FxHashMap; 11use rustc_hash::FxHashMap;
12 12
13use crate::{ 13use crate::{
14 db::RootDatabase, 14 db::{DebugData, RootDatabase},
15 status::syntax_tree_stats, 15 status::syntax_tree_stats,
16 symbol_index::{SymbolIndex, SymbolsDatabase}, 16 symbol_index::{SymbolIndex, SymbolsDatabase},
17}; 17};
@@ -23,6 +23,7 @@ pub struct AnalysisChange {
23 files_changed: Vec<(FileId, Arc<String>)>, 23 files_changed: Vec<(FileId, Arc<String>)>,
24 libraries_added: Vec<LibraryData>, 24 libraries_added: Vec<LibraryData>,
25 crate_graph: Option<CrateGraph>, 25 crate_graph: Option<CrateGraph>,
26 debug_data: DebugData,
26} 27}
27 28
28impl fmt::Debug for AnalysisChange { 29impl fmt::Debug for AnalysisChange {
@@ -83,6 +84,14 @@ impl AnalysisChange {
83 pub fn set_crate_graph(&mut self, graph: CrateGraph) { 84 pub fn set_crate_graph(&mut self, graph: CrateGraph) {
84 self.crate_graph = Some(graph); 85 self.crate_graph = Some(graph);
85 } 86 }
87
88 pub fn set_debug_crate_name(&mut self, crate_id: CrateId, name: String) {
89 self.debug_data.crate_names.insert(crate_id, name);
90 }
91
92 pub fn set_debug_root_path(&mut self, source_root_id: SourceRootId, path: String) {
93 self.debug_data.root_paths.insert(source_root_id, path);
94 }
86} 95}
87 96
88#[derive(Debug)] 97#[derive(Debug)]
@@ -200,6 +209,8 @@ impl RootDatabase {
200 if let Some(crate_graph) = change.crate_graph { 209 if let Some(crate_graph) = change.crate_graph {
201 self.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH) 210 self.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH)
202 } 211 }
212
213 Arc::make_mut(&mut self.debug_data).merge(change.debug_data)
203 } 214 }
204 215
205 fn apply_root_change(&mut self, root_id: SourceRootId, root_change: RootChange) { 216 fn apply_root_change(&mut self, root_id: SourceRootId, root_change: RootChange) {
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs
index f2e6b8f12..4c5159d61 100644
--- a/crates/ra_ide_api/src/db.rs
+++ b/crates/ra_ide_api/src/db.rs
@@ -2,8 +2,9 @@ use std::{sync::Arc, time};
2 2
3use ra_db::{ 3use ra_db::{
4 salsa::{self, Database, Durability}, 4 salsa::{self, Database, Durability},
5 Canceled, CheckCanceled, FileId, SourceDatabase, 5 Canceled, CheckCanceled, CrateId, FileId, SourceDatabase, SourceRootId,
6}; 6};
7use rustc_hash::FxHashMap;
7 8
8use crate::{ 9use crate::{
9 symbol_index::{self, SymbolsDatabase}, 10 symbol_index::{self, SymbolsDatabase},
@@ -23,10 +24,23 @@ use crate::{
23pub(crate) struct RootDatabase { 24pub(crate) struct RootDatabase {
24 runtime: salsa::Runtime<RootDatabase>, 25 runtime: salsa::Runtime<RootDatabase>,
25 pub(crate) feature_flags: Arc<FeatureFlags>, 26 pub(crate) feature_flags: Arc<FeatureFlags>,
27 pub(crate) debug_data: Arc<DebugData>,
26 pub(crate) last_gc: time::Instant, 28 pub(crate) last_gc: time::Instant,
27 pub(crate) last_gc_check: time::Instant, 29 pub(crate) last_gc_check: time::Instant,
28} 30}
29 31
32impl hir::debug::HirDebugHelper for RootDatabase {
33 fn crate_name(&self, krate: CrateId) -> Option<String> {
34 self.debug_data.crate_names.get(&krate).cloned()
35 }
36 fn file_path(&self, file_id: FileId) -> Option<String> {
37 let source_root_id = self.file_source_root(file_id);
38 let source_root_path = self.debug_data.root_paths.get(&source_root_id)?;
39 let file_path = self.file_relative_path(file_id);
40 Some(format!("{}/{}", source_root_path, file_path.display()))
41 }
42}
43
30impl salsa::Database for RootDatabase { 44impl salsa::Database for RootDatabase {
31 fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { 45 fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
32 &self.runtime 46 &self.runtime
@@ -58,6 +72,7 @@ impl RootDatabase {
58 last_gc: time::Instant::now(), 72 last_gc: time::Instant::now(),
59 last_gc_check: time::Instant::now(), 73 last_gc_check: time::Instant::now(),
60 feature_flags: Arc::new(feature_flags), 74 feature_flags: Arc::new(feature_flags),
75 debug_data: Default::default(),
61 }; 76 };
62 db.set_crate_graph_with_durability(Default::default(), Durability::HIGH); 77 db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
63 db.set_local_roots_with_durability(Default::default(), Durability::HIGH); 78 db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
@@ -77,6 +92,7 @@ impl salsa::ParallelDatabase for RootDatabase {
77 last_gc: self.last_gc, 92 last_gc: self.last_gc,
78 last_gc_check: self.last_gc_check, 93 last_gc_check: self.last_gc_check,
79 feature_flags: Arc::clone(&self.feature_flags), 94 feature_flags: Arc::clone(&self.feature_flags),
95 debug_data: Arc::clone(&self.debug_data),
80 }) 96 })
81 } 97 }
82} 98}
@@ -90,3 +106,16 @@ fn line_index(db: &impl ra_db::SourceDatabase, file_id: FileId) -> Arc<LineIndex
90 let text = db.file_text(file_id); 106 let text = db.file_text(file_id);
91 Arc::new(LineIndex::new(&*text)) 107 Arc::new(LineIndex::new(&*text))
92} 108}
109
110#[derive(Debug, Default, Clone)]
111pub(crate) struct DebugData {
112 pub(crate) root_paths: FxHashMap<SourceRootId, String>,
113 pub(crate) crate_names: FxHashMap<CrateId, String>,
114}
115
116impl DebugData {
117 pub(crate) fn merge(&mut self, other: DebugData) {
118 self.root_paths.extend(other.root_paths.into_iter());
119 self.crate_names.extend(other.crate_names.into_iter());
120 }
121}
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml
index 46a0f958c..677d81835 100644
--- a/crates/ra_lsp_server/Cargo.toml
+++ b/crates/ra_lsp_server/Cargo.toml
@@ -18,6 +18,7 @@ parking_lot = "0.9.0"
18jod-thread = "0.1.0" 18jod-thread = "0.1.0"
19ra_vfs = "0.4.0" 19ra_vfs = "0.4.0"
20ra_syntax = { path = "../ra_syntax" } 20ra_syntax = { path = "../ra_syntax" }
21ra_db = { path = "../ra_db" }
21ra_text_edit = { path = "../ra_text_edit" } 22ra_text_edit = { path = "../ra_text_edit" }
22ra_ide_api = { path = "../ra_ide_api" } 23ra_ide_api = { path = "../ra_ide_api" }
23lsp-server = "0.2.0" 24lsp-server = "0.2.0"
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs
index 086ecd587..232409c3b 100644
--- a/crates/ra_lsp_server/src/world.rs
+++ b/crates/ra_lsp_server/src/world.rs
@@ -92,6 +92,7 @@ impl WorldState {
92 let vfs_root_path = vfs.root2path(r); 92 let vfs_root_path = vfs.root2path(r);
93 let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it)); 93 let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it));
94 change.add_root(SourceRootId(r.0), is_local); 94 change.add_root(SourceRootId(r.0), is_local);
95 change.set_debug_root_path(SourceRootId(r.0), vfs_root_path.display().to_string());
95 } 96 }
96 97
97 // Create crate graph from all the workspaces 98 // Create crate graph from all the workspaces
@@ -101,7 +102,11 @@ impl WorldState {
101 vfs_file.map(|f| FileId(f.0)) 102 vfs_file.map(|f| FileId(f.0))
102 }; 103 };
103 for ws in workspaces.iter() { 104 for ws in workspaces.iter() {
104 crate_graph.extend(ws.to_crate_graph(&mut load)); 105 let (graph, crate_names) = ws.to_crate_graph(&mut load);
106 let shift = crate_graph.extend(graph);
107 for (crate_id, name) in crate_names {
108 change.set_debug_crate_name(crate_id.shift(shift), name)
109 }
105 } 110 }
106 change.set_crate_graph(crate_graph); 111 change.set_crate_graph(crate_graph);
107 112
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 9b2f534e7..4fa32dc34 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -9,7 +9,7 @@ use std::{
9 path::{Path, PathBuf}, 9 path::{Path, PathBuf},
10}; 10};
11 11
12use ra_db::{CrateGraph, Edition, FileId}; 12use ra_db::{CrateGraph, CrateId, Edition, FileId};
13use rustc_hash::FxHashMap; 13use rustc_hash::FxHashMap;
14use serde_json::from_reader; 14use serde_json::from_reader;
15 15
@@ -113,8 +113,12 @@ impl ProjectWorkspace {
113 } 113 }
114 } 114 }
115 115
116 pub fn to_crate_graph(&self, load: &mut dyn FnMut(&Path) -> Option<FileId>) -> CrateGraph { 116 pub fn to_crate_graph(
117 &self,
118 load: &mut dyn FnMut(&Path) -> Option<FileId>,
119 ) -> (CrateGraph, FxHashMap<CrateId, String>) {
117 let mut crate_graph = CrateGraph::default(); 120 let mut crate_graph = CrateGraph::default();
121 let mut names = FxHashMap::default();
118 match self { 122 match self {
119 ProjectWorkspace::Json { project } => { 123 ProjectWorkspace::Json { project } => {
120 let mut crates = FxHashMap::default(); 124 let mut crates = FxHashMap::default();
@@ -151,10 +155,9 @@ impl ProjectWorkspace {
151 let mut sysroot_crates = FxHashMap::default(); 155 let mut sysroot_crates = FxHashMap::default();
152 for krate in sysroot.crates() { 156 for krate in sysroot.crates() {
153 if let Some(file_id) = load(krate.root(&sysroot)) { 157 if let Some(file_id) = load(krate.root(&sysroot)) {
154 sysroot_crates.insert( 158 let crate_id = crate_graph.add_crate_root(file_id, Edition::Edition2018);
155 krate, 159 sysroot_crates.insert(krate, crate_id);
156 crate_graph.add_crate_root(file_id, Edition::Edition2018), 160 names.insert(crate_id, krate.name(&sysroot).to_string());
157 );
158 } 161 }
159 } 162 }
160 for from in sysroot.crates() { 163 for from in sysroot.crates() {
@@ -182,6 +185,7 @@ impl ProjectWorkspace {
182 if let Some(file_id) = load(root) { 185 if let Some(file_id) = load(root) {
183 let edition = pkg.edition(&cargo); 186 let edition = pkg.edition(&cargo);
184 let crate_id = crate_graph.add_crate_root(file_id, edition); 187 let crate_id = crate_graph.add_crate_root(file_id, edition);
188 names.insert(crate_id, pkg.name(&cargo).to_string());
185 if tgt.kind(&cargo) == TargetKind::Lib { 189 if tgt.kind(&cargo) == TargetKind::Lib {
186 lib_tgt = Some(crate_id); 190 lib_tgt = Some(crate_id);
187 pkg_to_lib_crate.insert(pkg, crate_id); 191 pkg_to_lib_crate.insert(pkg, crate_id);
@@ -212,7 +216,7 @@ impl ProjectWorkspace {
212 } 216 }
213 } 217 }
214 218
215 // Now add a dep ednge from all targets of upstream to the lib 219 // Now add a dep edge from all targets of upstream to the lib
216 // target of downstream. 220 // target of downstream.
217 for pkg in cargo.packages() { 221 for pkg in cargo.packages() {
218 for dep in pkg.dependencies(&cargo) { 222 for dep in pkg.dependencies(&cargo) {
@@ -233,7 +237,7 @@ impl ProjectWorkspace {
233 } 237 }
234 } 238 }
235 } 239 }
236 crate_graph 240 (crate_graph, names)
237 } 241 }
238 242
239 pub fn workspace_root_for(&self, path: &Path) -> Option<&Path> { 243 pub fn workspace_root_for(&self, path: &Path) -> Option<&Path> {