diff options
Diffstat (limited to 'crates/ide_db/src')
-rw-r--r-- | crates/ide_db/src/helpers/insert_use/tests.rs | 84 | ||||
-rw-r--r-- | crates/ide_db/src/helpers/merge_imports.rs | 16 | ||||
-rw-r--r-- | crates/ide_db/src/search.rs | 177 | ||||
-rw-r--r-- | crates/ide_db/src/ty_filter.rs | 6 |
4 files changed, 164 insertions, 119 deletions
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs index 048c213e2..248227d29 100644 --- a/crates/ide_db/src/helpers/insert_use/tests.rs +++ b/crates/ide_db/src/helpers/insert_use/tests.rs | |||
@@ -44,7 +44,7 @@ fn insert_not_group_empty() { | |||
44 | 44 | ||
45 | #[test] | 45 | #[test] |
46 | fn insert_existing() { | 46 | fn insert_existing() { |
47 | check_full("std::fs", "use std::fs;", "use std::fs;") | 47 | check_crate("std::fs", "use std::fs;", "use std::fs;") |
48 | } | 48 | } |
49 | 49 | ||
50 | #[test] | 50 | #[test] |
@@ -249,7 +249,7 @@ use self::fmt;", | |||
249 | 249 | ||
250 | #[test] | 250 | #[test] |
251 | fn insert_no_imports() { | 251 | fn insert_no_imports() { |
252 | check_full( | 252 | check_crate( |
253 | "foo::bar", | 253 | "foo::bar", |
254 | "fn main() {}", | 254 | "fn main() {}", |
255 | r"use foo::bar; | 255 | r"use foo::bar; |
@@ -263,7 +263,7 @@ fn insert_empty_file() { | |||
263 | cov_mark::check!(insert_group_empty_file); | 263 | cov_mark::check!(insert_group_empty_file); |
264 | // empty files will get two trailing newlines | 264 | // empty files will get two trailing newlines |
265 | // this is due to the test case insert_no_imports above | 265 | // this is due to the test case insert_no_imports above |
266 | check_full( | 266 | check_crate( |
267 | "foo::bar", | 267 | "foo::bar", |
268 | "", | 268 | "", |
269 | r"use foo::bar; | 269 | r"use foo::bar; |
@@ -290,7 +290,7 @@ fn insert_empty_module() { | |||
290 | #[test] | 290 | #[test] |
291 | fn insert_after_inner_attr() { | 291 | fn insert_after_inner_attr() { |
292 | cov_mark::check!(insert_group_empty_inner_attr); | 292 | cov_mark::check!(insert_group_empty_inner_attr); |
293 | check_full( | 293 | check_crate( |
294 | "foo::bar", | 294 | "foo::bar", |
295 | r"#![allow(unused_imports)]", | 295 | r"#![allow(unused_imports)]", |
296 | r"#![allow(unused_imports)] | 296 | r"#![allow(unused_imports)] |
@@ -301,7 +301,7 @@ use foo::bar;", | |||
301 | 301 | ||
302 | #[test] | 302 | #[test] |
303 | fn insert_after_inner_attr2() { | 303 | fn insert_after_inner_attr2() { |
304 | check_full( | 304 | check_crate( |
305 | "foo::bar", | 305 | "foo::bar", |
306 | r"#![allow(unused_imports)] | 306 | r"#![allow(unused_imports)] |
307 | 307 | ||
@@ -371,12 +371,12 @@ fn main() {}"#, | |||
371 | 371 | ||
372 | #[test] | 372 | #[test] |
373 | fn merge_groups() { | 373 | fn merge_groups() { |
374 | check_last("std::io", r"use std::fmt;", r"use std::{fmt, io};") | 374 | check_module("std::io", r"use std::fmt;", r"use std::{fmt, io};") |
375 | } | 375 | } |
376 | 376 | ||
377 | #[test] | 377 | #[test] |
378 | fn merge_groups_last() { | 378 | fn merge_groups_last() { |
379 | check_last( | 379 | check_module( |
380 | "std::io", | 380 | "std::io", |
381 | r"use std::fmt::{Result, Display};", | 381 | r"use std::fmt::{Result, Display};", |
382 | r"use std::fmt::{Result, Display}; | 382 | r"use std::fmt::{Result, Display}; |
@@ -386,12 +386,12 @@ use std::io;", | |||
386 | 386 | ||
387 | #[test] | 387 | #[test] |
388 | fn merge_last_into_self() { | 388 | fn merge_last_into_self() { |
389 | check_last("foo::bar::baz", r"use foo::bar;", r"use foo::bar::{self, baz};"); | 389 | check_module("foo::bar::baz", r"use foo::bar;", r"use foo::bar::{self, baz};"); |
390 | } | 390 | } |
391 | 391 | ||
392 | #[test] | 392 | #[test] |
393 | fn merge_groups_full() { | 393 | fn merge_groups_full() { |
394 | check_full( | 394 | check_crate( |
395 | "std::io", | 395 | "std::io", |
396 | r"use std::fmt::{Result, Display};", | 396 | r"use std::fmt::{Result, Display};", |
397 | r"use std::{fmt::{Result, Display}, io};", | 397 | r"use std::{fmt::{Result, Display}, io};", |
@@ -400,17 +400,21 @@ fn merge_groups_full() { | |||
400 | 400 | ||
401 | #[test] | 401 | #[test] |
402 | fn merge_groups_long_full() { | 402 | fn merge_groups_long_full() { |
403 | check_full("std::foo::bar::Baz", r"use std::foo::bar::Qux;", r"use std::foo::bar::{Baz, Qux};") | 403 | check_crate("std::foo::bar::Baz", r"use std::foo::bar::Qux;", r"use std::foo::bar::{Baz, Qux};") |
404 | } | 404 | } |
405 | 405 | ||
406 | #[test] | 406 | #[test] |
407 | fn merge_groups_long_last() { | 407 | fn merge_groups_long_last() { |
408 | check_last("std::foo::bar::Baz", r"use std::foo::bar::Qux;", r"use std::foo::bar::{Baz, Qux};") | 408 | check_module( |
409 | "std::foo::bar::Baz", | ||
410 | r"use std::foo::bar::Qux;", | ||
411 | r"use std::foo::bar::{Baz, Qux};", | ||
412 | ) | ||
409 | } | 413 | } |
410 | 414 | ||
411 | #[test] | 415 | #[test] |
412 | fn merge_groups_long_full_list() { | 416 | fn merge_groups_long_full_list() { |
413 | check_full( | 417 | check_crate( |
414 | "std::foo::bar::Baz", | 418 | "std::foo::bar::Baz", |
415 | r"use std::foo::bar::{Qux, Quux};", | 419 | r"use std::foo::bar::{Qux, Quux};", |
416 | r"use std::foo::bar::{Baz, Quux, Qux};", | 420 | r"use std::foo::bar::{Baz, Quux, Qux};", |
@@ -419,7 +423,7 @@ fn merge_groups_long_full_list() { | |||
419 | 423 | ||
420 | #[test] | 424 | #[test] |
421 | fn merge_groups_long_last_list() { | 425 | fn merge_groups_long_last_list() { |
422 | check_last( | 426 | check_module( |
423 | "std::foo::bar::Baz", | 427 | "std::foo::bar::Baz", |
424 | r"use std::foo::bar::{Qux, Quux};", | 428 | r"use std::foo::bar::{Qux, Quux};", |
425 | r"use std::foo::bar::{Baz, Quux, Qux};", | 429 | r"use std::foo::bar::{Baz, Quux, Qux};", |
@@ -428,7 +432,7 @@ fn merge_groups_long_last_list() { | |||
428 | 432 | ||
429 | #[test] | 433 | #[test] |
430 | fn merge_groups_long_full_nested() { | 434 | fn merge_groups_long_full_nested() { |
431 | check_full( | 435 | check_crate( |
432 | "std::foo::bar::Baz", | 436 | "std::foo::bar::Baz", |
433 | r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", | 437 | r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", |
434 | r"use std::foo::bar::{Baz, Qux, quux::{Fez, Fizz}};", | 438 | r"use std::foo::bar::{Baz, Qux, quux::{Fez, Fizz}};", |
@@ -437,7 +441,7 @@ fn merge_groups_long_full_nested() { | |||
437 | 441 | ||
438 | #[test] | 442 | #[test] |
439 | fn merge_groups_long_last_nested() { | 443 | fn merge_groups_long_last_nested() { |
440 | check_last( | 444 | check_module( |
441 | "std::foo::bar::Baz", | 445 | "std::foo::bar::Baz", |
442 | r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", | 446 | r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", |
443 | r"use std::foo::bar::Baz; | 447 | r"use std::foo::bar::Baz; |
@@ -447,7 +451,7 @@ use std::foo::bar::{Qux, quux::{Fez, Fizz}};", | |||
447 | 451 | ||
448 | #[test] | 452 | #[test] |
449 | fn merge_groups_full_nested_deep() { | 453 | fn merge_groups_full_nested_deep() { |
450 | check_full( | 454 | check_crate( |
451 | "std::foo::bar::quux::Baz", | 455 | "std::foo::bar::quux::Baz", |
452 | r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", | 456 | r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", |
453 | r"use std::foo::bar::{Qux, quux::{Baz, Fez, Fizz}};", | 457 | r"use std::foo::bar::{Qux, quux::{Baz, Fez, Fizz}};", |
@@ -456,7 +460,7 @@ fn merge_groups_full_nested_deep() { | |||
456 | 460 | ||
457 | #[test] | 461 | #[test] |
458 | fn merge_groups_full_nested_long() { | 462 | fn merge_groups_full_nested_long() { |
459 | check_full( | 463 | check_crate( |
460 | "std::foo::bar::Baz", | 464 | "std::foo::bar::Baz", |
461 | r"use std::{foo::bar::Qux};", | 465 | r"use std::{foo::bar::Qux};", |
462 | r"use std::{foo::bar::{Baz, Qux}};", | 466 | r"use std::{foo::bar::{Baz, Qux}};", |
@@ -465,7 +469,7 @@ fn merge_groups_full_nested_long() { | |||
465 | 469 | ||
466 | #[test] | 470 | #[test] |
467 | fn merge_groups_last_nested_long() { | 471 | fn merge_groups_last_nested_long() { |
468 | check_full( | 472 | check_crate( |
469 | "std::foo::bar::Baz", | 473 | "std::foo::bar::Baz", |
470 | r"use std::{foo::bar::Qux};", | 474 | r"use std::{foo::bar::Qux};", |
471 | r"use std::{foo::bar::{Baz, Qux}};", | 475 | r"use std::{foo::bar::{Baz, Qux}};", |
@@ -474,7 +478,7 @@ fn merge_groups_last_nested_long() { | |||
474 | 478 | ||
475 | #[test] | 479 | #[test] |
476 | fn merge_groups_skip_pub() { | 480 | fn merge_groups_skip_pub() { |
477 | check_full( | 481 | check_crate( |
478 | "std::io", | 482 | "std::io", |
479 | r"pub use std::fmt::{Result, Display};", | 483 | r"pub use std::fmt::{Result, Display};", |
480 | r"pub use std::fmt::{Result, Display}; | 484 | r"pub use std::fmt::{Result, Display}; |
@@ -484,7 +488,7 @@ use std::io;", | |||
484 | 488 | ||
485 | #[test] | 489 | #[test] |
486 | fn merge_groups_skip_pub_crate() { | 490 | fn merge_groups_skip_pub_crate() { |
487 | check_full( | 491 | check_crate( |
488 | "std::io", | 492 | "std::io", |
489 | r"pub(crate) use std::fmt::{Result, Display};", | 493 | r"pub(crate) use std::fmt::{Result, Display};", |
490 | r"pub(crate) use std::fmt::{Result, Display}; | 494 | r"pub(crate) use std::fmt::{Result, Display}; |
@@ -494,7 +498,7 @@ use std::io;", | |||
494 | 498 | ||
495 | #[test] | 499 | #[test] |
496 | fn merge_groups_skip_attributed() { | 500 | fn merge_groups_skip_attributed() { |
497 | check_full( | 501 | check_crate( |
498 | "std::io", | 502 | "std::io", |
499 | r#" | 503 | r#" |
500 | #[cfg(feature = "gated")] use std::fmt::{Result, Display}; | 504 | #[cfg(feature = "gated")] use std::fmt::{Result, Display}; |
@@ -509,7 +513,7 @@ use std::io; | |||
509 | #[test] | 513 | #[test] |
510 | #[ignore] // FIXME: Support this | 514 | #[ignore] // FIXME: Support this |
511 | fn split_out_merge() { | 515 | fn split_out_merge() { |
512 | check_last( | 516 | check_module( |
513 | "std::fmt::Result", | 517 | "std::fmt::Result", |
514 | r"use std::{fmt, io};", | 518 | r"use std::{fmt, io};", |
515 | r"use std::fmt::{self, Result}; | 519 | r"use std::fmt::{self, Result}; |
@@ -519,29 +523,33 @@ use std::io;", | |||
519 | 523 | ||
520 | #[test] | 524 | #[test] |
521 | fn merge_into_module_import() { | 525 | fn merge_into_module_import() { |
522 | check_full("std::fmt::Result", r"use std::{fmt, io};", r"use std::{fmt::{self, Result}, io};") | 526 | check_crate("std::fmt::Result", r"use std::{fmt, io};", r"use std::{fmt::{self, Result}, io};") |
523 | } | 527 | } |
524 | 528 | ||
525 | #[test] | 529 | #[test] |
526 | fn merge_groups_self() { | 530 | fn merge_groups_self() { |
527 | check_full("std::fmt::Debug", r"use std::fmt;", r"use std::fmt::{self, Debug};") | 531 | check_crate("std::fmt::Debug", r"use std::fmt;", r"use std::fmt::{self, Debug};") |
528 | } | 532 | } |
529 | 533 | ||
530 | #[test] | 534 | #[test] |
531 | fn merge_mod_into_glob() { | 535 | fn merge_mod_into_glob() { |
532 | check_full("token::TokenKind", r"use token::TokenKind::*;", r"use token::TokenKind::{*, self};") | 536 | check_crate( |
537 | "token::TokenKind", | ||
538 | r"use token::TokenKind::*;", | ||
539 | r"use token::TokenKind::{*, self};", | ||
540 | ) | ||
533 | // FIXME: have it emit `use token::TokenKind::{self, *}`? | 541 | // FIXME: have it emit `use token::TokenKind::{self, *}`? |
534 | } | 542 | } |
535 | 543 | ||
536 | #[test] | 544 | #[test] |
537 | fn merge_self_glob() { | 545 | fn merge_self_glob() { |
538 | check_full("self", r"use self::*;", r"use self::{*, self};") | 546 | check_crate("self", r"use self::*;", r"use self::{*, self};") |
539 | // FIXME: have it emit `use {self, *}`? | 547 | // FIXME: have it emit `use {self, *}`? |
540 | } | 548 | } |
541 | 549 | ||
542 | #[test] | 550 | #[test] |
543 | fn merge_glob_nested() { | 551 | fn merge_glob_nested() { |
544 | check_full( | 552 | check_crate( |
545 | "foo::bar::quux::Fez", | 553 | "foo::bar::quux::Fez", |
546 | r"use foo::bar::{Baz, quux::*};", | 554 | r"use foo::bar::{Baz, quux::*};", |
547 | r"use foo::bar::{Baz, quux::{self::*, Fez}};", | 555 | r"use foo::bar::{Baz, quux::{self::*, Fez}};", |
@@ -550,7 +558,7 @@ fn merge_glob_nested() { | |||
550 | 558 | ||
551 | #[test] | 559 | #[test] |
552 | fn merge_nested_considers_first_segments() { | 560 | fn merge_nested_considers_first_segments() { |
553 | check_full( | 561 | check_crate( |
554 | "hir_ty::display::write_bounds_like_dyn_trait", | 562 | "hir_ty::display::write_bounds_like_dyn_trait", |
555 | r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter}, method_resolution};", | 563 | r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter}, method_resolution};", |
556 | r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter, write_bounds_like_dyn_trait}, method_resolution};", | 564 | r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter, write_bounds_like_dyn_trait}, method_resolution};", |
@@ -559,7 +567,7 @@ fn merge_nested_considers_first_segments() { | |||
559 | 567 | ||
560 | #[test] | 568 | #[test] |
561 | fn skip_merge_last_too_long() { | 569 | fn skip_merge_last_too_long() { |
562 | check_last( | 570 | check_module( |
563 | "foo::bar", | 571 | "foo::bar", |
564 | r"use foo::bar::baz::Qux;", | 572 | r"use foo::bar::baz::Qux;", |
565 | r"use foo::bar; | 573 | r"use foo::bar; |
@@ -569,7 +577,7 @@ use foo::bar::baz::Qux;", | |||
569 | 577 | ||
570 | #[test] | 578 | #[test] |
571 | fn skip_merge_last_too_long2() { | 579 | fn skip_merge_last_too_long2() { |
572 | check_last( | 580 | check_module( |
573 | "foo::bar::baz::Qux", | 581 | "foo::bar::baz::Qux", |
574 | r"use foo::bar;", | 582 | r"use foo::bar;", |
575 | r"use foo::bar; | 583 | r"use foo::bar; |
@@ -592,7 +600,7 @@ fn merge_last_fail() { | |||
592 | check_merge_only_fail( | 600 | check_merge_only_fail( |
593 | r"use foo::bar::{baz::{Qux, Fez}};", | 601 | r"use foo::bar::{baz::{Qux, Fez}};", |
594 | r"use foo::bar::{baaz::{Quux, Feez}};", | 602 | r"use foo::bar::{baaz::{Quux, Feez}};", |
595 | MergeBehavior::Last, | 603 | MergeBehavior::Module, |
596 | ); | 604 | ); |
597 | } | 605 | } |
598 | 606 | ||
@@ -601,7 +609,7 @@ fn merge_last_fail1() { | |||
601 | check_merge_only_fail( | 609 | check_merge_only_fail( |
602 | r"use foo::bar::{baz::{Qux, Fez}};", | 610 | r"use foo::bar::{baz::{Qux, Fez}};", |
603 | r"use foo::bar::baaz::{Quux, Feez};", | 611 | r"use foo::bar::baaz::{Quux, Feez};", |
604 | MergeBehavior::Last, | 612 | MergeBehavior::Module, |
605 | ); | 613 | ); |
606 | } | 614 | } |
607 | 615 | ||
@@ -610,7 +618,7 @@ fn merge_last_fail2() { | |||
610 | check_merge_only_fail( | 618 | check_merge_only_fail( |
611 | r"use foo::bar::baz::{Qux, Fez};", | 619 | r"use foo::bar::baz::{Qux, Fez};", |
612 | r"use foo::bar::{baaz::{Quux, Feez}};", | 620 | r"use foo::bar::{baaz::{Quux, Feez}};", |
613 | MergeBehavior::Last, | 621 | MergeBehavior::Module, |
614 | ); | 622 | ); |
615 | } | 623 | } |
616 | 624 | ||
@@ -619,7 +627,7 @@ fn merge_last_fail3() { | |||
619 | check_merge_only_fail( | 627 | check_merge_only_fail( |
620 | r"use foo::bar::baz::{Qux, Fez};", | 628 | r"use foo::bar::baz::{Qux, Fez};", |
621 | r"use foo::bar::baaz::{Quux, Feez};", | 629 | r"use foo::bar::baaz::{Quux, Feez};", |
622 | MergeBehavior::Last, | 630 | MergeBehavior::Module, |
623 | ); | 631 | ); |
624 | } | 632 | } |
625 | 633 | ||
@@ -648,12 +656,12 @@ fn check( | |||
648 | assert_eq_text!(ra_fixture_after, &result); | 656 | assert_eq_text!(ra_fixture_after, &result); |
649 | } | 657 | } |
650 | 658 | ||
651 | fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | 659 | fn check_crate(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { |
652 | check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Full), false, true) | 660 | check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Crate), false, true) |
653 | } | 661 | } |
654 | 662 | ||
655 | fn check_last(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | 663 | fn check_module(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { |
656 | check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Last), false, true) | 664 | check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Module), false, true) |
657 | } | 665 | } |
658 | 666 | ||
659 | fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | 667 | fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { |
diff --git a/crates/ide_db/src/helpers/merge_imports.rs b/crates/ide_db/src/helpers/merge_imports.rs index 3f5bbef7f..af2a51a4d 100644 --- a/crates/ide_db/src/helpers/merge_imports.rs +++ b/crates/ide_db/src/helpers/merge_imports.rs | |||
@@ -9,19 +9,19 @@ use syntax::ast::{ | |||
9 | /// What type of merges are allowed. | 9 | /// What type of merges are allowed. |
10 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | 10 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
11 | pub enum MergeBehavior { | 11 | pub enum MergeBehavior { |
12 | /// Merge everything together creating deeply nested imports. | 12 | /// Merge imports from the same crate into a single use statement. |
13 | Full, | 13 | Crate, |
14 | /// Only merge the last import level, doesn't allow import nesting. | 14 | /// Merge imports from the same module into a single use statement. |
15 | Last, | 15 | Module, |
16 | } | 16 | } |
17 | 17 | ||
18 | impl MergeBehavior { | 18 | impl MergeBehavior { |
19 | #[inline] | 19 | #[inline] |
20 | fn is_tree_allowed(&self, tree: &ast::UseTree) -> bool { | 20 | fn is_tree_allowed(&self, tree: &ast::UseTree) -> bool { |
21 | match self { | 21 | match self { |
22 | MergeBehavior::Full => true, | 22 | MergeBehavior::Crate => true, |
23 | // only simple single segment paths are allowed | 23 | // only simple single segment paths are allowed |
24 | MergeBehavior::Last => { | 24 | MergeBehavior::Module => { |
25 | tree.use_tree_list().is_none() && tree.path().map(path_len) <= Some(1) | 25 | tree.use_tree_list().is_none() && tree.path().map(path_len) <= Some(1) |
26 | } | 26 | } |
27 | } | 27 | } |
@@ -137,7 +137,7 @@ fn recursive_merge( | |||
137 | None, | 137 | None, |
138 | false, | 138 | false, |
139 | ); | 139 | ); |
140 | use_trees.insert(idx, make::glob_use_tree()); | 140 | use_trees.insert(idx, make::use_tree_glob()); |
141 | continue; | 141 | continue; |
142 | } | 142 | } |
143 | 143 | ||
@@ -153,7 +153,7 @@ fn recursive_merge( | |||
153 | } | 153 | } |
154 | } | 154 | } |
155 | Err(_) | 155 | Err(_) |
156 | if merge == MergeBehavior::Last | 156 | if merge == MergeBehavior::Module |
157 | && use_trees.len() > 0 | 157 | && use_trees.len() > 0 |
158 | && rhs_t.use_tree_list().is_some() => | 158 | && rhs_t.use_tree_list().is_some() => |
159 | { | 159 | { |
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 8f899ea56..67840602b 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -233,6 +233,13 @@ impl Definition { | |||
233 | }; | 233 | }; |
234 | } | 234 | } |
235 | 235 | ||
236 | if let Definition::SelfType(impl_) = self { | ||
237 | return match impl_.source(db).map(|src| src.value.syntax().text_range()) { | ||
238 | Some(range) => SearchScope::file_range(FileRange { file_id, range }), | ||
239 | None => SearchScope::single_file(file_id), | ||
240 | }; | ||
241 | } | ||
242 | |||
236 | if let Definition::GenericParam(hir::GenericParam::LifetimeParam(param)) = self { | 243 | if let Definition::GenericParam(hir::GenericParam::LifetimeParam(param)) = self { |
237 | let range = match param.parent(db) { | 244 | let range = match param.parent(db) { |
238 | hir::GenericDef::Function(it) => { | 245 | hir::GenericDef::Function(it) => { |
@@ -297,7 +304,7 @@ impl Definition { | |||
297 | } | 304 | } |
298 | 305 | ||
299 | pub fn usages<'a>(&'a self, sema: &'a Semantics<RootDatabase>) -> FindUsages<'a> { | 306 | pub fn usages<'a>(&'a self, sema: &'a Semantics<RootDatabase>) -> FindUsages<'a> { |
300 | FindUsages { def: self, sema, scope: None, include_self_kw_refs: false } | 307 | FindUsages { def: self, sema, scope: None, include_self_kw_refs: None } |
301 | } | 308 | } |
302 | } | 309 | } |
303 | 310 | ||
@@ -305,12 +312,13 @@ pub struct FindUsages<'a> { | |||
305 | def: &'a Definition, | 312 | def: &'a Definition, |
306 | sema: &'a Semantics<'a, RootDatabase>, | 313 | sema: &'a Semantics<'a, RootDatabase>, |
307 | scope: Option<SearchScope>, | 314 | scope: Option<SearchScope>, |
308 | include_self_kw_refs: bool, | 315 | include_self_kw_refs: Option<hir::Type>, |
309 | } | 316 | } |
310 | 317 | ||
311 | impl<'a> FindUsages<'a> { | 318 | impl<'a> FindUsages<'a> { |
312 | pub fn include_self_kw_refs(mut self, include: bool) -> FindUsages<'a> { | 319 | /// Enable searching for `Self` when the definition is a type. |
313 | self.include_self_kw_refs = include; | 320 | pub fn include_self_refs(mut self) -> FindUsages<'a> { |
321 | self.include_self_kw_refs = def_to_ty(self.sema, self.def); | ||
314 | self | 322 | self |
315 | } | 323 | } |
316 | 324 | ||
@@ -354,13 +362,18 @@ impl<'a> FindUsages<'a> { | |||
354 | } | 362 | } |
355 | }; | 363 | }; |
356 | 364 | ||
357 | let name = match self.def.name(sema.db) { | 365 | let name = self.def.name(sema.db).or_else(|| { |
358 | Some(it) => it.to_string(), | 366 | self.include_self_kw_refs.as_ref().and_then(|ty| { |
367 | ty.as_adt() | ||
368 | .map(|adt| adt.name(self.sema.db)) | ||
369 | .or_else(|| ty.as_builtin().map(|builtin| builtin.name())) | ||
370 | }) | ||
371 | }); | ||
372 | let name = match name { | ||
373 | Some(name) => name.to_string(), | ||
359 | None => return, | 374 | None => return, |
360 | }; | 375 | }; |
361 | 376 | let name = name.as_str(); | |
362 | let pat = name.as_str(); | ||
363 | let search_for_self = self.include_self_kw_refs; | ||
364 | 377 | ||
365 | for (file_id, search_range) in search_scope { | 378 | for (file_id, search_range) in search_scope { |
366 | let text = sema.db.file_text(file_id); | 379 | let text = sema.db.file_text(file_id); |
@@ -369,51 +382,63 @@ impl<'a> FindUsages<'a> { | |||
369 | 382 | ||
370 | let tree = Lazy::new(|| sema.parse(file_id).syntax().clone()); | 383 | let tree = Lazy::new(|| sema.parse(file_id).syntax().clone()); |
371 | 384 | ||
372 | let mut handle_match = |idx: usize| -> bool { | 385 | for (idx, _) in text.match_indices(name) { |
373 | let offset: TextSize = idx.try_into().unwrap(); | 386 | let offset: TextSize = idx.try_into().unwrap(); |
374 | if !search_range.contains_inclusive(offset) { | 387 | if !search_range.contains_inclusive(offset) { |
375 | return false; | 388 | continue; |
376 | } | 389 | } |
377 | 390 | ||
378 | if let Some(name) = sema.find_node_at_offset_with_descend(&tree, offset) { | 391 | if let Some(name) = sema.find_node_at_offset_with_descend(&tree, offset) { |
379 | match name { | 392 | if match name { |
380 | ast::NameLike::NameRef(name_ref) => { | 393 | ast::NameLike::NameRef(name_ref) => self.found_name_ref(&name_ref, sink), |
381 | if self.found_name_ref(&name_ref, sink) { | 394 | ast::NameLike::Name(name) => self.found_name(&name, sink), |
382 | return true; | 395 | ast::NameLike::Lifetime(lifetime) => self.found_lifetime(&lifetime, sink), |
383 | } | 396 | } { |
384 | } | 397 | return; |
385 | ast::NameLike::Name(name) => { | ||
386 | if self.found_name(&name, sink) { | ||
387 | return true; | ||
388 | } | ||
389 | } | ||
390 | ast::NameLike::Lifetime(lifetime) => { | ||
391 | if self.found_lifetime(&lifetime, sink) { | ||
392 | return true; | ||
393 | } | ||
394 | } | ||
395 | } | 398 | } |
396 | } | 399 | } |
397 | |||
398 | return false; | ||
399 | }; | ||
400 | |||
401 | for (idx, _) in text.match_indices(pat) { | ||
402 | if handle_match(idx) { | ||
403 | return; | ||
404 | } | ||
405 | } | 400 | } |
406 | 401 | if let Some(self_ty) = &self.include_self_kw_refs { | |
407 | if search_for_self { | ||
408 | for (idx, _) in text.match_indices("Self") { | 402 | for (idx, _) in text.match_indices("Self") { |
409 | if handle_match(idx) { | 403 | let offset: TextSize = idx.try_into().unwrap(); |
410 | return; | 404 | if !search_range.contains_inclusive(offset) { |
405 | continue; | ||
406 | } | ||
407 | |||
408 | if let Some(ast::NameLike::NameRef(name_ref)) = | ||
409 | sema.find_node_at_offset_with_descend(&tree, offset) | ||
410 | { | ||
411 | if self.found_self_ty_name_ref(&self_ty, &name_ref, sink) { | ||
412 | return; | ||
413 | } | ||
411 | } | 414 | } |
412 | } | 415 | } |
413 | } | 416 | } |
414 | } | 417 | } |
415 | } | 418 | } |
416 | 419 | ||
420 | fn found_self_ty_name_ref( | ||
421 | &self, | ||
422 | self_ty: &hir::Type, | ||
423 | name_ref: &ast::NameRef, | ||
424 | sink: &mut dyn FnMut(FileId, FileReference) -> bool, | ||
425 | ) -> bool { | ||
426 | match NameRefClass::classify(self.sema, &name_ref) { | ||
427 | Some(NameRefClass::Definition(Definition::SelfType(impl_))) | ||
428 | if impl_.self_ty(self.sema.db) == *self_ty => | ||
429 | { | ||
430 | let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax()); | ||
431 | let reference = FileReference { | ||
432 | range, | ||
433 | name: ast::NameLike::NameRef(name_ref.clone()), | ||
434 | access: None, | ||
435 | }; | ||
436 | sink(file_id, reference) | ||
437 | } | ||
438 | _ => false, | ||
439 | } | ||
440 | } | ||
441 | |||
417 | fn found_lifetime( | 442 | fn found_lifetime( |
418 | &self, | 443 | &self, |
419 | lifetime: &ast::Lifetime, | 444 | lifetime: &ast::Lifetime, |
@@ -429,7 +454,7 @@ impl<'a> FindUsages<'a> { | |||
429 | }; | 454 | }; |
430 | sink(file_id, reference) | 455 | sink(file_id, reference) |
431 | } | 456 | } |
432 | _ => false, // not a usage | 457 | _ => false, |
433 | } | 458 | } |
434 | } | 459 | } |
435 | 460 | ||
@@ -448,42 +473,35 @@ impl<'a> FindUsages<'a> { | |||
448 | }; | 473 | }; |
449 | sink(file_id, reference) | 474 | sink(file_id, reference) |
450 | } | 475 | } |
451 | Some(NameRefClass::Definition(Definition::SelfType(impl_))) => { | 476 | Some(NameRefClass::Definition(def)) if self.include_self_kw_refs.is_some() => { |
452 | let ty = impl_.self_ty(self.sema.db); | 477 | if self.include_self_kw_refs == def_to_ty(self.sema, &def) { |
453 | 478 | let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax()); | |
454 | if let Some(adt) = ty.as_adt() { | 479 | let reference = FileReference { |
455 | if &Definition::ModuleDef(ModuleDef::Adt(adt)) == self.def { | 480 | range, |
456 | let FileRange { file_id, range } = | 481 | name: ast::NameLike::NameRef(name_ref.clone()), |
457 | self.sema.original_range(name_ref.syntax()); | 482 | access: reference_access(&def, &name_ref), |
458 | let reference = FileReference { | 483 | }; |
459 | range, | 484 | sink(file_id, reference) |
460 | name: ast::NameLike::NameRef(name_ref.clone()), | 485 | } else { |
461 | access: None, | 486 | false |
462 | }; | ||
463 | return sink(file_id, reference); | ||
464 | } | ||
465 | } | 487 | } |
466 | |||
467 | false | ||
468 | } | 488 | } |
469 | Some(NameRefClass::FieldShorthand { local_ref: local, field_ref: field }) => { | 489 | Some(NameRefClass::FieldShorthand { local_ref: local, field_ref: field }) => { |
470 | let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax()); | 490 | let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax()); |
471 | let reference = match self.def { | 491 | let access = match self.def { |
472 | Definition::Field(_) if &field == self.def => FileReference { | 492 | Definition::Field(_) if &field == self.def => { |
473 | range, | 493 | reference_access(&field, &name_ref) |
474 | name: ast::NameLike::NameRef(name_ref.clone()), | 494 | } |
475 | access: reference_access(&field, &name_ref), | 495 | Definition::Local(l) if &local == l => { |
476 | }, | 496 | reference_access(&Definition::Local(local), &name_ref) |
477 | Definition::Local(l) if &local == l => FileReference { | 497 | } |
478 | range, | 498 | _ => return false, |
479 | name: ast::NameLike::NameRef(name_ref.clone()), | ||
480 | access: reference_access(&Definition::Local(local), &name_ref), | ||
481 | }, | ||
482 | _ => return false, // not a usage | ||
483 | }; | 499 | }; |
500 | let reference = | ||
501 | FileReference { range, name: ast::NameLike::NameRef(name_ref.clone()), access }; | ||
484 | sink(file_id, reference) | 502 | sink(file_id, reference) |
485 | } | 503 | } |
486 | _ => false, // not a usage | 504 | _ => false, |
487 | } | 505 | } |
488 | } | 506 | } |
489 | 507 | ||
@@ -513,11 +531,30 @@ impl<'a> FindUsages<'a> { | |||
513 | FileReference { range, name: ast::NameLike::Name(name.clone()), access: None }; | 531 | FileReference { range, name: ast::NameLike::Name(name.clone()), access: None }; |
514 | sink(file_id, reference) | 532 | sink(file_id, reference) |
515 | } | 533 | } |
516 | _ => false, // not a usage | 534 | _ => false, |
517 | } | 535 | } |
518 | } | 536 | } |
519 | } | 537 | } |
520 | 538 | ||
539 | fn def_to_ty(sema: &Semantics<RootDatabase>, def: &Definition) -> Option<hir::Type> { | ||
540 | match def { | ||
541 | Definition::ModuleDef(def) => match def { | ||
542 | ModuleDef::Adt(adt) => Some(adt.ty(sema.db)), | ||
543 | ModuleDef::TypeAlias(it) => Some(it.ty(sema.db)), | ||
544 | ModuleDef::BuiltinType(it) => { | ||
545 | let graph = sema.db.crate_graph(); | ||
546 | let krate = graph.iter().next()?; | ||
547 | let root_file = graph[krate].root_file_id; | ||
548 | let module = sema.to_module_def(root_file)?; | ||
549 | Some(it.ty(sema.db, module)) | ||
550 | } | ||
551 | _ => None, | ||
552 | }, | ||
553 | Definition::SelfType(it) => Some(it.self_ty(sema.db)), | ||
554 | _ => None, | ||
555 | } | ||
556 | } | ||
557 | |||
521 | fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> { | 558 | fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> { |
522 | // Only Locals and Fields have accesses for now. | 559 | // Only Locals and Fields have accesses for now. |
523 | if !matches!(def, Definition::Local(_) | Definition::Field(_)) { | 560 | if !matches!(def, Definition::Local(_) | Definition::Field(_)) { |
diff --git a/crates/ide_db/src/ty_filter.rs b/crates/ide_db/src/ty_filter.rs index 988ecd060..00678bf3e 100644 --- a/crates/ide_db/src/ty_filter.rs +++ b/crates/ide_db/src/ty_filter.rs | |||
@@ -43,7 +43,7 @@ impl TryEnum { | |||
43 | pub fn sad_pattern(self) -> ast::Pat { | 43 | pub fn sad_pattern(self) -> ast::Pat { |
44 | match self { | 44 | match self { |
45 | TryEnum::Result => make::tuple_struct_pat( | 45 | TryEnum::Result => make::tuple_struct_pat( |
46 | make::path_unqualified(make::path_segment(make::name_ref("Err"))), | 46 | make::ext::ident_path("Err"), |
47 | iter::once(make::wildcard_pat().into()), | 47 | iter::once(make::wildcard_pat().into()), |
48 | ) | 48 | ) |
49 | .into(), | 49 | .into(), |
@@ -54,12 +54,12 @@ impl TryEnum { | |||
54 | pub fn happy_pattern(self) -> ast::Pat { | 54 | pub fn happy_pattern(self) -> ast::Pat { |
55 | match self { | 55 | match self { |
56 | TryEnum::Result => make::tuple_struct_pat( | 56 | TryEnum::Result => make::tuple_struct_pat( |
57 | make::path_unqualified(make::path_segment(make::name_ref("Ok"))), | 57 | make::ext::ident_path("Ok"), |
58 | iter::once(make::wildcard_pat().into()), | 58 | iter::once(make::wildcard_pat().into()), |
59 | ) | 59 | ) |
60 | .into(), | 60 | .into(), |
61 | TryEnum::Option => make::tuple_struct_pat( | 61 | TryEnum::Option => make::tuple_struct_pat( |
62 | make::path_unqualified(make::path_segment(make::name_ref("Some"))), | 62 | make::ext::ident_path("Some"), |
63 | iter::once(make::wildcard_pat().into()), | 63 | iter::once(make::wildcard_pat().into()), |
64 | ) | 64 | ) |
65 | .into(), | 65 | .into(), |