diff options
author | Aleksey Kladov <[email protected]> | 2018-12-19 09:20:54 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-12-20 09:15:38 +0000 |
commit | 85290bc1342560d5560f0b2151cff1c0c6dac155 (patch) | |
tree | e7817987dc9dba9485659b8c2585e3c6315496c9 /crates | |
parent | 815a0e577821a3876aa4c79c13200607acadcd2f (diff) |
switch analysis to vfs
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_analysis/src/db.rs | 2 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 88 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 96 | ||||
-rw-r--r-- | crates/ra_analysis/src/mock_analysis.rs | 8 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 22 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_db/src/mock.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/module/imp.rs | 17 |
8 files changed, 142 insertions, 100 deletions
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 9f39d3a59..b79baf037 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -63,8 +63,6 @@ salsa::database_storage! { | |||
63 | fn file_text() for ra_db::FileTextQuery; | 63 | fn file_text() for ra_db::FileTextQuery; |
64 | fn file_relative_path() for ra_db::FileRelativePathQuery; | 64 | fn file_relative_path() for ra_db::FileRelativePathQuery; |
65 | fn file_source_root() for ra_db::FileSourceRootQuery; | 65 | fn file_source_root() for ra_db::FileSourceRootQuery; |
66 | fn source_root_files() for ra_db::SourceRootFilesQuery; | ||
67 | fn source_root_file_by_path() for ra_db::SourceRootFileByPathQuery; | ||
68 | fn source_root() for ra_db::SourceRootQuery; | 66 | fn source_root() for ra_db::SourceRootQuery; |
69 | fn libraries() for ra_db::LibrariesQuery; | 67 | fn libraries() for ra_db::LibrariesQuery; |
70 | fn crate_graph() for ra_db::CrateGraphQuery; | 68 | fn crate_graph() for ra_db::CrateGraphQuery; |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index e2c20b0e3..51bcd5a73 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -12,7 +12,6 @@ use ra_syntax::{ | |||
12 | }; | 12 | }; |
13 | use ra_db::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE, SyntaxDatabase}; | 13 | use ra_db::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE, SyntaxDatabase}; |
14 | use rayon::prelude::*; | 14 | use rayon::prelude::*; |
15 | use rustc_hash::FxHashSet; | ||
16 | use salsa::{Database, ParallelDatabase}; | 15 | use salsa::{Database, ParallelDatabase}; |
17 | use hir::{ | 16 | use hir::{ |
18 | self, | 17 | self, |
@@ -25,7 +24,7 @@ use crate::{ | |||
25 | completion::{completions, CompletionItem}, | 24 | completion::{completions, CompletionItem}, |
26 | db, | 25 | db, |
27 | symbol_index::{SymbolIndex, SymbolsDatabase}, | 26 | symbol_index::{SymbolIndex, SymbolsDatabase}, |
28 | AnalysisChange, Cancelable, CrateId, Diagnostic, FileId, | 27 | AnalysisChange, RootChange, Cancelable, CrateId, Diagnostic, FileId, |
29 | FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, | 28 | FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, |
30 | ReferenceResolution, | 29 | ReferenceResolution, |
31 | }; | 30 | }; |
@@ -45,59 +44,22 @@ impl AnalysisHostImpl { | |||
45 | log::info!("apply_change {:?}", change); | 44 | log::info!("apply_change {:?}", change); |
46 | // self.gc_syntax_trees(); | 45 | // self.gc_syntax_trees(); |
47 | 46 | ||
47 | for (root_id, root_change) in change.roots_changed { | ||
48 | self.apply_root_change(root_id, root_change); | ||
49 | } | ||
48 | for (file_id, text) in change.files_changed { | 50 | for (file_id, text) in change.files_changed { |
49 | self.db | 51 | self.db |
50 | .query_mut(ra_db::FileTextQuery) | 52 | .query_mut(ra_db::FileTextQuery) |
51 | .set(file_id, Arc::new(text)) | 53 | .set(file_id, Arc::new(text)) |
52 | } | 54 | } |
53 | if !(change.files_added.is_empty() && change.files_removed.is_empty()) { | ||
54 | let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); | ||
55 | for (file_id, text) in change.files_added { | ||
56 | self.db | ||
57 | .query_mut(ra_db::FileTextQuery) | ||
58 | .set(file_id, Arc::new(text)); | ||
59 | self.db | ||
60 | .query_mut(ra_db::FileSourceRootQuery) | ||
61 | .set(file_id, ra_db::WORKSPACE); | ||
62 | source_root.files.insert(file_id); | ||
63 | } | ||
64 | for file_id in change.files_removed { | ||
65 | self.db | ||
66 | .query_mut(ra_db::FileTextQuery) | ||
67 | .set(file_id, Arc::new(String::new())); | ||
68 | source_root.files.remove(&file_id); | ||
69 | } | ||
70 | self.db | ||
71 | .query_mut(ra_db::SourceRootQuery) | ||
72 | .set(WORKSPACE, Arc::new(source_root)) | ||
73 | } | ||
74 | if !change.libraries_added.is_empty() { | 55 | if !change.libraries_added.is_empty() { |
75 | let mut libraries = Vec::clone(&self.db.libraries()); | 56 | let mut libraries = Vec::clone(&self.db.libraries()); |
76 | for library in change.libraries_added { | 57 | for library in change.libraries_added { |
77 | let source_root_id = SourceRootId(1 + libraries.len() as u32); | 58 | libraries.push(library.root_id); |
78 | libraries.push(source_root_id); | ||
79 | let mut files = FxHashSet::default(); | ||
80 | for (file_id, text) in library.files { | ||
81 | files.insert(file_id); | ||
82 | log::debug!( | ||
83 | "library file: {:?} {:?}", | ||
84 | file_id, | ||
85 | library.file_resolver.debug_path(file_id) | ||
86 | ); | ||
87 | self.db | ||
88 | .query_mut(ra_db::FileSourceRootQuery) | ||
89 | .set_constant(file_id, source_root_id); | ||
90 | self.db | ||
91 | .query_mut(ra_db::FileTextQuery) | ||
92 | .set_constant(file_id, Arc::new(text)); | ||
93 | } | ||
94 | let source_root = SourceRoot { files }; | ||
95 | self.db | 59 | self.db |
96 | .query_mut(ra_db::SourceRootQuery) | 60 | .query_mut(ra_db::SourceRootQuery) |
97 | .set(source_root_id, Arc::new(source_root)); | 61 | .set(library.root_id, Default::default()); |
98 | self.db | 62 | self.apply_root_change(library.root_id, library.root_change); |
99 | .query_mut(crate::symbol_index::LibrarySymbolsQuery) | ||
100 | .set(source_root_id, Arc::new(library.symbol_index)); | ||
101 | } | 63 | } |
102 | self.db | 64 | self.db |
103 | .query_mut(ra_db::LibrariesQuery) | 65 | .query_mut(ra_db::LibrariesQuery) |
@@ -110,6 +72,34 @@ impl AnalysisHostImpl { | |||
110 | } | 72 | } |
111 | } | 73 | } |
112 | 74 | ||
75 | fn apply_root_change(&mut self, root_id: SourceRootId, root_change: RootChange) { | ||
76 | let mut source_root = SourceRoot::clone(&self.db.source_root(root_id)); | ||
77 | for add_file in root_change.added { | ||
78 | self.db | ||
79 | .query_mut(ra_db::FileTextQuery) | ||
80 | .set(add_file.file_id, add_file.text); | ||
81 | self.db | ||
82 | .query_mut(ra_db::FileRelativePathQuery) | ||
83 | .set(add_file.file_id, add_file.path.clone()); | ||
84 | self.db | ||
85 | .query_mut(ra_db::FileSourceRootQuery) | ||
86 | .set(add_file.file_id, root_id); | ||
87 | source_root.files.insert(add_file.path, add_file.file_id); | ||
88 | } | ||
89 | for remove_file in root_change.removed { | ||
90 | self.db | ||
91 | .query_mut(ra_db::FileTextQuery) | ||
92 | .set(remove_file.file_id, Default::default()); | ||
93 | self.db | ||
94 | .query_mut(ra_db::FileRelativePathQuery) | ||
95 | .set(remove_file.file_id, Default::default()); | ||
96 | source_root.files.remove(&remove_file.path); | ||
97 | } | ||
98 | self.db | ||
99 | .query_mut(ra_db::SourceRootQuery) | ||
100 | .set(root_id, Arc::new(source_root)); | ||
101 | } | ||
102 | |||
113 | #[allow(unused)] | 103 | #[allow(unused)] |
114 | /// Ideally, we should call this function from time to time to collect heavy | 104 | /// Ideally, we should call this function from time to time to collect heavy |
115 | /// syntax trees. However, if we actually do that, everything is recomputed | 105 | /// syntax trees. However, if we actually do that, everything is recomputed |
@@ -156,7 +146,13 @@ impl AnalysisImpl { | |||
156 | .map(|&lib_id| self.db.library_symbols(lib_id)) | 146 | .map(|&lib_id| self.db.library_symbols(lib_id)) |
157 | .collect() | 147 | .collect() |
158 | } else { | 148 | } else { |
159 | let files = &self.db.source_root(WORKSPACE).files; | 149 | let files: Vec<FileId> = self |
150 | .db | ||
151 | .source_root(WORKSPACE) | ||
152 | .files | ||
153 | .values() | ||
154 | .map(|&it| it) | ||
155 | .collect(); | ||
160 | 156 | ||
161 | /// Need to wrap Snapshot to provide `Clone` impl for `map_with` | 157 | /// Need to wrap Snapshot to provide `Clone` impl for `map_with` |
162 | struct Snap(salsa::Snapshot<db::RootDatabase>); | 158 | struct Snap(salsa::Snapshot<db::RootDatabase>); |
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 22fff71ab..bfc4e0f17 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -18,9 +18,9 @@ pub mod mock_analysis; | |||
18 | 18 | ||
19 | use std::{fmt, sync::Arc}; | 19 | use std::{fmt, sync::Arc}; |
20 | 20 | ||
21 | use rustc_hash::FxHashMap; | ||
21 | use ra_syntax::{SourceFileNode, TextRange, TextUnit}; | 22 | use ra_syntax::{SourceFileNode, TextRange, TextUnit}; |
22 | use ra_text_edit::AtomTextEdit; | 23 | use ra_text_edit::AtomTextEdit; |
23 | use ra_db::FileResolverImp; | ||
24 | use rayon::prelude::*; | 24 | use rayon::prelude::*; |
25 | use relative_path::RelativePathBuf; | 25 | use relative_path::RelativePathBuf; |
26 | 26 | ||
@@ -39,28 +39,53 @@ pub use hir::FnSignatureInfo; | |||
39 | 39 | ||
40 | pub use ra_db::{ | 40 | pub use ra_db::{ |
41 | Canceled, Cancelable, FilePosition, | 41 | Canceled, Cancelable, FilePosition, |
42 | CrateGraph, CrateId, FileId, FileResolver | 42 | CrateGraph, CrateId, SourceRootId, FileId, FileResolver, |
43 | WORKSPACE | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | #[derive(Default)] | 46 | #[derive(Default)] |
46 | pub struct AnalysisChange { | 47 | pub struct AnalysisChange { |
47 | files_added: Vec<(FileId, String)>, | 48 | roots_changed: FxHashMap<SourceRootId, RootChange>, |
48 | files_changed: Vec<(FileId, String)>, | 49 | files_changed: Vec<(FileId, String)>, |
49 | files_removed: Vec<(FileId)>, | ||
50 | libraries_added: Vec<LibraryData>, | 50 | libraries_added: Vec<LibraryData>, |
51 | crate_graph: Option<CrateGraph>, | 51 | crate_graph: Option<CrateGraph>, |
52 | file_resolver: Option<FileResolverImp>, | 52 | } |
53 | |||
54 | #[derive(Default)] | ||
55 | struct RootChange { | ||
56 | added: Vec<AddFile>, | ||
57 | removed: Vec<RemoveFile>, | ||
58 | } | ||
59 | |||
60 | #[derive(Debug)] | ||
61 | struct AddFile { | ||
62 | file_id: FileId, | ||
63 | path: RelativePathBuf, | ||
64 | text: Arc<String>, | ||
65 | } | ||
66 | |||
67 | #[derive(Debug)] | ||
68 | struct RemoveFile { | ||
69 | file_id: FileId, | ||
70 | path: RelativePathBuf, | ||
53 | } | 71 | } |
54 | 72 | ||
55 | impl fmt::Debug for AnalysisChange { | 73 | impl fmt::Debug for AnalysisChange { |
56 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | 74 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
57 | fmt.debug_struct("AnalysisChange") | 75 | fmt.debug_struct("AnalysisChange") |
58 | .field("files_added", &self.files_added.len()) | 76 | .field("roots_changed", &self.roots_changed) |
59 | .field("files_changed", &self.files_changed.len()) | 77 | .field("files_changed", &self.files_changed.len()) |
60 | .field("files_removed", &self.files_removed.len()) | ||
61 | .field("libraries_added", &self.libraries_added.len()) | 78 | .field("libraries_added", &self.libraries_added.len()) |
62 | .field("crate_graph", &self.crate_graph) | 79 | .field("crate_graph", &self.crate_graph) |
63 | .field("file_resolver", &self.file_resolver) | 80 | .finish() |
81 | } | ||
82 | } | ||
83 | |||
84 | impl fmt::Debug for RootChange { | ||
85 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
86 | fmt.debug_struct("AnalysisChange") | ||
87 | .field("added", &self.added.len()) | ||
88 | .field("removed", &self.removed.len()) | ||
64 | .finish() | 89 | .finish() |
65 | } | 90 | } |
66 | } | 91 | } |
@@ -69,14 +94,34 @@ impl AnalysisChange { | |||
69 | pub fn new() -> AnalysisChange { | 94 | pub fn new() -> AnalysisChange { |
70 | AnalysisChange::default() | 95 | AnalysisChange::default() |
71 | } | 96 | } |
72 | pub fn add_file(&mut self, file_id: FileId, text: String) { | 97 | pub fn add_file( |
73 | self.files_added.push((file_id, text)) | 98 | &mut self, |
99 | root_id: SourceRootId, | ||
100 | file_id: FileId, | ||
101 | path: RelativePathBuf, | ||
102 | text: Arc<String>, | ||
103 | ) { | ||
104 | let file = AddFile { | ||
105 | file_id, | ||
106 | path, | ||
107 | text, | ||
108 | }; | ||
109 | self.roots_changed | ||
110 | .entry(root_id) | ||
111 | .or_default() | ||
112 | .added | ||
113 | .push(file); | ||
74 | } | 114 | } |
75 | pub fn change_file(&mut self, file_id: FileId, new_text: String) { | 115 | pub fn change_file(&mut self, file_id: FileId, new_text: String) { |
76 | self.files_changed.push((file_id, new_text)) | 116 | self.files_changed.push((file_id, new_text)) |
77 | } | 117 | } |
78 | pub fn remove_file(&mut self, file_id: FileId) { | 118 | pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) { |
79 | self.files_removed.push(file_id) | 119 | let file = RemoveFile { file_id, path }; |
120 | self.roots_changed | ||
121 | .entry(root_id) | ||
122 | .or_default() | ||
123 | .removed | ||
124 | .push(file); | ||
80 | } | 125 | } |
81 | pub fn add_library(&mut self, data: LibraryData) { | 126 | pub fn add_library(&mut self, data: LibraryData) { |
82 | self.libraries_added.push(data) | 127 | self.libraries_added.push(data) |
@@ -84,9 +129,6 @@ impl AnalysisChange { | |||
84 | pub fn set_crate_graph(&mut self, graph: CrateGraph) { | 129 | pub fn set_crate_graph(&mut self, graph: CrateGraph) { |
85 | self.crate_graph = Some(graph); | 130 | self.crate_graph = Some(graph); |
86 | } | 131 | } |
87 | pub fn set_file_resolver(&mut self, file_resolver: Arc<FileResolver>) { | ||
88 | self.file_resolver = Some(FileResolverImp::new(file_resolver)); | ||
89 | } | ||
90 | } | 132 | } |
91 | 133 | ||
92 | /// `AnalysisHost` stores the current state of the world. | 134 | /// `AnalysisHost` stores the current state of the world. |
@@ -313,20 +355,32 @@ impl Analysis { | |||
313 | 355 | ||
314 | #[derive(Debug)] | 356 | #[derive(Debug)] |
315 | pub struct LibraryData { | 357 | pub struct LibraryData { |
316 | files: Vec<(FileId, String)>, | 358 | root_id: SourceRootId, |
317 | file_resolver: FileResolverImp, | 359 | root_change: RootChange, |
318 | symbol_index: SymbolIndex, | 360 | symbol_index: SymbolIndex, |
319 | } | 361 | } |
320 | 362 | ||
321 | impl LibraryData { | 363 | impl LibraryData { |
322 | pub fn prepare(files: Vec<(FileId, String)>, file_resolver: Arc<FileResolver>) -> LibraryData { | 364 | pub fn prepare( |
323 | let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, text)| { | 365 | root_id: SourceRootId, |
366 | files: Vec<(FileId, RelativePathBuf, Arc<String>)>, | ||
367 | ) -> LibraryData { | ||
368 | let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, _, text)| { | ||
324 | let file = SourceFileNode::parse(text); | 369 | let file = SourceFileNode::parse(text); |
325 | (*file_id, file) | 370 | (*file_id, file) |
326 | })); | 371 | })); |
372 | let mut root_change = RootChange::default(); | ||
373 | root_change.added = files | ||
374 | .into_iter() | ||
375 | .map(|(file_id, path, text)| AddFile { | ||
376 | file_id, | ||
377 | path, | ||
378 | text, | ||
379 | }) | ||
380 | .collect(); | ||
327 | LibraryData { | 381 | LibraryData { |
328 | files, | 382 | root_id, |
329 | file_resolver: FileResolverImp::new(file_resolver), | 383 | root_change, |
330 | symbol_index, | 384 | symbol_index, |
331 | } | 385 | } |
332 | } | 386 | } |
diff --git a/crates/ra_analysis/src/mock_analysis.rs b/crates/ra_analysis/src/mock_analysis.rs index 0d9a7a147..691af4a48 100644 --- a/crates/ra_analysis/src/mock_analysis.rs +++ b/crates/ra_analysis/src/mock_analysis.rs | |||
@@ -4,7 +4,7 @@ use relative_path::{RelativePathBuf}; | |||
4 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; | 4 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; |
5 | use ra_db::mock::FileMap; | 5 | use ra_db::mock::FileMap; |
6 | 6 | ||
7 | use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FilePosition}; | 7 | use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FilePosition, WORKSPACE}; |
8 | 8 | ||
9 | /// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis | 9 | /// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis |
10 | /// from a set of in-memory files. | 10 | /// from a set of in-memory files. |
@@ -82,10 +82,10 @@ impl MockAnalysis { | |||
82 | for (path, contents) in self.files.into_iter() { | 82 | for (path, contents) in self.files.into_iter() { |
83 | assert!(path.starts_with('/')); | 83 | assert!(path.starts_with('/')); |
84 | let path = RelativePathBuf::from_path(&path[1..]).unwrap(); | 84 | let path = RelativePathBuf::from_path(&path[1..]).unwrap(); |
85 | let file_id = file_map.add(path); | 85 | let file_id = file_map.add(path.clone()); |
86 | change.add_file(file_id, contents); | 86 | change.add_file(WORKSPACE, file_id, path, Arc::new(contents)); |
87 | } | 87 | } |
88 | change.set_file_resolver(Arc::new(file_map)); | 88 | // change.set_file_resolver(Arc::new(file_map)); |
89 | host.apply_change(change); | 89 | host.apply_change(change); |
90 | host | 90 | host |
91 | } | 91 | } |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 65b674da9..51daa8e86 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -1,10 +1,15 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use rustc_hash::{FxHashSet, FxHashMap}; | 3 | use rustc_hash::{FxHashMap}; |
4 | use relative_path::RelativePathBuf; | 4 | use relative_path::RelativePathBuf; |
5 | use ra_syntax::SmolStr; | 5 | use ra_syntax::SmolStr; |
6 | use salsa; | 6 | use salsa; |
7 | 7 | ||
8 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
9 | pub struct SourceRootId(pub u32); | ||
10 | |||
11 | pub const WORKSPACE: SourceRootId = SourceRootId(0); | ||
12 | |||
8 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 13 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
9 | pub struct FileId(pub u32); | 14 | pub struct FileId(pub u32); |
10 | 15 | ||
@@ -93,14 +98,6 @@ salsa::query_group! { | |||
93 | type FileSourceRootQuery; | 98 | type FileSourceRootQuery; |
94 | storage input; | 99 | storage input; |
95 | } | 100 | } |
96 | fn source_root_files(id: SourceRootId) -> Arc<FxHashSet<FileId>> { | ||
97 | type SourceRootFilesQuery; | ||
98 | storage input; | ||
99 | } | ||
100 | fn source_root_file_by_path(id: SourceRootId, path: RelativePathBuf) -> Option<FileId> { | ||
101 | type SourceRootFileByPathQuery; | ||
102 | storage input; | ||
103 | } | ||
104 | fn source_root(id: SourceRootId) -> Arc<SourceRoot> { | 101 | fn source_root(id: SourceRootId) -> Arc<SourceRoot> { |
105 | type SourceRootQuery; | 102 | type SourceRootQuery; |
106 | storage input; | 103 | storage input; |
@@ -116,12 +113,7 @@ salsa::query_group! { | |||
116 | } | 113 | } |
117 | } | 114 | } |
118 | 115 | ||
119 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
120 | pub struct SourceRootId(pub u32); | ||
121 | |||
122 | #[derive(Default, Clone, Debug, PartialEq, Eq)] | 116 | #[derive(Default, Clone, Debug, PartialEq, Eq)] |
123 | pub struct SourceRoot { | 117 | pub struct SourceRoot { |
124 | pub files: FxHashSet<FileId>, | 118 | pub files: FxHashMap<RelativePathBuf, FileId>, |
125 | } | 119 | } |
126 | |||
127 | pub const WORKSPACE: SourceRootId = SourceRootId(0); | ||
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 783b7a799..d1db281e6 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -28,7 +28,7 @@ pub use crate::{ | |||
28 | input::{ | 28 | input::{ |
29 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, WORKSPACE, | 29 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, WORKSPACE, |
30 | FileTextQuery, FileSourceRootQuery, SourceRootQuery, LibrariesQuery, CrateGraphQuery, | 30 | FileTextQuery, FileSourceRootQuery, SourceRootQuery, LibrariesQuery, CrateGraphQuery, |
31 | FileRelativePathQuery, SourceRootFilesQuery, SourceRootFileByPathQuery, | 31 | FileRelativePathQuery |
32 | }, | 32 | }, |
33 | loc2id::{LocationIntener, NumericId}, | 33 | loc2id::{LocationIntener, NumericId}, |
34 | }; | 34 | }; |
diff --git a/crates/ra_db/src/mock.rs b/crates/ra_db/src/mock.rs index 14d9e79b5..efe987bdd 100644 --- a/crates/ra_db/src/mock.rs +++ b/crates/ra_db/src/mock.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use rustc_hash::FxHashSet; | 1 | use rustc_hash::FxHashSet; |
2 | use relative_path::{RelativePath, RelativePathBuf}; | 2 | use relative_path::{RelativePath, RelativePathBuf}; |
3 | 3 | ||
4 | use crate::{FileId, FileResolver, SourceRoot}; | 4 | use crate::{FileId, FileResolver}; |
5 | 5 | ||
6 | #[derive(Default, Debug, Clone)] | 6 | #[derive(Default, Debug, Clone)] |
7 | pub struct FileMap(Vec<(FileId, RelativePathBuf)>); | 7 | pub struct FileMap(Vec<(FileId, RelativePathBuf)>); |
@@ -13,11 +13,6 @@ impl FileMap { | |||
13 | file_id | 13 | file_id |
14 | } | 14 | } |
15 | 15 | ||
16 | pub fn into_source_root(self) -> SourceRoot { | ||
17 | let files = self.files(); | ||
18 | SourceRoot { files } | ||
19 | } | ||
20 | |||
21 | pub fn files(&self) -> FxHashSet<FileId> { | 16 | pub fn files(&self) -> FxHashSet<FileId> { |
22 | self.iter().map(|(id, _)| id).collect() | 17 | self.iter().map(|(id, _)| id).collect() |
23 | } | 18 | } |
diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs index d04d24a61..f3a346152 100644 --- a/crates/ra_hir/src/module/imp.rs +++ b/crates/ra_hir/src/module/imp.rs | |||
@@ -4,6 +4,7 @@ use ra_syntax::{ | |||
4 | ast::{self, NameOwner}, | 4 | ast::{self, NameOwner}, |
5 | SmolStr, | 5 | SmolStr, |
6 | }; | 6 | }; |
7 | use relative_path::{RelativePathBuf, RelativePath}; | ||
7 | use rustc_hash::{FxHashMap, FxHashSet}; | 8 | use rustc_hash::{FxHashMap, FxHashSet}; |
8 | use arrayvec::ArrayVec; | 9 | use arrayvec::ArrayVec; |
9 | use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; | 10 | use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; |
@@ -65,7 +66,7 @@ fn create_module_tree<'a>( | |||
65 | let mut visited = FxHashSet::default(); | 66 | let mut visited = FxHashSet::default(); |
66 | 67 | ||
67 | let source_root = db.source_root(source_root); | 68 | let source_root = db.source_root(source_root); |
68 | for &file_id in source_root.files.iter() { | 69 | for &file_id in source_root.files.values() { |
69 | let source = ModuleSource::new_file(file_id); | 70 | let source = ModuleSource::new_file(file_id); |
70 | if visited.contains(&source) { | 71 | if visited.contains(&source) { |
71 | continue; // TODO: use explicit crate_roots here | 72 | continue; // TODO: use explicit crate_roots here |
@@ -160,7 +161,8 @@ fn resolve_submodule( | |||
160 | let file_id = source.file_id(); | 161 | let file_id = source.file_id(); |
161 | let source_root_id = db.file_source_root(file_id); | 162 | let source_root_id = db.file_source_root(file_id); |
162 | let path = db.file_relative_path(file_id); | 163 | let path = db.file_relative_path(file_id); |
163 | let dir_path = path.parent().unwrap(); | 164 | let root = RelativePathBuf::default(); |
165 | let dir_path = path.parent().unwrap_or(&root); | ||
164 | let mod_name = path.file_stem().unwrap_or("unknown"); | 166 | let mod_name = path.file_stem().unwrap_or("unknown"); |
165 | let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; | 167 | let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; |
166 | 168 | ||
@@ -174,14 +176,19 @@ fn resolve_submodule( | |||
174 | } else { | 176 | } else { |
175 | candidates.push(file_dir_mod.clone()); | 177 | candidates.push(file_dir_mod.clone()); |
176 | }; | 178 | }; |
177 | 179 | let sr = db.source_root(source_root_id); | |
178 | let points_to = candidates | 180 | let points_to = candidates |
179 | .into_iter() | 181 | .into_iter() |
180 | .filter_map(|path| db.source_root_file_by_path(source_root_id, path)) | 182 | .filter_map(|path| sr.files.get(&path)) |
183 | .map(|&it| it) | ||
181 | .collect::<Vec<_>>(); | 184 | .collect::<Vec<_>>(); |
182 | let problem = if points_to.is_empty() { | 185 | let problem = if points_to.is_empty() { |
183 | Some(Problem::UnresolvedModule { | 186 | Some(Problem::UnresolvedModule { |
184 | candidate: if is_dir_owner { file_mod } else { file_dir_mod }, | 187 | candidate: RelativePath::new("../").join(&if is_dir_owner { |
188 | file_mod | ||
189 | } else { | ||
190 | file_dir_mod | ||
191 | }), | ||
185 | }) | 192 | }) |
186 | } else { | 193 | } else { |
187 | None | 194 | None |