diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-20 09:16:07 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-20 09:16:07 +0000 |
commit | 9a16cf2bf646a4a881f3f5acbf5582dacc4337bf (patch) | |
tree | ff90eb390a8f5af47b6d0c6ec4c49b4431b82d1c /crates/ra_analysis | |
parent | dbb62b5baa36783bbca06f09c77794fce3ceff0c (diff) | |
parent | a084412f0698d5f54d586f707930e141c88b0673 (diff) |
Merge #292
292: Vfs r=matklad a=matklad
closes #243
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r-- | crates/ra_analysis/src/db.rs | 10 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 139 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 104 | ||||
-rw-r--r-- | crates/ra_analysis/src/mock_analysis.rs | 10 |
4 files changed, 164 insertions, 99 deletions
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index b8d774eb5..3d0f13f34 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -30,11 +30,11 @@ impl Default for RootDatabase { | |||
30 | runtime: salsa::Runtime::default(), | 30 | runtime: salsa::Runtime::default(), |
31 | id_maps: Default::default(), | 31 | id_maps: Default::default(), |
32 | }; | 32 | }; |
33 | db.query_mut(ra_db::SourceRootQuery) | ||
34 | .set(ra_db::WORKSPACE, Default::default()); | ||
35 | db.query_mut(ra_db::CrateGraphQuery) | 33 | db.query_mut(ra_db::CrateGraphQuery) |
36 | .set((), Default::default()); | 34 | .set((), Default::default()); |
37 | db.query_mut(ra_db::LibrariesQuery) | 35 | db.query_mut(ra_db::LocalRootsQuery) |
36 | .set((), Default::default()); | ||
37 | db.query_mut(ra_db::LibraryRootsQuery) | ||
38 | .set((), Default::default()); | 38 | .set((), Default::default()); |
39 | db | 39 | db |
40 | } | 40 | } |
@@ -61,9 +61,11 @@ salsa::database_storage! { | |||
61 | pub(crate) struct RootDatabaseStorage for RootDatabase { | 61 | pub(crate) struct RootDatabaseStorage for RootDatabase { |
62 | impl ra_db::FilesDatabase { | 62 | impl ra_db::FilesDatabase { |
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_source_root() for ra_db::FileSourceRootQuery; | 65 | fn file_source_root() for ra_db::FileSourceRootQuery; |
65 | fn source_root() for ra_db::SourceRootQuery; | 66 | fn source_root() for ra_db::SourceRootQuery; |
66 | fn libraries() for ra_db::LibrariesQuery; | 67 | fn local_roots() for ra_db::LocalRootsQuery; |
68 | fn library_roots() for ra_db::LibraryRootsQuery; | ||
67 | fn crate_graph() for ra_db::CrateGraphQuery; | 69 | fn crate_graph() for ra_db::CrateGraphQuery; |
68 | } | 70 | } |
69 | impl ra_db::SyntaxDatabase { | 71 | impl ra_db::SyntaxDatabase { |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 0de0e2645..c4291885a 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -10,9 +10,8 @@ use ra_syntax::{ | |||
10 | SyntaxKind::*, | 10 | SyntaxKind::*, |
11 | SyntaxNodeRef, TextRange, TextUnit, | 11 | SyntaxNodeRef, TextRange, TextUnit, |
12 | }; | 12 | }; |
13 | use ra_db::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE, SyntaxDatabase}; | 13 | use ra_db::{FilesDatabase, SourceRoot, SourceRootId, 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, |
@@ -24,8 +23,8 @@ use hir::{ | |||
24 | use crate::{ | 23 | use crate::{ |
25 | completion::{completions, CompletionItem}, | 24 | completion::{completions, CompletionItem}, |
26 | db, | 25 | db, |
27 | symbol_index::{SymbolIndex, SymbolsDatabase}, | 26 | symbol_index::{SymbolIndex, SymbolsDatabase, LibrarySymbolsQuery}, |
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 | }; |
@@ -44,70 +43,41 @@ impl AnalysisHostImpl { | |||
44 | pub fn apply_change(&mut self, change: AnalysisChange) { | 43 | pub fn apply_change(&mut self, change: AnalysisChange) { |
45 | log::info!("apply_change {:?}", change); | 44 | log::info!("apply_change {:?}", change); |
46 | // self.gc_syntax_trees(); | 45 | // self.gc_syntax_trees(); |
47 | 46 | if !change.new_roots.is_empty() { | |
48 | for (file_id, text) in change.files_changed { | 47 | let mut local_roots = Vec::clone(&self.db.local_roots()); |
49 | self.db | 48 | for (root_id, is_local) in change.new_roots { |
50 | .query_mut(ra_db::FileTextQuery) | ||
51 | .set(file_id, Arc::new(text)) | ||
52 | } | ||
53 | if !(change.files_added.is_empty() && change.files_removed.is_empty()) { | ||
54 | let file_resolver = change | ||
55 | .file_resolver | ||
56 | .expect("change resolver when changing set of files"); | ||
57 | let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); | ||
58 | for (file_id, text) in change.files_added { | ||
59 | self.db | 49 | self.db |
60 | .query_mut(ra_db::FileTextQuery) | 50 | .query_mut(ra_db::SourceRootQuery) |
61 | .set(file_id, Arc::new(text)); | 51 | .set(root_id, Default::default()); |
62 | self.db | 52 | if is_local { |
63 | .query_mut(ra_db::FileSourceRootQuery) | 53 | local_roots.push(root_id); |
64 | .set(file_id, ra_db::WORKSPACE); | 54 | } |
65 | source_root.files.insert(file_id); | ||
66 | } | ||
67 | for file_id in change.files_removed { | ||
68 | self.db | ||
69 | .query_mut(ra_db::FileTextQuery) | ||
70 | .set(file_id, Arc::new(String::new())); | ||
71 | source_root.files.remove(&file_id); | ||
72 | } | 55 | } |
73 | source_root.file_resolver = file_resolver; | ||
74 | self.db | 56 | self.db |
75 | .query_mut(ra_db::SourceRootQuery) | 57 | .query_mut(ra_db::LocalRootsQuery) |
76 | .set(WORKSPACE, Arc::new(source_root)) | 58 | .set((), Arc::new(local_roots)); |
59 | } | ||
60 | |||
61 | for (root_id, root_change) in change.roots_changed { | ||
62 | self.apply_root_change(root_id, root_change); | ||
63 | } | ||
64 | for (file_id, text) in change.files_changed { | ||
65 | self.db.query_mut(ra_db::FileTextQuery).set(file_id, text) | ||
77 | } | 66 | } |
78 | if !change.libraries_added.is_empty() { | 67 | if !change.libraries_added.is_empty() { |
79 | let mut libraries = Vec::clone(&self.db.libraries()); | 68 | let mut libraries = Vec::clone(&self.db.library_roots()); |
80 | for library in change.libraries_added { | 69 | for library in change.libraries_added { |
81 | let source_root_id = SourceRootId(1 + libraries.len() as u32); | 70 | libraries.push(library.root_id); |
82 | libraries.push(source_root_id); | ||
83 | let mut files = FxHashSet::default(); | ||
84 | for (file_id, text) in library.files { | ||
85 | files.insert(file_id); | ||
86 | log::debug!( | ||
87 | "library file: {:?} {:?}", | ||
88 | file_id, | ||
89 | library.file_resolver.debug_path(file_id) | ||
90 | ); | ||
91 | self.db | ||
92 | .query_mut(ra_db::FileSourceRootQuery) | ||
93 | .set_constant(file_id, source_root_id); | ||
94 | self.db | ||
95 | .query_mut(ra_db::FileTextQuery) | ||
96 | .set_constant(file_id, Arc::new(text)); | ||
97 | } | ||
98 | let source_root = SourceRoot { | ||
99 | files, | ||
100 | file_resolver: library.file_resolver, | ||
101 | }; | ||
102 | self.db | 71 | self.db |
103 | .query_mut(ra_db::SourceRootQuery) | 72 | .query_mut(ra_db::SourceRootQuery) |
104 | .set(source_root_id, Arc::new(source_root)); | 73 | .set(library.root_id, Default::default()); |
105 | self.db | 74 | self.db |
106 | .query_mut(crate::symbol_index::LibrarySymbolsQuery) | 75 | .query_mut(LibrarySymbolsQuery) |
107 | .set(source_root_id, Arc::new(library.symbol_index)); | 76 | .set_constant(library.root_id, Arc::new(library.symbol_index)); |
77 | self.apply_root_change(library.root_id, library.root_change); | ||
108 | } | 78 | } |
109 | self.db | 79 | self.db |
110 | .query_mut(ra_db::LibrariesQuery) | 80 | .query_mut(ra_db::LibraryRootsQuery) |
111 | .set((), Arc::new(libraries)); | 81 | .set((), Arc::new(libraries)); |
112 | } | 82 | } |
113 | if let Some(crate_graph) = change.crate_graph { | 83 | if let Some(crate_graph) = change.crate_graph { |
@@ -117,6 +87,34 @@ impl AnalysisHostImpl { | |||
117 | } | 87 | } |
118 | } | 88 | } |
119 | 89 | ||
90 | fn apply_root_change(&mut self, root_id: SourceRootId, root_change: RootChange) { | ||
91 | let mut source_root = SourceRoot::clone(&self.db.source_root(root_id)); | ||
92 | for add_file in root_change.added { | ||
93 | self.db | ||
94 | .query_mut(ra_db::FileTextQuery) | ||
95 | .set(add_file.file_id, add_file.text); | ||
96 | self.db | ||
97 | .query_mut(ra_db::FileRelativePathQuery) | ||
98 | .set(add_file.file_id, add_file.path.clone()); | ||
99 | self.db | ||
100 | .query_mut(ra_db::FileSourceRootQuery) | ||
101 | .set(add_file.file_id, root_id); | ||
102 | source_root.files.insert(add_file.path, add_file.file_id); | ||
103 | } | ||
104 | for remove_file in root_change.removed { | ||
105 | self.db | ||
106 | .query_mut(ra_db::FileTextQuery) | ||
107 | .set(remove_file.file_id, Default::default()); | ||
108 | self.db | ||
109 | .query_mut(ra_db::FileRelativePathQuery) | ||
110 | .set(remove_file.file_id, Default::default()); | ||
111 | source_root.files.remove(&remove_file.path); | ||
112 | } | ||
113 | self.db | ||
114 | .query_mut(ra_db::SourceRootQuery) | ||
115 | .set(root_id, Arc::new(source_root)); | ||
116 | } | ||
117 | |||
120 | #[allow(unused)] | 118 | #[allow(unused)] |
121 | /// Ideally, we should call this function from time to time to collect heavy | 119 | /// Ideally, we should call this function from time to time to collect heavy |
122 | /// syntax trees. However, if we actually do that, everything is recomputed | 120 | /// syntax trees. However, if we actually do that, everything is recomputed |
@@ -156,21 +154,26 @@ impl AnalysisImpl { | |||
156 | self.db.file_lines(file_id) | 154 | self.db.file_lines(file_id) |
157 | } | 155 | } |
158 | pub fn world_symbols(&self, query: Query) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 156 | pub fn world_symbols(&self, query: Query) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
157 | /// Need to wrap Snapshot to provide `Clone` impl for `map_with` | ||
158 | struct Snap(salsa::Snapshot<db::RootDatabase>); | ||
159 | impl Clone for Snap { | ||
160 | fn clone(&self) -> Snap { | ||
161 | Snap(self.0.snapshot()) | ||
162 | } | ||
163 | } | ||
164 | |||
159 | let buf: Vec<Arc<SymbolIndex>> = if query.libs { | 165 | let buf: Vec<Arc<SymbolIndex>> = if query.libs { |
166 | let snap = Snap(self.db.snapshot()); | ||
160 | self.db | 167 | self.db |
161 | .libraries() | 168 | .library_roots() |
162 | .iter() | 169 | .par_iter() |
163 | .map(|&lib_id| self.db.library_symbols(lib_id)) | 170 | .map_with(snap, |db, &lib_id| db.0.library_symbols(lib_id)) |
164 | .collect() | 171 | .collect() |
165 | } else { | 172 | } else { |
166 | let files = &self.db.source_root(WORKSPACE).files; | 173 | let mut files = Vec::new(); |
167 | 174 | for &root in self.db.local_roots().iter() { | |
168 | /// Need to wrap Snapshot to provide `Clone` impl for `map_with` | 175 | let sr = self.db.source_root(root); |
169 | struct Snap(salsa::Snapshot<db::RootDatabase>); | 176 | files.extend(sr.files.values().map(|&it| it)) |
170 | impl Clone for Snap { | ||
171 | fn clone(&self) -> Snap { | ||
172 | Snap(self.0.snapshot()) | ||
173 | } | ||
174 | } | 177 | } |
175 | 178 | ||
176 | let snap = Snap(self.db.snapshot()); | 179 | let snap = Snap(self.db.snapshot()); |
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 22fff71ab..a1d462528 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,54 @@ 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 |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #[derive(Default)] | 45 | #[derive(Default)] |
46 | pub struct AnalysisChange { | 46 | pub struct AnalysisChange { |
47 | files_added: Vec<(FileId, String)>, | 47 | new_roots: Vec<(SourceRootId, bool)>, |
48 | files_changed: Vec<(FileId, String)>, | 48 | roots_changed: FxHashMap<SourceRootId, RootChange>, |
49 | files_removed: Vec<(FileId)>, | 49 | files_changed: Vec<(FileId, Arc<String>)>, |
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("new_roots", &self.new_roots) |
77 | .field("roots_changed", &self.roots_changed) | ||
59 | .field("files_changed", &self.files_changed.len()) | 78 | .field("files_changed", &self.files_changed.len()) |
60 | .field("files_removed", &self.files_removed.len()) | ||
61 | .field("libraries_added", &self.libraries_added.len()) | 79 | .field("libraries_added", &self.libraries_added.len()) |
62 | .field("crate_graph", &self.crate_graph) | 80 | .field("crate_graph", &self.crate_graph) |
63 | .field("file_resolver", &self.file_resolver) | 81 | .finish() |
82 | } | ||
83 | } | ||
84 | |||
85 | impl fmt::Debug for RootChange { | ||
86 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
87 | fmt.debug_struct("AnalysisChange") | ||
88 | .field("added", &self.added.len()) | ||
89 | .field("removed", &self.removed.len()) | ||
64 | .finish() | 90 | .finish() |
65 | } | 91 | } |
66 | } | 92 | } |
@@ -69,14 +95,37 @@ impl AnalysisChange { | |||
69 | pub fn new() -> AnalysisChange { | 95 | pub fn new() -> AnalysisChange { |
70 | AnalysisChange::default() | 96 | AnalysisChange::default() |
71 | } | 97 | } |
72 | pub fn add_file(&mut self, file_id: FileId, text: String) { | 98 | pub fn add_root(&mut self, root_id: SourceRootId, is_local: bool) { |
73 | self.files_added.push((file_id, text)) | 99 | self.new_roots.push((root_id, is_local)); |
74 | } | 100 | } |
75 | pub fn change_file(&mut self, file_id: FileId, new_text: String) { | 101 | pub fn add_file( |
102 | &mut self, | ||
103 | root_id: SourceRootId, | ||
104 | file_id: FileId, | ||
105 | path: RelativePathBuf, | ||
106 | text: Arc<String>, | ||
107 | ) { | ||
108 | let file = AddFile { | ||
109 | file_id, | ||
110 | path, | ||
111 | text, | ||
112 | }; | ||
113 | self.roots_changed | ||
114 | .entry(root_id) | ||
115 | .or_default() | ||
116 | .added | ||
117 | .push(file); | ||
118 | } | ||
119 | pub fn change_file(&mut self, file_id: FileId, new_text: Arc<String>) { | ||
76 | self.files_changed.push((file_id, new_text)) | 120 | self.files_changed.push((file_id, new_text)) |
77 | } | 121 | } |
78 | pub fn remove_file(&mut self, file_id: FileId) { | 122 | pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) { |
79 | self.files_removed.push(file_id) | 123 | let file = RemoveFile { file_id, path }; |
124 | self.roots_changed | ||
125 | .entry(root_id) | ||
126 | .or_default() | ||
127 | .removed | ||
128 | .push(file); | ||
80 | } | 129 | } |
81 | pub fn add_library(&mut self, data: LibraryData) { | 130 | pub fn add_library(&mut self, data: LibraryData) { |
82 | self.libraries_added.push(data) | 131 | self.libraries_added.push(data) |
@@ -84,9 +133,6 @@ impl AnalysisChange { | |||
84 | pub fn set_crate_graph(&mut self, graph: CrateGraph) { | 133 | pub fn set_crate_graph(&mut self, graph: CrateGraph) { |
85 | self.crate_graph = Some(graph); | 134 | self.crate_graph = Some(graph); |
86 | } | 135 | } |
87 | pub fn set_file_resolver(&mut self, file_resolver: Arc<FileResolver>) { | ||
88 | self.file_resolver = Some(FileResolverImp::new(file_resolver)); | ||
89 | } | ||
90 | } | 136 | } |
91 | 137 | ||
92 | /// `AnalysisHost` stores the current state of the world. | 138 | /// `AnalysisHost` stores the current state of the world. |
@@ -313,20 +359,32 @@ impl Analysis { | |||
313 | 359 | ||
314 | #[derive(Debug)] | 360 | #[derive(Debug)] |
315 | pub struct LibraryData { | 361 | pub struct LibraryData { |
316 | files: Vec<(FileId, String)>, | 362 | root_id: SourceRootId, |
317 | file_resolver: FileResolverImp, | 363 | root_change: RootChange, |
318 | symbol_index: SymbolIndex, | 364 | symbol_index: SymbolIndex, |
319 | } | 365 | } |
320 | 366 | ||
321 | impl LibraryData { | 367 | impl LibraryData { |
322 | pub fn prepare(files: Vec<(FileId, String)>, file_resolver: Arc<FileResolver>) -> LibraryData { | 368 | pub fn prepare( |
323 | let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, text)| { | 369 | root_id: SourceRootId, |
370 | files: Vec<(FileId, RelativePathBuf, Arc<String>)>, | ||
371 | ) -> LibraryData { | ||
372 | let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, _, text)| { | ||
324 | let file = SourceFileNode::parse(text); | 373 | let file = SourceFileNode::parse(text); |
325 | (*file_id, file) | 374 | (*file_id, file) |
326 | })); | 375 | })); |
376 | let mut root_change = RootChange::default(); | ||
377 | root_change.added = files | ||
378 | .into_iter() | ||
379 | .map(|(file_id, path, text)| AddFile { | ||
380 | file_id, | ||
381 | path, | ||
382 | text, | ||
383 | }) | ||
384 | .collect(); | ||
327 | LibraryData { | 385 | LibraryData { |
328 | files, | 386 | root_id, |
329 | file_resolver: FileResolverImp::new(file_resolver), | 387 | root_change, |
330 | symbol_index, | 388 | symbol_index, |
331 | } | 389 | } |
332 | } | 390 | } |
diff --git a/crates/ra_analysis/src/mock_analysis.rs b/crates/ra_analysis/src/mock_analysis.rs index 0d9a7a147..7cbdfb953 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, SourceRootId}; |
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. |
@@ -78,14 +78,16 @@ impl MockAnalysis { | |||
78 | pub fn analysis_host(self) -> AnalysisHost { | 78 | pub fn analysis_host(self) -> AnalysisHost { |
79 | let mut host = AnalysisHost::default(); | 79 | let mut host = AnalysisHost::default(); |
80 | let mut file_map = FileMap::default(); | 80 | let mut file_map = FileMap::default(); |
81 | let source_root = SourceRootId(0); | ||
81 | let mut change = AnalysisChange::new(); | 82 | let mut change = AnalysisChange::new(); |
83 | change.add_root(source_root, true); | ||
82 | for (path, contents) in self.files.into_iter() { | 84 | for (path, contents) in self.files.into_iter() { |
83 | assert!(path.starts_with('/')); | 85 | assert!(path.starts_with('/')); |
84 | let path = RelativePathBuf::from_path(&path[1..]).unwrap(); | 86 | let path = RelativePathBuf::from_path(&path[1..]).unwrap(); |
85 | let file_id = file_map.add(path); | 87 | let file_id = file_map.add(path.clone()); |
86 | change.add_file(file_id, contents); | 88 | change.add_file(source_root, file_id, path, Arc::new(contents)); |
87 | } | 89 | } |
88 | change.set_file_resolver(Arc::new(file_map)); | 90 | // change.set_file_resolver(Arc::new(file_map)); |
89 | host.apply_change(change); | 91 | host.apply_change(change); |
90 | host | 92 | host |
91 | } | 93 | } |