diff options
-rw-r--r-- | crates/ide/src/annotations.rs | 895 |
1 files changed, 707 insertions, 188 deletions
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs index 43250bf5d..414a60bed 100644 --- a/crates/ide/src/annotations.rs +++ b/crates/ide/src/annotations.rs | |||
@@ -154,103 +154,143 @@ fn should_skip_runnable(kind: &RunnableKind, binary_target: bool) -> bool { | |||
154 | 154 | ||
155 | #[cfg(test)] | 155 | #[cfg(test)] |
156 | mod tests { | 156 | mod tests { |
157 | use ide_db::base_db::{FileId, FileRange}; | 157 | use expect_test::{expect, Expect}; |
158 | use syntax::{TextRange, TextSize}; | ||
159 | 158 | ||
160 | use crate::{fixture, Annotation, AnnotationConfig, AnnotationKind, RunnableKind}; | 159 | use crate::{fixture, Annotation, AnnotationConfig}; |
161 | 160 | ||
162 | fn get_annotations( | 161 | fn check(ra_fixture: &str, expect: Expect) { |
163 | ra_fixture: &str, | ||
164 | annotation_config: AnnotationConfig, | ||
165 | ) -> (FileId, Vec<Annotation>) { | ||
166 | let (analysis, file_id) = fixture::file(ra_fixture); | 162 | let (analysis, file_id) = fixture::file(ra_fixture); |
167 | 163 | ||
168 | let annotations: Vec<Annotation> = analysis | 164 | let annotations: Vec<Annotation> = analysis |
169 | .annotations(file_id, annotation_config) | 165 | .annotations( |
166 | file_id, | ||
167 | AnnotationConfig { | ||
168 | binary_target: true, | ||
169 | annotate_runnables: true, | ||
170 | annotate_impls: true, | ||
171 | annotate_references: true, | ||
172 | annotate_method_references: true, | ||
173 | run: true, | ||
174 | debug: true, | ||
175 | }, | ||
176 | ) | ||
170 | .unwrap() | 177 | .unwrap() |
171 | .into_iter() | 178 | .into_iter() |
172 | .map(move |annotation| analysis.resolve_annotation(annotation).unwrap()) | 179 | .map(|annotation| analysis.resolve_annotation(annotation).unwrap()) |
173 | .collect(); | 180 | .collect(); |
174 | 181 | ||
175 | if annotations.len() == 0 { | 182 | expect.assert_debug_eq(&annotations); |
176 | panic!("unresolved annotations") | ||
177 | } | ||
178 | |||
179 | (file_id, annotations) | ||
180 | } | ||
181 | |||
182 | macro_rules! check_annotation { | ||
183 | ( $ra_fixture:expr, $config:expr, $item_positions:expr, $pattern:pat, $checker:expr ) => { | ||
184 | let (file_id, annotations) = get_annotations($ra_fixture, $config); | ||
185 | |||
186 | annotations.into_iter().for_each(|annotation| { | ||
187 | assert!($item_positions.contains(&annotation.range)); | ||
188 | |||
189 | match annotation.kind { | ||
190 | $pattern => $checker(file_id), | ||
191 | _ => panic!("Unexpected annotation kind"), | ||
192 | } | ||
193 | }); | ||
194 | }; | ||
195 | } | 183 | } |
196 | 184 | ||
197 | #[test] | 185 | #[test] |
198 | fn const_annotations() { | 186 | fn const_annotations() { |
199 | check_annotation!( | 187 | check( |
200 | r#" | 188 | r#" |
201 | const DEMO: i32 = 123; | 189 | const DEMO: i32 = 123; |
202 | 190 | ||
191 | const UNUSED: i32 = 123; | ||
192 | |||
203 | fn main() { | 193 | fn main() { |
204 | let hello = DEMO; | 194 | let hello = DEMO; |
205 | } | 195 | } |
206 | "#, | 196 | "#, |
207 | AnnotationConfig { | 197 | expect![[r#" |
208 | binary_target: false, | 198 | [ |
209 | annotate_runnables: false, | 199 | Annotation { |
210 | annotate_impls: false, | 200 | range: 50..85, |
211 | annotate_references: true, | 201 | kind: Runnable { |
212 | annotate_method_references: false, | 202 | debug: true, |
213 | run: false, | 203 | runnable: Runnable { |
214 | debug: false, | 204 | nav: NavigationTarget { |
215 | }, | 205 | file_id: FileId( |
216 | &[TextRange::new(TextSize::from(0), TextSize::from(22))], | 206 | 0, |
217 | AnnotationKind::HasReferences { data: Some(ranges), .. }, | 207 | ), |
218 | |file_id| assert_eq!( | 208 | full_range: 50..85, |
219 | *ranges.first().unwrap(), | 209 | focus_range: 53..57, |
220 | FileRange { | 210 | name: "main", |
221 | file_id, | 211 | kind: Function, |
222 | range: TextRange::new(TextSize::from(52), TextSize::from(56)) | 212 | }, |
223 | } | 213 | kind: Bin, |
224 | ) | 214 | cfg: None, |
225 | ); | 215 | }, |
226 | } | 216 | }, |
227 | 217 | }, | |
228 | #[test] | 218 | Annotation { |
229 | fn unused_const_annotations() { | 219 | range: 50..85, |
230 | check_annotation!( | 220 | kind: Runnable { |
231 | r#" | 221 | debug: false, |
232 | const DEMO: i32 = 123; | 222 | runnable: Runnable { |
233 | 223 | nav: NavigationTarget { | |
234 | fn main() {} | 224 | file_id: FileId( |
235 | "#, | 225 | 0, |
236 | AnnotationConfig { | 226 | ), |
237 | binary_target: false, | 227 | full_range: 50..85, |
238 | annotate_runnables: false, | 228 | focus_range: 53..57, |
239 | annotate_impls: false, | 229 | name: "main", |
240 | annotate_references: true, | 230 | kind: Function, |
241 | annotate_method_references: false, | 231 | }, |
242 | run: false, | 232 | kind: Bin, |
243 | debug: false, | 233 | cfg: None, |
244 | }, | 234 | }, |
245 | &[TextRange::new(TextSize::from(0), TextSize::from(22))], | 235 | }, |
246 | AnnotationKind::HasReferences { data: Some(ranges), .. }, | 236 | }, |
247 | |_| assert_eq!(ranges.len(), 0) | 237 | Annotation { |
238 | range: 0..22, | ||
239 | kind: HasReferences { | ||
240 | position: FilePosition { | ||
241 | file_id: FileId( | ||
242 | 0, | ||
243 | ), | ||
244 | offset: 6, | ||
245 | }, | ||
246 | data: Some( | ||
247 | [ | ||
248 | FileRange { | ||
249 | file_id: FileId( | ||
250 | 0, | ||
251 | ), | ||
252 | range: 78..82, | ||
253 | }, | ||
254 | ], | ||
255 | ), | ||
256 | }, | ||
257 | }, | ||
258 | Annotation { | ||
259 | range: 24..48, | ||
260 | kind: HasReferences { | ||
261 | position: FilePosition { | ||
262 | file_id: FileId( | ||
263 | 0, | ||
264 | ), | ||
265 | offset: 30, | ||
266 | }, | ||
267 | data: Some( | ||
268 | [], | ||
269 | ), | ||
270 | }, | ||
271 | }, | ||
272 | Annotation { | ||
273 | range: 53..57, | ||
274 | kind: HasReferences { | ||
275 | position: FilePosition { | ||
276 | file_id: FileId( | ||
277 | 0, | ||
278 | ), | ||
279 | offset: 53, | ||
280 | }, | ||
281 | data: Some( | ||
282 | [], | ||
283 | ), | ||
284 | }, | ||
285 | }, | ||
286 | ] | ||
287 | "#]], | ||
248 | ); | 288 | ); |
249 | } | 289 | } |
250 | 290 | ||
251 | #[test] | 291 | #[test] |
252 | fn struct_references_annotations() { | 292 | fn struct_references_annotations() { |
253 | check_annotation!( | 293 | check( |
254 | r#" | 294 | r#" |
255 | struct Test; | 295 | struct Test; |
256 | 296 | ||
@@ -258,30 +298,103 @@ fn main() { | |||
258 | let test = Test; | 298 | let test = Test; |
259 | } | 299 | } |
260 | "#, | 300 | "#, |
261 | AnnotationConfig { | 301 | expect![[r#" |
262 | binary_target: false, | 302 | [ |
263 | annotate_runnables: false, | 303 | Annotation { |
264 | annotate_impls: false, | 304 | range: 14..48, |
265 | annotate_references: true, | 305 | kind: Runnable { |
266 | annotate_method_references: false, | 306 | debug: true, |
267 | run: false, | 307 | runnable: Runnable { |
268 | debug: false, | 308 | nav: NavigationTarget { |
269 | }, | 309 | file_id: FileId( |
270 | &[TextRange::new(TextSize::from(0), TextSize::from(12))], | 310 | 0, |
271 | AnnotationKind::HasReferences { data: Some(ranges), .. }, | 311 | ), |
272 | |file_id| assert_eq!( | 312 | full_range: 14..48, |
273 | *ranges.first().unwrap(), | 313 | focus_range: 17..21, |
274 | FileRange { | 314 | name: "main", |
275 | file_id, | 315 | kind: Function, |
276 | range: TextRange::new(TextSize::from(41), TextSize::from(45)) | 316 | }, |
277 | } | 317 | kind: Bin, |
278 | ) | 318 | cfg: None, |
319 | }, | ||
320 | }, | ||
321 | }, | ||
322 | Annotation { | ||
323 | range: 14..48, | ||
324 | kind: Runnable { | ||
325 | debug: false, | ||
326 | runnable: Runnable { | ||
327 | nav: NavigationTarget { | ||
328 | file_id: FileId( | ||
329 | 0, | ||
330 | ), | ||
331 | full_range: 14..48, | ||
332 | focus_range: 17..21, | ||
333 | name: "main", | ||
334 | kind: Function, | ||
335 | }, | ||
336 | kind: Bin, | ||
337 | cfg: None, | ||
338 | }, | ||
339 | }, | ||
340 | }, | ||
341 | Annotation { | ||
342 | range: 0..12, | ||
343 | kind: HasImpls { | ||
344 | position: FilePosition { | ||
345 | file_id: FileId( | ||
346 | 0, | ||
347 | ), | ||
348 | offset: 7, | ||
349 | }, | ||
350 | data: Some( | ||
351 | [], | ||
352 | ), | ||
353 | }, | ||
354 | }, | ||
355 | Annotation { | ||
356 | range: 0..12, | ||
357 | kind: HasReferences { | ||
358 | position: FilePosition { | ||
359 | file_id: FileId( | ||
360 | 0, | ||
361 | ), | ||
362 | offset: 7, | ||
363 | }, | ||
364 | data: Some( | ||
365 | [ | ||
366 | FileRange { | ||
367 | file_id: FileId( | ||
368 | 0, | ||
369 | ), | ||
370 | range: 41..45, | ||
371 | }, | ||
372 | ], | ||
373 | ), | ||
374 | }, | ||
375 | }, | ||
376 | Annotation { | ||
377 | range: 17..21, | ||
378 | kind: HasReferences { | ||
379 | position: FilePosition { | ||
380 | file_id: FileId( | ||
381 | 0, | ||
382 | ), | ||
383 | offset: 17, | ||
384 | }, | ||
385 | data: Some( | ||
386 | [], | ||
387 | ), | ||
388 | }, | ||
389 | }, | ||
390 | ] | ||
391 | "#]], | ||
279 | ); | 392 | ); |
280 | } | 393 | } |
281 | 394 | ||
282 | #[test] | 395 | #[test] |
283 | fn struct_and_trait_impls_annotations() { | 396 | fn struct_and_trait_impls_annotations() { |
284 | check_annotation!( | 397 | check( |
285 | r#" | 398 | r#" |
286 | struct Test; | 399 | struct Test; |
287 | 400 | ||
@@ -293,84 +406,229 @@ fn main() { | |||
293 | let test = Test; | 406 | let test = Test; |
294 | } | 407 | } |
295 | "#, | 408 | "#, |
296 | AnnotationConfig { | 409 | expect![[r#" |
297 | binary_target: false, | 410 | [ |
298 | annotate_runnables: false, | 411 | Annotation { |
299 | annotate_impls: true, | 412 | range: 66..100, |
300 | annotate_references: false, | 413 | kind: Runnable { |
301 | annotate_method_references: false, | 414 | debug: true, |
302 | run: false, | 415 | runnable: Runnable { |
303 | debug: false, | 416 | nav: NavigationTarget { |
304 | }, | 417 | file_id: FileId( |
305 | &[ | 418 | 0, |
306 | TextRange::new(TextSize::from(0), TextSize::from(12)), | 419 | ), |
307 | TextRange::new(TextSize::from(14), TextSize::from(34)) | 420 | full_range: 66..100, |
308 | ], | 421 | focus_range: 69..73, |
309 | AnnotationKind::HasImpls { data: Some(ranges), .. }, | 422 | name: "main", |
310 | |_| assert_eq!( | 423 | kind: Function, |
311 | ranges.first().unwrap().full_range, | 424 | }, |
312 | TextRange::new(TextSize::from(36), TextSize::from(64)) | 425 | kind: Bin, |
313 | ) | 426 | cfg: None, |
314 | ); | 427 | }, |
315 | } | 428 | }, |
316 | 429 | }, | |
317 | #[test] | 430 | Annotation { |
318 | fn run_annotation() { | 431 | range: 66..100, |
319 | check_annotation!( | 432 | kind: Runnable { |
320 | r#" | 433 | debug: false, |
321 | fn main() {} | 434 | runnable: Runnable { |
322 | "#, | 435 | nav: NavigationTarget { |
323 | AnnotationConfig { | 436 | file_id: FileId( |
324 | binary_target: true, | 437 | 0, |
325 | annotate_runnables: true, | 438 | ), |
326 | annotate_impls: false, | 439 | full_range: 66..100, |
327 | annotate_references: false, | 440 | focus_range: 69..73, |
328 | annotate_method_references: false, | 441 | name: "main", |
329 | run: true, | 442 | kind: Function, |
330 | debug: false, | 443 | }, |
331 | }, | 444 | kind: Bin, |
332 | &[TextRange::new(TextSize::from(0), TextSize::from(12))], | 445 | cfg: None, |
333 | AnnotationKind::Runnable { debug: false, runnable }, | 446 | }, |
334 | |_| { | 447 | }, |
335 | assert!(matches!(runnable.kind, RunnableKind::Bin)); | 448 | }, |
336 | assert!(runnable.action().run_title.contains("Run")); | 449 | Annotation { |
337 | } | 450 | range: 0..12, |
451 | kind: HasImpls { | ||
452 | position: FilePosition { | ||
453 | file_id: FileId( | ||
454 | 0, | ||
455 | ), | ||
456 | offset: 7, | ||
457 | }, | ||
458 | data: Some( | ||
459 | [ | ||
460 | NavigationTarget { | ||
461 | file_id: FileId( | ||
462 | 0, | ||
463 | ), | ||
464 | full_range: 36..64, | ||
465 | focus_range: 57..61, | ||
466 | name: "impl", | ||
467 | kind: Impl, | ||
468 | }, | ||
469 | ], | ||
470 | ), | ||
471 | }, | ||
472 | }, | ||
473 | Annotation { | ||
474 | range: 0..12, | ||
475 | kind: HasReferences { | ||
476 | position: FilePosition { | ||
477 | file_id: FileId( | ||
478 | 0, | ||
479 | ), | ||
480 | offset: 7, | ||
481 | }, | ||
482 | data: Some( | ||
483 | [ | ||
484 | FileRange { | ||
485 | file_id: FileId( | ||
486 | 0, | ||
487 | ), | ||
488 | range: 57..61, | ||
489 | }, | ||
490 | FileRange { | ||
491 | file_id: FileId( | ||
492 | 0, | ||
493 | ), | ||
494 | range: 93..97, | ||
495 | }, | ||
496 | ], | ||
497 | ), | ||
498 | }, | ||
499 | }, | ||
500 | Annotation { | ||
501 | range: 14..34, | ||
502 | kind: HasImpls { | ||
503 | position: FilePosition { | ||
504 | file_id: FileId( | ||
505 | 0, | ||
506 | ), | ||
507 | offset: 20, | ||
508 | }, | ||
509 | data: Some( | ||
510 | [ | ||
511 | NavigationTarget { | ||
512 | file_id: FileId( | ||
513 | 0, | ||
514 | ), | ||
515 | full_range: 36..64, | ||
516 | focus_range: 57..61, | ||
517 | name: "impl", | ||
518 | kind: Impl, | ||
519 | }, | ||
520 | ], | ||
521 | ), | ||
522 | }, | ||
523 | }, | ||
524 | Annotation { | ||
525 | range: 14..34, | ||
526 | kind: HasReferences { | ||
527 | position: FilePosition { | ||
528 | file_id: FileId( | ||
529 | 0, | ||
530 | ), | ||
531 | offset: 20, | ||
532 | }, | ||
533 | data: Some( | ||
534 | [ | ||
535 | FileRange { | ||
536 | file_id: FileId( | ||
537 | 0, | ||
538 | ), | ||
539 | range: 41..52, | ||
540 | }, | ||
541 | ], | ||
542 | ), | ||
543 | }, | ||
544 | }, | ||
545 | Annotation { | ||
546 | range: 69..73, | ||
547 | kind: HasReferences { | ||
548 | position: FilePosition { | ||
549 | file_id: FileId( | ||
550 | 0, | ||
551 | ), | ||
552 | offset: 69, | ||
553 | }, | ||
554 | data: Some( | ||
555 | [], | ||
556 | ), | ||
557 | }, | ||
558 | }, | ||
559 | ] | ||
560 | "#]], | ||
338 | ); | 561 | ); |
339 | } | 562 | } |
340 | 563 | ||
341 | #[test] | 564 | #[test] |
342 | fn debug_annotation() { | 565 | fn runnable_annotation() { |
343 | check_annotation!( | 566 | check( |
344 | r#" | 567 | r#" |
345 | fn main() {} | 568 | fn main() {} |
346 | "#, | 569 | "#, |
347 | AnnotationConfig { | 570 | expect![[r#" |
348 | binary_target: true, | 571 | [ |
349 | annotate_runnables: true, | 572 | Annotation { |
350 | annotate_impls: false, | 573 | range: 0..12, |
351 | annotate_references: false, | 574 | kind: Runnable { |
352 | annotate_method_references: false, | 575 | debug: true, |
353 | run: false, | 576 | runnable: Runnable { |
354 | debug: true, | 577 | nav: NavigationTarget { |
355 | }, | 578 | file_id: FileId( |
356 | &[TextRange::new(TextSize::from(0), TextSize::from(12))], | 579 | 0, |
357 | AnnotationKind::Runnable { debug: true, runnable }, | 580 | ), |
358 | |_| { | 581 | full_range: 0..12, |
359 | assert!(matches!(runnable.kind, RunnableKind::Bin)); | 582 | focus_range: 3..7, |
360 | assert!(runnable.action().debugee); | 583 | name: "main", |
361 | } | 584 | kind: Function, |
585 | }, | ||
586 | kind: Bin, | ||
587 | cfg: None, | ||
588 | }, | ||
589 | }, | ||
590 | }, | ||
591 | Annotation { | ||
592 | range: 0..12, | ||
593 | kind: Runnable { | ||
594 | debug: false, | ||
595 | runnable: Runnable { | ||
596 | nav: NavigationTarget { | ||
597 | file_id: FileId( | ||
598 | 0, | ||
599 | ), | ||
600 | full_range: 0..12, | ||
601 | focus_range: 3..7, | ||
602 | name: "main", | ||
603 | kind: Function, | ||
604 | }, | ||
605 | kind: Bin, | ||
606 | cfg: None, | ||
607 | }, | ||
608 | }, | ||
609 | }, | ||
610 | Annotation { | ||
611 | range: 3..7, | ||
612 | kind: HasReferences { | ||
613 | position: FilePosition { | ||
614 | file_id: FileId( | ||
615 | 0, | ||
616 | ), | ||
617 | offset: 3, | ||
618 | }, | ||
619 | data: Some( | ||
620 | [], | ||
621 | ), | ||
622 | }, | ||
623 | }, | ||
624 | ] | ||
625 | "#]], | ||
362 | ); | 626 | ); |
363 | } | 627 | } |
364 | 628 | ||
365 | #[test] | 629 | #[test] |
366 | fn method_annotations() { | 630 | fn method_annotations() { |
367 | // We actually want to skip `fn main` annotation, as it has no references in it | 631 | check( |
368 | // but just ignoring empty reference slices would lead to false-positive if something | ||
369 | // goes wrong in annotation resolving mechanism. By tracking if we iterated before finding | ||
370 | // an empty slice we can track if everything is settled. | ||
371 | let mut iterated_once = false; | ||
372 | |||
373 | check_annotation!( | ||
374 | r#" | 632 | r#" |
375 | struct Test; | 633 | struct Test; |
376 | 634 | ||
@@ -382,37 +640,298 @@ fn main() { | |||
382 | Test.self_by_ref(); | 640 | Test.self_by_ref(); |
383 | } | 641 | } |
384 | "#, | 642 | "#, |
385 | AnnotationConfig { | 643 | expect![[r#" |
386 | binary_target: false, | 644 | [ |
387 | annotate_runnables: false, | 645 | Annotation { |
388 | annotate_impls: false, | 646 | range: 58..95, |
389 | annotate_references: false, | 647 | kind: Runnable { |
390 | annotate_method_references: true, | 648 | debug: true, |
391 | run: false, | 649 | runnable: Runnable { |
392 | debug: false, | 650 | nav: NavigationTarget { |
393 | }, | 651 | file_id: FileId( |
394 | &[ | 652 | 0, |
395 | TextRange::new(TextSize::from(33), TextSize::from(44)), | 653 | ), |
396 | TextRange::new(TextSize::from(61), TextSize::from(65)) | 654 | full_range: 58..95, |
397 | ], | 655 | focus_range: 61..65, |
398 | AnnotationKind::HasReferences { data: Some(ranges), .. }, | 656 | name: "main", |
399 | |file_id| { | 657 | kind: Function, |
400 | match ranges.as_slice() { | 658 | }, |
401 | [first, ..] => { | 659 | kind: Bin, |
402 | assert_eq!( | 660 | cfg: None, |
403 | *first, | 661 | }, |
404 | FileRange { | 662 | }, |
405 | file_id, | 663 | }, |
406 | range: TextRange::new(TextSize::from(79), TextSize::from(90)) | 664 | Annotation { |
407 | } | 665 | range: 58..95, |
408 | ); | 666 | kind: Runnable { |
409 | 667 | debug: false, | |
410 | iterated_once = true; | 668 | runnable: Runnable { |
411 | } | 669 | nav: NavigationTarget { |
412 | [] if iterated_once => {} | 670 | file_id: FileId( |
413 | [] => panic!("One reference was expected but not found"), | 671 | 0, |
414 | } | 672 | ), |
415 | } | 673 | full_range: 58..95, |
674 | focus_range: 61..65, | ||
675 | name: "main", | ||
676 | kind: Function, | ||
677 | }, | ||
678 | kind: Bin, | ||
679 | cfg: None, | ||
680 | }, | ||
681 | }, | ||
682 | }, | ||
683 | Annotation { | ||
684 | range: 0..12, | ||
685 | kind: HasImpls { | ||
686 | position: FilePosition { | ||
687 | file_id: FileId( | ||
688 | 0, | ||
689 | ), | ||
690 | offset: 7, | ||
691 | }, | ||
692 | data: Some( | ||
693 | [ | ||
694 | NavigationTarget { | ||
695 | file_id: FileId( | ||
696 | 0, | ||
697 | ), | ||
698 | full_range: 14..56, | ||
699 | focus_range: 19..23, | ||
700 | name: "impl", | ||
701 | kind: Impl, | ||
702 | }, | ||
703 | ], | ||
704 | ), | ||
705 | }, | ||
706 | }, | ||
707 | Annotation { | ||
708 | range: 0..12, | ||
709 | kind: HasReferences { | ||
710 | position: FilePosition { | ||
711 | file_id: FileId( | ||
712 | 0, | ||
713 | ), | ||
714 | offset: 7, | ||
715 | }, | ||
716 | data: Some( | ||
717 | [ | ||
718 | FileRange { | ||
719 | file_id: FileId( | ||
720 | 0, | ||
721 | ), | ||
722 | range: 19..23, | ||
723 | }, | ||
724 | FileRange { | ||
725 | file_id: FileId( | ||
726 | 0, | ||
727 | ), | ||
728 | range: 74..78, | ||
729 | }, | ||
730 | ], | ||
731 | ), | ||
732 | }, | ||
733 | }, | ||
734 | Annotation { | ||
735 | range: 33..44, | ||
736 | kind: HasReferences { | ||
737 | position: FilePosition { | ||
738 | file_id: FileId( | ||
739 | 0, | ||
740 | ), | ||
741 | offset: 33, | ||
742 | }, | ||
743 | data: Some( | ||
744 | [ | ||
745 | FileRange { | ||
746 | file_id: FileId( | ||
747 | 0, | ||
748 | ), | ||
749 | range: 79..90, | ||
750 | }, | ||
751 | ], | ||
752 | ), | ||
753 | }, | ||
754 | }, | ||
755 | Annotation { | ||
756 | range: 61..65, | ||
757 | kind: HasReferences { | ||
758 | position: FilePosition { | ||
759 | file_id: FileId( | ||
760 | 0, | ||
761 | ), | ||
762 | offset: 61, | ||
763 | }, | ||
764 | data: Some( | ||
765 | [], | ||
766 | ), | ||
767 | }, | ||
768 | }, | ||
769 | ] | ||
770 | "#]], | ||
771 | ); | ||
772 | } | ||
773 | |||
774 | #[test] | ||
775 | fn test_annotations() { | ||
776 | check( | ||
777 | r#" | ||
778 | fn main() {} | ||
779 | |||
780 | mod tests { | ||
781 | #[test] | ||
782 | fn my_cool_test() {} | ||
783 | } | ||
784 | "#, | ||
785 | expect![[r#" | ||
786 | [ | ||
787 | Annotation { | ||
788 | range: 0..12, | ||
789 | kind: Runnable { | ||
790 | debug: true, | ||
791 | runnable: Runnable { | ||
792 | nav: NavigationTarget { | ||
793 | file_id: FileId( | ||
794 | 0, | ||
795 | ), | ||
796 | full_range: 0..12, | ||
797 | focus_range: 3..7, | ||
798 | name: "main", | ||
799 | kind: Function, | ||
800 | }, | ||
801 | kind: Bin, | ||
802 | cfg: None, | ||
803 | }, | ||
804 | }, | ||
805 | }, | ||
806 | Annotation { | ||
807 | range: 0..12, | ||
808 | kind: Runnable { | ||
809 | debug: false, | ||
810 | runnable: Runnable { | ||
811 | nav: NavigationTarget { | ||
812 | file_id: FileId( | ||
813 | 0, | ||
814 | ), | ||
815 | full_range: 0..12, | ||
816 | focus_range: 3..7, | ||
817 | name: "main", | ||
818 | kind: Function, | ||
819 | }, | ||
820 | kind: Bin, | ||
821 | cfg: None, | ||
822 | }, | ||
823 | }, | ||
824 | }, | ||
825 | Annotation { | ||
826 | range: 14..64, | ||
827 | kind: Runnable { | ||
828 | debug: true, | ||
829 | runnable: Runnable { | ||
830 | nav: NavigationTarget { | ||
831 | file_id: FileId( | ||
832 | 0, | ||
833 | ), | ||
834 | full_range: 14..64, | ||
835 | focus_range: 18..23, | ||
836 | name: "tests", | ||
837 | kind: Module, | ||
838 | }, | ||
839 | kind: TestMod { | ||
840 | path: "tests", | ||
841 | }, | ||
842 | cfg: None, | ||
843 | }, | ||
844 | }, | ||
845 | }, | ||
846 | Annotation { | ||
847 | range: 14..64, | ||
848 | kind: Runnable { | ||
849 | debug: false, | ||
850 | runnable: Runnable { | ||
851 | nav: NavigationTarget { | ||
852 | file_id: FileId( | ||
853 | 0, | ||
854 | ), | ||
855 | full_range: 14..64, | ||
856 | focus_range: 18..23, | ||
857 | name: "tests", | ||
858 | kind: Module, | ||
859 | }, | ||
860 | kind: TestMod { | ||
861 | path: "tests", | ||
862 | }, | ||
863 | cfg: None, | ||
864 | }, | ||
865 | }, | ||
866 | }, | ||
867 | Annotation { | ||
868 | range: 30..62, | ||
869 | kind: Runnable { | ||
870 | debug: true, | ||
871 | runnable: Runnable { | ||
872 | nav: NavigationTarget { | ||
873 | file_id: FileId( | ||
874 | 0, | ||
875 | ), | ||
876 | full_range: 30..62, | ||
877 | focus_range: 45..57, | ||
878 | name: "my_cool_test", | ||
879 | kind: Function, | ||
880 | }, | ||
881 | kind: Test { | ||
882 | test_id: Path( | ||
883 | "tests::my_cool_test", | ||
884 | ), | ||
885 | attr: TestAttr { | ||
886 | ignore: false, | ||
887 | }, | ||
888 | }, | ||
889 | cfg: None, | ||
890 | }, | ||
891 | }, | ||
892 | }, | ||
893 | Annotation { | ||
894 | range: 30..62, | ||
895 | kind: Runnable { | ||
896 | debug: false, | ||
897 | runnable: Runnable { | ||
898 | nav: NavigationTarget { | ||
899 | file_id: FileId( | ||
900 | 0, | ||
901 | ), | ||
902 | full_range: 30..62, | ||
903 | focus_range: 45..57, | ||
904 | name: "my_cool_test", | ||
905 | kind: Function, | ||
906 | }, | ||
907 | kind: Test { | ||
908 | test_id: Path( | ||
909 | "tests::my_cool_test", | ||
910 | ), | ||
911 | attr: TestAttr { | ||
912 | ignore: false, | ||
913 | }, | ||
914 | }, | ||
915 | cfg: None, | ||
916 | }, | ||
917 | }, | ||
918 | }, | ||
919 | Annotation { | ||
920 | range: 3..7, | ||
921 | kind: HasReferences { | ||
922 | position: FilePosition { | ||
923 | file_id: FileId( | ||
924 | 0, | ||
925 | ), | ||
926 | offset: 3, | ||
927 | }, | ||
928 | data: Some( | ||
929 | [], | ||
930 | ), | ||
931 | }, | ||
932 | }, | ||
933 | ] | ||
934 | "#]], | ||
416 | ); | 935 | ); |
417 | } | 936 | } |
418 | } | 937 | } |