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.rs118
1 files changed, 49 insertions, 69 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index d9a3f97e9..0faf8b85d 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -1,9 +1,6 @@
1use std::{ 1use std::sync::Arc;
2 fmt,
3 sync::Arc,
4};
5 2
6use salsa::{Database, ParallelDatabase}; 3use salsa::Database;
7 4
8use hir::{ 5use hir::{
9 self, FnSignatureInfo, Problem, source_binder, 6 self, FnSignatureInfo, Problem, source_binder,
@@ -21,18 +18,12 @@ use ra_syntax::{
21use crate::{ 18use crate::{
22 AnalysisChange, 19 AnalysisChange,
23 Cancelable, NavigationTarget, 20 Cancelable, NavigationTarget,
24 completion::{CompletionItem, completions},
25 CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, 21 CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit,
26 Query, ReferenceResolution, RootChange, SourceChange, SourceFileEdit, 22 Query, ReferenceResolution, RootChange, SourceChange, SourceFileEdit,
27 symbol_index::{LibrarySymbolsQuery, FileSymbol}, 23 symbol_index::{LibrarySymbolsQuery, FileSymbol},
28}; 24};
29 25
30impl db::RootDatabase { 26impl db::RootDatabase {
31 pub(crate) fn analysis(&self) -> AnalysisImpl {
32 AnalysisImpl {
33 db: self.snapshot(),
34 }
35 }
36 pub(crate) fn apply_change(&mut self, change: AnalysisChange) { 27 pub(crate) fn apply_change(&mut self, change: AnalysisChange) {
37 log::info!("apply_change {:?}", change); 28 log::info!("apply_change {:?}", change);
38 // self.gc_syntax_trees(); 29 // self.gc_syntax_trees();
@@ -108,20 +99,9 @@ impl db::RootDatabase {
108 } 99 }
109} 100}
110 101
111pub(crate) struct AnalysisImpl { 102impl db::RootDatabase {
112 pub(crate) db: salsa::Snapshot<db::RootDatabase>,
113}
114
115impl fmt::Debug for AnalysisImpl {
116 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
117 let db: &db::RootDatabase = &self.db;
118 fmt.debug_struct("AnalysisImpl").field("db", db).finish()
119 }
120}
121
122impl AnalysisImpl {
123 pub(crate) fn module_path(&self, position: FilePosition) -> Cancelable<Option<String>> { 103 pub(crate) fn module_path(&self, position: FilePosition) -> Cancelable<Option<String>> {
124 let descr = match source_binder::module_from_position(&*self.db, position)? { 104 let descr = match source_binder::module_from_position(self, position)? {
125 None => return Ok(None), 105 None => return Ok(None),
126 Some(it) => it, 106 Some(it) => it,
127 }; 107 };
@@ -143,12 +123,15 @@ impl AnalysisImpl {
143 123
144 /// This returns `Vec` because a module may be included from several places. We 124 /// This returns `Vec` because a module may be included from several places. We
145 /// don't handle this case yet though, so the Vec has length at most one. 125 /// don't handle this case yet though, so the Vec has length at most one.
146 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { 126 pub(crate) fn parent_module(
147 let descr = match source_binder::module_from_position(&*self.db, position)? { 127 &self,
128 position: FilePosition,
129 ) -> Cancelable<Vec<NavigationTarget>> {
130 let descr = match source_binder::module_from_position(self, position)? {
148 None => return Ok(Vec::new()), 131 None => return Ok(Vec::new()),
149 Some(it) => it, 132 Some(it) => it,
150 }; 133 };
151 let (file_id, decl) = match descr.parent_link_source(&*self.db) { 134 let (file_id, decl) = match descr.parent_link_source(self) {
152 None => return Ok(Vec::new()), 135 None => return Ok(Vec::new()),
153 Some(it) => it, 136 Some(it) => it,
154 }; 137 };
@@ -162,39 +145,33 @@ impl AnalysisImpl {
162 Ok(vec![NavigationTarget { file_id, symbol }]) 145 Ok(vec![NavigationTarget { file_id, symbol }])
163 } 146 }
164 /// Returns `Vec` for the same reason as `parent_module` 147 /// Returns `Vec` for the same reason as `parent_module`
165 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { 148 pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
166 let descr = match source_binder::module_from_file_id(&*self.db, file_id)? { 149 let descr = match source_binder::module_from_file_id(self, file_id)? {
167 None => return Ok(Vec::new()), 150 None => return Ok(Vec::new()),
168 Some(it) => it, 151 Some(it) => it,
169 }; 152 };
170 let root = descr.crate_root(); 153 let root = descr.crate_root();
171 let file_id = root.file_id(); 154 let file_id = root.file_id();
172 155
173 let crate_graph = self.db.crate_graph(); 156 let crate_graph = self.crate_graph();
174 let crate_id = crate_graph.crate_id_for_crate_root(file_id); 157 let crate_id = crate_graph.crate_id_for_crate_root(file_id);
175 Ok(crate_id.into_iter().collect()) 158 Ok(crate_id.into_iter().collect())
176 } 159 }
177 pub fn crate_root(&self, crate_id: CrateId) -> FileId { 160 pub(crate) fn crate_root(&self, crate_id: CrateId) -> FileId {
178 self.db.crate_graph().crate_root(crate_id) 161 self.crate_graph().crate_root(crate_id)
179 }
180 pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> {
181 let completions = completions(&self.db, position)?;
182 Ok(completions.map(|it| it.into()))
183 } 162 }
184 pub fn approximately_resolve_symbol( 163 pub(crate) fn approximately_resolve_symbol(
185 &self, 164 &self,
186 position: FilePosition, 165 position: FilePosition,
187 ) -> Cancelable<Option<ReferenceResolution>> { 166 ) -> Cancelable<Option<ReferenceResolution>> {
188 let file = self.db.source_file(position.file_id); 167 let file = self.source_file(position.file_id);
189 let syntax = file.syntax(); 168 let syntax = file.syntax();
190 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { 169 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) {
191 let mut rr = ReferenceResolution::new(name_ref.syntax().range()); 170 let mut rr = ReferenceResolution::new(name_ref.syntax().range());
192 if let Some(fn_descr) = source_binder::function_from_child_node( 171 if let Some(fn_descr) =
193 &*self.db, 172 source_binder::function_from_child_node(self, position.file_id, name_ref.syntax())?
194 position.file_id, 173 {
195 name_ref.syntax(), 174 let scope = fn_descr.scopes(self);
196 )? {
197 let scope = fn_descr.scopes(&*self.db);
198 // First try to resolve the symbol locally 175 // First try to resolve the symbol locally
199 if let Some(entry) = scope.resolve_local_name(name_ref) { 176 if let Some(entry) = scope.resolve_local_name(name_ref) {
200 rr.add_resolution( 177 rr.add_resolution(
@@ -219,7 +196,7 @@ impl AnalysisImpl {
219 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { 196 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) {
220 if module.has_semi() { 197 if module.has_semi() {
221 if let Some(child_module) = 198 if let Some(child_module) =
222 source_binder::module_from_declaration(&*self.db, position.file_id, module)? 199 source_binder::module_from_declaration(self, position.file_id, module)?
223 { 200 {
224 let file_id = child_module.file_id(); 201 let file_id = child_module.file_id();
225 let name = match child_module.name() { 202 let name = match child_module.name() {
@@ -240,10 +217,13 @@ impl AnalysisImpl {
240 Ok(None) 217 Ok(None)
241 } 218 }
242 219
243 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { 220 pub(crate) fn find_all_refs(
244 let file = self.db.source_file(position.file_id); 221 &self,
222 position: FilePosition,
223 ) -> Cancelable<Vec<(FileId, TextRange)>> {
224 let file = self.source_file(position.file_id);
245 // Find the binding associated with the offset 225 // Find the binding associated with the offset
246 let (binding, descr) = match find_binding(&self.db, &file, position)? { 226 let (binding, descr) = match find_binding(self, &file, position)? {
247 None => return Ok(Vec::new()), 227 None => return Ok(Vec::new()),
248 Some(it) => it, 228 Some(it) => it,
249 }; 229 };
@@ -255,7 +235,7 @@ impl AnalysisImpl {
255 .collect::<Vec<_>>(); 235 .collect::<Vec<_>>();
256 ret.extend( 236 ret.extend(
257 descr 237 descr
258 .scopes(&*self.db) 238 .scopes(self)
259 .find_all_refs(binding) 239 .find_all_refs(binding)
260 .into_iter() 240 .into_iter()
261 .map(|ref_desc| (position.file_id, ref_desc.range)), 241 .map(|ref_desc| (position.file_id, ref_desc.range)),
@@ -293,8 +273,8 @@ impl AnalysisImpl {
293 Ok(Some((binding, descr))) 273 Ok(Some((binding, descr)))
294 } 274 }
295 } 275 }
296 pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> { 276 pub(crate) fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> {
297 let file = self.db.source_file(nav.file_id); 277 let file = self.source_file(nav.file_id);
298 let result = match (nav.symbol.description(&file), nav.symbol.docs(&file)) { 278 let result = match (nav.symbol.description(&file), nav.symbol.docs(&file)) {
299 (Some(desc), Some(docs)) => { 279 (Some(desc), Some(docs)) => {
300 Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs) 280 Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs)
@@ -307,8 +287,8 @@ impl AnalysisImpl {
307 Ok(result) 287 Ok(result)
308 } 288 }
309 289
310 pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { 290 pub(crate) fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> {
311 let syntax = self.db.source_file(file_id); 291 let syntax = self.source_file(file_id);
312 292
313 let mut res = ra_editor::diagnostics(&syntax) 293 let mut res = ra_editor::diagnostics(&syntax)
314 .into_iter() 294 .into_iter()
@@ -319,9 +299,9 @@ impl AnalysisImpl {
319 fix: d.fix.map(|fix| SourceChange::from_local_edit(file_id, fix)), 299 fix: d.fix.map(|fix| SourceChange::from_local_edit(file_id, fix)),
320 }) 300 })
321 .collect::<Vec<_>>(); 301 .collect::<Vec<_>>();
322 if let Some(m) = source_binder::module_from_file_id(&*self.db, file_id)? { 302 if let Some(m) = source_binder::module_from_file_id(self, file_id)? {
323 for (name_node, problem) in m.problems(&*self.db) { 303 for (name_node, problem) in m.problems(self) {
324 let source_root = self.db.file_source_root(file_id); 304 let source_root = self.file_source_root(file_id);
325 let diag = match problem { 305 let diag = match problem {
326 Problem::UnresolvedModule { candidate } => { 306 Problem::UnresolvedModule { candidate } => {
327 let create_file = FileSystemEdit::CreateFile { 307 let create_file = FileSystemEdit::CreateFile {
@@ -371,8 +351,8 @@ impl AnalysisImpl {
371 Ok(res) 351 Ok(res)
372 } 352 }
373 353
374 pub fn assists(&self, frange: FileRange) -> Vec<SourceChange> { 354 pub(crate) fn assists(&self, frange: FileRange) -> Vec<SourceChange> {
375 let file = self.db.source_file(frange.file_id); 355 let file = self.source_file(frange.file_id);
376 let offset = frange.range.start(); 356 let offset = frange.range.start();
377 let actions = vec![ 357 let actions = vec![
378 ra_editor::flip_comma(&file, offset).map(|f| f()), 358 ra_editor::flip_comma(&file, offset).map(|f| f()),
@@ -389,11 +369,11 @@ impl AnalysisImpl {
389 .collect() 369 .collect()
390 } 370 }
391 371
392 pub fn resolve_callable( 372 pub(crate) fn resolve_callable(
393 &self, 373 &self,
394 position: FilePosition, 374 position: FilePosition,
395 ) -> Cancelable<Option<(FnSignatureInfo, Option<usize>)>> { 375 ) -> Cancelable<Option<(FnSignatureInfo, Option<usize>)>> {
396 let file = self.db.source_file(position.file_id); 376 let file = self.source_file(position.file_id);
397 let syntax = file.syntax(); 377 let syntax = file.syntax();
398 378
399 // Find the calling expression and it's NameRef 379 // Find the calling expression and it's NameRef
@@ -404,12 +384,12 @@ impl AnalysisImpl {
404 let file_symbols = self.index_resolve(name_ref)?; 384 let file_symbols = self.index_resolve(name_ref)?;
405 for (fn_file_id, fs) in file_symbols { 385 for (fn_file_id, fs) in file_symbols {
406 if fs.kind == FN_DEF { 386 if fs.kind == FN_DEF {
407 let fn_file = self.db.source_file(fn_file_id); 387 let fn_file = self.source_file(fn_file_id);
408 if let Some(fn_def) = find_node_at_offset(fn_file.syntax(), fs.node_range.start()) { 388 if let Some(fn_def) = find_node_at_offset(fn_file.syntax(), fs.node_range.start()) {
409 let descr = ctry!(source_binder::function_from_source( 389 let descr = ctry!(source_binder::function_from_source(
410 &*self.db, fn_file_id, fn_def 390 self, fn_file_id, fn_def
411 )?); 391 )?);
412 if let Some(descriptor) = descr.signature_info(&*self.db) { 392 if let Some(descriptor) = descr.signature_info(self) {
413 // If we have a calling expression let's find which argument we are on 393 // If we have a calling expression let's find which argument we are on
414 let mut current_parameter = None; 394 let mut current_parameter = None;
415 395
@@ -456,20 +436,20 @@ impl AnalysisImpl {
456 Ok(None) 436 Ok(None)
457 } 437 }
458 438
459 pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> { 439 pub(crate) fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> {
460 let file = self.db.source_file(frange.file_id); 440 let file = self.source_file(frange.file_id);
461 let syntax = file.syntax(); 441 let syntax = file.syntax();
462 let node = find_covering_node(syntax, frange.range); 442 let node = find_covering_node(syntax, frange.range);
463 let parent_fn = ctry!(node.ancestors().find_map(FnDef::cast)); 443 let parent_fn = ctry!(node.ancestors().find_map(FnDef::cast));
464 let function = ctry!(source_binder::function_from_source( 444 let function = ctry!(source_binder::function_from_source(
465 &*self.db, 445 self,
466 frange.file_id, 446 frange.file_id,
467 parent_fn 447 parent_fn
468 )?); 448 )?);
469 let infer = function.infer(&*self.db)?; 449 let infer = function.infer(self)?;
470 Ok(infer.type_of_node(node).map(|t| t.to_string())) 450 Ok(infer.type_of_node(node).map(|t| t.to_string()))
471 } 451 }
472 pub fn rename( 452 pub(crate) fn rename(
473 &self, 453 &self,
474 position: FilePosition, 454 position: FilePosition,
475 new_name: &str, 455 new_name: &str,
@@ -493,7 +473,7 @@ impl AnalysisImpl {
493 let mut query = Query::new(name.to_string()); 473 let mut query = Query::new(name.to_string());
494 query.exact(); 474 query.exact();
495 query.limit(4); 475 query.limit(4);
496 crate::symbol_index::world_symbols(&*self.db, query) 476 crate::symbol_index::world_symbols(self, query)
497 } 477 }
498} 478}
499 479