aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-02-01 22:06:57 +0000
committerFlorian Diebold <[email protected]>2019-02-01 22:24:26 +0000
commitc5852f422ff45adaa21815c1a15e03b067a56a82 (patch)
treec53ff3531cbbad182e821eb92fa9ad201d2bff0c /crates
parentd571d26955148befd6986008a5112fff3a901c43 (diff)
Some cleanup and additional tests
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/resolve.rs3
-rw-r--r--crates/ra_hir/src/source_binder.rs21
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs11
-rw-r--r--crates/ra_ide_api/src/completion/complete_scope.rs57
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap40
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap36
6 files changed, 138 insertions, 30 deletions
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 7929e8b7c..6c87d0df7 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -46,7 +46,6 @@ pub(crate) enum Scope {
46 46
47#[derive(Debug, Clone, PartialEq, Eq)] 47#[derive(Debug, Clone, PartialEq, Eq)]
48pub enum Resolution { 48pub enum Resolution {
49 // FIXME make these tuple variants
50 /// An item 49 /// An item
51 Def(ModuleDef), 50 Def(ModuleDef),
52 /// A local binding (only value namespace) 51 /// A local binding (only value namespace)
@@ -85,7 +84,7 @@ impl Resolver {
85 84
86 pub fn all_names(&self) -> FxHashMap<Name, PerNs<Resolution>> { 85 pub fn all_names(&self) -> FxHashMap<Name, PerNs<Resolution>> {
87 let mut names = FxHashMap::default(); 86 let mut names = FxHashMap::default();
88 for scope in &self.scopes { 87 for scope in self.scopes.iter().rev() {
89 scope.collect_names(&mut |name, res| { 88 scope.collect_names(&mut |name, res| {
90 let current: &mut PerNs<Resolution> = names.entry(name).or_default(); 89 let current: &mut PerNs<Resolution> = names.entry(name).or_default();
91 if current.types.is_none() { 90 if current.types.is_none() {
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index ce929cf3e..59f782277 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -204,12 +204,13 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te
204} 204}
205 205
206pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver { 206pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver {
207 let file = db.parse(position.file_id); 207 let file_id = position.file_id;
208 let file = db.parse(file_id);
208 find_leaf_at_offset(file.syntax(), position.offset) 209 find_leaf_at_offset(file.syntax(), position.offset)
209 .find_map(|node| { 210 .find_map(|node| {
210 node.ancestors().find_map(|node| { 211 node.ancestors().find_map(|node| {
211 if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() { 212 if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() {
212 if let Some(func) = function_from_child_node(db, position.file_id, node) { 213 if let Some(func) = function_from_child_node(db, file_id, node) {
213 let scopes = func.scopes(db); 214 let scopes = func.scopes(db);
214 let scope = scopes.scope_for_offset(position.offset); 215 let scope = scopes.scope_for_offset(position.offset);
215 Some(expr::resolver_for_scope(func.body(db), db, scope)) 216 Some(expr::resolver_for_scope(func.body(db), db, scope))
@@ -218,9 +219,15 @@ pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> R
218 None 219 None
219 } 220 }
220 } else if let Some(module) = ast::Module::cast(node) { 221 } else if let Some(module) = ast::Module::cast(node) {
221 Some(module_from_declaration(db, position.file_id, module)?.resolver(db)) 222 Some(module_from_declaration(db, file_id, module)?.resolver(db))
222 } else if let Some(_) = ast::SourceFile::cast(node) { 223 } else if let Some(_) = ast::SourceFile::cast(node) {
223 Some(module_from_source(db, position.file_id.into(), None)?.resolver(db)) 224 Some(module_from_source(db, file_id.into(), None)?.resolver(db))
225 } else if let Some(s) = ast::StructDef::cast(node) {
226 let module = module_from_child_node(db, file_id, s.syntax())?;
227 Some(struct_from_module(db, module, s).resolver(db))
228 } else if let Some(e) = ast::EnumDef::cast(node) {
229 let module = module_from_child_node(db, file_id, e.syntax())?;
230 Some(enum_from_module(db, module, e).resolver(db))
224 } else { 231 } else {
225 // TODO add missing cases 232 // TODO add missing cases
226 None 233 None
@@ -246,6 +253,12 @@ pub fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNo
246 Some(module_from_declaration(db, file_id, module)?.resolver(db)) 253 Some(module_from_declaration(db, file_id, module)?.resolver(db))
247 } else if let Some(_) = ast::SourceFile::cast(node) { 254 } else if let Some(_) = ast::SourceFile::cast(node) {
248 Some(module_from_source(db, file_id.into(), None)?.resolver(db)) 255 Some(module_from_source(db, file_id.into(), None)?.resolver(db))
256 } else if let Some(s) = ast::StructDef::cast(node) {
257 let module = module_from_child_node(db, file_id, s.syntax())?;
258 Some(struct_from_module(db, module, s).resolver(db))
259 } else if let Some(e) = ast::EnumDef::cast(node) {
260 let module = module_from_child_node(db, file_id, e.syntax())?;
261 Some(enum_from_module(db, module, e).resolver(db))
249 } else { 262 } else {
250 // TODO add missing cases 263 // TODO add missing cases
251 None 264 None
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 8e0f6a79e..0b9948d4b 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -66,6 +66,17 @@ mod tests {
66 } 66 }
67 67
68 #[test] 68 #[test]
69 #[ignore] // should not complete foo, which currently doesn't work
70 fn dont_complete_current_use() {
71 check_reference_completion(
72 "dont_complete_current_use",
73 r"
74 use self::foo<|>;
75 ",
76 );
77 }
78
79 #[test]
69 fn completes_mod_with_docs() { 80 fn completes_mod_with_docs() {
70 check_reference_completion( 81 check_reference_completion(
71 "mod_with_docs", 82 "mod_with_docs",
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs
index 3488d6480..44514ab2b 100644
--- a/crates/ra_ide_api/src/completion/complete_scope.rs
+++ b/crates/ra_ide_api/src/completion/complete_scope.rs
@@ -6,29 +6,15 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
6 } 6 }
7 let names = ctx.resolver.all_names(); 7 let names = ctx.resolver.all_names();
8 8
9 // let module_scope = module.scope(ctx.db); 9 names.into_iter().for_each(|(name, res)| {
10 names 10 CompletionItem::new(
11 .into_iter() 11 CompletionKind::Reference,
12 // FIXME check tests 12 ctx.source_range(),
13 // .filter(|(_name, res)| { 13 name.to_string(),
14 // // For cases like `use self::foo<|>` don't suggest foo itself. 14 )
15 // match res.import { 15 .from_resolution(ctx, &res)
16 // None => true, 16 .add_to(acc)
17 // Some(import) => { 17 });
18 // let source = module.import_source(ctx.db, import);
19 // !source.syntax().range().is_subrange(&ctx.leaf.range())
20 // }
21 // }
22 // })
23 .for_each(|(name, res)| {
24 CompletionItem::new(
25 CompletionKind::Reference,
26 ctx.source_range(),
27 name.to_string(),
28 )
29 .from_resolution(ctx, &res)
30 .add_to(acc)
31 });
32} 18}
33 19
34#[cfg(test)] 20#[cfg(test)]
@@ -87,6 +73,30 @@ mod tests {
87 } 73 }
88 74
89 #[test] 75 #[test]
76 fn completes_generic_params() {
77 check_reference_completion(
78 "generic_params",
79 r"
80 fn quux<T>() {
81 <|>
82 }
83 ",
84 );
85 }
86
87 #[test]
88 fn completes_generic_params_in_struct() {
89 check_reference_completion(
90 "generic_params_in_struct",
91 r"
92 struct X<T> {
93 x: <|>
94 }
95 ",
96 );
97 }
98
99 #[test]
90 fn completes_module_items() { 100 fn completes_module_items() {
91 check_reference_completion( 101 check_reference_completion(
92 "module_items", 102 "module_items",
@@ -145,5 +155,4 @@ mod tests {
145 fn completes_self_in_methods() { 155 fn completes_self_in_methods() {
146 check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }") 156 check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }")
147 } 157 }
148
149} 158}
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap
new file mode 100644
index 000000000..71cb55a5b
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap
@@ -0,0 +1,40 @@
1---
2created: "2019-02-01T22:20:40.580128393+00:00"
3creator: [email protected]
4expression: kind_completions
5source: crates/ra_ide_api/src/completion/completion_item.rs
6---
7[
8 CompletionItem {
9 completion_kind: Reference,
10 label: "T",
11 kind: Some(
12 TypeParam
13 ),
14 detail: None,
15 documentation: None,
16 lookup: None,
17 insert_text: None,
18 insert_text_format: PlainText,
19 source_range: [44; 44),
20 text_edit: None
21 },
22 CompletionItem {
23 completion_kind: Reference,
24 label: "quux",
25 kind: Some(
26 Function
27 ),
28 detail: Some(
29 "fn quux<T>()"
30 ),
31 documentation: None,
32 lookup: None,
33 insert_text: Some(
34 "quux()$0"
35 ),
36 insert_text_format: Snippet,
37 source_range: [44; 44),
38 text_edit: None
39 }
40]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap
new file mode 100644
index 000000000..a35c0cd13
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap
@@ -0,0 +1,36 @@
1---
2created: "2019-02-01T22:23:21.508620224+00:00"
3creator: [email protected]
4expression: kind_completions
5source: crates/ra_ide_api/src/completion/completion_item.rs
6---
7[
8 CompletionItem {
9 completion_kind: Reference,
10 label: "T",
11 kind: Some(
12 TypeParam
13 ),
14 detail: None,
15 documentation: None,
16 lookup: None,
17 insert_text: None,
18 insert_text_format: PlainText,
19 source_range: [46; 46),
20 text_edit: None
21 },
22 CompletionItem {
23 completion_kind: Reference,
24 label: "X",
25 kind: Some(
26 Struct
27 ),
28 detail: None,
29 documentation: None,
30 lookup: None,
31 insert_text: None,
32 insert_text_format: PlainText,
33 source_range: [46; 46),
34 text_edit: None
35 }
36]