diff options
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/completion/complete_attribute.rs | 973 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_keyword.rs | 445 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_record.rs | 546 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/completion_item.rs | 20 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs | 680 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/test_utils.rs | 36 | ||||
-rw-r--r-- | crates/ra_ide/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/references/rename.rs | 1043 |
8 files changed, 1344 insertions, 2401 deletions
diff --git a/crates/ra_ide/src/completion/complete_attribute.rs b/crates/ra_ide/src/completion/complete_attribute.rs index 6beeca457..9db317509 100644 --- a/crates/ra_ide/src/completion/complete_attribute.rs +++ b/crates/ra_ide/src/completion/complete_attribute.rs | |||
@@ -46,7 +46,7 @@ fn complete_attribute_start(acc: &mut Completions, ctx: &CompletionContext, attr | |||
46 | _ => {} | 46 | _ => {} |
47 | } | 47 | } |
48 | 48 | ||
49 | if attribute.kind() == ast::AttrKind::Inner || !attr_completion.should_be_inner { | 49 | if attribute.kind() == ast::AttrKind::Inner || !attr_completion.prefer_inner { |
50 | acc.add(item); | 50 | acc.add(item); |
51 | } | 51 | } |
52 | } | 52 | } |
@@ -56,159 +56,72 @@ struct AttrCompletion { | |||
56 | label: &'static str, | 56 | label: &'static str, |
57 | lookup: Option<&'static str>, | 57 | lookup: Option<&'static str>, |
58 | snippet: Option<&'static str>, | 58 | snippet: Option<&'static str>, |
59 | should_be_inner: bool, | 59 | prefer_inner: bool, |
60 | } | ||
61 | |||
62 | impl AttrCompletion { | ||
63 | const fn prefer_inner(self) -> AttrCompletion { | ||
64 | AttrCompletion { prefer_inner: true, ..self } | ||
65 | } | ||
66 | } | ||
67 | |||
68 | const fn attr( | ||
69 | label: &'static str, | ||
70 | lookup: Option<&'static str>, | ||
71 | snippet: Option<&'static str>, | ||
72 | ) -> AttrCompletion { | ||
73 | AttrCompletion { label, lookup, snippet, prefer_inner: false } | ||
60 | } | 74 | } |
61 | 75 | ||
62 | const ATTRIBUTES: &[AttrCompletion] = &[ | 76 | const ATTRIBUTES: &[AttrCompletion] = &[ |
63 | AttrCompletion { | 77 | attr("allow(…)", Some("allow"), Some("allow(${0:lint})")), |
64 | label: "allow(…)", | 78 | attr("cfg_attr(…)", Some("cfg_attr"), Some("cfg_attr(${1:predicate}, ${0:attr})")), |
65 | snippet: Some("allow(${0:lint})"), | 79 | attr("cfg(…)", Some("cfg"), Some("cfg(${0:predicate})")), |
66 | should_be_inner: false, | 80 | attr("deny(…)", Some("deny"), Some("deny(${0:lint})")), |
67 | lookup: Some("allow"), | 81 | attr(r#"deprecated = "…""#, Some("deprecated"), Some(r#"deprecated = "${0:reason}""#)), |
68 | }, | 82 | attr("derive(…)", Some("derive"), Some(r#"derive(${0:Debug})"#)), |
69 | AttrCompletion { | 83 | attr(r#"doc = "…""#, Some("doc"), Some(r#"doc = "${0:docs}""#)), |
70 | label: "cfg_attr(…)", | 84 | attr("feature(…)", Some("feature"), Some("feature(${0:flag})")).prefer_inner(), |
71 | snippet: Some("cfg_attr(${1:predicate}, ${0:attr})"), | 85 | attr("forbid(…)", Some("forbid"), Some("forbid(${0:lint})")), |
72 | should_be_inner: false, | ||
73 | lookup: Some("cfg_attr"), | ||
74 | }, | ||
75 | AttrCompletion { | ||
76 | label: "cfg(…)", | ||
77 | snippet: Some("cfg(${0:predicate})"), | ||
78 | should_be_inner: false, | ||
79 | lookup: Some("cfg"), | ||
80 | }, | ||
81 | AttrCompletion { | ||
82 | label: "deny(…)", | ||
83 | snippet: Some("deny(${0:lint})"), | ||
84 | should_be_inner: false, | ||
85 | lookup: Some("deny"), | ||
86 | }, | ||
87 | AttrCompletion { | ||
88 | label: r#"deprecated = "…""#, | ||
89 | snippet: Some(r#"deprecated = "${0:reason}""#), | ||
90 | should_be_inner: false, | ||
91 | lookup: Some("deprecated"), | ||
92 | }, | ||
93 | AttrCompletion { | ||
94 | label: "derive(…)", | ||
95 | snippet: Some(r#"derive(${0:Debug})"#), | ||
96 | should_be_inner: false, | ||
97 | lookup: Some("derive"), | ||
98 | }, | ||
99 | AttrCompletion { | ||
100 | label: r#"doc = "…""#, | ||
101 | snippet: Some(r#"doc = "${0:docs}""#), | ||
102 | should_be_inner: false, | ||
103 | lookup: Some("doc"), | ||
104 | }, | ||
105 | AttrCompletion { | ||
106 | label: "feature(…)", | ||
107 | snippet: Some("feature(${0:flag})"), | ||
108 | should_be_inner: true, | ||
109 | lookup: Some("feature"), | ||
110 | }, | ||
111 | AttrCompletion { | ||
112 | label: "forbid(…)", | ||
113 | snippet: Some("forbid(${0:lint})"), | ||
114 | should_be_inner: false, | ||
115 | lookup: Some("forbid"), | ||
116 | }, | ||
117 | // FIXME: resolve through macro resolution? | 86 | // FIXME: resolve through macro resolution? |
118 | AttrCompletion { | 87 | attr("global_allocator", None, None).prefer_inner(), |
119 | label: "global_allocator", | 88 | attr("ignore(…)", Some("ignore"), Some("ignore(${0:lint})")), |
120 | snippet: None, | 89 | attr("inline(…)", Some("inline"), Some("inline(${0:lint})")), |
121 | should_be_inner: true, | 90 | attr(r#"link_name = "…""#, Some("link_name"), Some(r#"link_name = "${0:symbol_name}""#)), |
122 | lookup: None, | 91 | attr("link", None, None), |
123 | }, | 92 | attr("macro_export", None, None), |
124 | AttrCompletion { | 93 | attr("macro_use", None, None), |
125 | label: "ignore(…)", | 94 | attr(r#"must_use = "…""#, Some("must_use"), Some(r#"must_use = "${0:reason}""#)), |
126 | snippet: Some("ignore(${0:lint})"), | 95 | attr("no_mangle", None, None), |
127 | should_be_inner: false, | 96 | attr("no_std", None, None).prefer_inner(), |
128 | lookup: Some("ignore"), | 97 | attr("non_exhaustive", None, None), |
129 | }, | 98 | attr("panic_handler", None, None).prefer_inner(), |
130 | AttrCompletion { | 99 | attr("path = \"…\"", Some("path"), Some("path =\"${0:path}\"")), |
131 | label: "inline(…)", | 100 | attr("proc_macro", None, None), |
132 | snippet: Some("inline(${0:lint})"), | 101 | attr("proc_macro_attribute", None, None), |
133 | should_be_inner: false, | 102 | attr("proc_macro_derive(…)", Some("proc_macro_derive"), Some("proc_macro_derive(${0:Trait})")), |
134 | lookup: Some("inline"), | 103 | attr("recursion_limit = …", Some("recursion_limit"), Some("recursion_limit = ${0:128}")) |
135 | }, | 104 | .prefer_inner(), |
136 | AttrCompletion { | 105 | attr("repr(…)", Some("repr"), Some("repr(${0:C})")), |
137 | label: r#"link_name = "…""#, | 106 | attr( |
138 | snippet: Some(r#"link_name = "${0:symbol_name}""#), | 107 | "should_panic(…)", |
139 | should_be_inner: false, | 108 | Some("should_panic"), |
140 | lookup: Some("link_name"), | 109 | Some(r#"should_panic(expected = "${0:reason}")"#), |
141 | }, | 110 | ), |
142 | AttrCompletion { label: "link", snippet: None, should_be_inner: false, lookup: None }, | 111 | attr( |
143 | AttrCompletion { label: "macro_export", snippet: None, should_be_inner: false, lookup: None }, | 112 | r#"target_feature = "…""#, |
144 | AttrCompletion { label: "macro_use", snippet: None, should_be_inner: false, lookup: None }, | 113 | Some("target_feature"), |
145 | AttrCompletion { | 114 | Some("target_feature = \"${0:feature}\""), |
146 | label: r#"must_use = "…""#, | 115 | ), |
147 | snippet: Some(r#"must_use = "${0:reason}""#), | 116 | attr("test", None, None), |
148 | should_be_inner: false, | 117 | attr("used", None, None), |
149 | lookup: Some("must_use"), | 118 | attr("warn(…)", Some("warn"), Some("warn(${0:lint})")), |
150 | }, | 119 | attr( |
151 | AttrCompletion { label: "no_mangle", snippet: None, should_be_inner: false, lookup: None }, | 120 | r#"windows_subsystem = "…""#, |
152 | AttrCompletion { label: "no_std", snippet: None, should_be_inner: true, lookup: None }, | 121 | Some("windows_subsystem"), |
153 | AttrCompletion { label: "non_exhaustive", snippet: None, should_be_inner: false, lookup: None }, | 122 | Some(r#"windows_subsystem = "${0:subsystem}""#), |
154 | AttrCompletion { label: "panic_handler", snippet: None, should_be_inner: true, lookup: None }, | 123 | ) |
155 | AttrCompletion { | 124 | .prefer_inner(), |
156 | label: "path = \"…\"", | ||
157 | snippet: Some("path =\"${0:path}\""), | ||
158 | should_be_inner: false, | ||
159 | lookup: Some("path"), | ||
160 | }, | ||
161 | AttrCompletion { label: "proc_macro", snippet: None, should_be_inner: false, lookup: None }, | ||
162 | AttrCompletion { | ||
163 | label: "proc_macro_attribute", | ||
164 | snippet: None, | ||
165 | should_be_inner: false, | ||
166 | lookup: None, | ||
167 | }, | ||
168 | AttrCompletion { | ||
169 | label: "proc_macro_derive(…)", | ||
170 | snippet: Some("proc_macro_derive(${0:Trait})"), | ||
171 | should_be_inner: false, | ||
172 | lookup: Some("proc_macro_derive"), | ||
173 | }, | ||
174 | AttrCompletion { | ||
175 | label: "recursion_limit = …", | ||
176 | snippet: Some("recursion_limit = ${0:128}"), | ||
177 | should_be_inner: true, | ||
178 | lookup: Some("recursion_limit"), | ||
179 | }, | ||
180 | AttrCompletion { | ||
181 | label: "repr(…)", | ||
182 | snippet: Some("repr(${0:C})"), | ||
183 | should_be_inner: false, | ||
184 | lookup: Some("repr"), | ||
185 | }, | ||
186 | AttrCompletion { | ||
187 | label: "should_panic(…)", | ||
188 | snippet: Some(r#"should_panic(expected = "${0:reason}")"#), | ||
189 | should_be_inner: false, | ||
190 | lookup: Some("should_panic"), | ||
191 | }, | ||
192 | AttrCompletion { | ||
193 | label: r#"target_feature = "…""#, | ||
194 | snippet: Some("target_feature = \"${0:feature}\""), | ||
195 | should_be_inner: false, | ||
196 | lookup: Some("target_feature"), | ||
197 | }, | ||
198 | AttrCompletion { label: "test", snippet: None, should_be_inner: false, lookup: None }, | ||
199 | AttrCompletion { label: "used", snippet: None, should_be_inner: false, lookup: None }, | ||
200 | AttrCompletion { | ||
201 | label: "warn(…)", | ||
202 | snippet: Some("warn(${0:lint})"), | ||
203 | should_be_inner: false, | ||
204 | lookup: Some("warn"), | ||
205 | }, | ||
206 | AttrCompletion { | ||
207 | label: r#"windows_subsystem = "…""#, | ||
208 | snippet: Some(r#"windows_subsystem = "${0:subsystem}""#), | ||
209 | should_be_inner: true, | ||
210 | lookup: Some("windows_subsystem"), | ||
211 | }, | ||
212 | ]; | 125 | ]; |
213 | 126 | ||
214 | fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input: ast::TokenTree) { | 127 | fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input: ast::TokenTree) { |
@@ -313,677 +226,147 @@ const DEFAULT_DERIVE_COMPLETIONS: &[DeriveCompletion] = &[ | |||
313 | 226 | ||
314 | #[cfg(test)] | 227 | #[cfg(test)] |
315 | mod tests { | 228 | mod tests { |
316 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; | 229 | use expect::{expect, Expect}; |
317 | use insta::assert_debug_snapshot; | ||
318 | 230 | ||
319 | fn do_attr_completion(code: &str) -> Vec<CompletionItem> { | 231 | use crate::completion::{test_utils::completion_list, CompletionKind}; |
320 | do_completion(code, CompletionKind::Attribute) | 232 | |
233 | fn check(ra_fixture: &str, expect: Expect) { | ||
234 | let actual = completion_list(ra_fixture, CompletionKind::Attribute); | ||
235 | expect.assert_eq(&actual); | ||
321 | } | 236 | } |
322 | 237 | ||
323 | #[test] | 238 | #[test] |
324 | fn empty_derive_completion() { | 239 | fn empty_derive_completion() { |
325 | assert_debug_snapshot!( | 240 | check( |
326 | do_attr_completion( | 241 | r#" |
327 | r" | 242 | #[derive(<|>)] |
328 | #[derive(<|>)] | 243 | struct Test {} |
329 | struct Test {} | 244 | "#, |
330 | ", | 245 | expect![[r#" |
331 | ), | 246 | at Clone |
332 | @r###" | 247 | at Copy, Clone |
333 | [ | 248 | at Debug |
334 | CompletionItem { | 249 | at Default |
335 | label: "Clone", | 250 | at Eq, PartialEq |
336 | source_range: 9..9, | 251 | at Hash |
337 | delete: 9..9, | 252 | at Ord, PartialOrd, Eq, PartialEq |
338 | insert: "Clone", | 253 | at PartialEq |
339 | kind: Attribute, | 254 | at PartialOrd, PartialEq |
340 | }, | 255 | "#]], |
341 | CompletionItem { | ||
342 | label: "Copy, Clone", | ||
343 | source_range: 9..9, | ||
344 | delete: 9..9, | ||
345 | insert: "Copy, Clone", | ||
346 | kind: Attribute, | ||
347 | }, | ||
348 | CompletionItem { | ||
349 | label: "Debug", | ||
350 | source_range: 9..9, | ||
351 | delete: 9..9, | ||
352 | insert: "Debug", | ||
353 | kind: Attribute, | ||
354 | }, | ||
355 | CompletionItem { | ||
356 | label: "Default", | ||
357 | source_range: 9..9, | ||
358 | delete: 9..9, | ||
359 | insert: "Default", | ||
360 | kind: Attribute, | ||
361 | }, | ||
362 | CompletionItem { | ||
363 | label: "Eq, PartialEq", | ||
364 | source_range: 9..9, | ||
365 | delete: 9..9, | ||
366 | insert: "Eq, PartialEq", | ||
367 | kind: Attribute, | ||
368 | }, | ||
369 | CompletionItem { | ||
370 | label: "Hash", | ||
371 | source_range: 9..9, | ||
372 | delete: 9..9, | ||
373 | insert: "Hash", | ||
374 | kind: Attribute, | ||
375 | }, | ||
376 | CompletionItem { | ||
377 | label: "Ord, PartialOrd, Eq, PartialEq", | ||
378 | source_range: 9..9, | ||
379 | delete: 9..9, | ||
380 | insert: "Ord, PartialOrd, Eq, PartialEq", | ||
381 | kind: Attribute, | ||
382 | }, | ||
383 | CompletionItem { | ||
384 | label: "PartialEq", | ||
385 | source_range: 9..9, | ||
386 | delete: 9..9, | ||
387 | insert: "PartialEq", | ||
388 | kind: Attribute, | ||
389 | }, | ||
390 | CompletionItem { | ||
391 | label: "PartialOrd, PartialEq", | ||
392 | source_range: 9..9, | ||
393 | delete: 9..9, | ||
394 | insert: "PartialOrd, PartialEq", | ||
395 | kind: Attribute, | ||
396 | }, | ||
397 | ] | ||
398 | "### | ||
399 | ); | 256 | ); |
400 | } | 257 | } |
401 | 258 | ||
402 | #[test] | 259 | #[test] |
403 | fn no_completion_for_incorrect_derive() { | 260 | fn no_completion_for_incorrect_derive() { |
404 | assert_debug_snapshot!( | 261 | check( |
405 | do_attr_completion( | 262 | r#" |
406 | r" | 263 | #[derive{<|>)] |
407 | #[derive{<|>)] | 264 | struct Test {} |
408 | struct Test {} | 265 | "#, |
409 | ", | 266 | expect![[r#""#]], |
410 | ), | 267 | ) |
411 | @"[]" | ||
412 | ); | ||
413 | } | 268 | } |
414 | 269 | ||
415 | #[test] | 270 | #[test] |
416 | fn derive_with_input_completion() { | 271 | fn derive_with_input_completion() { |
417 | assert_debug_snapshot!( | 272 | check( |
418 | do_attr_completion( | 273 | r#" |
419 | r" | 274 | #[derive(serde::Serialize, PartialEq, <|>)] |
420 | #[derive(serde::Serialize, PartialEq, <|>)] | 275 | struct Test {} |
421 | struct Test {} | 276 | "#, |
422 | ", | 277 | expect![[r#" |
423 | ), | 278 | at Clone |
424 | @r###" | 279 | at Copy, Clone |
425 | [ | 280 | at Debug |
426 | CompletionItem { | 281 | at Default |
427 | label: "Clone", | 282 | at Eq |
428 | source_range: 38..38, | 283 | at Hash |
429 | delete: 38..38, | 284 | at Ord, PartialOrd, Eq |
430 | insert: "Clone", | 285 | at PartialOrd |
431 | kind: Attribute, | 286 | "#]], |
432 | }, | 287 | ) |
433 | CompletionItem { | ||
434 | label: "Copy, Clone", | ||
435 | source_range: 38..38, | ||
436 | delete: 38..38, | ||
437 | insert: "Copy, Clone", | ||
438 | kind: Attribute, | ||
439 | }, | ||
440 | CompletionItem { | ||
441 | label: "Debug", | ||
442 | source_range: 38..38, | ||
443 | delete: 38..38, | ||
444 | insert: "Debug", | ||
445 | kind: Attribute, | ||
446 | }, | ||
447 | CompletionItem { | ||
448 | label: "Default", | ||
449 | source_range: 38..38, | ||
450 | delete: 38..38, | ||
451 | insert: "Default", | ||
452 | kind: Attribute, | ||
453 | }, | ||
454 | CompletionItem { | ||
455 | label: "Eq", | ||
456 | source_range: 38..38, | ||
457 | delete: 38..38, | ||
458 | insert: "Eq", | ||
459 | kind: Attribute, | ||
460 | }, | ||
461 | CompletionItem { | ||
462 | label: "Hash", | ||
463 | source_range: 38..38, | ||
464 | delete: 38..38, | ||
465 | insert: "Hash", | ||
466 | kind: Attribute, | ||
467 | }, | ||
468 | CompletionItem { | ||
469 | label: "Ord, PartialOrd, Eq", | ||
470 | source_range: 38..38, | ||
471 | delete: 38..38, | ||
472 | insert: "Ord, PartialOrd, Eq", | ||
473 | kind: Attribute, | ||
474 | }, | ||
475 | CompletionItem { | ||
476 | label: "PartialOrd", | ||
477 | source_range: 38..38, | ||
478 | delete: 38..38, | ||
479 | insert: "PartialOrd", | ||
480 | kind: Attribute, | ||
481 | }, | ||
482 | ] | ||
483 | "### | ||
484 | ); | ||
485 | } | 288 | } |
486 | 289 | ||
487 | #[test] | 290 | #[test] |
488 | fn test_attribute_completion() { | 291 | fn test_attribute_completion() { |
489 | assert_debug_snapshot!( | 292 | check( |
490 | do_attr_completion( | 293 | r#"#[<|>]"#, |
491 | r" | 294 | expect![[r#" |
492 | #[<|>] | 295 | at allow(…) |
493 | ", | 296 | at cfg(…) |
494 | ), | 297 | at cfg_attr(…) |
495 | @r###" | 298 | at deny(…) |
496 | [ | 299 | at deprecated = "…" |
497 | CompletionItem { | 300 | at derive(…) |
498 | label: "allow(…)", | 301 | at doc = "…" |
499 | source_range: 2..2, | 302 | at forbid(…) |
500 | delete: 2..2, | 303 | at ignore(…) |
501 | insert: "allow(${0:lint})", | 304 | at inline(…) |
502 | kind: Attribute, | 305 | at link |
503 | lookup: "allow", | 306 | at link_name = "…" |
504 | }, | 307 | at macro_export |
505 | CompletionItem { | 308 | at macro_use |
506 | label: "cfg(…)", | 309 | at must_use = "…" |
507 | source_range: 2..2, | 310 | at no_mangle |
508 | delete: 2..2, | 311 | at non_exhaustive |
509 | insert: "cfg(${0:predicate})", | 312 | at path = "…" |
510 | kind: Attribute, | 313 | at proc_macro |
511 | lookup: "cfg", | 314 | at proc_macro_attribute |
512 | }, | 315 | at proc_macro_derive(…) |
513 | CompletionItem { | 316 | at repr(…) |
514 | label: "cfg_attr(…)", | 317 | at should_panic(…) |
515 | source_range: 2..2, | 318 | at target_feature = "…" |
516 | delete: 2..2, | 319 | at test |
517 | insert: "cfg_attr(${1:predicate}, ${0:attr})", | 320 | at used |
518 | kind: Attribute, | 321 | at warn(…) |
519 | lookup: "cfg_attr", | 322 | "#]], |
520 | }, | 323 | ) |
521 | CompletionItem { | ||
522 | label: "deny(…)", | ||
523 | source_range: 2..2, | ||
524 | delete: 2..2, | ||
525 | insert: "deny(${0:lint})", | ||
526 | kind: Attribute, | ||
527 | lookup: "deny", | ||
528 | }, | ||
529 | CompletionItem { | ||
530 | label: "deprecated = \"…\"", | ||
531 | source_range: 2..2, | ||
532 | delete: 2..2, | ||
533 | insert: "deprecated = \"${0:reason}\"", | ||
534 | kind: Attribute, | ||
535 | lookup: "deprecated", | ||
536 | }, | ||
537 | CompletionItem { | ||
538 | label: "derive(…)", | ||
539 | source_range: 2..2, | ||
540 | delete: 2..2, | ||
541 | insert: "derive(${0:Debug})", | ||
542 | kind: Attribute, | ||
543 | lookup: "derive", | ||
544 | }, | ||
545 | CompletionItem { | ||
546 | label: "doc = \"…\"", | ||
547 | source_range: 2..2, | ||
548 | delete: 2..2, | ||
549 | insert: "doc = \"${0:docs}\"", | ||
550 | kind: Attribute, | ||
551 | lookup: "doc", | ||
552 | }, | ||
553 | CompletionItem { | ||
554 | label: "forbid(…)", | ||
555 | source_range: 2..2, | ||
556 | delete: 2..2, | ||
557 | insert: "forbid(${0:lint})", | ||
558 | kind: Attribute, | ||
559 | lookup: "forbid", | ||
560 | }, | ||
561 | CompletionItem { | ||
562 | label: "ignore(…)", | ||
563 | source_range: 2..2, | ||
564 | delete: 2..2, | ||
565 | insert: "ignore(${0:lint})", | ||
566 | kind: Attribute, | ||
567 | lookup: "ignore", | ||
568 | }, | ||
569 | CompletionItem { | ||
570 | label: "inline(…)", | ||
571 | source_range: 2..2, | ||
572 | delete: 2..2, | ||
573 | insert: "inline(${0:lint})", | ||
574 | kind: Attribute, | ||
575 | lookup: "inline", | ||
576 | }, | ||
577 | CompletionItem { | ||
578 | label: "link", | ||
579 | source_range: 2..2, | ||
580 | delete: 2..2, | ||
581 | insert: "link", | ||
582 | kind: Attribute, | ||
583 | }, | ||
584 | CompletionItem { | ||
585 | label: "link_name = \"…\"", | ||
586 | source_range: 2..2, | ||
587 | delete: 2..2, | ||
588 | insert: "link_name = \"${0:symbol_name}\"", | ||
589 | kind: Attribute, | ||
590 | lookup: "link_name", | ||
591 | }, | ||
592 | CompletionItem { | ||
593 | label: "macro_export", | ||
594 | source_range: 2..2, | ||
595 | delete: 2..2, | ||
596 | insert: "macro_export", | ||
597 | kind: Attribute, | ||
598 | }, | ||
599 | CompletionItem { | ||
600 | label: "macro_use", | ||
601 | source_range: 2..2, | ||
602 | delete: 2..2, | ||
603 | insert: "macro_use", | ||
604 | kind: Attribute, | ||
605 | }, | ||
606 | CompletionItem { | ||
607 | label: "must_use = \"…\"", | ||
608 | source_range: 2..2, | ||
609 | delete: 2..2, | ||
610 | insert: "must_use = \"${0:reason}\"", | ||
611 | kind: Attribute, | ||
612 | lookup: "must_use", | ||
613 | }, | ||
614 | CompletionItem { | ||
615 | label: "no_mangle", | ||
616 | source_range: 2..2, | ||
617 | delete: 2..2, | ||
618 | insert: "no_mangle", | ||
619 | kind: Attribute, | ||
620 | }, | ||
621 | CompletionItem { | ||
622 | label: "non_exhaustive", | ||
623 | source_range: 2..2, | ||
624 | delete: 2..2, | ||
625 | insert: "non_exhaustive", | ||
626 | kind: Attribute, | ||
627 | }, | ||
628 | CompletionItem { | ||
629 | label: "path = \"…\"", | ||
630 | source_range: 2..2, | ||
631 | delete: 2..2, | ||
632 | insert: "path =\"${0:path}\"", | ||
633 | kind: Attribute, | ||
634 | lookup: "path", | ||
635 | }, | ||
636 | CompletionItem { | ||
637 | label: "proc_macro", | ||
638 | source_range: 2..2, | ||
639 | delete: 2..2, | ||
640 | insert: "proc_macro", | ||
641 | kind: Attribute, | ||
642 | }, | ||
643 | CompletionItem { | ||
644 | label: "proc_macro_attribute", | ||
645 | source_range: 2..2, | ||
646 | delete: 2..2, | ||
647 | insert: "proc_macro_attribute", | ||
648 | kind: Attribute, | ||
649 | }, | ||
650 | CompletionItem { | ||
651 | label: "proc_macro_derive(…)", | ||
652 | source_range: 2..2, | ||
653 | delete: 2..2, | ||
654 | insert: "proc_macro_derive(${0:Trait})", | ||
655 | kind: Attribute, | ||
656 | lookup: "proc_macro_derive", | ||
657 | }, | ||
658 | CompletionItem { | ||
659 | label: "repr(…)", | ||
660 | source_range: 2..2, | ||
661 | delete: 2..2, | ||
662 | insert: "repr(${0:C})", | ||
663 | kind: Attribute, | ||
664 | lookup: "repr", | ||
665 | }, | ||
666 | CompletionItem { | ||
667 | label: "should_panic(…)", | ||
668 | source_range: 2..2, | ||
669 | delete: 2..2, | ||
670 | insert: "should_panic(expected = \"${0:reason}\")", | ||
671 | kind: Attribute, | ||
672 | lookup: "should_panic", | ||
673 | }, | ||
674 | CompletionItem { | ||
675 | label: "target_feature = \"…\"", | ||
676 | source_range: 2..2, | ||
677 | delete: 2..2, | ||
678 | insert: "target_feature = \"${0:feature}\"", | ||
679 | kind: Attribute, | ||
680 | lookup: "target_feature", | ||
681 | }, | ||
682 | CompletionItem { | ||
683 | label: "test", | ||
684 | source_range: 2..2, | ||
685 | delete: 2..2, | ||
686 | insert: "test", | ||
687 | kind: Attribute, | ||
688 | }, | ||
689 | CompletionItem { | ||
690 | label: "used", | ||
691 | source_range: 2..2, | ||
692 | delete: 2..2, | ||
693 | insert: "used", | ||
694 | kind: Attribute, | ||
695 | }, | ||
696 | CompletionItem { | ||
697 | label: "warn(…)", | ||
698 | source_range: 2..2, | ||
699 | delete: 2..2, | ||
700 | insert: "warn(${0:lint})", | ||
701 | kind: Attribute, | ||
702 | lookup: "warn", | ||
703 | }, | ||
704 | ] | ||
705 | "### | ||
706 | ); | ||
707 | } | 324 | } |
708 | 325 | ||
709 | #[test] | 326 | #[test] |
710 | fn test_attribute_completion_inside_nested_attr() { | 327 | fn test_attribute_completion_inside_nested_attr() { |
711 | assert_debug_snapshot!( | 328 | check(r#"#[allow(<|>)]"#, expect![[]]) |
712 | do_attr_completion( | ||
713 | r" | ||
714 | #[allow(<|>)] | ||
715 | ", | ||
716 | ), | ||
717 | @r###" | ||
718 | [] | ||
719 | "### | ||
720 | ); | ||
721 | } | 329 | } |
722 | 330 | ||
723 | #[test] | 331 | #[test] |
724 | fn test_inner_attribute_completion() { | 332 | fn test_inner_attribute_completion() { |
725 | assert_debug_snapshot!( | 333 | check( |
726 | do_attr_completion( | 334 | r"#![<|>]", |
727 | r" | 335 | expect![[r#" |
728 | #![<|>] | 336 | at allow(…) |
729 | ", | 337 | at cfg(…) |
730 | ), | 338 | at cfg_attr(…) |
731 | @r###" | 339 | at deny(…) |
732 | [ | 340 | at deprecated = "…" |
733 | CompletionItem { | 341 | at derive(…) |
734 | label: "allow(…)", | 342 | at doc = "…" |
735 | source_range: 3..3, | 343 | at feature(…) |
736 | delete: 3..3, | 344 | at forbid(…) |
737 | insert: "allow(${0:lint})", | 345 | at global_allocator |
738 | kind: Attribute, | 346 | at ignore(…) |
739 | lookup: "allow", | 347 | at inline(…) |
740 | }, | 348 | at link |
741 | CompletionItem { | 349 | at link_name = "…" |
742 | label: "cfg(…)", | 350 | at macro_export |
743 | source_range: 3..3, | 351 | at macro_use |
744 | delete: 3..3, | 352 | at must_use = "…" |
745 | insert: "cfg(${0:predicate})", | 353 | at no_mangle |
746 | kind: Attribute, | 354 | at no_std |
747 | lookup: "cfg", | 355 | at non_exhaustive |
748 | }, | 356 | at panic_handler |
749 | CompletionItem { | 357 | at path = "…" |
750 | label: "cfg_attr(…)", | 358 | at proc_macro |
751 | source_range: 3..3, | 359 | at proc_macro_attribute |
752 | delete: 3..3, | 360 | at proc_macro_derive(…) |
753 | insert: "cfg_attr(${1:predicate}, ${0:attr})", | 361 | at recursion_limit = … |
754 | kind: Attribute, | 362 | at repr(…) |
755 | lookup: "cfg_attr", | 363 | at should_panic(…) |
756 | }, | 364 | at target_feature = "…" |
757 | CompletionItem { | 365 | at test |
758 | label: "deny(…)", | 366 | at used |
759 | source_range: 3..3, | 367 | at warn(…) |
760 | delete: 3..3, | 368 | at windows_subsystem = "…" |
761 | insert: "deny(${0:lint})", | 369 | "#]], |
762 | kind: Attribute, | ||
763 | lookup: "deny", | ||
764 | }, | ||
765 | CompletionItem { | ||
766 | label: "deprecated = \"…\"", | ||
767 | source_range: 3..3, | ||
768 | delete: 3..3, | ||
769 | insert: "deprecated = \"${0:reason}\"", | ||
770 | kind: Attribute, | ||
771 | lookup: "deprecated", | ||
772 | }, | ||
773 | CompletionItem { | ||
774 | label: "derive(…)", | ||
775 | source_range: 3..3, | ||
776 | delete: 3..3, | ||
777 | insert: "derive(${0:Debug})", | ||
778 | kind: Attribute, | ||
779 | lookup: "derive", | ||
780 | }, | ||
781 | CompletionItem { | ||
782 | label: "doc = \"…\"", | ||
783 | source_range: 3..3, | ||
784 | delete: 3..3, | ||
785 | insert: "doc = \"${0:docs}\"", | ||
786 | kind: Attribute, | ||
787 | lookup: "doc", | ||
788 | }, | ||
789 | CompletionItem { | ||
790 | label: "feature(…)", | ||
791 | source_range: 3..3, | ||
792 | delete: 3..3, | ||
793 | insert: "feature(${0:flag})", | ||
794 | kind: Attribute, | ||
795 | lookup: "feature", | ||
796 | }, | ||
797 | CompletionItem { | ||
798 | label: "forbid(…)", | ||
799 | source_range: 3..3, | ||
800 | delete: 3..3, | ||
801 | insert: "forbid(${0:lint})", | ||
802 | kind: Attribute, | ||
803 | lookup: "forbid", | ||
804 | }, | ||
805 | CompletionItem { | ||
806 | label: "global_allocator", | ||
807 | source_range: 3..3, | ||
808 | delete: 3..3, | ||
809 | insert: "global_allocator", | ||
810 | kind: Attribute, | ||
811 | }, | ||
812 | CompletionItem { | ||
813 | label: "ignore(…)", | ||
814 | source_range: 3..3, | ||
815 | delete: 3..3, | ||
816 | insert: "ignore(${0:lint})", | ||
817 | kind: Attribute, | ||
818 | lookup: "ignore", | ||
819 | }, | ||
820 | CompletionItem { | ||
821 | label: "inline(…)", | ||
822 | source_range: 3..3, | ||
823 | delete: 3..3, | ||
824 | insert: "inline(${0:lint})", | ||
825 | kind: Attribute, | ||
826 | lookup: "inline", | ||
827 | }, | ||
828 | CompletionItem { | ||
829 | label: "link", | ||
830 | source_range: 3..3, | ||
831 | delete: 3..3, | ||
832 | insert: "link", | ||
833 | kind: Attribute, | ||
834 | }, | ||
835 | CompletionItem { | ||
836 | label: "link_name = \"…\"", | ||
837 | source_range: 3..3, | ||
838 | delete: 3..3, | ||
839 | insert: "link_name = \"${0:symbol_name}\"", | ||
840 | kind: Attribute, | ||
841 | lookup: "link_name", | ||
842 | }, | ||
843 | CompletionItem { | ||
844 | label: "macro_export", | ||
845 | source_range: 3..3, | ||
846 | delete: 3..3, | ||
847 | insert: "macro_export", | ||
848 | kind: Attribute, | ||
849 | }, | ||
850 | CompletionItem { | ||
851 | label: "macro_use", | ||
852 | source_range: 3..3, | ||
853 | delete: 3..3, | ||
854 | insert: "macro_use", | ||
855 | kind: Attribute, | ||
856 | }, | ||
857 | CompletionItem { | ||
858 | label: "must_use = \"…\"", | ||
859 | source_range: 3..3, | ||
860 | delete: 3..3, | ||
861 | insert: "must_use = \"${0:reason}\"", | ||
862 | kind: Attribute, | ||
863 | lookup: "must_use", | ||
864 | }, | ||
865 | CompletionItem { | ||
866 | label: "no_mangle", | ||
867 | source_range: 3..3, | ||
868 | delete: 3..3, | ||
869 | insert: "no_mangle", | ||
870 | kind: Attribute, | ||
871 | }, | ||
872 | CompletionItem { | ||
873 | label: "no_std", | ||
874 | source_range: 3..3, | ||
875 | delete: 3..3, | ||
876 | insert: "no_std", | ||
877 | kind: Attribute, | ||
878 | }, | ||
879 | CompletionItem { | ||
880 | label: "non_exhaustive", | ||
881 | source_range: 3..3, | ||
882 | delete: 3..3, | ||
883 | insert: "non_exhaustive", | ||
884 | kind: Attribute, | ||
885 | }, | ||
886 | CompletionItem { | ||
887 | label: "panic_handler", | ||
888 | source_range: 3..3, | ||
889 | delete: 3..3, | ||
890 | insert: "panic_handler", | ||
891 | kind: Attribute, | ||
892 | }, | ||
893 | CompletionItem { | ||
894 | label: "path = \"…\"", | ||
895 | source_range: 3..3, | ||
896 | delete: 3..3, | ||
897 | insert: "path =\"${0:path}\"", | ||
898 | kind: Attribute, | ||
899 | lookup: "path", | ||
900 | }, | ||
901 | CompletionItem { | ||
902 | label: "proc_macro", | ||
903 | source_range: 3..3, | ||
904 | delete: 3..3, | ||
905 | insert: "proc_macro", | ||
906 | kind: Attribute, | ||
907 | }, | ||
908 | CompletionItem { | ||
909 | label: "proc_macro_attribute", | ||
910 | source_range: 3..3, | ||
911 | delete: 3..3, | ||
912 | insert: "proc_macro_attribute", | ||
913 | kind: Attribute, | ||
914 | }, | ||
915 | CompletionItem { | ||
916 | label: "proc_macro_derive(…)", | ||
917 | source_range: 3..3, | ||
918 | delete: 3..3, | ||
919 | insert: "proc_macro_derive(${0:Trait})", | ||
920 | kind: Attribute, | ||
921 | lookup: "proc_macro_derive", | ||
922 | }, | ||
923 | CompletionItem { | ||
924 | label: "recursion_limit = …", | ||
925 | source_range: 3..3, | ||
926 | delete: 3..3, | ||
927 | insert: "recursion_limit = ${0:128}", | ||
928 | kind: Attribute, | ||
929 | lookup: "recursion_limit", | ||
930 | }, | ||
931 | CompletionItem { | ||
932 | label: "repr(…)", | ||
933 | source_range: 3..3, | ||
934 | delete: 3..3, | ||
935 | insert: "repr(${0:C})", | ||
936 | kind: Attribute, | ||
937 | lookup: "repr", | ||
938 | }, | ||
939 | CompletionItem { | ||
940 | label: "should_panic(…)", | ||
941 | source_range: 3..3, | ||
942 | delete: 3..3, | ||
943 | insert: "should_panic(expected = \"${0:reason}\")", | ||
944 | kind: Attribute, | ||
945 | lookup: "should_panic", | ||
946 | }, | ||
947 | CompletionItem { | ||
948 | label: "target_feature = \"…\"", | ||
949 | source_range: 3..3, | ||
950 | delete: 3..3, | ||
951 | insert: "target_feature = \"${0:feature}\"", | ||
952 | kind: Attribute, | ||
953 | lookup: "target_feature", | ||
954 | }, | ||
955 | CompletionItem { | ||
956 | label: "test", | ||
957 | source_range: 3..3, | ||
958 | delete: 3..3, | ||
959 | insert: "test", | ||
960 | kind: Attribute, | ||
961 | }, | ||
962 | CompletionItem { | ||
963 | label: "used", | ||
964 | source_range: 3..3, | ||
965 | delete: 3..3, | ||
966 | insert: "used", | ||
967 | kind: Attribute, | ||
968 | }, | ||
969 | CompletionItem { | ||
970 | label: "warn(…)", | ||
971 | source_range: 3..3, | ||
972 | delete: 3..3, | ||
973 | insert: "warn(${0:lint})", | ||
974 | kind: Attribute, | ||
975 | lookup: "warn", | ||
976 | }, | ||
977 | CompletionItem { | ||
978 | label: "windows_subsystem = \"…\"", | ||
979 | source_range: 3..3, | ||
980 | delete: 3..3, | ||
981 | insert: "windows_subsystem = \"${0:subsystem}\"", | ||
982 | kind: Attribute, | ||
983 | lookup: "windows_subsystem", | ||
984 | }, | ||
985 | ] | ||
986 | "### | ||
987 | ); | 370 | ); |
988 | } | 371 | } |
989 | } | 372 | } |
diff --git a/crates/ra_ide/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs index e599cc3d1..086b917ce 100644 --- a/crates/ra_ide/src/completion/complete_keyword.rs +++ b/crates/ra_ide/src/completion/complete_keyword.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use ra_syntax::{ast, SyntaxKind}; | 3 | use ra_syntax::{ast, SyntaxKind}; |
4 | use test_utils::mark; | ||
4 | 5 | ||
5 | use crate::completion::{ | 6 | use crate::completion::{ |
6 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, | 7 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, |
@@ -38,6 +39,7 @@ pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC | |||
38 | 39 | ||
39 | pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { | 40 | pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { |
40 | if ctx.token.kind() == SyntaxKind::COMMENT { | 41 | if ctx.token.kind() == SyntaxKind::COMMENT { |
42 | mark::hit!(no_keyword_completion_in_comments); | ||
41 | return; | 43 | return; |
42 | } | 44 | } |
43 | 45 | ||
@@ -174,289 +176,318 @@ fn complete_return( | |||
174 | 176 | ||
175 | #[cfg(test)] | 177 | #[cfg(test)] |
176 | mod tests { | 178 | mod tests { |
177 | use crate::completion::{test_utils::completion_list, CompletionKind}; | 179 | use expect::{expect, Expect}; |
178 | use insta::assert_snapshot; | ||
179 | 180 | ||
180 | fn get_keyword_completions(code: &str) -> String { | 181 | use crate::completion::{ |
181 | completion_list(code, CompletionKind::Keyword) | 182 | test_utils::{check_edit, completion_list}, |
183 | CompletionKind, | ||
184 | }; | ||
185 | use test_utils::mark; | ||
186 | |||
187 | fn check(ra_fixture: &str, expect: Expect) { | ||
188 | let actual = completion_list(ra_fixture, CompletionKind::Keyword); | ||
189 | expect.assert_eq(&actual) | ||
182 | } | 190 | } |
183 | 191 | ||
184 | #[test] | 192 | #[test] |
185 | fn test_keywords_in_use_stmt() { | 193 | fn test_keywords_in_use_stmt() { |
186 | assert_snapshot!( | 194 | check( |
187 | get_keyword_completions(r"use <|>"), | 195 | r"use <|>", |
188 | @r###" | 196 | expect![[r#" |
189 | kw crate:: | 197 | kw crate:: |
190 | kw self | 198 | kw self |
191 | kw super:: | 199 | kw super:: |
192 | "### | 200 | "#]], |
193 | ); | 201 | ); |
194 | 202 | ||
195 | assert_snapshot!( | 203 | check( |
196 | get_keyword_completions(r"use a::<|>"), | 204 | r"use a::<|>", |
197 | @r###" | 205 | expect![[r#" |
198 | kw self | 206 | kw self |
199 | kw super:: | 207 | kw super:: |
200 | "### | 208 | "#]], |
201 | ); | 209 | ); |
202 | 210 | ||
203 | assert_snapshot!( | 211 | check( |
204 | get_keyword_completions(r"use a::{b, <|>}"), | 212 | r"use a::{b, <|>}", |
205 | @r###" | 213 | expect![[r#" |
206 | kw self | 214 | kw self |
207 | kw super:: | 215 | kw super:: |
208 | "### | 216 | "#]], |
209 | ); | 217 | ); |
210 | } | 218 | } |
211 | 219 | ||
212 | #[test] | 220 | #[test] |
213 | fn test_keywords_at_source_file_level() { | 221 | fn test_keywords_at_source_file_level() { |
214 | assert_snapshot!( | 222 | check( |
215 | get_keyword_completions(r"m<|>"), | 223 | r"m<|>", |
216 | @r###" | 224 | expect![[r#" |
217 | kw const | 225 | kw const |
218 | kw enum | 226 | kw enum |
219 | kw extern | 227 | kw extern |
220 | kw fn | 228 | kw fn |
221 | kw impl | 229 | kw impl |
222 | kw mod | 230 | kw mod |
223 | kw pub | 231 | kw pub |
224 | kw static | 232 | kw static |
225 | kw struct | 233 | kw struct |
226 | kw trait | 234 | kw trait |
227 | kw type | 235 | kw type |
228 | kw union | 236 | kw union |
229 | kw unsafe | 237 | kw unsafe |
230 | kw use | 238 | kw use |
231 | "### | 239 | "#]], |
232 | ); | 240 | ); |
233 | } | 241 | } |
234 | 242 | ||
235 | #[test] | 243 | #[test] |
236 | fn test_keywords_in_function() { | 244 | fn test_keywords_in_function() { |
237 | assert_snapshot!( | 245 | check( |
238 | get_keyword_completions(r"fn quux() { <|> }"), | 246 | r"fn quux() { <|> }", |
239 | @r###" | 247 | expect![[r#" |
240 | kw const | 248 | kw const |
241 | kw extern | 249 | kw extern |
242 | kw fn | 250 | kw fn |
243 | kw if | 251 | kw if |
244 | kw if let | 252 | kw if let |
245 | kw impl | 253 | kw impl |
246 | kw let | 254 | kw let |
247 | kw loop | 255 | kw loop |
248 | kw match | 256 | kw match |
249 | kw mod | 257 | kw mod |
250 | kw return | 258 | kw return |
251 | kw static | 259 | kw static |
252 | kw trait | 260 | kw trait |
253 | kw type | 261 | kw type |
254 | kw unsafe | 262 | kw unsafe |
255 | kw use | 263 | kw use |
256 | kw while | 264 | kw while |
257 | "### | 265 | "#]], |
258 | ); | 266 | ); |
259 | } | 267 | } |
260 | 268 | ||
261 | #[test] | 269 | #[test] |
262 | fn test_keywords_inside_block() { | 270 | fn test_keywords_inside_block() { |
263 | assert_snapshot!( | 271 | check( |
264 | get_keyword_completions(r"fn quux() { if true { <|> } }"), | 272 | r"fn quux() { if true { <|> } }", |
265 | @r###" | 273 | expect![[r#" |
266 | kw const | 274 | kw const |
267 | kw extern | 275 | kw extern |
268 | kw fn | 276 | kw fn |
269 | kw if | 277 | kw if |
270 | kw if let | 278 | kw if let |
271 | kw impl | 279 | kw impl |
272 | kw let | 280 | kw let |
273 | kw loop | 281 | kw loop |
274 | kw match | 282 | kw match |
275 | kw mod | 283 | kw mod |
276 | kw return | 284 | kw return |
277 | kw static | 285 | kw static |
278 | kw trait | 286 | kw trait |
279 | kw type | 287 | kw type |
280 | kw unsafe | 288 | kw unsafe |
281 | kw use | 289 | kw use |
282 | kw while | 290 | kw while |
283 | "### | 291 | "#]], |
284 | ); | 292 | ); |
285 | } | 293 | } |
286 | 294 | ||
287 | #[test] | 295 | #[test] |
288 | fn test_keywords_after_if() { | 296 | fn test_keywords_after_if() { |
289 | assert_snapshot!( | 297 | check( |
290 | get_keyword_completions( | 298 | r#"fn quux() { if true { () } <|> }"#, |
291 | r" | 299 | expect![[r#" |
292 | fn quux() { | 300 | kw const |
293 | if true { | 301 | kw else |
294 | () | 302 | kw else if |
295 | } <|> | 303 | kw extern |
296 | } | 304 | kw fn |
297 | ", | 305 | kw if |
298 | ), | 306 | kw if let |
299 | @r###" | 307 | kw impl |
300 | kw const | 308 | kw let |
301 | kw else | 309 | kw loop |
302 | kw else if | 310 | kw match |
303 | kw extern | 311 | kw mod |
304 | kw fn | 312 | kw return |
305 | kw if | 313 | kw static |
306 | kw if let | 314 | kw trait |
307 | kw impl | 315 | kw type |
308 | kw let | 316 | kw unsafe |
309 | kw loop | 317 | kw use |
310 | kw match | 318 | kw while |
311 | kw mod | 319 | "#]], |
312 | kw return | 320 | ); |
313 | kw static | 321 | check_edit( |
314 | kw trait | 322 | "else", |
315 | kw type | 323 | r#"fn quux() { if true { () } <|> }"#, |
316 | kw unsafe | 324 | r#"fn quux() { if true { () } else {$0} }"#, |
317 | kw use | ||
318 | kw while | ||
319 | "### | ||
320 | ); | 325 | ); |
321 | } | 326 | } |
322 | 327 | ||
323 | #[test] | 328 | #[test] |
324 | fn test_keywords_in_match_arm() { | 329 | fn test_keywords_in_match_arm() { |
325 | assert_snapshot!( | 330 | check( |
326 | get_keyword_completions( | 331 | r#" |
327 | r" | 332 | fn quux() -> i32 { |
328 | fn quux() -> i32 { | 333 | match () { |
329 | match () { | 334 | () => <|> |
330 | () => <|> | 335 | } |
331 | } | 336 | } |
332 | } | 337 | "#, |
333 | ", | 338 | expect![[r#" |
334 | ), | 339 | kw if |
335 | @r###" | 340 | kw if let |
336 | kw if | 341 | kw loop |
337 | kw if let | 342 | kw match |
338 | kw loop | 343 | kw return |
339 | kw match | 344 | kw unsafe |
340 | kw return | 345 | "#]], |
341 | kw unsafe | ||
342 | "### | ||
343 | ); | 346 | ); |
344 | } | 347 | } |
345 | 348 | ||
346 | #[test] | 349 | #[test] |
347 | fn test_keywords_in_trait_def() { | 350 | fn test_keywords_in_trait_def() { |
348 | assert_snapshot!( | 351 | check( |
349 | get_keyword_completions(r"trait My { <|> }"), | 352 | r"trait My { <|> }", |
350 | @r###" | 353 | expect![[r#" |
351 | kw const | 354 | kw const |
352 | kw fn | 355 | kw fn |
353 | kw type | 356 | kw type |
354 | kw unsafe | 357 | kw unsafe |
355 | "### | 358 | "#]], |
356 | ); | 359 | ); |
357 | } | 360 | } |
358 | 361 | ||
359 | #[test] | 362 | #[test] |
360 | fn test_keywords_in_impl_def() { | 363 | fn test_keywords_in_impl_def() { |
361 | assert_snapshot!( | 364 | check( |
362 | get_keyword_completions(r"impl My { <|> }"), | 365 | r"impl My { <|> }", |
363 | @r###" | 366 | expect![[r#" |
364 | kw const | 367 | kw const |
365 | kw fn | 368 | kw fn |
366 | kw pub | 369 | kw pub |
367 | kw type | 370 | kw type |
368 | kw unsafe | 371 | kw unsafe |
369 | "### | 372 | "#]], |
370 | ); | 373 | ); |
371 | } | 374 | } |
372 | 375 | ||
373 | #[test] | 376 | #[test] |
374 | fn test_keywords_in_loop() { | 377 | fn test_keywords_in_loop() { |
375 | assert_snapshot!( | 378 | check( |
376 | get_keyword_completions(r"fn my() { loop { <|> } }"), | 379 | r"fn my() { loop { <|> } }", |
377 | @r###" | 380 | expect![[r#" |
378 | kw break | 381 | kw break |
379 | kw const | 382 | kw const |
380 | kw continue | 383 | kw continue |
381 | kw extern | 384 | kw extern |
382 | kw fn | 385 | kw fn |
383 | kw if | 386 | kw if |
384 | kw if let | 387 | kw if let |
385 | kw impl | 388 | kw impl |
386 | kw let | 389 | kw let |
387 | kw loop | 390 | kw loop |
388 | kw match | 391 | kw match |
389 | kw mod | 392 | kw mod |
390 | kw return | 393 | kw return |
391 | kw static | 394 | kw static |
392 | kw trait | 395 | kw trait |
393 | kw type | 396 | kw type |
394 | kw unsafe | 397 | kw unsafe |
395 | kw use | 398 | kw use |
396 | kw while | 399 | kw while |
397 | "### | 400 | "#]], |
398 | ); | 401 | ); |
399 | } | 402 | } |
400 | 403 | ||
401 | #[test] | 404 | #[test] |
402 | fn test_keywords_after_unsafe_in_item_list() { | 405 | fn test_keywords_after_unsafe_in_item_list() { |
403 | assert_snapshot!( | 406 | check( |
404 | get_keyword_completions(r"unsafe <|>"), | 407 | r"unsafe <|>", |
405 | @r###" | 408 | expect![[r#" |
406 | kw fn | 409 | kw fn |
407 | kw impl | 410 | kw impl |
408 | kw trait | 411 | kw trait |
409 | "### | 412 | "#]], |
410 | ); | 413 | ); |
411 | } | 414 | } |
412 | 415 | ||
413 | #[test] | 416 | #[test] |
414 | fn test_keywords_after_unsafe_in_block_expr() { | 417 | fn test_keywords_after_unsafe_in_block_expr() { |
415 | assert_snapshot!( | 418 | check( |
416 | get_keyword_completions(r"fn my_fn() { unsafe <|> }"), | 419 | r"fn my_fn() { unsafe <|> }", |
417 | @r###" | 420 | expect![[r#" |
418 | kw fn | 421 | kw fn |
419 | kw impl | 422 | kw impl |
420 | kw trait | 423 | kw trait |
421 | "### | 424 | "#]], |
422 | ); | 425 | ); |
423 | } | 426 | } |
424 | 427 | ||
425 | #[test] | 428 | #[test] |
426 | fn test_mut_in_ref_and_in_fn_parameters_list() { | 429 | fn test_mut_in_ref_and_in_fn_parameters_list() { |
427 | assert_snapshot!( | 430 | check( |
428 | get_keyword_completions(r"fn my_fn(&<|>) {}"), | 431 | r"fn my_fn(&<|>) {}", |
429 | @r###" | 432 | expect![[r#" |
430 | kw mut | 433 | kw mut |
431 | "### | 434 | "#]], |
432 | ); | 435 | ); |
433 | assert_snapshot!( | 436 | check( |
434 | get_keyword_completions(r"fn my_fn(<|>) {}"), | 437 | r"fn my_fn(<|>) {}", |
435 | @r###" | 438 | expect![[r#" |
436 | kw mut | 439 | kw mut |
437 | "### | 440 | "#]], |
438 | ); | 441 | ); |
439 | assert_snapshot!( | 442 | check( |
440 | get_keyword_completions(r"fn my_fn() { let &<|> }"), | 443 | r"fn my_fn() { let &<|> }", |
441 | @r###" | 444 | expect![[r#" |
442 | kw mut | 445 | kw mut |
443 | "### | 446 | "#]], |
444 | ); | 447 | ); |
445 | } | 448 | } |
446 | 449 | ||
447 | #[test] | 450 | #[test] |
448 | fn test_where_keyword() { | 451 | fn test_where_keyword() { |
449 | assert_snapshot!( | 452 | check( |
450 | get_keyword_completions(r"trait A <|>"), | 453 | r"trait A <|>", |
451 | @r###" | 454 | expect![[r#" |
452 | kw where | 455 | kw where |
453 | "### | 456 | "#]], |
457 | ); | ||
458 | check( | ||
459 | r"impl A <|>", | ||
460 | expect![[r#" | ||
461 | kw where | ||
462 | "#]], | ||
463 | ); | ||
464 | } | ||
465 | |||
466 | #[test] | ||
467 | fn no_keyword_completion_in_comments() { | ||
468 | mark::check!(no_keyword_completion_in_comments); | ||
469 | check( | ||
470 | r#" | ||
471 | fn test() { | ||
472 | let x = 2; // A comment<|> | ||
473 | } | ||
474 | "#, | ||
475 | expect![[""]], | ||
476 | ); | ||
477 | check( | ||
478 | r#" | ||
479 | /* | ||
480 | Some multi-line comment<|> | ||
481 | */ | ||
482 | "#, | ||
483 | expect![[""]], | ||
454 | ); | 484 | ); |
455 | assert_snapshot!( | 485 | check( |
456 | get_keyword_completions(r"impl A <|>"), | 486 | r#" |
457 | @r###" | 487 | /// Some doc comment |
458 | kw where | 488 | /// let test<|> = 1 |
459 | "### | 489 | "#, |
490 | expect![[""]], | ||
460 | ); | 491 | ); |
461 | } | 492 | } |
462 | } | 493 | } |
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)] |
20 | mod tests { | 20 | mod 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 } } | 34 | struct S { foo: u32 } |
99 | struct S { foo: u32 } | ||
100 | 35 | ||
101 | fn process(f: S) { | 36 | fn 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 { | 52 | enum E { S { foo: u32, bar: () } } |
127 | foo1: u32, | ||
128 | foo2: u32, | ||
129 | bar: u32, | ||
130 | baz: u32, | ||
131 | } | ||
132 | 53 | ||
133 | fn main() { | 54 | fn 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" |
71 | macro_rules! m { ($e:expr) => { $e } } | ||
72 | struct S { foo: u32 } | ||
73 | |||
74 | fn 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#" | ||
90 | struct S { | ||
91 | foo1: u32, foo2: u32, | ||
92 | bar: u32, baz: u32, | ||
93 | } | ||
175 | 94 | ||
176 | #[test] | 95 | fn 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 } | 114 | struct A { the_field: u32 } |
209 | fn foo() { | 115 | fn 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 { | 129 | enum E { A { a: u32 } } |
233 | A { a: u32 } | 130 | fn 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 } | 144 | struct A { a: u32 } |
259 | struct B { b: u32 } | 145 | struct B { b: u32 } |
260 | 146 | ||
261 | fn foo() { | 147 | fn 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 } | 161 | struct A<T> { a: T } |
285 | 162 | ||
286 | fn foo() { | 163 | fn 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 } } | 177 | macro_rules! m { ($e:expr) => { $e } } |
310 | struct A { the_field: u32 } | 178 | struct A { the_field: u32 } |
311 | fn foo() { | 179 | fn 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 { | 193 | struct 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() { | 198 | fn 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 { | 214 | struct S { foo1: u32, foo2: u32 } |
378 | foo1: u32, | ||
379 | foo2: u32, | ||
380 | } | ||
381 | 215 | ||
382 | fn main() { | 216 | fn 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..fd12673b2 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -383,12 +383,14 @@ impl Builder { | |||
383 | return self; | 383 | return self; |
384 | } | 384 | } |
385 | if ctx.use_item_syntax.is_some() || ctx.is_call { | 385 | if ctx.use_item_syntax.is_some() || ctx.is_call { |
386 | mark::hit!(no_parens_in_use_item); | ||
386 | return self; | 387 | return self; |
387 | } | 388 | } |
388 | 389 | ||
389 | // Don't add parentheses if the expected type is some function reference. | 390 | // Don't add parentheses if the expected type is some function reference. |
390 | if let Some(ty) = &ctx.expected_type { | 391 | if let Some(ty) = &ctx.expected_type { |
391 | if ty.is_fn() { | 392 | if ty.is_fn() { |
393 | mark::hit!(no_call_parens_if_fn_ptr_needed); | ||
392 | return self; | 394 | return self; |
393 | } | 395 | } |
394 | } | 396 | } |
@@ -413,7 +415,10 @@ impl Builder { | |||
413 | .sep_by(", "); | 415 | .sep_by(", "); |
414 | format!("{}({})$0", name, function_params_snippet) | 416 | format!("{}({})$0", name, function_params_snippet) |
415 | } | 417 | } |
416 | _ => format!("{}($0)", name), | 418 | _ => { |
419 | mark::hit!(suppress_arg_snippets); | ||
420 | format!("{}($0)", name) | ||
421 | } | ||
417 | }; | 422 | }; |
418 | 423 | ||
419 | (snippet, format!("{}(…)", name)) | 424 | (snippet, format!("{}(…)", name)) |
@@ -460,7 +465,7 @@ mod tests { | |||
460 | use test_utils::mark; | 465 | use test_utils::mark; |
461 | 466 | ||
462 | use crate::completion::{ | 467 | use crate::completion::{ |
463 | test_utils::{do_completion, do_completion_with_options}, | 468 | test_utils::{check_edit, check_edit_with_config, do_completion}, |
464 | CompletionConfig, CompletionItem, CompletionKind, | 469 | CompletionConfig, CompletionItem, CompletionKind, |
465 | }; | 470 | }; |
466 | 471 | ||
@@ -468,13 +473,6 @@ mod tests { | |||
468 | do_completion(ra_fixture, CompletionKind::Reference) | 473 | do_completion(ra_fixture, CompletionKind::Reference) |
469 | } | 474 | } |
470 | 475 | ||
471 | fn do_reference_completion_with_options( | ||
472 | ra_fixture: &str, | ||
473 | options: CompletionConfig, | ||
474 | ) -> Vec<CompletionItem> { | ||
475 | do_completion_with_options(ra_fixture, CompletionKind::Reference, &options) | ||
476 | } | ||
477 | |||
478 | #[test] | 476 | #[test] |
479 | fn enum_detail_includes_names_for_record() { | 477 | fn enum_detail_includes_names_for_record() { |
480 | assert_debug_snapshot!( | 478 | assert_debug_snapshot!( |
@@ -606,448 +604,240 @@ mod tests { | |||
606 | ] | 604 | ] |
607 | "### | 605 | "### |
608 | ); | 606 | ); |
609 | } | ||
610 | 607 | ||
611 | #[test] | 608 | assert_debug_snapshot!(do_reference_completion( |
612 | fn inserts_parens_for_function_calls() { | 609 | r#" |
613 | mark::check!(inserts_parens_for_function_calls); | 610 | struct A { |
614 | assert_debug_snapshot!( | 611 | #[deprecated] |
615 | do_reference_completion( | 612 | the_field: u32, |
616 | r" | 613 | } |
617 | fn no_args() {} | 614 | fn foo() { |
618 | fn main() { no_<|> } | 615 | A { the<|> } |
619 | " | 616 | } |
620 | ), | 617 | "#, |
621 | @r###" | 618 | ), |
622 | [ | 619 | @r###" |
623 | CompletionItem { | ||
624 | label: "main()", | ||
625 | source_range: 28..31, | ||
626 | delete: 28..31, | ||
627 | insert: "main()$0", | ||
628 | kind: Function, | ||
629 | lookup: "main", | ||
630 | detail: "fn main()", | ||
631 | }, | ||
632 | CompletionItem { | ||
633 | label: "no_args()", | ||
634 | source_range: 28..31, | ||
635 | delete: 28..31, | ||
636 | insert: "no_args()$0", | ||
637 | kind: Function, | ||
638 | lookup: "no_args", | ||
639 | detail: "fn no_args()", | ||
640 | }, | ||
641 | ] | ||
642 | "### | ||
643 | ); | ||
644 | assert_debug_snapshot!( | ||
645 | do_reference_completion( | ||
646 | r" | ||
647 | fn with_args(x: i32, y: String) {} | ||
648 | fn main() { with_<|> } | ||
649 | " | ||
650 | ), | ||
651 | @r###" | ||
652 | [ | 620 | [ |
653 | CompletionItem { | 621 | CompletionItem { |
654 | label: "main()", | 622 | label: "the_field", |
655 | source_range: 47..52, | 623 | source_range: 69..72, |
656 | delete: 47..52, | 624 | delete: 69..72, |
657 | insert: "main()$0", | 625 | insert: "the_field", |
658 | kind: Function, | 626 | kind: Field, |
659 | lookup: "main", | 627 | detail: "u32", |
660 | detail: "fn main()", | 628 | deprecated: true, |
661 | }, | ||
662 | CompletionItem { | ||
663 | label: "with_args(…)", | ||
664 | source_range: 47..52, | ||
665 | delete: 47..52, | ||
666 | insert: "with_args(${1:x}, ${2:y})$0", | ||
667 | kind: Function, | ||
668 | lookup: "with_args", | ||
669 | detail: "fn with_args(x: i32, y: String)", | ||
670 | trigger_call_info: true, | ||
671 | }, | 629 | }, |
672 | ] | 630 | ] |
673 | "### | 631 | "###); |
632 | } | ||
633 | |||
634 | #[test] | ||
635 | fn inserts_parens_for_function_calls() { | ||
636 | mark::check!(inserts_parens_for_function_calls); | ||
637 | check_edit( | ||
638 | "no_args", | ||
639 | r#" | ||
640 | fn no_args() {} | ||
641 | fn main() { no_<|> } | ||
642 | "#, | ||
643 | r#" | ||
644 | fn no_args() {} | ||
645 | fn main() { no_args()$0 } | ||
646 | "#, | ||
674 | ); | 647 | ); |
675 | assert_debug_snapshot!( | 648 | |
676 | do_reference_completion( | 649 | check_edit( |
677 | r" | 650 | "with_args", |
678 | fn with_ignored_args(_foo: i32, ___bar: bool, ho_ge_: String) {} | 651 | r#" |
679 | fn main() { with_<|> } | 652 | fn with_args(x: i32, y: String) {} |
680 | " | 653 | fn main() { with_<|> } |
681 | ), | 654 | "#, |
682 | @r###" | 655 | r#" |
683 | [ | 656 | fn with_args(x: i32, y: String) {} |
684 | CompletionItem { | 657 | fn main() { with_args(${1:x}, ${2:y})$0 } |
685 | label: "main()", | 658 | "#, |
686 | source_range: 77..82, | ||
687 | delete: 77..82, | ||
688 | insert: "main()$0", | ||
689 | kind: Function, | ||
690 | lookup: "main", | ||
691 | detail: "fn main()", | ||
692 | }, | ||
693 | CompletionItem { | ||
694 | label: "with_ignored_args(…)", | ||
695 | source_range: 77..82, | ||
696 | delete: 77..82, | ||
697 | insert: "with_ignored_args(${1:foo}, ${2:bar}, ${3:ho_ge_})$0", | ||
698 | kind: Function, | ||
699 | lookup: "with_ignored_args", | ||
700 | detail: "fn with_ignored_args(_foo: i32, ___bar: bool, ho_ge_: String)", | ||
701 | trigger_call_info: true, | ||
702 | }, | ||
703 | ] | ||
704 | "### | ||
705 | ); | 659 | ); |
706 | assert_debug_snapshot!( | 660 | |
707 | do_reference_completion( | 661 | check_edit( |
708 | r" | 662 | "foo", |
709 | struct S {} | 663 | r#" |
710 | impl S { | 664 | struct S; |
711 | fn foo(&self) {} | 665 | impl S { |
712 | } | 666 | fn foo(&self) {} |
713 | fn bar(s: &S) { | 667 | } |
714 | s.f<|> | 668 | fn bar(s: &S) { s.f<|> } |
715 | } | 669 | "#, |
716 | " | 670 | r#" |
717 | ), | 671 | struct S; |
718 | @r###" | 672 | impl S { |
719 | [ | 673 | fn foo(&self) {} |
720 | CompletionItem { | 674 | } |
721 | label: "foo()", | 675 | fn bar(s: &S) { s.foo()$0 } |
722 | source_range: 66..67, | 676 | "#, |
723 | delete: 66..67, | ||
724 | insert: "foo()$0", | ||
725 | kind: Method, | ||
726 | lookup: "foo", | ||
727 | detail: "fn foo(&self)", | ||
728 | }, | ||
729 | ] | ||
730 | "### | ||
731 | ); | 677 | ); |
732 | assert_debug_snapshot!( | 678 | |
733 | do_reference_completion( | 679 | check_edit( |
734 | r" | 680 | "foo", |
735 | struct S {} | 681 | r#" |
736 | impl S { | 682 | struct S {} |
737 | fn foo_ignored_args(&self, _a: bool, b: i32) {} | 683 | impl S { |
738 | } | 684 | fn foo(&self, x: i32) {} |
739 | fn bar(s: &S) { | 685 | } |
740 | s.f<|> | 686 | fn bar(s: &S) { |
741 | } | 687 | s.f<|> |
742 | " | 688 | } |
743 | ), | 689 | "#, |
744 | @r###" | 690 | r#" |
745 | [ | 691 | struct S {} |
746 | CompletionItem { | 692 | impl S { |
747 | label: "foo_ignored_args(…)", | 693 | fn foo(&self, x: i32) {} |
748 | source_range: 97..98, | 694 | } |
749 | delete: 97..98, | 695 | fn bar(s: &S) { |
750 | insert: "foo_ignored_args(${1:a}, ${2:b})$0", | 696 | s.foo(${1:x})$0 |
751 | kind: Method, | 697 | } |
752 | lookup: "foo_ignored_args", | 698 | "#, |
753 | detail: "fn foo_ignored_args(&self, _a: bool, b: i32)", | ||
754 | trigger_call_info: true, | ||
755 | }, | ||
756 | ] | ||
757 | "### | ||
758 | ); | 699 | ); |
759 | } | 700 | } |
760 | 701 | ||
761 | #[test] | 702 | #[test] |
762 | fn inserts_parens_for_tuple_enums() { | 703 | fn suppress_arg_snippets() { |
763 | assert_debug_snapshot!( | 704 | mark::check!(suppress_arg_snippets); |
764 | do_reference_completion( | 705 | check_edit_with_config( |
765 | r" | 706 | "with_args", |
766 | enum Option<T> { Some(T), None } | 707 | r#" |
767 | use Option::*; | 708 | fn with_args(x: i32, y: String) {} |
768 | fn main() -> Option<i32> { | 709 | fn main() { with_<|> } |
769 | Som<|> | 710 | "#, |
770 | } | 711 | r#" |
771 | " | 712 | fn with_args(x: i32, y: String) {} |
772 | ), | 713 | fn main() { with_args($0) } |
773 | @r###" | 714 | "#, |
774 | [ | 715 | &CompletionConfig { add_call_argument_snippets: false, ..CompletionConfig::default() }, |
775 | CompletionItem { | ||
776 | label: "None", | ||
777 | source_range: 79..82, | ||
778 | delete: 79..82, | ||
779 | insert: "None", | ||
780 | kind: EnumVariant, | ||
781 | detail: "()", | ||
782 | }, | ||
783 | CompletionItem { | ||
784 | label: "Option", | ||
785 | source_range: 79..82, | ||
786 | delete: 79..82, | ||
787 | insert: "Option", | ||
788 | kind: Enum, | ||
789 | }, | ||
790 | CompletionItem { | ||
791 | label: "Some(…)", | ||
792 | source_range: 79..82, | ||
793 | delete: 79..82, | ||
794 | insert: "Some($0)", | ||
795 | kind: EnumVariant, | ||
796 | lookup: "Some", | ||
797 | detail: "(T)", | ||
798 | trigger_call_info: true, | ||
799 | }, | ||
800 | CompletionItem { | ||
801 | label: "main()", | ||
802 | source_range: 79..82, | ||
803 | delete: 79..82, | ||
804 | insert: "main()$0", | ||
805 | kind: Function, | ||
806 | lookup: "main", | ||
807 | detail: "fn main() -> Option<i32>", | ||
808 | }, | ||
809 | ] | ||
810 | "### | ||
811 | ); | ||
812 | assert_debug_snapshot!( | ||
813 | do_reference_completion( | ||
814 | r" | ||
815 | enum Option<T> { Some(T), None } | ||
816 | use Option::*; | ||
817 | fn main(value: Option<i32>) { | ||
818 | match value { | ||
819 | Som<|> | ||
820 | } | ||
821 | } | ||
822 | " | ||
823 | ), | ||
824 | @r###" | ||
825 | [ | ||
826 | CompletionItem { | ||
827 | label: "None", | ||
828 | source_range: 104..107, | ||
829 | delete: 104..107, | ||
830 | insert: "None", | ||
831 | kind: EnumVariant, | ||
832 | detail: "()", | ||
833 | }, | ||
834 | CompletionItem { | ||
835 | label: "Option", | ||
836 | source_range: 104..107, | ||
837 | delete: 104..107, | ||
838 | insert: "Option", | ||
839 | kind: Enum, | ||
840 | }, | ||
841 | CompletionItem { | ||
842 | label: "Some(…)", | ||
843 | source_range: 104..107, | ||
844 | delete: 104..107, | ||
845 | insert: "Some($0)", | ||
846 | kind: EnumVariant, | ||
847 | lookup: "Some", | ||
848 | detail: "(T)", | ||
849 | trigger_call_info: true, | ||
850 | }, | ||
851 | ] | ||
852 | "### | ||
853 | ); | 716 | ); |
854 | } | 717 | } |
855 | 718 | ||
856 | #[test] | 719 | #[test] |
857 | fn no_call_parens_if_fn_ptr_needed() { | 720 | fn strips_underscores_from_args() { |
858 | assert_debug_snapshot!( | 721 | check_edit( |
859 | do_reference_completion( | 722 | "foo", |
860 | r" | 723 | r#" |
861 | fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8) {} | 724 | fn foo(_foo: i32, ___bar: bool, ho_ge_: String) {} |
862 | 725 | fn main() { f<|> } | |
863 | struct ManualVtable { | 726 | "#, |
864 | method: fn(u8, u8, u8, u8, u8), | 727 | r#" |
865 | } | 728 | fn foo(_foo: i32, ___bar: bool, ho_ge_: String) {} |
866 | 729 | fn main() { foo(${1:foo}, ${2:bar}, ${3:ho_ge_})$0 } | |
867 | fn main() -> ManualVtable { | 730 | "#, |
868 | ManualVtable { | ||
869 | method: some<|> | ||
870 | } | ||
871 | } | ||
872 | " | ||
873 | ), | ||
874 | @r###" | ||
875 | [ | ||
876 | CompletionItem { | ||
877 | label: "ManualVtable", | ||
878 | source_range: 182..186, | ||
879 | delete: 182..186, | ||
880 | insert: "ManualVtable", | ||
881 | kind: Struct, | ||
882 | }, | ||
883 | CompletionItem { | ||
884 | label: "main", | ||
885 | source_range: 182..186, | ||
886 | delete: 182..186, | ||
887 | insert: "main", | ||
888 | kind: Function, | ||
889 | detail: "fn main() -> ManualVtable", | ||
890 | }, | ||
891 | CompletionItem { | ||
892 | label: "somefn", | ||
893 | source_range: 182..186, | ||
894 | delete: 182..186, | ||
895 | insert: "somefn", | ||
896 | kind: Function, | ||
897 | detail: "fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8)", | ||
898 | }, | ||
899 | ] | ||
900 | "### | ||
901 | ); | 731 | ); |
902 | } | 732 | } |
903 | 733 | ||
904 | #[test] | 734 | #[test] |
905 | fn arg_snippets_for_method_call() { | 735 | fn inserts_parens_for_tuple_enums() { |
906 | assert_debug_snapshot!( | 736 | check_edit( |
907 | do_reference_completion( | 737 | "Some", |
908 | r" | 738 | r#" |
909 | struct S {} | 739 | enum Option<T> { Some(T), None } |
910 | impl S { | 740 | use Option::*; |
911 | fn foo(&self, x: i32) {} | 741 | fn main() -> Option<i32> { |
912 | } | 742 | Som<|> |
913 | fn bar(s: &S) { | 743 | } |
914 | s.f<|> | 744 | "#, |
915 | } | 745 | r#" |
916 | " | 746 | enum Option<T> { Some(T), None } |
917 | ), | 747 | use Option::*; |
918 | @r###" | 748 | fn main() -> Option<i32> { |
919 | [ | 749 | Some($0) |
920 | CompletionItem { | 750 | } |
921 | label: "foo(…)", | 751 | "#, |
922 | source_range: 74..75, | 752 | ); |
923 | delete: 74..75, | 753 | check_edit( |
924 | insert: "foo(${1:x})$0", | 754 | "Some", |
925 | kind: Method, | 755 | r#" |
926 | lookup: "foo", | 756 | enum Option<T> { Some(T), None } |
927 | detail: "fn foo(&self, x: i32)", | 757 | use Option::*; |
928 | trigger_call_info: true, | 758 | fn main(value: Option<i32>) { |
929 | }, | 759 | match value { |
930 | ] | 760 | Som<|> |
931 | "### | 761 | } |
932 | ) | 762 | } |
763 | "#, | ||
764 | r#" | ||
765 | enum Option<T> { Some(T), None } | ||
766 | use Option::*; | ||
767 | fn main(value: Option<i32>) { | ||
768 | match value { | ||
769 | Some($0) | ||
770 | } | ||
771 | } | ||
772 | "#, | ||
773 | ); | ||
933 | } | 774 | } |
934 | 775 | ||
935 | #[test] | 776 | #[test] |
936 | fn no_arg_snippets_for_method_call() { | 777 | fn no_call_parens_if_fn_ptr_needed() { |
937 | assert_debug_snapshot!( | 778 | mark::check!(no_call_parens_if_fn_ptr_needed); |
938 | do_reference_completion_with_options( | 779 | check_edit( |
939 | r" | 780 | "foo", |
940 | struct S {} | 781 | r#" |
941 | impl S { | 782 | fn foo(foo: u8, bar: u8) {} |
942 | fn foo(&self, x: i32) {} | 783 | struct ManualVtable { f: fn(u8, u8) } |
943 | } | 784 | |
944 | fn bar(s: &S) { | 785 | fn main() -> ManualVtable { |
945 | s.f<|> | 786 | ManualVtable { f: f<|> } |
946 | } | 787 | } |
947 | ", | 788 | "#, |
948 | CompletionConfig { | 789 | r#" |
949 | add_call_argument_snippets: false, | 790 | fn foo(foo: u8, bar: u8) {} |
950 | .. Default::default() | 791 | struct ManualVtable { f: fn(u8, u8) } |
951 | } | 792 | |
952 | ), | 793 | fn main() -> ManualVtable { |
953 | @r###" | 794 | ManualVtable { f: foo } |
954 | [ | 795 | } |
955 | CompletionItem { | 796 | "#, |
956 | label: "foo(…)", | 797 | ); |
957 | source_range: 74..75, | ||
958 | delete: 74..75, | ||
959 | insert: "foo($0)", | ||
960 | kind: Method, | ||
961 | lookup: "foo", | ||
962 | detail: "fn foo(&self, x: i32)", | ||
963 | trigger_call_info: true, | ||
964 | }, | ||
965 | ] | ||
966 | "### | ||
967 | ) | ||
968 | } | 798 | } |
969 | 799 | ||
970 | #[test] | 800 | #[test] |
971 | fn dont_render_function_parens_in_use_item() { | 801 | fn no_parens_in_use_item() { |
972 | assert_debug_snapshot!( | 802 | mark::check!(no_parens_in_use_item); |
973 | do_reference_completion( | 803 | check_edit( |
974 | " | 804 | "foo", |
975 | //- /lib.rs | 805 | r#" |
976 | mod m { pub fn foo() {} } | 806 | mod m { pub fn foo() {} } |
977 | use crate::m::f<|>; | 807 | use crate::m::f<|>; |
978 | " | 808 | "#, |
979 | ), | 809 | r#" |
980 | @r###" | 810 | mod m { pub fn foo() {} } |
981 | [ | 811 | use crate::m::foo; |
982 | CompletionItem { | 812 | "#, |
983 | label: "foo", | ||
984 | source_range: 40..41, | ||
985 | delete: 40..41, | ||
986 | insert: "foo", | ||
987 | kind: Function, | ||
988 | detail: "pub fn foo()", | ||
989 | }, | ||
990 | ] | ||
991 | "### | ||
992 | ); | 813 | ); |
993 | } | 814 | } |
994 | 815 | ||
995 | #[test] | 816 | #[test] |
996 | fn dont_render_function_parens_if_already_call() { | 817 | fn no_parens_in_call() { |
997 | assert_debug_snapshot!( | 818 | check_edit( |
998 | do_reference_completion( | 819 | "foo", |
999 | " | 820 | r#" |
1000 | //- /lib.rs | 821 | fn foo(x: i32) {} |
1001 | fn frobnicate() {} | 822 | fn main() { f<|>(); } |
1002 | fn main() { | 823 | "#, |
1003 | frob<|>(); | 824 | r#" |
1004 | } | 825 | fn foo(x: i32) {} |
1005 | " | 826 | fn main() { foo(); } |
1006 | ), | 827 | "#, |
1007 | @r###" | ||
1008 | [ | ||
1009 | CompletionItem { | ||
1010 | label: "frobnicate", | ||
1011 | source_range: 35..39, | ||
1012 | delete: 35..39, | ||
1013 | insert: "frobnicate", | ||
1014 | kind: Function, | ||
1015 | detail: "fn frobnicate()", | ||
1016 | }, | ||
1017 | CompletionItem { | ||
1018 | label: "main", | ||
1019 | source_range: 35..39, | ||
1020 | delete: 35..39, | ||
1021 | insert: "main", | ||
1022 | kind: Function, | ||
1023 | detail: "fn main()", | ||
1024 | }, | ||
1025 | ] | ||
1026 | "### | ||
1027 | ); | 828 | ); |
1028 | assert_debug_snapshot!( | 829 | check_edit( |
1029 | do_reference_completion( | 830 | "foo", |
1030 | " | 831 | r#" |
1031 | //- /lib.rs | 832 | struct Foo; |
1032 | struct Foo {} | 833 | impl Foo { fn foo(&self){} } |
1033 | impl Foo { fn new() -> Foo {} } | 834 | fn f(foo: &Foo) { foo.f<|>(); } |
1034 | fn main() { | 835 | "#, |
1035 | Foo::ne<|>(); | 836 | r#" |
1036 | } | 837 | struct Foo; |
1037 | " | 838 | impl Foo { fn foo(&self){} } |
1038 | ), | 839 | fn f(foo: &Foo) { foo.foo(); } |
1039 | @r###" | 840 | "#, |
1040 | [ | ||
1041 | CompletionItem { | ||
1042 | label: "new", | ||
1043 | source_range: 67..69, | ||
1044 | delete: 67..69, | ||
1045 | insert: "new", | ||
1046 | kind: Function, | ||
1047 | detail: "fn new() -> Foo", | ||
1048 | }, | ||
1049 | ] | ||
1050 | "### | ||
1051 | ); | 841 | ); |
1052 | } | 842 | } |
1053 | 843 | ||
@@ -1516,54 +1306,4 @@ mod tests { | |||
1516 | "### | 1306 | "### |
1517 | ); | 1307 | ); |
1518 | } | 1308 | } |
1519 | |||
1520 | #[test] | ||
1521 | fn no_keyword_autocompletion_on_line_comments() { | ||
1522 | assert_debug_snapshot!( | ||
1523 | do_completion( | ||
1524 | r" | ||
1525 | fn test() { | ||
1526 | let x = 2; // A comment<|> | ||
1527 | } | ||
1528 | ", | ||
1529 | CompletionKind::Keyword | ||
1530 | ), | ||
1531 | @r###" | ||
1532 | [] | ||
1533 | "### | ||
1534 | ); | ||
1535 | } | ||
1536 | |||
1537 | #[test] | ||
1538 | fn no_keyword_autocompletion_on_multi_line_comments() { | ||
1539 | assert_debug_snapshot!( | ||
1540 | do_completion( | ||
1541 | r" | ||
1542 | /* | ||
1543 | Some multi-line comment<|> | ||
1544 | */ | ||
1545 | ", | ||
1546 | CompletionKind::Keyword | ||
1547 | ), | ||
1548 | @r###" | ||
1549 | [] | ||
1550 | "### | ||
1551 | ); | ||
1552 | } | ||
1553 | |||
1554 | #[test] | ||
1555 | fn no_keyword_autocompletion_on_doc_comments() { | ||
1556 | assert_debug_snapshot!( | ||
1557 | do_completion( | ||
1558 | r" | ||
1559 | /// Some doc comment | ||
1560 | /// let test<|> = 1 | ||
1561 | ", | ||
1562 | CompletionKind::Keyword | ||
1563 | ), | ||
1564 | @r###" | ||
1565 | [] | ||
1566 | "### | ||
1567 | ); | ||
1568 | } | ||
1569 | } | 1309 | } |
diff --git a/crates/ra_ide/src/completion/test_utils.rs b/crates/ra_ide/src/completion/test_utils.rs index 5c01654cc..145d36c98 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 | ||
3 | use hir::Semantics; | 3 | use hir::Semantics; |
4 | use itertools::Itertools; | ||
4 | use ra_syntax::{AstNode, NodeOrToken, SyntaxElement}; | 5 | use ra_syntax::{AstNode, NodeOrToken, SyntaxElement}; |
6 | use stdx::{format_to, trim_indent}; | ||
7 | use test_utils::assert_eq_text; | ||
5 | 8 | ||
6 | use crate::{ | 9 | use crate::{ |
7 | completion::{completion_item::CompletionKind, CompletionConfig}, | 10 | completion::{completion_item::CompletionKind, CompletionConfig}, |
@@ -42,10 +45,41 @@ 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 | ||
59 | pub(crate) fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | ||
60 | check_edit_with_config(what, ra_fixture_before, ra_fixture_after, &CompletionConfig::default()) | ||
61 | } | ||
62 | |||
63 | pub(crate) fn check_edit_with_config( | ||
64 | what: &str, | ||
65 | ra_fixture_before: &str, | ||
66 | ra_fixture_after: &str, | ||
67 | config: &CompletionConfig, | ||
68 | ) { | ||
69 | let ra_fixture_after = trim_indent(ra_fixture_after); | ||
70 | let (analysis, position) = analysis_and_position(ra_fixture_before); | ||
71 | let completions: Vec<CompletionItem> = | ||
72 | analysis.completions(config, position).unwrap().unwrap().into(); | ||
73 | let (completion,) = completions | ||
74 | .iter() | ||
75 | .filter(|it| it.lookup() == what) | ||
76 | .collect_tuple() | ||
77 | .unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions)); | ||
78 | let mut actual = analysis.file_text(position.file_id).unwrap().to_string(); | ||
79 | completion.text_edit().apply(&mut actual); | ||
80 | assert_eq_text!(&ra_fixture_after, &actual) | ||
81 | } | ||
82 | |||
49 | pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) { | 83 | pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) { |
50 | let (analysis, pos) = analysis_and_position(code); | 84 | let (analysis, pos) = analysis_and_position(code); |
51 | analysis | 85 | analysis |
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index 8660278f1..dcfa186dc 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs | |||
@@ -76,7 +76,7 @@ pub use crate::{ | |||
76 | }; | 76 | }; |
77 | 77 | ||
78 | pub use hir::{Documentation, Semantics}; | 78 | pub use hir::{Documentation, Semantics}; |
79 | pub use ra_assists::{Assist, AssistConfig, AssistId, ResolvedAssist}; | 79 | pub use ra_assists::{Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist}; |
80 | pub use ra_db::{ | 80 | pub use ra_db::{ |
81 | Canceled, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, | 81 | Canceled, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, |
82 | SourceRootId, | 82 | SourceRootId, |
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index b6a2266b4..8735ec53c 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs | |||
@@ -116,8 +116,7 @@ fn rename_mod( | |||
116 | } else { | 116 | } else { |
117 | format!("{}.rs", new_name) | 117 | format!("{}.rs", new_name) |
118 | }; | 118 | }; |
119 | let move_file = | 119 | let move_file = FileSystemEdit::MoveFile { src: file_id, anchor: file_id, dst }; |
120 | FileSystemEdit::MoveFile { src: file_id, anchor: position.file_id, dst }; | ||
121 | file_system_edits.push(move_file); | 120 | file_system_edits.push(move_file); |
122 | } | 121 | } |
123 | ModuleSource::Module(..) => {} | 122 | ModuleSource::Module(..) => {} |
@@ -271,51 +270,51 @@ fn rename_reference( | |||
271 | 270 | ||
272 | #[cfg(test)] | 271 | #[cfg(test)] |
273 | mod tests { | 272 | mod tests { |
274 | use insta::assert_debug_snapshot; | 273 | use expect::{expect, Expect}; |
275 | use ra_text_edit::TextEditBuilder; | 274 | use ra_text_edit::TextEditBuilder; |
276 | use stdx::trim_indent; | 275 | use stdx::trim_indent; |
277 | use test_utils::{assert_eq_text, mark}; | 276 | use test_utils::{assert_eq_text, mark}; |
278 | 277 | ||
279 | use crate::{mock_analysis::analysis_and_position, FileId}; | 278 | use crate::{mock_analysis::analysis_and_position, FileId}; |
280 | 279 | ||
280 | fn check(new_name: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | ||
281 | let ra_fixture_after = &trim_indent(ra_fixture_after); | ||
282 | let (analysis, position) = analysis_and_position(ra_fixture_before); | ||
283 | let source_change = analysis.rename(position, new_name).unwrap(); | ||
284 | let mut text_edit_builder = TextEditBuilder::default(); | ||
285 | let mut file_id: Option<FileId> = None; | ||
286 | if let Some(change) = source_change { | ||
287 | for edit in change.info.source_file_edits { | ||
288 | file_id = Some(edit.file_id); | ||
289 | for indel in edit.edit.into_iter() { | ||
290 | text_edit_builder.replace(indel.delete, indel.insert); | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string(); | ||
295 | text_edit_builder.finish().apply(&mut result); | ||
296 | assert_eq_text!(ra_fixture_after, &*result); | ||
297 | } | ||
298 | |||
299 | fn check_expect(new_name: &str, ra_fixture: &str, expect: Expect) { | ||
300 | let (analysis, position) = analysis_and_position(ra_fixture); | ||
301 | let source_change = analysis.rename(position, new_name).unwrap().unwrap(); | ||
302 | expect.assert_debug_eq(&source_change) | ||
303 | } | ||
304 | |||
281 | #[test] | 305 | #[test] |
282 | fn test_rename_to_underscore() { | 306 | fn test_rename_to_underscore() { |
283 | test_rename( | 307 | check("_", r#"fn main() { let i<|> = 1; }"#, r#"fn main() { let _ = 1; }"#); |
284 | r#" | ||
285 | fn main() { | ||
286 | let i<|> = 1; | ||
287 | }"#, | ||
288 | "_", | ||
289 | r#" | ||
290 | fn main() { | ||
291 | let _ = 1; | ||
292 | }"#, | ||
293 | ); | ||
294 | } | 308 | } |
295 | 309 | ||
296 | #[test] | 310 | #[test] |
297 | fn test_rename_to_raw_identifier() { | 311 | fn test_rename_to_raw_identifier() { |
298 | test_rename( | 312 | check("r#fn", r#"fn main() { let i<|> = 1; }"#, r#"fn main() { let r#fn = 1; }"#); |
299 | r#" | ||
300 | fn main() { | ||
301 | let i<|> = 1; | ||
302 | }"#, | ||
303 | "r#fn", | ||
304 | r#" | ||
305 | fn main() { | ||
306 | let r#fn = 1; | ||
307 | }"#, | ||
308 | ); | ||
309 | } | 313 | } |
310 | 314 | ||
311 | #[test] | 315 | #[test] |
312 | fn test_rename_to_invalid_identifier() { | 316 | fn test_rename_to_invalid_identifier() { |
313 | let (analysis, position) = analysis_and_position( | 317 | let (analysis, position) = analysis_and_position(r#"fn main() { let i<|> = 1; }"#); |
314 | " | ||
315 | fn main() { | ||
316 | let i<|> = 1; | ||
317 | }", | ||
318 | ); | ||
319 | let new_name = "invalid!"; | 318 | let new_name = "invalid!"; |
320 | let source_change = analysis.rename(position, new_name).unwrap(); | 319 | let source_change = analysis.rename(position, new_name).unwrap(); |
321 | assert!(source_change.is_none()); | 320 | assert!(source_change.is_none()); |
@@ -323,318 +322,269 @@ mod tests { | |||
323 | 322 | ||
324 | #[test] | 323 | #[test] |
325 | fn test_rename_for_local() { | 324 | fn test_rename_for_local() { |
326 | test_rename( | 325 | check( |
326 | "k", | ||
327 | r#" | 327 | r#" |
328 | fn main() { | 328 | fn main() { |
329 | let mut i = 1; | 329 | let mut i = 1; |
330 | let j = 1; | 330 | let j = 1; |
331 | i = i<|> + j; | 331 | i = i<|> + j; |
332 | 332 | ||
333 | { | 333 | { i = 0; } |
334 | i = 0; | ||
335 | } | ||
336 | 334 | ||
337 | i = 5; | 335 | i = 5; |
338 | }"#, | 336 | } |
339 | "k", | 337 | "#, |
340 | r#" | 338 | r#" |
341 | fn main() { | 339 | fn main() { |
342 | let mut k = 1; | 340 | let mut k = 1; |
343 | let j = 1; | 341 | let j = 1; |
344 | k = k + j; | 342 | k = k + j; |
345 | 343 | ||
346 | { | 344 | { k = 0; } |
347 | k = 0; | ||
348 | } | ||
349 | 345 | ||
350 | k = 5; | 346 | k = 5; |
351 | }"#, | 347 | } |
348 | "#, | ||
352 | ); | 349 | ); |
353 | } | 350 | } |
354 | 351 | ||
355 | #[test] | 352 | #[test] |
356 | fn test_rename_for_macro_args() { | 353 | fn test_rename_for_macro_args() { |
357 | test_rename( | 354 | check( |
358 | r#" | ||
359 | macro_rules! foo {($i:ident) => {$i} } | ||
360 | fn main() { | ||
361 | let a<|> = "test"; | ||
362 | foo!(a); | ||
363 | }"#, | ||
364 | "b", | 355 | "b", |
365 | r#" | 356 | r#" |
366 | macro_rules! foo {($i:ident) => {$i} } | 357 | macro_rules! foo {($i:ident) => {$i} } |
367 | fn main() { | 358 | fn main() { |
368 | let b = "test"; | 359 | let a<|> = "test"; |
369 | foo!(b); | 360 | foo!(a); |
370 | }"#, | 361 | } |
362 | "#, | ||
363 | r#" | ||
364 | macro_rules! foo {($i:ident) => {$i} } | ||
365 | fn main() { | ||
366 | let b = "test"; | ||
367 | foo!(b); | ||
368 | } | ||
369 | "#, | ||
371 | ); | 370 | ); |
372 | } | 371 | } |
373 | 372 | ||
374 | #[test] | 373 | #[test] |
375 | fn test_rename_for_macro_args_rev() { | 374 | fn test_rename_for_macro_args_rev() { |
376 | test_rename( | 375 | check( |
377 | r#" | ||
378 | macro_rules! foo {($i:ident) => {$i} } | ||
379 | fn main() { | ||
380 | let a = "test"; | ||
381 | foo!(a<|>); | ||
382 | }"#, | ||
383 | "b", | 376 | "b", |
384 | r#" | 377 | r#" |
385 | macro_rules! foo {($i:ident) => {$i} } | 378 | macro_rules! foo {($i:ident) => {$i} } |
386 | fn main() { | 379 | fn main() { |
387 | let b = "test"; | 380 | let a = "test"; |
388 | foo!(b); | 381 | foo!(a<|>); |
389 | }"#, | 382 | } |
383 | "#, | ||
384 | r#" | ||
385 | macro_rules! foo {($i:ident) => {$i} } | ||
386 | fn main() { | ||
387 | let b = "test"; | ||
388 | foo!(b); | ||
389 | } | ||
390 | "#, | ||
390 | ); | 391 | ); |
391 | } | 392 | } |
392 | 393 | ||
393 | #[test] | 394 | #[test] |
394 | fn test_rename_for_macro_define_fn() { | 395 | fn test_rename_for_macro_define_fn() { |
395 | test_rename( | 396 | check( |
396 | r#" | ||
397 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | ||
398 | define_fn!(foo); | ||
399 | fn main() { | ||
400 | fo<|>o(); | ||
401 | }"#, | ||
402 | "bar", | 397 | "bar", |
403 | r#" | 398 | r#" |
404 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | 399 | macro_rules! define_fn {($id:ident) => { fn $id{} }} |
405 | define_fn!(bar); | 400 | define_fn!(foo); |
406 | fn main() { | 401 | fn main() { |
407 | bar(); | 402 | fo<|>o(); |
408 | }"#, | 403 | } |
404 | "#, | ||
405 | r#" | ||
406 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | ||
407 | define_fn!(bar); | ||
408 | fn main() { | ||
409 | bar(); | ||
410 | } | ||
411 | "#, | ||
409 | ); | 412 | ); |
410 | } | 413 | } |
411 | 414 | ||
412 | #[test] | 415 | #[test] |
413 | fn test_rename_for_macro_define_fn_rev() { | 416 | fn test_rename_for_macro_define_fn_rev() { |
414 | test_rename( | 417 | check( |
415 | r#" | ||
416 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | ||
417 | define_fn!(fo<|>o); | ||
418 | fn main() { | ||
419 | foo(); | ||
420 | }"#, | ||
421 | "bar", | 418 | "bar", |
422 | r#" | 419 | r#" |
423 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | 420 | macro_rules! define_fn {($id:ident) => { fn $id{} }} |
424 | define_fn!(bar); | 421 | define_fn!(fo<|>o); |
425 | fn main() { | 422 | fn main() { |
426 | bar(); | 423 | foo(); |
427 | }"#, | 424 | } |
425 | "#, | ||
426 | r#" | ||
427 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | ||
428 | define_fn!(bar); | ||
429 | fn main() { | ||
430 | bar(); | ||
431 | } | ||
432 | "#, | ||
428 | ); | 433 | ); |
429 | } | 434 | } |
430 | 435 | ||
431 | #[test] | 436 | #[test] |
432 | fn test_rename_for_param_inside() { | 437 | fn test_rename_for_param_inside() { |
433 | test_rename( | 438 | check("j", r#"fn foo(i : u32) -> u32 { i<|> }"#, r#"fn foo(j : u32) -> u32 { j }"#); |
434 | r#" | ||
435 | fn foo(i : u32) -> u32 { | ||
436 | i<|> | ||
437 | }"#, | ||
438 | "j", | ||
439 | r#" | ||
440 | fn foo(j : u32) -> u32 { | ||
441 | j | ||
442 | }"#, | ||
443 | ); | ||
444 | } | 439 | } |
445 | 440 | ||
446 | #[test] | 441 | #[test] |
447 | fn test_rename_refs_for_fn_param() { | 442 | fn test_rename_refs_for_fn_param() { |
448 | test_rename( | 443 | check("j", r#"fn foo(i<|> : u32) -> u32 { i }"#, r#"fn foo(j : u32) -> u32 { j }"#); |
449 | r#" | ||
450 | fn foo(i<|> : u32) -> u32 { | ||
451 | i | ||
452 | }"#, | ||
453 | "new_name", | ||
454 | r#" | ||
455 | fn foo(new_name : u32) -> u32 { | ||
456 | new_name | ||
457 | }"#, | ||
458 | ); | ||
459 | } | 444 | } |
460 | 445 | ||
461 | #[test] | 446 | #[test] |
462 | fn test_rename_for_mut_param() { | 447 | fn test_rename_for_mut_param() { |
463 | test_rename( | 448 | check("j", r#"fn foo(mut i<|> : u32) -> u32 { i }"#, r#"fn foo(mut j : u32) -> u32 { j }"#); |
464 | r#" | ||
465 | fn foo(mut i<|> : u32) -> u32 { | ||
466 | i | ||
467 | }"#, | ||
468 | "new_name", | ||
469 | r#" | ||
470 | fn foo(mut new_name : u32) -> u32 { | ||
471 | new_name | ||
472 | }"#, | ||
473 | ); | ||
474 | } | 449 | } |
475 | 450 | ||
476 | #[test] | 451 | #[test] |
477 | fn test_rename_struct_field() { | 452 | fn test_rename_struct_field() { |
478 | test_rename( | 453 | check( |
454 | "j", | ||
479 | r#" | 455 | r#" |
480 | struct Foo { | 456 | struct Foo { i<|>: i32 } |
481 | i<|>: i32, | ||
482 | } | ||
483 | 457 | ||
484 | impl Foo { | 458 | impl Foo { |
485 | fn new(i: i32) -> Self { | 459 | fn new(i: i32) -> Self { |
486 | Self { i: i } | 460 | Self { i: i } |
487 | } | ||
488 | } | 461 | } |
489 | "#, | 462 | } |
490 | "j", | 463 | "#, |
491 | r#" | 464 | r#" |
492 | struct Foo { | 465 | struct Foo { j: i32 } |
493 | j: i32, | ||
494 | } | ||
495 | 466 | ||
496 | impl Foo { | 467 | impl Foo { |
497 | fn new(i: i32) -> Self { | 468 | fn new(i: i32) -> Self { |
498 | Self { j: i } | 469 | Self { j: i } |
499 | } | ||
500 | } | 470 | } |
501 | "#, | 471 | } |
472 | "#, | ||
502 | ); | 473 | ); |
503 | } | 474 | } |
504 | 475 | ||
505 | #[test] | 476 | #[test] |
506 | fn test_rename_struct_field_for_shorthand() { | 477 | fn test_rename_struct_field_for_shorthand() { |
507 | mark::check!(test_rename_struct_field_for_shorthand); | 478 | mark::check!(test_rename_struct_field_for_shorthand); |
508 | test_rename( | 479 | check( |
480 | "j", | ||
509 | r#" | 481 | r#" |
510 | struct Foo { | 482 | struct Foo { i<|>: i32 } |
511 | i<|>: i32, | ||
512 | } | ||
513 | 483 | ||
514 | impl Foo { | 484 | impl Foo { |
515 | fn new(i: i32) -> Self { | 485 | fn new(i: i32) -> Self { |
516 | Self { i } | 486 | Self { i } |
517 | } | ||
518 | } | 487 | } |
519 | "#, | 488 | } |
520 | "j", | 489 | "#, |
521 | r#" | 490 | r#" |
522 | struct Foo { | 491 | struct Foo { j: i32 } |
523 | j: i32, | ||
524 | } | ||
525 | 492 | ||
526 | impl Foo { | 493 | impl Foo { |
527 | fn new(i: i32) -> Self { | 494 | fn new(i: i32) -> Self { |
528 | Self { j: i } | 495 | Self { j: i } |
529 | } | ||
530 | } | 496 | } |
531 | "#, | 497 | } |
498 | "#, | ||
532 | ); | 499 | ); |
533 | } | 500 | } |
534 | 501 | ||
535 | #[test] | 502 | #[test] |
536 | fn test_rename_local_for_field_shorthand() { | 503 | fn test_rename_local_for_field_shorthand() { |
537 | mark::check!(test_rename_local_for_field_shorthand); | 504 | mark::check!(test_rename_local_for_field_shorthand); |
538 | test_rename( | 505 | check( |
506 | "j", | ||
539 | r#" | 507 | r#" |
540 | struct Foo { | 508 | struct Foo { i: i32 } |
541 | i: i32, | ||
542 | } | ||
543 | 509 | ||
544 | impl Foo { | 510 | impl Foo { |
545 | fn new(i<|>: i32) -> Self { | 511 | fn new(i<|>: i32) -> Self { |
546 | Self { i } | 512 | Self { i } |
547 | } | ||
548 | } | 513 | } |
549 | "#, | 514 | } |
550 | "j", | 515 | "#, |
551 | r#" | 516 | r#" |
552 | struct Foo { | 517 | struct Foo { i: i32 } |
553 | i: i32, | ||
554 | } | ||
555 | 518 | ||
556 | impl Foo { | 519 | impl Foo { |
557 | fn new(j: i32) -> Self { | 520 | fn new(j: i32) -> Self { |
558 | Self { i: j } | 521 | Self { i: j } |
559 | } | ||
560 | } | 522 | } |
561 | "#, | 523 | } |
524 | "#, | ||
562 | ); | 525 | ); |
563 | } | 526 | } |
564 | 527 | ||
565 | #[test] | 528 | #[test] |
566 | fn test_field_shorthand_correct_struct() { | 529 | fn test_field_shorthand_correct_struct() { |
567 | test_rename( | 530 | check( |
568 | r#" | ||
569 | struct Foo { | ||
570 | i<|>: i32, | ||
571 | } | ||
572 | |||
573 | struct Bar { | ||
574 | i: i32, | ||
575 | } | ||
576 | |||
577 | impl Bar { | ||
578 | fn new(i: i32) -> Self { | ||
579 | Self { i } | ||
580 | } | ||
581 | } | ||
582 | "#, | ||
583 | "j", | 531 | "j", |
584 | r#" | 532 | r#" |
585 | struct Foo { | 533 | struct Foo { i<|>: i32 } |
586 | j: i32, | 534 | struct Bar { i: i32 } |
587 | } | ||
588 | 535 | ||
589 | struct Bar { | 536 | impl Bar { |
590 | i: i32, | 537 | fn new(i: i32) -> Self { |
538 | Self { i } | ||
591 | } | 539 | } |
540 | } | ||
541 | "#, | ||
542 | r#" | ||
543 | struct Foo { j: i32 } | ||
544 | struct Bar { i: i32 } | ||
592 | 545 | ||
593 | impl Bar { | 546 | impl Bar { |
594 | fn new(i: i32) -> Self { | 547 | fn new(i: i32) -> Self { |
595 | Self { i } | 548 | Self { i } |
596 | } | ||
597 | } | 549 | } |
598 | "#, | 550 | } |
551 | "#, | ||
599 | ); | 552 | ); |
600 | } | 553 | } |
601 | 554 | ||
602 | #[test] | 555 | #[test] |
603 | fn test_shadow_local_for_struct_shorthand() { | 556 | fn test_shadow_local_for_struct_shorthand() { |
604 | test_rename( | 557 | check( |
558 | "j", | ||
605 | r#" | 559 | r#" |
606 | struct Foo { | 560 | struct Foo { i: i32 } |
607 | i: i32, | ||
608 | } | ||
609 | 561 | ||
610 | fn baz(i<|>: i32) -> Self { | 562 | fn baz(i<|>: i32) -> Self { |
611 | let x = Foo { i }; | 563 | let x = Foo { i }; |
612 | { | 564 | { |
613 | let i = 0; | 565 | let i = 0; |
614 | Foo { i } | 566 | Foo { i } |
615 | } | ||
616 | } | 567 | } |
617 | "#, | 568 | } |
618 | "j", | 569 | "#, |
619 | r#" | 570 | r#" |
620 | struct Foo { | 571 | struct Foo { i: i32 } |
621 | i: i32, | ||
622 | } | ||
623 | 572 | ||
624 | fn baz(j: i32) -> Self { | 573 | fn baz(j: i32) -> Self { |
625 | let x = Foo { i: j }; | 574 | let x = Foo { i: j }; |
626 | { | 575 | { |
627 | let i = 0; | 576 | let i = 0; |
628 | Foo { i } | 577 | Foo { i } |
629 | } | ||
630 | } | 578 | } |
631 | "#, | 579 | } |
580 | "#, | ||
632 | ); | 581 | ); |
633 | } | 582 | } |
634 | 583 | ||
635 | #[test] | 584 | #[test] |
636 | fn test_rename_mod() { | 585 | fn test_rename_mod() { |
637 | let (analysis, position) = analysis_and_position( | 586 | check_expect( |
587 | "foo2", | ||
638 | r#" | 588 | r#" |
639 | //- /lib.rs | 589 | //- /lib.rs |
640 | mod bar; | 590 | mod bar; |
@@ -643,53 +593,49 @@ mod bar; | |||
643 | mod foo<|>; | 593 | mod foo<|>; |
644 | 594 | ||
645 | //- /bar/foo.rs | 595 | //- /bar/foo.rs |
646 | // emtpy | 596 | // empty |
647 | "#, | 597 | "#, |
648 | ); | 598 | expect![[r#" |
649 | let new_name = "foo2"; | 599 | RangeInfo { |
650 | let source_change = analysis.rename(position, new_name).unwrap(); | 600 | range: 4..7, |
651 | assert_debug_snapshot!(&source_change, | 601 | info: SourceChange { |
652 | @r###" | 602 | source_file_edits: [ |
653 | Some( | 603 | SourceFileEdit { |
654 | RangeInfo { | 604 | file_id: FileId( |
655 | range: 4..7, | 605 | 2, |
656 | info: SourceChange { | 606 | ), |
657 | source_file_edits: [ | 607 | edit: TextEdit { |
658 | SourceFileEdit { | 608 | indels: [ |
659 | file_id: FileId( | 609 | Indel { |
660 | 2, | 610 | insert: "foo2", |
661 | ), | 611 | delete: 4..7, |
662 | edit: TextEdit { | 612 | }, |
663 | indels: [ | 613 | ], |
664 | Indel { | 614 | }, |
665 | insert: "foo2", | ||
666 | delete: 4..7, | ||
667 | }, | ||
668 | ], | ||
669 | }, | 615 | }, |
670 | }, | 616 | ], |
671 | ], | 617 | file_system_edits: [ |
672 | file_system_edits: [ | 618 | MoveFile { |
673 | MoveFile { | 619 | src: FileId( |
674 | src: FileId( | 620 | 3, |
675 | 3, | 621 | ), |
676 | ), | 622 | anchor: FileId( |
677 | anchor: FileId( | 623 | 3, |
678 | 2, | 624 | ), |
679 | ), | 625 | dst: "foo2.rs", |
680 | dst: "foo2.rs", | 626 | }, |
681 | }, | 627 | ], |
682 | ], | 628 | is_snippet: false, |
683 | is_snippet: false, | 629 | }, |
684 | }, | 630 | } |
685 | }, | 631 | "#]], |
686 | ) | 632 | ); |
687 | "###); | ||
688 | } | 633 | } |
689 | 634 | ||
690 | #[test] | 635 | #[test] |
691 | fn test_rename_mod_in_use_tree() { | 636 | fn test_rename_mod_in_use_tree() { |
692 | let (analysis, position) = analysis_and_position( | 637 | check_expect( |
638 | "quux", | ||
693 | r#" | 639 | r#" |
694 | //- /main.rs | 640 | //- /main.rs |
695 | pub mod foo; | 641 | pub mod foo; |
@@ -701,140 +647,173 @@ pub struct FooContent; | |||
701 | 647 | ||
702 | //- /bar.rs | 648 | //- /bar.rs |
703 | use crate::foo<|>::FooContent; | 649 | use crate::foo<|>::FooContent; |
704 | "#, | 650 | "#, |
705 | ); | 651 | expect![[r#" |
706 | let new_name = "qux"; | 652 | RangeInfo { |
707 | let source_change = analysis.rename(position, new_name).unwrap(); | 653 | range: 11..14, |
708 | assert_debug_snapshot!(&source_change, | 654 | info: SourceChange { |
709 | @r###" | 655 | source_file_edits: [ |
710 | Some( | 656 | SourceFileEdit { |
711 | RangeInfo { | 657 | file_id: FileId( |
712 | range: 11..14, | 658 | 1, |
713 | info: SourceChange { | 659 | ), |
714 | source_file_edits: [ | 660 | edit: TextEdit { |
715 | SourceFileEdit { | 661 | indels: [ |
716 | file_id: FileId( | 662 | Indel { |
717 | 1, | 663 | insert: "quux", |
718 | ), | 664 | delete: 8..11, |
719 | edit: TextEdit { | 665 | }, |
720 | indels: [ | 666 | ], |
721 | Indel { | 667 | }, |
722 | insert: "qux", | ||
723 | delete: 8..11, | ||
724 | }, | ||
725 | ], | ||
726 | }, | 668 | }, |
727 | }, | 669 | SourceFileEdit { |
728 | SourceFileEdit { | 670 | file_id: FileId( |
729 | file_id: FileId( | 671 | 3, |
730 | 3, | 672 | ), |
731 | ), | 673 | edit: TextEdit { |
732 | edit: TextEdit { | 674 | indels: [ |
733 | indels: [ | 675 | Indel { |
734 | Indel { | 676 | insert: "quux", |
735 | insert: "qux", | 677 | delete: 11..14, |
736 | delete: 11..14, | 678 | }, |
737 | }, | 679 | ], |
738 | ], | 680 | }, |
739 | }, | 681 | }, |
740 | }, | 682 | ], |
741 | ], | 683 | file_system_edits: [ |
742 | file_system_edits: [ | 684 | MoveFile { |
743 | MoveFile { | 685 | src: FileId( |
744 | src: FileId( | 686 | 2, |
745 | 2, | 687 | ), |
746 | ), | 688 | anchor: FileId( |
747 | anchor: FileId( | 689 | 2, |
748 | 3, | 690 | ), |
749 | ), | 691 | dst: "quux.rs", |
750 | dst: "qux.rs", | 692 | }, |
751 | }, | 693 | ], |
752 | ], | 694 | is_snippet: false, |
753 | is_snippet: false, | 695 | }, |
754 | }, | 696 | } |
755 | }, | 697 | "#]], |
756 | ) | 698 | ); |
757 | "###); | ||
758 | } | 699 | } |
759 | 700 | ||
760 | #[test] | 701 | #[test] |
761 | fn test_rename_mod_in_dir() { | 702 | fn test_rename_mod_in_dir() { |
762 | let (analysis, position) = analysis_and_position( | 703 | check_expect( |
704 | "foo2", | ||
763 | r#" | 705 | r#" |
764 | //- /lib.rs | 706 | //- /lib.rs |
765 | mod fo<|>o; | 707 | mod fo<|>o; |
766 | //- /foo/mod.rs | 708 | //- /foo/mod.rs |
767 | // emtpy | 709 | // emtpy |
768 | "#, | 710 | "#, |
769 | ); | 711 | expect![[r#" |
770 | let new_name = "foo2"; | 712 | RangeInfo { |
771 | let source_change = analysis.rename(position, new_name).unwrap(); | 713 | range: 4..7, |
772 | assert_debug_snapshot!(&source_change, | 714 | info: SourceChange { |
773 | @r###" | 715 | source_file_edits: [ |
774 | Some( | 716 | SourceFileEdit { |
775 | RangeInfo { | 717 | file_id: FileId( |
776 | range: 4..7, | 718 | 1, |
777 | info: SourceChange { | 719 | ), |
778 | source_file_edits: [ | 720 | edit: TextEdit { |
779 | SourceFileEdit { | 721 | indels: [ |
780 | file_id: FileId( | 722 | Indel { |
781 | 1, | 723 | insert: "foo2", |
782 | ), | 724 | delete: 4..7, |
783 | edit: TextEdit { | 725 | }, |
784 | indels: [ | 726 | ], |
785 | Indel { | 727 | }, |
786 | insert: "foo2", | ||
787 | delete: 4..7, | ||
788 | }, | ||
789 | ], | ||
790 | }, | 728 | }, |
791 | }, | 729 | ], |
792 | ], | 730 | file_system_edits: [ |
793 | file_system_edits: [ | 731 | MoveFile { |
794 | MoveFile { | 732 | src: FileId( |
795 | src: FileId( | 733 | 2, |
796 | 2, | 734 | ), |
797 | ), | 735 | anchor: FileId( |
798 | anchor: FileId( | 736 | 2, |
799 | 1, | 737 | ), |
800 | ), | 738 | dst: "../foo2/mod.rs", |
801 | dst: "../foo2/mod.rs", | 739 | }, |
802 | }, | 740 | ], |
803 | ], | 741 | is_snippet: false, |
804 | is_snippet: false, | 742 | }, |
805 | }, | 743 | } |
806 | }, | 744 | "#]], |
807 | ) | 745 | ); |
808 | "### | ||
809 | ); | ||
810 | } | 746 | } |
811 | 747 | ||
812 | #[test] | 748 | #[test] |
813 | fn test_module_rename_in_path() { | 749 | fn test_rename_unusually_nested_mod() { |
814 | test_rename( | 750 | check_expect( |
751 | "bar", | ||
815 | r#" | 752 | r#" |
816 | mod <|>foo { | 753 | //- /lib.rs |
817 | pub fn bar() {} | 754 | mod outer { mod fo<|>o; } |
755 | |||
756 | //- /outer/foo.rs | ||
757 | // emtpy | ||
758 | "#, | ||
759 | expect![[r#" | ||
760 | RangeInfo { | ||
761 | range: 16..19, | ||
762 | info: SourceChange { | ||
763 | source_file_edits: [ | ||
764 | SourceFileEdit { | ||
765 | file_id: FileId( | ||
766 | 1, | ||
767 | ), | ||
768 | edit: TextEdit { | ||
769 | indels: [ | ||
770 | Indel { | ||
771 | insert: "bar", | ||
772 | delete: 16..19, | ||
773 | }, | ||
774 | ], | ||
775 | }, | ||
776 | }, | ||
777 | ], | ||
778 | file_system_edits: [ | ||
779 | MoveFile { | ||
780 | src: FileId( | ||
781 | 2, | ||
782 | ), | ||
783 | anchor: FileId( | ||
784 | 2, | ||
785 | ), | ||
786 | dst: "bar.rs", | ||
787 | }, | ||
788 | ], | ||
789 | is_snippet: false, | ||
790 | }, | ||
791 | } | ||
792 | "#]], | ||
793 | ); | ||
818 | } | 794 | } |
819 | 795 | ||
820 | fn main() { | 796 | #[test] |
821 | foo::bar(); | 797 | fn test_module_rename_in_path() { |
822 | }"#, | 798 | check( |
823 | "baz", | 799 | "baz", |
824 | r#" | 800 | r#" |
825 | mod baz { | 801 | mod <|>foo { pub fn bar() {} } |
826 | pub fn bar() {} | ||
827 | } | ||
828 | 802 | ||
829 | fn main() { | 803 | fn main() { foo::bar(); } |
830 | baz::bar(); | 804 | "#, |
831 | }"#, | 805 | r#" |
806 | mod baz { pub fn bar() {} } | ||
807 | |||
808 | fn main() { baz::bar(); } | ||
809 | "#, | ||
832 | ); | 810 | ); |
833 | } | 811 | } |
834 | 812 | ||
835 | #[test] | 813 | #[test] |
836 | fn test_rename_mod_filename_and_path() { | 814 | fn test_rename_mod_filename_and_path() { |
837 | let (analysis, position) = analysis_and_position( | 815 | check_expect( |
816 | "foo2", | ||
838 | r#" | 817 | r#" |
839 | //- /lib.rs | 818 | //- /lib.rs |
840 | mod bar; | 819 | mod bar; |
@@ -847,229 +826,185 @@ pub mod foo<|>; | |||
847 | 826 | ||
848 | //- /bar/foo.rs | 827 | //- /bar/foo.rs |
849 | // pub fn fun() {} | 828 | // pub fn fun() {} |
850 | "#, | 829 | "#, |
851 | ); | 830 | expect![[r#" |
852 | let new_name = "foo2"; | 831 | RangeInfo { |
853 | let source_change = analysis.rename(position, new_name).unwrap(); | 832 | range: 8..11, |
854 | assert_debug_snapshot!(&source_change, | 833 | info: SourceChange { |
855 | @r###" | 834 | source_file_edits: [ |
856 | Some( | 835 | SourceFileEdit { |
857 | RangeInfo { | 836 | file_id: FileId( |
858 | range: 8..11, | 837 | 2, |
859 | info: SourceChange { | 838 | ), |
860 | source_file_edits: [ | 839 | edit: TextEdit { |
861 | SourceFileEdit { | 840 | indels: [ |
862 | file_id: FileId( | 841 | Indel { |
863 | 2, | 842 | insert: "foo2", |
864 | ), | 843 | delete: 8..11, |
865 | edit: TextEdit { | 844 | }, |
866 | indels: [ | 845 | ], |
867 | Indel { | 846 | }, |
868 | insert: "foo2", | ||
869 | delete: 8..11, | ||
870 | }, | ||
871 | ], | ||
872 | }, | 847 | }, |
873 | }, | 848 | SourceFileEdit { |
874 | SourceFileEdit { | 849 | file_id: FileId( |
875 | file_id: FileId( | 850 | 1, |
876 | 1, | 851 | ), |
877 | ), | 852 | edit: TextEdit { |
878 | edit: TextEdit { | 853 | indels: [ |
879 | indels: [ | 854 | Indel { |
880 | Indel { | 855 | insert: "foo2", |
881 | insert: "foo2", | 856 | delete: 27..30, |
882 | delete: 27..30, | 857 | }, |
883 | }, | 858 | ], |
884 | ], | 859 | }, |
885 | }, | 860 | }, |
886 | }, | 861 | ], |
887 | ], | 862 | file_system_edits: [ |
888 | file_system_edits: [ | 863 | MoveFile { |
889 | MoveFile { | 864 | src: FileId( |
890 | src: FileId( | 865 | 3, |
891 | 3, | 866 | ), |
892 | ), | 867 | anchor: FileId( |
893 | anchor: FileId( | 868 | 3, |
894 | 2, | 869 | ), |
895 | ), | 870 | dst: "foo2.rs", |
896 | dst: "foo2.rs", | 871 | }, |
897 | }, | 872 | ], |
898 | ], | 873 | is_snippet: false, |
899 | is_snippet: false, | 874 | }, |
900 | }, | 875 | } |
901 | }, | 876 | "#]], |
902 | ) | 877 | ); |
903 | "###); | ||
904 | } | 878 | } |
905 | 879 | ||
906 | #[test] | 880 | #[test] |
907 | fn test_enum_variant_from_module_1() { | 881 | fn test_enum_variant_from_module_1() { |
908 | test_rename( | 882 | check( |
883 | "Baz", | ||
909 | r#" | 884 | r#" |
910 | mod foo { | 885 | mod foo { |
911 | pub enum Foo { | 886 | pub enum Foo { Bar<|> } |
912 | Bar<|>, | 887 | } |
913 | } | ||
914 | } | ||
915 | 888 | ||
916 | fn func(f: foo::Foo) { | 889 | fn func(f: foo::Foo) { |
917 | match f { | 890 | match f { |
918 | foo::Foo::Bar => {} | 891 | foo::Foo::Bar => {} |
919 | } | ||
920 | } | 892 | } |
921 | "#, | 893 | } |
922 | "Baz", | 894 | "#, |
923 | r#" | 895 | r#" |
924 | mod foo { | 896 | mod foo { |
925 | pub enum Foo { | 897 | pub enum Foo { Baz } |
926 | Baz, | 898 | } |
927 | } | ||
928 | } | ||
929 | 899 | ||
930 | fn func(f: foo::Foo) { | 900 | fn func(f: foo::Foo) { |
931 | match f { | 901 | match f { |
932 | foo::Foo::Baz => {} | 902 | foo::Foo::Baz => {} |
933 | } | ||
934 | } | 903 | } |
935 | "#, | 904 | } |
905 | "#, | ||
936 | ); | 906 | ); |
937 | } | 907 | } |
938 | 908 | ||
939 | #[test] | 909 | #[test] |
940 | fn test_enum_variant_from_module_2() { | 910 | fn test_enum_variant_from_module_2() { |
941 | test_rename( | 911 | check( |
912 | "baz", | ||
942 | r#" | 913 | r#" |
943 | mod foo { | 914 | mod foo { |
944 | pub struct Foo { | 915 | pub struct Foo { pub bar<|>: uint } |
945 | pub bar<|>: uint, | 916 | } |
946 | } | ||
947 | } | ||
948 | 917 | ||
949 | fn foo(f: foo::Foo) { | 918 | fn foo(f: foo::Foo) { |
950 | let _ = f.bar; | 919 | let _ = f.bar; |
951 | } | 920 | } |
952 | "#, | 921 | "#, |
953 | "baz", | ||
954 | r#" | 922 | r#" |
955 | mod foo { | 923 | mod foo { |
956 | pub struct Foo { | 924 | pub struct Foo { pub baz: uint } |
957 | pub baz: uint, | 925 | } |
958 | } | ||
959 | } | ||
960 | 926 | ||
961 | fn foo(f: foo::Foo) { | 927 | fn foo(f: foo::Foo) { |
962 | let _ = f.baz; | 928 | let _ = f.baz; |
963 | } | 929 | } |
964 | "#, | 930 | "#, |
965 | ); | 931 | ); |
966 | } | 932 | } |
967 | 933 | ||
968 | #[test] | 934 | #[test] |
969 | fn test_parameter_to_self() { | 935 | fn test_parameter_to_self() { |
970 | test_rename( | 936 | check( |
937 | "self", | ||
971 | r#" | 938 | r#" |
972 | struct Foo { | 939 | struct Foo { i: i32 } |
973 | i: i32, | ||
974 | } | ||
975 | 940 | ||
976 | impl Foo { | 941 | impl Foo { |
977 | fn f(foo<|>: &mut Foo) -> i32 { | 942 | fn f(foo<|>: &mut Foo) -> i32 { |
978 | foo.i | 943 | foo.i |
979 | } | ||
980 | } | 944 | } |
981 | "#, | 945 | } |
982 | "self", | 946 | "#, |
983 | r#" | 947 | r#" |
984 | struct Foo { | 948 | struct Foo { i: i32 } |
985 | i: i32, | ||
986 | } | ||
987 | 949 | ||
988 | impl Foo { | 950 | impl Foo { |
989 | fn f(&mut self) -> i32 { | 951 | fn f(&mut self) -> i32 { |
990 | self.i | 952 | self.i |
991 | } | ||
992 | } | 953 | } |
993 | "#, | 954 | } |
955 | "#, | ||
994 | ); | 956 | ); |
995 | } | 957 | } |
996 | 958 | ||
997 | #[test] | 959 | #[test] |
998 | fn test_self_to_parameter() { | 960 | fn test_self_to_parameter() { |
999 | test_rename( | 961 | check( |
962 | "foo", | ||
1000 | r#" | 963 | r#" |
1001 | struct Foo { | 964 | struct Foo { i: i32 } |
1002 | i: i32, | ||
1003 | } | ||
1004 | 965 | ||
1005 | impl Foo { | 966 | impl Foo { |
1006 | fn f(&mut <|>self) -> i32 { | 967 | fn f(&mut <|>self) -> i32 { |
1007 | self.i | 968 | self.i |
1008 | } | ||
1009 | } | 969 | } |
1010 | "#, | 970 | } |
1011 | "foo", | 971 | "#, |
1012 | r#" | 972 | r#" |
1013 | struct Foo { | 973 | struct Foo { i: i32 } |
1014 | i: i32, | ||
1015 | } | ||
1016 | 974 | ||
1017 | impl Foo { | 975 | impl Foo { |
1018 | fn f(foo: &mut Foo) -> i32 { | 976 | fn f(foo: &mut Foo) -> i32 { |
1019 | foo.i | 977 | foo.i |
1020 | } | ||
1021 | } | 978 | } |
1022 | "#, | 979 | } |
980 | "#, | ||
1023 | ); | 981 | ); |
1024 | } | 982 | } |
1025 | 983 | ||
1026 | #[test] | 984 | #[test] |
1027 | fn test_self_in_path_to_parameter() { | 985 | fn test_self_in_path_to_parameter() { |
1028 | test_rename( | 986 | check( |
987 | "foo", | ||
1029 | r#" | 988 | r#" |
1030 | struct Foo { | 989 | struct Foo { i: i32 } |
1031 | i: i32, | ||
1032 | } | ||
1033 | 990 | ||
1034 | impl Foo { | 991 | impl Foo { |
1035 | fn f(&self) -> i32 { | 992 | fn f(&self) -> i32 { |
1036 | let self_var = 1; | 993 | let self_var = 1; |
1037 | self<|>.i | 994 | self<|>.i |
1038 | } | ||
1039 | } | 995 | } |
1040 | "#, | 996 | } |
1041 | "foo", | 997 | "#, |
1042 | r#" | 998 | r#" |
1043 | struct Foo { | 999 | struct Foo { i: i32 } |
1044 | i: i32, | ||
1045 | } | ||
1046 | 1000 | ||
1047 | impl Foo { | 1001 | impl Foo { |
1048 | fn f(foo: &Foo) -> i32 { | 1002 | fn f(foo: &Foo) -> i32 { |
1049 | let self_var = 1; | 1003 | let self_var = 1; |
1050 | foo.i | 1004 | foo.i |
1051 | } | ||
1052 | } | 1005 | } |
1053 | "#, | 1006 | } |
1007 | "#, | ||
1054 | ); | 1008 | ); |
1055 | } | 1009 | } |
1056 | |||
1057 | fn test_rename(ra_fixture_before: &str, new_name: &str, ra_fixture_after: &str) { | ||
1058 | let ra_fixture_after = &trim_indent(ra_fixture_after); | ||
1059 | let (analysis, position) = analysis_and_position(ra_fixture_before); | ||
1060 | let source_change = analysis.rename(position, new_name).unwrap(); | ||
1061 | let mut text_edit_builder = TextEditBuilder::default(); | ||
1062 | let mut file_id: Option<FileId> = None; | ||
1063 | if let Some(change) = source_change { | ||
1064 | for edit in change.info.source_file_edits { | ||
1065 | file_id = Some(edit.file_id); | ||
1066 | for indel in edit.edit.into_iter() { | ||
1067 | text_edit_builder.replace(indel.delete, indel.insert); | ||
1068 | } | ||
1069 | } | ||
1070 | } | ||
1071 | let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string(); | ||
1072 | text_edit_builder.finish().apply(&mut result); | ||
1073 | assert_eq_text!(ra_fixture_after, &*result); | ||
1074 | } | ||
1075 | } | 1010 | } |