aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_batch/src/lib.rs2
-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.rs83
-rw-r--r--crates/ra_hir/src/lib.rs1
-rw-r--r--crates/ra_hir/src/mock.rs25
-rw-r--r--crates/ra_hir/src/ty/tests.rs12
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs12
-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_parser/src/grammar.rs2
-rw-r--r--crates/ra_parser/src/grammar/attributes.rs2
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs4
-rw-r--r--crates/ra_parser/src/grammar/type_params.rs5
-rw-r--r--crates/ra_project_model/src/lib.rs20
17 files changed, 201 insertions, 40 deletions
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs
index 07a7e0c86..a14139b26 100644
--- a/crates/ra_batch/src/lib.rs
+++ b/crates/ra_batch/src/lib.rs
@@ -39,7 +39,7 @@ pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap<SourceRootId,
39 sender, 39 sender,
40 Watch(false), 40 Watch(false),
41 ); 41 );
42 let crate_graph = ws.to_crate_graph(&mut |path: &Path| { 42 let (crate_graph, _crate_names) = ws.to_crate_graph(&mut |path: &Path| {
43 let vfs_file = vfs.load(path); 43 let vfs_file = vfs.load(path);
44 log::debug!("vfs file {:?} -> {:?}", path, vfs_file); 44 log::debug!("vfs file {:?} -> {:?}", path, vfs_file);
45 vfs_file.map(vfs_file_to_id) 45 vfs_file.map(vfs_file_to_id)
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..87f3180c3
--- /dev/null
+++ b/crates/ra_hir/src/debug.rs
@@ -0,0 +1,83 @@
1//! printf debugging infrastructure for rust-analyzer.
2//!
3//! When you print a hir type, like a module, using `eprintln!("{:?}", module)`,
4//! you usually get back a numeric ID, which doesn't tell you much:
5//! `Module(92)`.
6//!
7//! This module adds convenience `debug` methods to various types, which resolve
8//! the id to a human-readable location info:
9//!
10//! ```not_rust
11//! eprintln!("{:?}", module.debug(db));
12//! =>
13//! Module { name: collections, path: "liballoc/collections/mod.rs" }
14//! ```
15//!
16//! Note that to get this info, we might need to execute queries! So
17//!
18//! * don't use the `debug` methods for logging
19//! * when debugging, be aware that interference is possible.
20
21use std::fmt;
22
23use ra_db::{CrateId, FileId};
24
25use crate::{db::HirDatabase, Crate, Module, Name};
26
27impl Crate {
28 pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ {
29 debug_fn(move |fmt| db.debug_crate(self, fmt))
30 }
31}
32
33impl Module {
34 pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ {
35 debug_fn(move |fmt| db.debug_module(self, fmt))
36 }
37}
38
39pub trait HirDebugHelper: HirDatabase {
40 fn crate_name(&self, _krate: CrateId) -> Option<String> {
41 None
42 }
43 fn file_path(&self, _file_id: FileId) -> Option<String> {
44 None
45 }
46}
47
48pub trait HirDebugDatabase {
49 fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
50 fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
51}
52
53impl<DB: HirDebugHelper> HirDebugDatabase for DB {
54 fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
55 let mut builder = fmt.debug_tuple("Crate");
56 match self.crate_name(krate.crate_id) {
57 Some(name) => builder.field(&name),
58 None => builder.field(&krate.crate_id),
59 }
60 .finish()
61 }
62
63 fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
64 let file_id = module.definition_source(self).file_id.original_file(self);
65 let path = self.file_path(file_id);
66 fmt.debug_struct("Module")
67 .field("name", &module.name(self).unwrap_or_else(Name::missing))
68 .field("path", &path.unwrap_or_else(|| "N/A".to_string()))
69 .finish()
70 }
71}
72
73fn debug_fn(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug {
74 struct DebugFn<F>(F);
75
76 impl<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result> fmt::Debug for DebugFn<F> {
77 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
78 (&self.0)(fmt)
79 }
80 }
81
82 DebugFn(f)
83}
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_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 38fe62279..c60e72abf 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -3065,7 +3065,7 @@ impl<T, U> Into<U> for T where U: From<T> {}
3065fn test() { S2.into()<|>; } 3065fn test() { S2.into()<|>; }
3066"#, 3066"#,
3067 ); 3067 );
3068 assert_eq!(t, "S1"); 3068 assert_eq!(t, "{unknown}");
3069} 3069}
3070 3070
3071#[test] 3071#[test]
@@ -3082,7 +3082,7 @@ impl<T, U: From<T>> Into<U> for T {}
3082fn test() { S2.into()<|>; } 3082fn test() { S2.into()<|>; }
3083"#, 3083"#,
3084 ); 3084 );
3085 assert_eq!(t, "S1"); 3085 assert_eq!(t, "{unknown}");
3086} 3086}
3087 3087
3088#[test] 3088#[test]
@@ -3124,7 +3124,7 @@ impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {}
3124fn test() { (S {}).method()<|>; } 3124fn test() { (S {}).method()<|>; }
3125"#, 3125"#,
3126 ); 3126 );
3127 assert_eq!(t, "{unknown}"); 3127 assert_eq!(t, "()");
3128} 3128}
3129 3129
3130#[test] 3130#[test]
@@ -3604,11 +3604,11 @@ fn test(x: Trait, y: &Trait) -> u64 {
3604 [129; 132) 'bar': fn bar() -> {unknown} 3604 [129; 132) 'bar': fn bar() -> {unknown}
3605 [129; 134) 'bar()': {unknown} 3605 [129; 134) 'bar()': {unknown}
3606 [140; 141) 'x': {unknown} 3606 [140; 141) 'x': {unknown}
3607 [140; 147) 'x.foo()': {unknown} 3607 [140; 147) 'x.foo()': u64
3608 [153; 154) 'y': &{unknown} 3608 [153; 154) 'y': &{unknown}
3609 [153; 160) 'y.foo()': {unknown} 3609 [153; 160) 'y.foo()': u64
3610 [166; 167) 'z': {unknown} 3610 [166; 167) 'z': {unknown}
3611 [166; 173) 'z.foo()': {unknown} 3611 [166; 173) 'z.foo()': u64
3612 "### 3612 "###
3613 ); 3613 );
3614} 3614}
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 8a127efa1..0367c6560 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -356,14 +356,6 @@ fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
356 } 356 }
357} 357}
358 358
359fn is_non_enumerable_trait(db: &impl HirDatabase, trait_: Trait) -> bool {
360 let name = trait_.name(db).unwrap_or_else(crate::Name::missing).to_string();
361 match &*name {
362 "Sized" => true,
363 _ => false,
364 }
365}
366
367fn convert_where_clauses( 359fn convert_where_clauses(
368 db: &impl HirDatabase, 360 db: &impl HirDatabase,
369 def: GenericDef, 361 def: GenericDef,
@@ -486,7 +478,7 @@ pub(crate) fn trait_datum_query(
486 associated_ty_ids: Vec::new(), 478 associated_ty_ids: Vec::new(),
487 where_clauses: Vec::new(), 479 where_clauses: Vec::new(),
488 flags: chalk_rust_ir::TraitFlags { 480 flags: chalk_rust_ir::TraitFlags {
489 non_enumerable: false, 481 non_enumerable: true,
490 auto: false, 482 auto: false,
491 marker: false, 483 marker: false,
492 upstream: true, 484 upstream: true,
@@ -503,7 +495,7 @@ pub(crate) fn trait_datum_query(
503 let flags = chalk_rust_ir::TraitFlags { 495 let flags = chalk_rust_ir::TraitFlags {
504 auto: trait_.is_auto(db), 496 auto: trait_.is_auto(db),
505 upstream: trait_.module(db).krate(db) != Some(krate), 497 upstream: trait_.module(db).krate(db) != Some(krate),
506 non_enumerable: is_non_enumerable_trait(db, trait_), 498 non_enumerable: true,
507 // FIXME set these flags correctly 499 // FIXME set these flags correctly
508 marker: false, 500 marker: false,
509 fundamental: false, 501 fundamental: false,
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_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs
index be9419e0c..a2ad580bc 100644
--- a/crates/ra_parser/src/grammar.rs
+++ b/crates/ra_parser/src/grammar.rs
@@ -125,7 +125,7 @@ pub(crate) mod fragments {
125 let m = p.start(); 125 let m = p.start();
126 126
127 while !p.at(EOF) { 127 while !p.at(EOF) {
128 if p.current() == T![;] { 128 if p.at(T![;]) {
129 p.bump(); 129 p.bump();
130 continue; 130 continue;
131 } 131 }
diff --git a/crates/ra_parser/src/grammar/attributes.rs b/crates/ra_parser/src/grammar/attributes.rs
index 20d58445f..e97170203 100644
--- a/crates/ra_parser/src/grammar/attributes.rs
+++ b/crates/ra_parser/src/grammar/attributes.rs
@@ -1,7 +1,7 @@
1use super::*; 1use super::*;
2 2
3pub(super) fn inner_attributes(p: &mut Parser) { 3pub(super) fn inner_attributes(p: &mut Parser) {
4 while p.current() == T![#] && p.nth(1) == T![!] { 4 while p.at(T![#]) && p.nth(1) == T![!] {
5 attribute(p, true) 5 attribute(p, true)
6 } 6 }
7} 7}
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index ba8386d11..855418f1c 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -197,7 +197,7 @@ pub(crate) fn expr_block_contents(p: &mut Parser) {
197 // struct S {}; 197 // struct S {};
198 // } 198 // }
199 199
200 if p.current() == T![;] { 200 if p.at(T![;]) {
201 p.bump(); 201 p.bump();
202 continue; 202 continue;
203 } 203 }
@@ -302,7 +302,7 @@ fn expr_bp(
302 newly_dollar_open = false; 302 newly_dollar_open = false;
303 } 303 }
304 304
305 let is_range = p.current() == T![..] || p.current() == T![..=]; 305 let is_range = p.at(T![..]) || p.at(T![..=]);
306 let (op_bp, op) = current_op(p); 306 let (op_bp, op) = current_op(p);
307 if op_bp < bp { 307 if op_bp < bp {
308 break; 308 break;
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs
index d739df727..cf54344c6 100644
--- a/crates/ra_parser/src/grammar/type_params.rs
+++ b/crates/ra_parser/src/grammar/type_params.rs
@@ -156,7 +156,10 @@ fn is_where_predicate(p: &mut Parser) -> bool {
156} 156}
157 157
158fn is_where_clause_end(p: &mut Parser) -> bool { 158fn is_where_clause_end(p: &mut Parser) -> bool {
159 p.current() == T!['{'] || p.current() == T![;] || p.current() == T![=] 159 match p.current() {
160 T!['{'] | T![;] | T![=] => true,
161 _ => false,
162 }
160} 163}
161 164
162fn where_predicate(p: &mut Parser) { 165fn where_predicate(p: &mut Parser) {
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> {