aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion')
-rw-r--r--crates/ra_ide/src/completion/complete_keyword.rs414
-rw-r--r--crates/ra_ide/src/completion/complete_record.rs546
-rw-r--r--crates/ra_ide/src/completion/completion_item.rs20
-rw-r--r--crates/ra_ide/src/completion/presentation.rs25
-rw-r--r--crates/ra_ide/src/completion/test_utils.rs23
5 files changed, 447 insertions, 581 deletions
diff --git a/crates/ra_ide/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs
index e599cc3d1..34d061f5a 100644
--- a/crates/ra_ide/src/completion/complete_keyword.rs
+++ b/crates/ra_ide/src/completion/complete_keyword.rs
@@ -174,289 +174,289 @@ fn complete_return(
174 174
175#[cfg(test)] 175#[cfg(test)]
176mod tests { 176mod tests {
177 use crate::completion::{test_utils::completion_list, CompletionKind}; 177 use expect::{expect, Expect};
178 use insta::assert_snapshot;
179 178
180 fn get_keyword_completions(code: &str) -> String { 179 use crate::completion::{
181 completion_list(code, CompletionKind::Keyword) 180 test_utils::{check_edit, completion_list},
181 CompletionKind,
182 };
183
184 fn check(ra_fixture: &str, expect: Expect) {
185 let actual = completion_list(ra_fixture, CompletionKind::Keyword);
186 expect.assert_eq(&actual)
182 } 187 }
183 188
184 #[test] 189 #[test]
185 fn test_keywords_in_use_stmt() { 190 fn test_keywords_in_use_stmt() {
186 assert_snapshot!( 191 check(
187 get_keyword_completions(r"use <|>"), 192 r"use <|>",
188 @r###" 193 expect![[r#"
189 kw crate:: 194 kw crate::
190 kw self 195 kw self
191 kw super:: 196 kw super::
192 "### 197 "#]],
193 ); 198 );
194 199
195 assert_snapshot!( 200 check(
196 get_keyword_completions(r"use a::<|>"), 201 r"use a::<|>",
197 @r###" 202 expect![[r#"
198 kw self 203 kw self
199 kw super:: 204 kw super::
200 "### 205 "#]],
201 ); 206 );
202 207
203 assert_snapshot!( 208 check(
204 get_keyword_completions(r"use a::{b, <|>}"), 209 r"use a::{b, <|>}",
205 @r###" 210 expect![[r#"
206 kw self 211 kw self
207 kw super:: 212 kw super::
208 "### 213 "#]],
209 ); 214 );
210 } 215 }
211 216
212 #[test] 217 #[test]
213 fn test_keywords_at_source_file_level() { 218 fn test_keywords_at_source_file_level() {
214 assert_snapshot!( 219 check(
215 get_keyword_completions(r"m<|>"), 220 r"m<|>",
216 @r###" 221 expect![[r#"
217 kw const 222 kw const
218 kw enum 223 kw enum
219 kw extern 224 kw extern
220 kw fn 225 kw fn
221 kw impl 226 kw impl
222 kw mod 227 kw mod
223 kw pub 228 kw pub
224 kw static 229 kw static
225 kw struct 230 kw struct
226 kw trait 231 kw trait
227 kw type 232 kw type
228 kw union 233 kw union
229 kw unsafe 234 kw unsafe
230 kw use 235 kw use
231 "### 236 "#]],
232 ); 237 );
233 } 238 }
234 239
235 #[test] 240 #[test]
236 fn test_keywords_in_function() { 241 fn test_keywords_in_function() {
237 assert_snapshot!( 242 check(
238 get_keyword_completions(r"fn quux() { <|> }"), 243 r"fn quux() { <|> }",
239 @r###" 244 expect![[r#"
240 kw const 245 kw const
241 kw extern 246 kw extern
242 kw fn 247 kw fn
243 kw if 248 kw if
244 kw if let 249 kw if let
245 kw impl 250 kw impl
246 kw let 251 kw let
247 kw loop 252 kw loop
248 kw match 253 kw match
249 kw mod 254 kw mod
250 kw return 255 kw return
251 kw static 256 kw static
252 kw trait 257 kw trait
253 kw type 258 kw type
254 kw unsafe 259 kw unsafe
255 kw use 260 kw use
256 kw while 261 kw while
257 "### 262 "#]],
258 ); 263 );
259 } 264 }
260 265
261 #[test] 266 #[test]
262 fn test_keywords_inside_block() { 267 fn test_keywords_inside_block() {
263 assert_snapshot!( 268 check(
264 get_keyword_completions(r"fn quux() { if true { <|> } }"), 269 r"fn quux() { if true { <|> } }",
265 @r###" 270 expect![[r#"
266 kw const 271 kw const
267 kw extern 272 kw extern
268 kw fn 273 kw fn
269 kw if 274 kw if
270 kw if let 275 kw if let
271 kw impl 276 kw impl
272 kw let 277 kw let
273 kw loop 278 kw loop
274 kw match 279 kw match
275 kw mod 280 kw mod
276 kw return 281 kw return
277 kw static 282 kw static
278 kw trait 283 kw trait
279 kw type 284 kw type
280 kw unsafe 285 kw unsafe
281 kw use 286 kw use
282 kw while 287 kw while
283 "### 288 "#]],
284 ); 289 );
285 } 290 }
286 291
287 #[test] 292 #[test]
288 fn test_keywords_after_if() { 293 fn test_keywords_after_if() {
289 assert_snapshot!( 294 check(
290 get_keyword_completions( 295 r#"fn quux() { if true { () } <|> }"#,
291 r" 296 expect![[r#"
292 fn quux() { 297 kw const
293 if true { 298 kw else
294 () 299 kw else if
295 } <|> 300 kw extern
296 } 301 kw fn
297 ", 302 kw if
298 ), 303 kw if let
299 @r###" 304 kw impl
300 kw const 305 kw let
301 kw else 306 kw loop
302 kw else if 307 kw match
303 kw extern 308 kw mod
304 kw fn 309 kw return
305 kw if 310 kw static
306 kw if let 311 kw trait
307 kw impl 312 kw type
308 kw let 313 kw unsafe
309 kw loop 314 kw use
310 kw match 315 kw while
311 kw mod 316 "#]],
312 kw return 317 );
313 kw static 318 check_edit(
314 kw trait 319 "else",
315 kw type 320 r#"fn quux() { if true { () } <|> }"#,
316 kw unsafe 321 r#"fn quux() { if true { () } else {$0} }"#,
317 kw use
318 kw while
319 "###
320 ); 322 );
321 } 323 }
322 324
323 #[test] 325 #[test]
324 fn test_keywords_in_match_arm() { 326 fn test_keywords_in_match_arm() {
325 assert_snapshot!( 327 check(
326 get_keyword_completions( 328 r#"
327 r" 329fn quux() -> i32 {
328 fn quux() -> i32 { 330 match () {
329 match () { 331 () => <|>
330 () => <|> 332 }
331 } 333}
332 } 334"#,
333 ", 335 expect![[r#"
334 ), 336 kw if
335 @r###" 337 kw if let
336 kw if 338 kw loop
337 kw if let 339 kw match
338 kw loop 340 kw return
339 kw match 341 kw unsafe
340 kw return 342 "#]],
341 kw unsafe
342 "###
343 ); 343 );
344 } 344 }
345 345
346 #[test] 346 #[test]
347 fn test_keywords_in_trait_def() { 347 fn test_keywords_in_trait_def() {
348 assert_snapshot!( 348 check(
349 get_keyword_completions(r"trait My { <|> }"), 349 r"trait My { <|> }",
350 @r###" 350 expect![[r#"
351 kw const 351 kw const
352 kw fn 352 kw fn
353 kw type 353 kw type
354 kw unsafe 354 kw unsafe
355 "### 355 "#]],
356 ); 356 );
357 } 357 }
358 358
359 #[test] 359 #[test]
360 fn test_keywords_in_impl_def() { 360 fn test_keywords_in_impl_def() {
361 assert_snapshot!( 361 check(
362 get_keyword_completions(r"impl My { <|> }"), 362 r"impl My { <|> }",
363 @r###" 363 expect![[r#"
364 kw const 364 kw const
365 kw fn 365 kw fn
366 kw pub 366 kw pub
367 kw type 367 kw type
368 kw unsafe 368 kw unsafe
369 "### 369 "#]],
370 ); 370 );
371 } 371 }
372 372
373 #[test] 373 #[test]
374 fn test_keywords_in_loop() { 374 fn test_keywords_in_loop() {
375 assert_snapshot!( 375 check(
376 get_keyword_completions(r"fn my() { loop { <|> } }"), 376 r"fn my() { loop { <|> } }",
377 @r###" 377 expect![[r#"
378 kw break 378 kw break
379 kw const 379 kw const
380 kw continue 380 kw continue
381 kw extern 381 kw extern
382 kw fn 382 kw fn
383 kw if 383 kw if
384 kw if let 384 kw if let
385 kw impl 385 kw impl
386 kw let 386 kw let
387 kw loop 387 kw loop
388 kw match 388 kw match
389 kw mod 389 kw mod
390 kw return 390 kw return
391 kw static 391 kw static
392 kw trait 392 kw trait
393 kw type 393 kw type
394 kw unsafe 394 kw unsafe
395 kw use 395 kw use
396 kw while 396 kw while
397 "### 397 "#]],
398 ); 398 );
399 } 399 }
400 400
401 #[test] 401 #[test]
402 fn test_keywords_after_unsafe_in_item_list() { 402 fn test_keywords_after_unsafe_in_item_list() {
403 assert_snapshot!( 403 check(
404 get_keyword_completions(r"unsafe <|>"), 404 r"unsafe <|>",
405 @r###" 405 expect![[r#"
406 kw fn 406 kw fn
407 kw impl 407 kw impl
408 kw trait 408 kw trait
409 "### 409 "#]],
410 ); 410 );
411 } 411 }
412 412
413 #[test] 413 #[test]
414 fn test_keywords_after_unsafe_in_block_expr() { 414 fn test_keywords_after_unsafe_in_block_expr() {
415 assert_snapshot!( 415 check(
416 get_keyword_completions(r"fn my_fn() { unsafe <|> }"), 416 r"fn my_fn() { unsafe <|> }",
417 @r###" 417 expect![[r#"
418 kw fn 418 kw fn
419 kw impl 419 kw impl
420 kw trait 420 kw trait
421 "### 421 "#]],
422 ); 422 );
423 } 423 }
424 424
425 #[test] 425 #[test]
426 fn test_mut_in_ref_and_in_fn_parameters_list() { 426 fn test_mut_in_ref_and_in_fn_parameters_list() {
427 assert_snapshot!( 427 check(
428 get_keyword_completions(r"fn my_fn(&<|>) {}"), 428 r"fn my_fn(&<|>) {}",
429 @r###" 429 expect![[r#"
430 kw mut 430 kw mut
431 "### 431 "#]],
432 ); 432 );
433 assert_snapshot!( 433 check(
434 get_keyword_completions(r"fn my_fn(<|>) {}"), 434 r"fn my_fn(<|>) {}",
435 @r###" 435 expect![[r#"
436 kw mut 436 kw mut
437 "### 437 "#]],
438 ); 438 );
439 assert_snapshot!( 439 check(
440 get_keyword_completions(r"fn my_fn() { let &<|> }"), 440 r"fn my_fn() { let &<|> }",
441 @r###" 441 expect![[r#"
442 kw mut 442 kw mut
443 "### 443 "#]],
444 ); 444 );
445 } 445 }
446 446
447 #[test] 447 #[test]
448 fn test_where_keyword() { 448 fn test_where_keyword() {
449 assert_snapshot!( 449 check(
450 get_keyword_completions(r"trait A <|>"), 450 r"trait A <|>",
451 @r###" 451 expect![[r#"
452 kw where 452 kw where
453 "### 453 "#]],
454 ); 454 );
455 assert_snapshot!( 455 check(
456 get_keyword_completions(r"impl A <|>"), 456 r"impl A <|>",
457 @r###" 457 expect![[r#"
458 kw where 458 kw where
459 "### 459 "#]],
460 ); 460 );
461 } 461 }
462} 462}
diff --git a/crates/ra_ide/src/completion/complete_record.rs b/crates/ra_ide/src/completion/complete_record.rs
index 13eb2f79f..74b94594d 100644
--- a/crates/ra_ide/src/completion/complete_record.rs
+++ b/crates/ra_ide/src/completion/complete_record.rs
@@ -18,389 +18,209 @@ pub(super) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
18 18
19#[cfg(test)] 19#[cfg(test)]
20mod tests { 20mod tests {
21 mod record_pat_tests { 21 use expect::{expect, Expect};
22 use insta::assert_debug_snapshot;
23 22
24 use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; 23 use crate::completion::{test_utils::completion_list, CompletionKind};
25 24
26 fn complete(code: &str) -> Vec<CompletionItem> { 25 fn check(ra_fixture: &str, expect: Expect) {
27 do_completion(code, CompletionKind::Reference) 26 let actual = completion_list(ra_fixture, CompletionKind::Reference);
28 } 27 expect.assert_eq(&actual);
29 28 }
30 #[test]
31 fn test_record_pattern_field() {
32 let completions = complete(
33 r"
34 struct S { foo: u32 }
35
36 fn process(f: S) {
37 match f {
38 S { f<|>: 92 } => (),
39 }
40 }
41 ",
42 );
43 assert_debug_snapshot!(completions, @r###"
44 [
45 CompletionItem {
46 label: "foo",
47 source_range: 68..69,
48 delete: 68..69,
49 insert: "foo",
50 kind: Field,
51 detail: "u32",
52 },
53 ]
54 "###);
55 }
56
57 #[test]
58 fn test_record_pattern_enum_variant() {
59 let completions = complete(
60 r"
61 enum E {
62 S { foo: u32, bar: () }
63 }
64
65 fn process(e: E) {
66 match e {
67 E::S { <|> } => (),
68 }
69 }
70 ",
71 );
72 assert_debug_snapshot!(completions, @r###"
73 [
74 CompletionItem {
75 label: "bar",
76 source_range: 88..88,
77 delete: 88..88,
78 insert: "bar",
79 kind: Field,
80 detail: "()",
81 },
82 CompletionItem {
83 label: "foo",
84 source_range: 88..88,
85 delete: 88..88,
86 insert: "foo",
87 kind: Field,
88 detail: "u32",
89 },
90 ]
91 "###);
92 }
93 29
94 #[test] 30 #[test]
95 fn test_record_pattern_field_in_simple_macro() { 31 fn test_record_pattern_field() {
96 let completions = complete( 32 check(
97 r" 33 r#"
98 macro_rules! m { ($e:expr) => { $e } } 34struct S { foo: u32 }
99 struct S { foo: u32 }
100 35
101 fn process(f: S) { 36fn process(f: S) {
102 m!(match f { 37 match f {
103 S { f<|>: 92 } => (), 38 S { f<|>: 92 } => (),
104 }) 39 }
105 } 40}
106 ", 41"#,
107 ); 42 expect![[r#"
108 assert_debug_snapshot!(completions, @r###" 43 fd foo u32
109 [ 44 "#]],
110 CompletionItem { 45 );
111 label: "foo", 46 }
112 source_range: 110..111,
113 delete: 110..111,
114 insert: "foo",
115 kind: Field,
116 detail: "u32",
117 },
118 ]
119 "###);
120 }
121 47
122 #[test] 48 #[test]
123 fn only_missing_fields_are_completed_in_destruct_pats() { 49 fn test_record_pattern_enum_variant() {
124 let completions = complete( 50 check(
125 r" 51 r#"
126 struct S { 52enum E { S { foo: u32, bar: () } }
127 foo1: u32,
128 foo2: u32,
129 bar: u32,
130 baz: u32,
131 }
132 53
133 fn main() { 54fn process(e: E) {
134 let s = S { 55 match e {
135 foo1: 1, 56 E::S { <|> } => (),
136 foo2: 2, 57 }
137 bar: 3, 58}
138 baz: 4, 59"#,
139 }; 60 expect![[r#"
140 if let S { foo1, foo2: a, <|> } = s {} 61 fd bar ()
141 } 62 fd foo u32
142 ", 63 "#]],
143 ); 64 );
144 assert_debug_snapshot!(completions, @r###"
145 [
146 CompletionItem {
147 label: "bar",
148 source_range: 203..203,
149 delete: 203..203,
150 insert: "bar",
151 kind: Field,
152 detail: "u32",
153 },
154 CompletionItem {
155 label: "baz",
156 source_range: 203..203,
157 delete: 203..203,
158 insert: "baz",
159 kind: Field,
160 detail: "u32",
161 },
162 ]
163 "###);
164 }
165 } 65 }
166 66
167 mod record_lit_tests { 67 #[test]
168 use insta::assert_debug_snapshot; 68 fn test_record_pattern_field_in_simple_macro() {
169 69 check(
170 use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; 70 r"
71macro_rules! m { ($e:expr) => { $e } }
72struct S { foo: u32 }
73
74fn process(f: S) {
75 m!(match f {
76 S { f<|>: 92 } => (),
77 })
78}
79",
80 expect![[r#"
81 fd foo u32
82 "#]],
83 );
84 }
171 85
172 fn complete(code: &str) -> Vec<CompletionItem> { 86 #[test]
173 do_completion(code, CompletionKind::Reference) 87 fn only_missing_fields_are_completed_in_destruct_pats() {
174 } 88 check(
89 r#"
90struct S {
91 foo1: u32, foo2: u32,
92 bar: u32, baz: u32,
93}
175 94
176 #[test] 95fn main() {
177 fn test_record_literal_deprecated_field() { 96 let s = S {
178 let completions = complete( 97 foo1: 1, foo2: 2,
179 r" 98 bar: 3, baz: 4,
180 struct A { 99 };
181 #[deprecated] 100 if let S { foo1, foo2: a, <|> } = s {}
182 the_field: u32, 101}
183 } 102"#,
184 fn foo() { 103 expect![[r#"
185 A { the<|> } 104 fd bar u32
186 } 105 fd baz u32
187 ", 106 "#]],
188 ); 107 );
189 assert_debug_snapshot!(completions, @r###" 108 }
190 [
191 CompletionItem {
192 label: "the_field",
193 source_range: 69..72,
194 delete: 69..72,
195 insert: "the_field",
196 kind: Field,
197 detail: "u32",
198 deprecated: true,
199 },
200 ]
201 "###);
202 }
203 109
204 #[test] 110 #[test]
205 fn test_record_literal_field() { 111 fn test_record_literal_field() {
206 let completions = complete( 112 check(
207 r" 113 r#"
208 struct A { the_field: u32 } 114struct A { the_field: u32 }
209 fn foo() { 115fn foo() {
210 A { the<|> } 116 A { the<|> }
211 } 117}
212 ", 118"#,
213 ); 119 expect![[r#"
214 assert_debug_snapshot!(completions, @r###" 120 fd the_field u32
215 [ 121 "#]],
216 CompletionItem { 122 );
217 label: "the_field", 123 }
218 source_range: 46..49,
219 delete: 46..49,
220 insert: "the_field",
221 kind: Field,
222 detail: "u32",
223 },
224 ]
225 "###);
226 }
227 124
228 #[test] 125 #[test]
229 fn test_record_literal_enum_variant() { 126 fn test_record_literal_enum_variant() {
230 let completions = complete( 127 check(
231 r" 128 r#"
232 enum E { 129enum E { A { a: u32 } }
233 A { a: u32 } 130fn foo() {
234 } 131 let _ = E::A { <|> }
235 fn foo() { 132}
236 let _ = E::A { <|> } 133"#,
237 } 134 expect![[r#"
238 ", 135 fd a u32
239 ); 136 "#]],
240 assert_debug_snapshot!(completions, @r###" 137 );
241 [ 138 }
242 CompletionItem {
243 label: "a",
244 source_range: 58..58,
245 delete: 58..58,
246 insert: "a",
247 kind: Field,
248 detail: "u32",
249 },
250 ]
251 "###);
252 }
253 139
254 #[test] 140 #[test]
255 fn test_record_literal_two_structs() { 141 fn test_record_literal_two_structs() {
256 let completions = complete( 142 check(
257 r" 143 r#"
258 struct A { a: u32 } 144struct A { a: u32 }
259 struct B { b: u32 } 145struct B { b: u32 }
260 146
261 fn foo() { 147fn foo() {
262 let _: A = B { <|> } 148 let _: A = B { <|> }
263 } 149}
264 ", 150"#,
265 ); 151 expect![[r#"
266 assert_debug_snapshot!(completions, @r###" 152 fd b u32
267 [ 153 "#]],
268 CompletionItem { 154 );
269 label: "b", 155 }
270 source_range: 70..70,
271 delete: 70..70,
272 insert: "b",
273 kind: Field,
274 detail: "u32",
275 },
276 ]
277 "###);
278 }
279 156
280 #[test] 157 #[test]
281 fn test_record_literal_generic_struct() { 158 fn test_record_literal_generic_struct() {
282 let completions = complete( 159 check(
283 r" 160 r#"
284 struct A<T> { a: T } 161struct A<T> { a: T }
285 162
286 fn foo() { 163fn foo() {
287 let _: A<u32> = A { <|> } 164 let _: A<u32> = A { <|> }
288 } 165}
289 ", 166"#,
290 ); 167 expect![[r#"
291 assert_debug_snapshot!(completions, @r###" 168 fd a u32
292 [ 169 "#]],
293 CompletionItem { 170 );
294 label: "a", 171 }
295 source_range: 56..56,
296 delete: 56..56,
297 insert: "a",
298 kind: Field,
299 detail: "u32",
300 },
301 ]
302 "###);
303 }
304 172
305 #[test] 173 #[test]
306 fn test_record_literal_field_in_simple_macro() { 174 fn test_record_literal_field_in_simple_macro() {
307 let completions = complete( 175 check(
308 r" 176 r#"
309 macro_rules! m { ($e:expr) => { $e } } 177macro_rules! m { ($e:expr) => { $e } }
310 struct A { the_field: u32 } 178struct A { the_field: u32 }
311 fn foo() { 179fn foo() {
312 m!(A { the<|> }) 180 m!(A { the<|> })
313 } 181}
314 ", 182"#,
315 ); 183 expect![[r#"
316 assert_debug_snapshot!(completions, @r###" 184 fd the_field u32
317 [ 185 "#]],
318 CompletionItem { 186 );
319 label: "the_field", 187 }
320 source_range: 88..91,
321 delete: 88..91,
322 insert: "the_field",
323 kind: Field,
324 detail: "u32",
325 },
326 ]
327 "###);
328 }
329 188
330 #[test] 189 #[test]
331 fn only_missing_fields_are_completed() { 190 fn only_missing_fields_are_completed() {
332 let completions = complete( 191 check(
333 r" 192 r#"
334 struct S { 193struct S {
335 foo1: u32, 194 foo1: u32, foo2: u32,
336 foo2: u32, 195 bar: u32, baz: u32,
337 bar: u32, 196}
338 baz: u32,
339 }
340 197
341 fn main() { 198fn main() {
342 let foo1 = 1; 199 let foo1 = 1;
343 let s = S { 200 let s = S { foo1, foo2: 5, <|> }
344 foo1, 201}
345 foo2: 5, 202"#,
346 <|> 203 expect![[r#"
347 } 204 fd bar u32
348 } 205 fd baz u32
349 ", 206 "#]],
350 ); 207 );
351 assert_debug_snapshot!(completions, @r###" 208 }
352 [
353 CompletionItem {
354 label: "bar",
355 source_range: 157..157,
356 delete: 157..157,
357 insert: "bar",
358 kind: Field,
359 detail: "u32",
360 },
361 CompletionItem {
362 label: "baz",
363 source_range: 157..157,
364 delete: 157..157,
365 insert: "baz",
366 kind: Field,
367 detail: "u32",
368 },
369 ]
370 "###);
371 }
372 209
373 #[test] 210 #[test]
374 fn completes_functional_update() { 211 fn completes_functional_update() {
375 let completions = complete( 212 check(
376 r" 213 r#"
377 struct S { 214struct S { foo1: u32, foo2: u32 }
378 foo1: u32,
379 foo2: u32,
380 }
381 215
382 fn main() { 216fn main() {
383 let foo1 = 1; 217 let foo1 = 1;
384 let s = S { 218 let s = S { foo1, <|> .. loop {} }
385 foo1, 219}
386 <|> 220"#,
387 .. loop {} 221 expect![[r#"
388 } 222 fd foo2 u32
389 } 223 "#]],
390 ", 224 );
391 );
392 assert_debug_snapshot!(completions, @r###"
393 [
394 CompletionItem {
395 label: "foo2",
396 source_range: 112..112,
397 delete: 112..112,
398 insert: "foo2",
399 kind: Field,
400 detail: "u32",
401 },
402 ]
403 "###);
404 }
405 } 225 }
406} 226}
diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs
index 98348b349..4db371d57 100644
--- a/crates/ra_ide/src/completion/completion_item.rs
+++ b/crates/ra_ide/src/completion/completion_item.rs
@@ -129,24 +129,24 @@ impl CompletionItemKind {
129 #[cfg(test)] 129 #[cfg(test)]
130 pub(crate) fn tag(&self) -> &'static str { 130 pub(crate) fn tag(&self) -> &'static str {
131 match self { 131 match self {
132 CompletionItemKind::Snippet => "sn", 132 CompletionItemKind::Attribute => "at",
133 CompletionItemKind::Keyword => "kw", 133 CompletionItemKind::Binding => "bn",
134 CompletionItemKind::Module => "md",
135 CompletionItemKind::Function => "fn",
136 CompletionItemKind::BuiltinType => "bt", 134 CompletionItemKind::BuiltinType => "bt",
137 CompletionItemKind::Struct => "st", 135 CompletionItemKind::Const => "ct",
138 CompletionItemKind::Enum => "en", 136 CompletionItemKind::Enum => "en",
139 CompletionItemKind::EnumVariant => "ev", 137 CompletionItemKind::EnumVariant => "ev",
140 CompletionItemKind::Binding => "bn",
141 CompletionItemKind::Field => "fd", 138 CompletionItemKind::Field => "fd",
139 CompletionItemKind::Function => "fn",
140 CompletionItemKind::Keyword => "kw",
141 CompletionItemKind::Macro => "ma",
142 CompletionItemKind::Method => "me",
143 CompletionItemKind::Module => "md",
144 CompletionItemKind::Snippet => "sn",
142 CompletionItemKind::Static => "sc", 145 CompletionItemKind::Static => "sc",
143 CompletionItemKind::Const => "ct", 146 CompletionItemKind::Struct => "st",
144 CompletionItemKind::Trait => "tt", 147 CompletionItemKind::Trait => "tt",
145 CompletionItemKind::TypeAlias => "ta", 148 CompletionItemKind::TypeAlias => "ta",
146 CompletionItemKind::Method => "me",
147 CompletionItemKind::TypeParam => "tp", 149 CompletionItemKind::TypeParam => "tp",
148 CompletionItemKind::Macro => "ma",
149 CompletionItemKind::Attribute => "at",
150 } 150 }
151 } 151 }
152} 152}
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index b18279746..bd274bd74 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -606,6 +606,31 @@ mod tests {
606 ] 606 ]
607 "### 607 "###
608 ); 608 );
609
610 assert_debug_snapshot!(do_reference_completion(
611 r#"
612struct A {
613 #[deprecated]
614 the_field: u32,
615}
616fn foo() {
617 A { the<|> }
618}
619"#,
620 ),
621 @r###"
622 [
623 CompletionItem {
624 label: "the_field",
625 source_range: 69..72,
626 delete: 69..72,
627 insert: "the_field",
628 kind: Field,
629 detail: "u32",
630 deprecated: true,
631 },
632 ]
633 "###);
609 } 634 }
610 635
611 #[test] 636 #[test]
diff --git a/crates/ra_ide/src/completion/test_utils.rs b/crates/ra_ide/src/completion/test_utils.rs
index 5c01654cc..9c036eac7 100644
--- a/crates/ra_ide/src/completion/test_utils.rs
+++ b/crates/ra_ide/src/completion/test_utils.rs
@@ -1,7 +1,10 @@
1//! Runs completion for testing purposes. 1//! Runs completion for testing purposes.
2 2
3use hir::Semantics; 3use hir::Semantics;
4use itertools::Itertools;
4use ra_syntax::{AstNode, NodeOrToken, SyntaxElement}; 5use ra_syntax::{AstNode, NodeOrToken, SyntaxElement};
6use stdx::format_to;
7use test_utils::assert_eq_text;
5 8
6use crate::{ 9use crate::{
7 completion::{completion_item::CompletionKind, CompletionConfig}, 10 completion::{completion_item::CompletionKind, CompletionConfig},
@@ -42,10 +45,28 @@ pub(crate) fn completion_list_with_options(
42 kind_completions.sort_by_key(|c| c.label().to_owned()); 45 kind_completions.sort_by_key(|c| c.label().to_owned());
43 kind_completions 46 kind_completions
44 .into_iter() 47 .into_iter()
45 .map(|it| format!("{} {}\n", it.kind().unwrap().tag(), it.label())) 48 .map(|it| {
49 let mut buf = format!("{} {}", it.kind().unwrap().tag(), it.label());
50 if let Some(detail) = it.detail() {
51 format_to!(buf, " {}", detail);
52 }
53 format_to!(buf, "\n");
54 buf
55 })
46 .collect() 56 .collect()
47} 57}
48 58
59pub(crate) fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
60 let (analysis, position) = analysis_and_position(ra_fixture_before);
61 let completions: Vec<CompletionItem> =
62 analysis.completions(&CompletionConfig::default(), position).unwrap().unwrap().into();
63 let (completion,) =
64 completions.into_iter().filter(|it| it.label() == what).collect_tuple().unwrap();
65 let mut actual = analysis.file_text(position.file_id).unwrap().to_string();
66 completion.text_edit().apply(&mut actual);
67 assert_eq_text!(ra_fixture_after, &actual)
68}
69
49pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) { 70pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) {
50 let (analysis, pos) = analysis_and_position(code); 71 let (analysis, pos) = analysis_and_position(code);
51 analysis 72 analysis