aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r--crates/ra_analysis/src/completion/complete_dot.rs10
-rw-r--r--crates/ra_analysis/src/completion/complete_scope.rs14
-rw-r--r--crates/ra_analysis/src/db.rs3
-rw-r--r--crates/ra_analysis/src/goto_defenition.rs6
-rw-r--r--crates/ra_analysis/src/hover.rs28
-rw-r--r--crates/ra_analysis/src/imp.rs34
-rw-r--r--crates/ra_analysis/src/lib.rs2
-rw-r--r--crates/ra_analysis/src/runnables.rs9
-rw-r--r--crates/ra_analysis/tests/test/main.rs3
9 files changed, 65 insertions, 44 deletions
diff --git a/crates/ra_analysis/src/completion/complete_dot.rs b/crates/ra_analysis/src/completion/complete_dot.rs
index 031d8b98f..54ce1b638 100644
--- a/crates/ra_analysis/src/completion/complete_dot.rs
+++ b/crates/ra_analysis/src/completion/complete_dot.rs
@@ -1,4 +1,3 @@
1use ra_syntax::ast::AstNode;
2use hir::{Ty, Def}; 1use hir::{Ty, Def};
3 2
4use crate::Cancelable; 3use crate::Cancelable;
@@ -11,11 +10,12 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Ca
11 _ => return Ok(()), 10 _ => return Ok(()),
12 }; 11 };
13 let infer_result = function.infer(ctx.db)?; 12 let infer_result = function.infer(ctx.db)?;
14 let receiver_ty = if let Some(ty) = infer_result.type_of_node(receiver.syntax()) { 13 let syntax_mapping = function.body_syntax_mapping(ctx.db)?;
15 ty 14 let expr = match syntax_mapping.node_expr(receiver) {
16 } else { 15 Some(expr) => expr,
17 return Ok(()); 16 None => return Ok(()),
18 }; 17 };
18 let receiver_ty = infer_result[expr].clone();
19 if !ctx.is_method_call { 19 if !ctx.is_method_call {
20 complete_fields(acc, ctx, receiver_ty)?; 20 complete_fields(acc, ctx, receiver_ty)?;
21 } 21 }
diff --git a/crates/ra_analysis/src/completion/complete_scope.rs b/crates/ra_analysis/src/completion/complete_scope.rs
index 4dead3689..ee9052d3d 100644
--- a/crates/ra_analysis/src/completion/complete_scope.rs
+++ b/crates/ra_analysis/src/completion/complete_scope.rs
@@ -15,19 +15,22 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) ->
15 None => return Ok(()), 15 None => return Ok(()),
16 }; 16 };
17 if let Some(function) = &ctx.function { 17 if let Some(function) = &ctx.function {
18 let scopes = function.scopes(ctx.db); 18 let scopes = function.scopes(ctx.db)?;
19 complete_fn(acc, &scopes, ctx.offset); 19 complete_fn(acc, &scopes, ctx.offset);
20 } 20 }
21 21
22 let module_scope = module.scope(ctx.db)?; 22 let module_scope = module.scope(ctx.db)?;
23 let (file_id, _) = module.defenition_source(ctx.db)?;
23 module_scope 24 module_scope
24 .entries() 25 .entries()
25 .filter(|(_name, res)| { 26 .filter(|(_name, res)| {
26 // Don't expose this item 27 // Don't expose this item
28 // FIXME: this penetrates through all kinds of abstractions,
29 // we need to figura out the way to do it less ugly.
27 match res.import { 30 match res.import {
28 None => true, 31 None => true,
29 Some(import) => { 32 Some(import) => {
30 let range = import.range(ctx.db, module.file_id()); 33 let range = import.range(ctx.db, file_id);
31 !range.is_subrange(&ctx.leaf.range()) 34 !range.is_subrange(&ctx.leaf.range())
32 } 35 }
33 } 36 }
@@ -40,20 +43,17 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) ->
40 Ok(()) 43 Ok(())
41} 44}
42 45
43fn complete_fn(acc: &mut Completions, scopes: &hir::FnScopes, offset: TextUnit) { 46fn complete_fn(acc: &mut Completions, scopes: &hir::ScopesWithSyntaxMapping, offset: TextUnit) {
44 let mut shadowed = FxHashSet::default(); 47 let mut shadowed = FxHashSet::default();
45 scopes 48 scopes
46 .scope_chain_for_offset(offset) 49 .scope_chain_for_offset(offset)
47 .flat_map(|scope| scopes.entries(scope).iter()) 50 .flat_map(|scope| scopes.scopes.entries(scope).iter())
48 .filter(|entry| shadowed.insert(entry.name())) 51 .filter(|entry| shadowed.insert(entry.name()))
49 .for_each(|entry| { 52 .for_each(|entry| {
50 CompletionItem::new(CompletionKind::Reference, entry.name().to_string()) 53 CompletionItem::new(CompletionKind::Reference, entry.name().to_string())
51 .kind(CompletionItemKind::Binding) 54 .kind(CompletionItemKind::Binding)
52 .add_to(acc) 55 .add_to(acc)
53 }); 56 });
54 if scopes.self_param.is_some() {
55 CompletionItem::new(CompletionKind::Reference, "self").add_to(acc);
56 }
57} 57}
58 58
59#[cfg(test)] 59#[cfg(test)]
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs
index 5422a400b..1709be5cf 100644
--- a/crates/ra_analysis/src/db.rs
+++ b/crates/ra_analysis/src/db.rs
@@ -106,6 +106,9 @@ salsa::database_storage! {
106 fn struct_data() for hir::db::StructDataQuery; 106 fn struct_data() for hir::db::StructDataQuery;
107 fn enum_data() for hir::db::EnumDataQuery; 107 fn enum_data() for hir::db::EnumDataQuery;
108 fn impls_in_module() for hir::db::ImplsInModuleQuery; 108 fn impls_in_module() for hir::db::ImplsInModuleQuery;
109 fn body_hir() for hir::db::BodyHirQuery;
110 fn body_syntax_mapping() for hir::db::BodySyntaxMappingQuery;
111 fn fn_signature() for hir::db::FnSignatureQuery;
109 } 112 }
110 } 113 }
111} 114}
diff --git a/crates/ra_analysis/src/goto_defenition.rs b/crates/ra_analysis/src/goto_defenition.rs
index e37421f8d..aa0616e3b 100644
--- a/crates/ra_analysis/src/goto_defenition.rs
+++ b/crates/ra_analysis/src/goto_defenition.rs
@@ -28,7 +28,7 @@ pub(crate) fn reference_defenition(
28 if let Some(fn_descr) = 28 if let Some(fn_descr) =
29 hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax())? 29 hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax())?
30 { 30 {
31 let scope = fn_descr.scopes(db); 31 let scope = fn_descr.scopes(db)?;
32 // First try to resolve the symbol locally 32 // First try to resolve the symbol locally
33 if let Some(entry) = scope.resolve_local_name(name_ref) { 33 if let Some(entry) = scope.resolve_local_name(name_ref) {
34 let nav = NavigationTarget { 34 let nav = NavigationTarget {
@@ -60,8 +60,8 @@ fn name_defenition(
60 if let Some(child_module) = 60 if let Some(child_module) =
61 hir::source_binder::module_from_declaration(db, file_id, module)? 61 hir::source_binder::module_from_declaration(db, file_id, module)?
62 { 62 {
63 let file_id = child_module.file_id(); 63 let (file_id, _) = child_module.defenition_source(db)?;
64 let name = match child_module.name() { 64 let name = match child_module.name(db)? {
65 Some(name) => name.to_string().into(), 65 Some(name) => name.to_string().into(),
66 None => "".into(), 66 None => "".into(),
67 }; 67 };
diff --git a/crates/ra_analysis/src/hover.rs b/crates/ra_analysis/src/hover.rs
index 2cf79eebf..06632df4f 100644
--- a/crates/ra_analysis/src/hover.rs
+++ b/crates/ra_analysis/src/hover.rs
@@ -3,7 +3,7 @@ use ra_editor::find_node_at_offset;
3use ra_syntax::{ 3use ra_syntax::{
4 AstNode, SyntaxNode, 4 AstNode, SyntaxNode,
5 ast::{self, NameOwner}, 5 ast::{self, NameOwner},
6 algo::{find_covering_node, visit::{visitor, Visitor}}, 6 algo::{find_covering_node, find_leaf_at_offset, visit::{visitor, Visitor}},
7}; 7};
8 8
9use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget}; 9use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget};
@@ -26,13 +26,17 @@ pub(crate) fn hover(
26 } 26 }
27 } 27 }
28 if range.is_none() { 28 if range.is_none() {
29 let expr: ast::Expr = ctry!(find_node_at_offset(file.syntax(), position.offset)); 29 let node = find_leaf_at_offset(file.syntax(), position.offset).find_map(|leaf| {
30 leaf.ancestors()
31 .find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some())
32 });
33 let node = ctry!(node);
30 let frange = FileRange { 34 let frange = FileRange {
31 file_id: position.file_id, 35 file_id: position.file_id,
32 range: expr.syntax().range(), 36 range: node.range(),
33 }; 37 };
34 res.extend(type_of(db, frange)?); 38 res.extend(type_of(db, frange)?);
35 range = Some(expr.syntax().range()); 39 range = Some(node.range());
36 }; 40 };
37 41
38 let range = ctry!(range); 42 let range = ctry!(range);
@@ -60,7 +64,14 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Cancelable<Option
60 parent_fn 64 parent_fn
61 )?); 65 )?);
62 let infer = function.infer(db)?; 66 let infer = function.infer(db)?;
63 Ok(infer.type_of_node(node).map(|t| t.to_string())) 67 let syntax_mapping = function.body_syntax_mapping(db)?;
68 if let Some(expr) = ast::Expr::cast(node).and_then(|e| syntax_mapping.node_expr(e)) {
69 Ok(Some(infer[expr].to_string()))
70 } else if let Some(pat) = ast::Pat::cast(node).and_then(|p| syntax_mapping.node_pat(p)) {
71 Ok(Some(infer[pat].to_string()))
72 } else {
73 Ok(None)
74 }
64} 75}
65 76
66// FIXME: this should not really use navigation target. Rather, approximatelly 77// FIXME: this should not really use navigation target. Rather, approximatelly
@@ -193,6 +204,13 @@ mod tests {
193 } 204 }
194 205
195 #[test] 206 #[test]
207 fn hover_for_local_variable_pat() {
208 let (analysis, position) = single_file_with_position("fn func(fo<|>o: i32) {}");
209 let hover = analysis.hover(position).unwrap().unwrap();
210 assert_eq!(hover.info, "i32");
211 }
212
213 #[test]
196 fn test_type_of_for_function() { 214 fn test_type_of_for_function() {
197 let (analysis, range) = single_file_with_range( 215 let (analysis, range) = single_file_with_range(
198 " 216 "
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 6ab3c5476..07a966290 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -105,39 +105,35 @@ impl db::RootDatabase {
105 &self, 105 &self,
106 position: FilePosition, 106 position: FilePosition,
107 ) -> Cancelable<Vec<NavigationTarget>> { 107 ) -> Cancelable<Vec<NavigationTarget>> {
108 let descr = match source_binder::module_from_position(self, position)? { 108 let module = match source_binder::module_from_position(self, position)? {
109 None => return Ok(Vec::new()), 109 None => return Ok(Vec::new()),
110 Some(it) => it, 110 Some(it) => it,
111 }; 111 };
112 let (file_id, decl) = match descr.parent_link_source(self) { 112 let (file_id, ast_module) = match module.declaration_source(self)? {
113 None => return Ok(Vec::new()), 113 None => return Ok(Vec::new()),
114 Some(it) => it, 114 Some(it) => it,
115 }; 115 };
116 let decl = decl.borrowed(); 116 let ast_module = ast_module.borrowed();
117 let decl_name = decl.name().unwrap(); 117 let name = ast_module.name().unwrap();
118 Ok(vec![NavigationTarget { 118 Ok(vec![NavigationTarget {
119 file_id, 119 file_id,
120 name: decl_name.text(), 120 name: name.text(),
121 range: decl_name.syntax().range(), 121 range: name.syntax().range(),
122 kind: MODULE, 122 kind: MODULE,
123 ptr: None, 123 ptr: None,
124 }]) 124 }])
125 } 125 }
126 /// Returns `Vec` for the same reason as `parent_module` 126 /// Returns `Vec` for the same reason as `parent_module`
127 pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { 127 pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
128 let descr = match source_binder::module_from_file_id(self, file_id)? { 128 let module = match source_binder::module_from_file_id(self, file_id)? {
129 Some(it) => it,
129 None => return Ok(Vec::new()), 130 None => return Ok(Vec::new()),
131 };
132 let krate = match module.krate(self)? {
130 Some(it) => it, 133 Some(it) => it,
134 None => return Ok(Vec::new()),
131 }; 135 };
132 let root = descr.crate_root(); 136 Ok(vec![krate.crate_id()])
133 let file_id = root.file_id();
134
135 let crate_graph = self.crate_graph();
136 let crate_id = crate_graph.crate_id_for_crate_root(file_id);
137 Ok(crate_id.into_iter().collect())
138 }
139 pub(crate) fn crate_root(&self, crate_id: CrateId) -> FileId {
140 self.crate_graph().crate_root(crate_id)
141 } 137 }
142 pub(crate) fn find_all_refs( 138 pub(crate) fn find_all_refs(
143 &self, 139 &self,
@@ -157,7 +153,7 @@ impl db::RootDatabase {
157 .collect::<Vec<_>>(); 153 .collect::<Vec<_>>();
158 ret.extend( 154 ret.extend(
159 descr 155 descr
160 .scopes(self) 156 .scopes(self)?
161 .find_all_refs(binding) 157 .find_all_refs(binding)
162 .into_iter() 158 .into_iter()
163 .map(|ref_desc| (position.file_id, ref_desc.range)), 159 .map(|ref_desc| (position.file_id, ref_desc.range)),
@@ -185,7 +181,7 @@ impl db::RootDatabase {
185 position.file_id, 181 position.file_id,
186 name_ref.syntax(), 182 name_ref.syntax(),
187 )?); 183 )?);
188 let scope = descr.scopes(db); 184 let scope = descr.scopes(db)?;
189 let resolved = ctry!(scope.resolve_local_name(name_ref)); 185 let resolved = ctry!(scope.resolve_local_name(name_ref));
190 let resolved = resolved.ptr().resolve(source_file); 186 let resolved = resolved.ptr().resolve(source_file);
191 let binding = ctry!(find_node_at_offset::<ast::BindPat>( 187 let binding = ctry!(find_node_at_offset::<ast::BindPat>(
@@ -209,7 +205,7 @@ impl db::RootDatabase {
209 }) 205 })
210 .collect::<Vec<_>>(); 206 .collect::<Vec<_>>();
211 if let Some(m) = source_binder::module_from_file_id(self, file_id)? { 207 if let Some(m) = source_binder::module_from_file_id(self, file_id)? {
212 for (name_node, problem) in m.problems(self) { 208 for (name_node, problem) in m.problems(self)? {
213 let source_root = self.file_source_root(file_id); 209 let source_root = self.file_source_root(file_id);
214 let diag = match problem { 210 let diag = match problem {
215 Problem::UnresolvedModule { candidate } => { 211 Problem::UnresolvedModule { candidate } => {
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index feed44b2d..c8f846c56 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -401,7 +401,7 @@ impl Analysis {
401 } 401 }
402 /// Returns the root file of the given crate. 402 /// Returns the root file of the given crate.
403 pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> { 403 pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> {
404 Ok(self.db.crate_root(crate_id)) 404 Ok(self.db.crate_graph().crate_root(crate_id))
405 } 405 }
406 /// Returns the set of possible targets to run for the current file. 406 /// Returns the set of possible targets to run for the current file.
407 pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> { 407 pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> {
diff --git a/crates/ra_analysis/src/runnables.rs b/crates/ra_analysis/src/runnables.rs
index 474267605..216209098 100644
--- a/crates/ra_analysis/src/runnables.rs
+++ b/crates/ra_analysis/src/runnables.rs
@@ -72,12 +72,15 @@ fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Opti
72 let range = module.syntax().range(); 72 let range = module.syntax().range();
73 let module = 73 let module =
74 hir::source_binder::module_from_child_node(db, file_id, module.syntax()).ok()??; 74 hir::source_binder::module_from_child_node(db, file_id, module.syntax()).ok()??;
75
76 // FIXME: thread cancellation instead of `.ok`ing
75 let path = module 77 let path = module
76 .path_to_root() 78 .path_to_root(db)
79 .ok()?
77 .into_iter() 80 .into_iter()
78 .rev() 81 .rev()
79 .into_iter() 82 .filter_map(|it| it.name(db).ok())
80 .filter_map(|it| it.name().map(Clone::clone)) 83 .filter_map(|it| it)
81 .join("::"); 84 .join("::");
82 Some(Runnable { 85 Some(Runnable {
83 range, 86 range,
diff --git a/crates/ra_analysis/tests/test/main.rs b/crates/ra_analysis/tests/test/main.rs
index 26da7c10c..1f70af12a 100644
--- a/crates/ra_analysis/tests/test/main.rs
+++ b/crates/ra_analysis/tests/test/main.rs
@@ -31,6 +31,7 @@ fn test_unresolved_module_diagnostic() {
31 ); 31 );
32} 32}
33 33
34// FIXME: move this test to hir
34#[test] 35#[test]
35fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { 36fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() {
36 let (analysis, file_id) = single_file("mod foo {}"); 37 let (analysis, file_id) = single_file("mod foo {}");
@@ -69,7 +70,7 @@ fn test_resolve_parent_module_for_inline() {
69 ); 70 );
70 let symbols = analysis.parent_module(pos).unwrap(); 71 let symbols = analysis.parent_module(pos).unwrap();
71 assert_eq_dbg( 72 assert_eq_dbg(
72 r#"[NavigationTarget { file_id: FileId(1), name: "bar", kind: MODULE, range: [18; 21), ptr: None }]"#, 73 r#"[NavigationTarget { file_id: FileId(1), name: "baz", kind: MODULE, range: [36; 39), ptr: None }]"#,
73 &symbols, 74 &symbols,
74 ); 75 );
75} 76}