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