aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion/complete_scope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/completion/complete_scope.rs')
-rw-r--r--crates/ra_ide_api/src/completion/complete_scope.rs62
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 @@
1use rustc_hash::FxHashSet; 1use rustc_hash::FxHashSet;
2use ra_syntax::{AstNode, TextUnit}; 2use ra_syntax::ast::AstNode;
3
4use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext}; 3use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
5 4
6pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { 5pub(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
39fn complete_fn(acc: &mut Completions, scopes: &hir::ScopesWithSyntaxMapping, offset: TextUnit) { 42fn 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)]
53mod tests { 64mod 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}