diff options
Diffstat (limited to 'crates/ra_ide_api/src/completion/complete_scope.rs')
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_scope.rs | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 4276e47e8..20fc77f06 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -1,6 +1,5 @@ | |||
1 | use rustc_hash::FxHashSet; | 1 | use rustc_hash::FxHashSet; |
2 | use ra_syntax::{AstNode, TextUnit}; | 2 | use ra_syntax::ast::AstNode; |
3 | |||
4 | use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext}; | 3 | use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext}; |
5 | 4 | ||
6 | pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | 5 | pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { |
@@ -13,7 +12,7 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | |||
13 | }; | 12 | }; |
14 | if let Some(function) = &ctx.function { | 13 | if let Some(function) = &ctx.function { |
15 | let scopes = function.scopes(ctx.db); | 14 | let scopes = function.scopes(ctx.db); |
16 | complete_fn(acc, &scopes, ctx.offset); | 15 | complete_fn(acc, &scopes, ctx); |
17 | } | 16 | } |
18 | 17 | ||
19 | let module_scope = module.scope(ctx.db); | 18 | let module_scope = module.scope(ctx.db); |
@@ -30,36 +29,50 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | |||
30 | } | 29 | } |
31 | }) | 30 | }) |
32 | .for_each(|(name, res)| { | 31 | .for_each(|(name, res)| { |
33 | CompletionItem::new(CompletionKind::Reference, name.to_string()) | 32 | CompletionItem::new( |
34 | .from_resolution(ctx, res) | 33 | CompletionKind::Reference, |
35 | .add_to(acc) | 34 | ctx.source_range(), |
35 | name.to_string(), | ||
36 | ) | ||
37 | .from_resolution(ctx, res) | ||
38 | .add_to(acc) | ||
36 | }); | 39 | }); |
37 | } | 40 | } |
38 | 41 | ||
39 | fn complete_fn(acc: &mut Completions, scopes: &hir::ScopesWithSyntaxMapping, offset: TextUnit) { | 42 | fn complete_fn( |
43 | acc: &mut Completions, | ||
44 | scopes: &hir::ScopesWithSyntaxMapping, | ||
45 | ctx: &CompletionContext, | ||
46 | ) { | ||
40 | let mut shadowed = FxHashSet::default(); | 47 | let mut shadowed = FxHashSet::default(); |
41 | scopes | 48 | scopes |
42 | .scope_chain_for_offset(offset) | 49 | .scope_chain_for_offset(ctx.offset) |
43 | .flat_map(|scope| scopes.scopes.entries(scope).iter()) | 50 | .flat_map(|scope| scopes.scopes.entries(scope).iter()) |
44 | .filter(|entry| shadowed.insert(entry.name())) | 51 | .filter(|entry| shadowed.insert(entry.name())) |
45 | .for_each(|entry| { | 52 | .for_each(|entry| { |
46 | CompletionItem::new(CompletionKind::Reference, entry.name().to_string()) | 53 | CompletionItem::new( |
47 | .kind(CompletionItemKind::Binding) | 54 | CompletionKind::Reference, |
48 | .add_to(acc) | 55 | ctx.source_range(), |
56 | entry.name().to_string(), | ||
57 | ) | ||
58 | .kind(CompletionItemKind::Binding) | ||
59 | .add_to(acc) | ||
49 | }); | 60 | }); |
50 | } | 61 | } |
51 | 62 | ||
52 | #[cfg(test)] | 63 | #[cfg(test)] |
53 | mod tests { | 64 | mod tests { |
54 | use crate::completion::{CompletionKind, check_completion}; | 65 | use crate::completion::CompletionKind; |
66 | use crate::completion::completion_item::check_completion; | ||
55 | 67 | ||
56 | fn check_reference_completion(code: &str, expected_completions: &str) { | 68 | fn check_reference_completion(name: &str, code: &str) { |
57 | check_completion(code, expected_completions, CompletionKind::Reference); | 69 | check_completion(name, code, CompletionKind::Reference); |
58 | } | 70 | } |
59 | 71 | ||
60 | #[test] | 72 | #[test] |
61 | fn completes_bindings_from_let() { | 73 | fn completes_bindings_from_let() { |
62 | check_reference_completion( | 74 | check_reference_completion( |
75 | "bindings_from_let", | ||
63 | r" | 76 | r" |
64 | fn quux(x: i32) { | 77 | fn quux(x: i32) { |
65 | let y = 92; | 78 | let y = 92; |
@@ -67,13 +80,13 @@ mod tests { | |||
67 | let z = (); | 80 | let z = (); |
68 | } | 81 | } |
69 | ", | 82 | ", |
70 | r#"y;x;quux "quux($0)""#, | ||
71 | ); | 83 | ); |
72 | } | 84 | } |
73 | 85 | ||
74 | #[test] | 86 | #[test] |
75 | fn completes_bindings_from_if_let() { | 87 | fn completes_bindings_from_if_let() { |
76 | check_reference_completion( | 88 | check_reference_completion( |
89 | "bindings_from_if_let", | ||
77 | r" | 90 | r" |
78 | fn quux() { | 91 | fn quux() { |
79 | if let Some(x) = foo() { | 92 | if let Some(x) = foo() { |
@@ -85,13 +98,13 @@ mod tests { | |||
85 | } | 98 | } |
86 | } | 99 | } |
87 | ", | 100 | ", |
88 | r#"b;a;quux "quux()$0""#, | ||
89 | ); | 101 | ); |
90 | } | 102 | } |
91 | 103 | ||
92 | #[test] | 104 | #[test] |
93 | fn completes_bindings_from_for() { | 105 | fn completes_bindings_from_for() { |
94 | check_reference_completion( | 106 | check_reference_completion( |
107 | "bindings_from_for", | ||
95 | r" | 108 | r" |
96 | fn quux() { | 109 | fn quux() { |
97 | for x in &[1, 2, 3] { | 110 | for x in &[1, 2, 3] { |
@@ -99,13 +112,13 @@ mod tests { | |||
99 | } | 112 | } |
100 | } | 113 | } |
101 | ", | 114 | ", |
102 | r#"x;quux "quux()$0""#, | ||
103 | ); | 115 | ); |
104 | } | 116 | } |
105 | 117 | ||
106 | #[test] | 118 | #[test] |
107 | fn completes_module_items() { | 119 | fn completes_module_items() { |
108 | check_reference_completion( | 120 | check_reference_completion( |
121 | "module_items", | ||
109 | r" | 122 | r" |
110 | struct Foo; | 123 | struct Foo; |
111 | enum Baz {} | 124 | enum Baz {} |
@@ -113,13 +126,13 @@ mod tests { | |||
113 | <|> | 126 | <|> |
114 | } | 127 | } |
115 | ", | 128 | ", |
116 | r#"quux "quux()$0";Foo;Baz"#, | ||
117 | ); | 129 | ); |
118 | } | 130 | } |
119 | 131 | ||
120 | #[test] | 132 | #[test] |
121 | fn completes_module_items_in_nested_modules() { | 133 | fn completes_module_items_in_nested_modules() { |
122 | check_reference_completion( | 134 | check_reference_completion( |
135 | "module_items_in_nested_modules", | ||
123 | r" | 136 | r" |
124 | struct Foo; | 137 | struct Foo; |
125 | mod m { | 138 | mod m { |
@@ -127,24 +140,24 @@ mod tests { | |||
127 | fn quux() { <|> } | 140 | fn quux() { <|> } |
128 | } | 141 | } |
129 | ", | 142 | ", |
130 | r#"quux "quux()$0";Bar"#, | ||
131 | ); | 143 | ); |
132 | } | 144 | } |
133 | 145 | ||
134 | #[test] | 146 | #[test] |
135 | fn completes_return_type() { | 147 | fn completes_return_type() { |
136 | check_reference_completion( | 148 | check_reference_completion( |
149 | "return_type", | ||
137 | r" | 150 | r" |
138 | struct Foo; | 151 | struct Foo; |
139 | fn x() -> <|> | 152 | fn x() -> <|> |
140 | ", | 153 | ", |
141 | r#"Foo;x "x()$0""#, | ||
142 | ) | 154 | ) |
143 | } | 155 | } |
144 | 156 | ||
145 | #[test] | 157 | #[test] |
146 | fn dont_show_both_completions_for_shadowing() { | 158 | fn dont_show_both_completions_for_shadowing() { |
147 | check_reference_completion( | 159 | check_reference_completion( |
160 | "dont_show_both_completions_for_shadowing", | ||
148 | r" | 161 | r" |
149 | fn foo() -> { | 162 | fn foo() -> { |
150 | let bar = 92; | 163 | let bar = 92; |
@@ -154,32 +167,29 @@ mod tests { | |||
154 | } | 167 | } |
155 | } | 168 | } |
156 | ", | 169 | ", |
157 | r#"bar;foo "foo()$0""#, | ||
158 | ) | 170 | ) |
159 | } | 171 | } |
160 | 172 | ||
161 | #[test] | 173 | #[test] |
162 | fn completes_self_in_methods() { | 174 | fn completes_self_in_methods() { |
163 | check_reference_completion(r"impl S { fn foo(&self) { <|> } }", "self") | 175 | check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }") |
164 | } | 176 | } |
165 | 177 | ||
166 | #[test] | 178 | #[test] |
167 | fn inserts_parens_for_function_calls() { | 179 | fn inserts_parens_for_function_calls() { |
168 | check_reference_completion( | 180 | check_reference_completion( |
181 | "inserts_parens_for_function_calls1", | ||
169 | r" | 182 | r" |
170 | fn no_args() {} | 183 | fn no_args() {} |
171 | fn main() { no_<|> } | 184 | fn main() { no_<|> } |
172 | ", | 185 | ", |
173 | r#"no_args "no_args()$0" | ||
174 | main "main()$0""#, | ||
175 | ); | 186 | ); |
176 | check_reference_completion( | 187 | check_reference_completion( |
188 | "inserts_parens_for_function_calls2", | ||
177 | r" | 189 | r" |
178 | fn with_args(x: i32, y: String) {} | 190 | fn with_args(x: i32, y: String) {} |
179 | fn main() { with_<|> } | 191 | fn main() { with_<|> } |
180 | ", | 192 | ", |
181 | r#"main "main()$0" | ||
182 | with_args "with_args($0)""#, | ||
183 | ); | 193 | ); |
184 | } | 194 | } |
185 | } | 195 | } |