aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/imp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r--crates/ra_analysis/src/imp.rs139
1 files changed, 71 insertions, 68 deletions
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};
13use ra_db::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE, SyntaxDatabase}; 13use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase};
14use rayon::prelude::*; 14use rayon::prelude::*;
15use rustc_hash::FxHashSet;
16use salsa::{Database, ParallelDatabase}; 15use salsa::{Database, ParallelDatabase};
17use hir::{ 16use hir::{
18 self, 17 self,
@@ -24,8 +23,8 @@ use hir::{
24use crate::{ 23use 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());