aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion/complete_dot.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion/complete_dot.rs')
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs145
1 files changed, 141 insertions, 4 deletions
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index f433faef3..cb899d8ff 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -1,13 +1,23 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{HasVisibility, Type}; 3use hir::{
4 HasVisibility,
5 // HirDisplay,
6 Type,
7};
4 8
5use crate::completion::completion_item::CompletionKind; 9use crate::completion::completion_item::CompletionKind;
6use crate::{ 10use crate::{
7 completion::{completion_context::CompletionContext, completion_item::Completions}, 11 call_info::call_info,
12 completion::{
13 completion_context::CompletionContext,
14 completion_item::{Completions, SortOption},
15 },
16 // CallInfo,
8 CompletionItem, 17 CompletionItem,
9}; 18};
10use rustc_hash::FxHashSet; 19use rustc_hash::FxHashSet;
20// use std::cmp::Ordering;
11 21
12/// Complete dot accesses, i.e. fields or methods (and .await syntax). 22/// Complete dot accesses, i.e. fields or methods (and .await syntax).
13pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { 23pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
@@ -37,7 +47,41 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
37 47
38fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { 48fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) {
39 for receiver in receiver.autoderef(ctx.db) { 49 for receiver in receiver.autoderef(ctx.db) {
40 for (field, ty) in receiver.fields(ctx.db) { 50 let fields = receiver.fields(ctx.db);
51
52 // If we use this implementation we can delete call_info in the CompletionContext
53 if let Some(call_info) = call_info(ctx.db, ctx.file_position) {
54 acc.with_sort_option(SortOption::CallFn(call_info));
55 }
56
57 // // For Call Fn
58 // if let Some(call_info) = &ctx.call_info {
59 // if let Some(active_parameter_type) = call_info.active_parameter_type() {
60 // let active_parameter_name = call_info.active_parameter_name().unwrap();
61 // fields.sort_by(|a, b| {
62 // // For the same type
63 // if active_parameter_type == a.1.display(ctx.db).to_string() {
64 // // If same type + same name then go top position
65 // if active_parameter_name == a.0.name(ctx.db).to_string() {
66 // Ordering::Less
67 // } else {
68 // if active_parameter_type == b.1.display(ctx.db).to_string() {
69 // Ordering::Equal
70 // } else {
71 // Ordering::Less
72 // }
73 // }
74 // } else {
75 // Ordering::Greater
76 // }
77 // });
78 // }
79 // }
80
81 // For Lit struct fields
82 // ---
83
84 for (field, ty) in fields {
41 if ctx.scope().module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) { 85 if ctx.scope().module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) {
42 // Skip private field. FIXME: If the definition location of the 86 // Skip private field. FIXME: If the definition location of the
43 // field is editable, we should show the completion 87 // field is editable, we should show the completion
@@ -70,13 +114,20 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &T
70 114
71#[cfg(test)] 115#[cfg(test)]
72mod tests { 116mod tests {
73 use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; 117 use crate::completion::{
118 test_utils::{do_completion, do_completion_without_sort},
119 CompletionItem, CompletionKind,
120 };
74 use insta::assert_debug_snapshot; 121 use insta::assert_debug_snapshot;
75 122
76 fn do_ref_completion(code: &str) -> Vec<CompletionItem> { 123 fn do_ref_completion(code: &str) -> Vec<CompletionItem> {
77 do_completion(code, CompletionKind::Reference) 124 do_completion(code, CompletionKind::Reference)
78 } 125 }
79 126
127 fn do_ref_completion_without_sort(code: &str) -> Vec<CompletionItem> {
128 do_completion_without_sort(code, CompletionKind::Reference)
129 }
130
80 #[test] 131 #[test]
81 fn test_struct_field_completion() { 132 fn test_struct_field_completion() {
82 assert_debug_snapshot!( 133 assert_debug_snapshot!(
@@ -104,6 +155,92 @@ mod tests {
104 } 155 }
105 156
106 #[test] 157 #[test]
158 fn test_struct_field_completion_in_func_call() {
159 assert_debug_snapshot!(
160 do_ref_completion_without_sort(
161 r"
162 struct A { another_field: i64, the_field: u32, my_string: String }
163 fn test(my_param: u32) -> u32 { my_param }
164 fn foo(a: A) {
165 test(a.<|>)
166 }
167 ",
168 ),
169 @r###"
170 [
171 CompletionItem {
172 label: "the_field",
173 source_range: [201; 201),
174 delete: [201; 201),
175 insert: "the_field",
176 kind: Field,
177 detail: "u32",
178 },
179 CompletionItem {
180 label: "another_field",
181 source_range: [201; 201),
182 delete: [201; 201),
183 insert: "another_field",
184 kind: Field,
185 detail: "i64",
186 },
187 CompletionItem {
188 label: "my_string",
189 source_range: [201; 201),
190 delete: [201; 201),
191 insert: "my_string",
192 kind: Field,
193 detail: "{unknown}",
194 },
195 ]
196 "###
197 );
198 }
199
200 #[test]
201 fn test_struct_field_completion_in_func_call_with_type_and_name() {
202 assert_debug_snapshot!(
203 do_ref_completion_without_sort(
204 r"
205 struct A { another_field: i64, another_good_type: u32, the_field: u32 }
206 fn test(the_field: u32) -> u32 { the_field }
207 fn foo(a: A) {
208 test(a.<|>)
209 }
210 ",
211 ),
212 @r###"
213 [
214 CompletionItem {
215 label: "the_field",
216 source_range: [208; 208),
217 delete: [208; 208),
218 insert: "the_field",
219 kind: Field,
220 detail: "u32",
221 },
222 CompletionItem {
223 label: "another_good_type",
224 source_range: [208; 208),
225 delete: [208; 208),
226 insert: "another_good_type",
227 kind: Field,
228 detail: "u32",
229 },
230 CompletionItem {
231 label: "another_field",
232 source_range: [208; 208),
233 delete: [208; 208),
234 insert: "another_field",
235 kind: Field,
236 detail: "i64",
237 },
238 ]
239 "###
240 );
241 }
242
243 #[test]
107 fn test_struct_field_completion_self() { 244 fn test_struct_field_completion_self() {
108 assert_debug_snapshot!( 245 assert_debug_snapshot!(
109 do_ref_completion( 246 do_ref_completion(