diff options
Diffstat (limited to 'crates/ide/src/hover.rs')
-rw-r--r-- | crates/ide/src/hover.rs | 188 |
1 files changed, 114 insertions, 74 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index ea45086ce..325014622 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use either::Either; | 1 | use either::Either; |
2 | use hir::{ | 2 | use hir::{ |
3 | Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource, | 3 | AsAssocItem, AssocItemContainer, GenericParam, HasAttrs, HasSource, HirDisplay, Module, |
4 | HirDisplay, Module, ModuleDef, ModuleSource, Semantics, | 4 | ModuleDef, Semantics, |
5 | }; | 5 | }; |
6 | use ide_db::{ | 6 | use ide_db::{ |
7 | base_db::SourceDatabase, | 7 | base_db::SourceDatabase, |
@@ -14,7 +14,7 @@ use stdx::format_to; | |||
14 | use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; | 14 | use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; |
15 | 15 | ||
16 | use crate::{ | 16 | use crate::{ |
17 | display::{macro_label, ShortLabel, TryToNav}, | 17 | display::{macro_label, TryToNav}, |
18 | doc_links::{remove_links, rewrite_links}, | 18 | doc_links::{remove_links, rewrite_links}, |
19 | markdown_remove::remove_markdown, | 19 | markdown_remove::remove_markdown, |
20 | markup::Markup, | 20 | markup::Markup, |
@@ -92,7 +92,7 @@ pub(crate) fn hover( | |||
92 | 92 | ||
93 | let mut res = HoverResult::default(); | 93 | let mut res = HoverResult::default(); |
94 | 94 | ||
95 | let node = token.parent(); | 95 | let node = token.parent()?; |
96 | let definition = match_ast! { | 96 | let definition = match_ast! { |
97 | match node { | 97 | match node { |
98 | // we don't use NameClass::referenced_or_defined here as we do not want to resolve | 98 | // we don't use NameClass::referenced_or_defined here as we do not want to resolve |
@@ -335,61 +335,34 @@ fn hover_for_definition( | |||
335 | let label = macro_label(&it.source(db)?.value); | 335 | let label = macro_label(&it.source(db)?.value); |
336 | from_def_source_labeled(db, it, Some(label), mod_path) | 336 | from_def_source_labeled(db, it, Some(label), mod_path) |
337 | } | 337 | } |
338 | Definition::Field(def) => { | 338 | Definition::Field(def) => from_hir_fmt(db, def, mod_path), |
339 | let src = def.source(db)?.value; | ||
340 | if let FieldSource::Named(it) = src { | ||
341 | from_def_source_labeled(db, def, it.short_label(), mod_path) | ||
342 | } else { | ||
343 | None | ||
344 | } | ||
345 | } | ||
346 | Definition::ModuleDef(it) => match it { | 339 | Definition::ModuleDef(it) => match it { |
347 | ModuleDef::Module(it) => from_def_source_labeled( | 340 | ModuleDef::Module(it) => from_hir_fmt(db, it, mod_path), |
348 | db, | 341 | ModuleDef::Function(it) => from_hir_fmt(db, it, mod_path), |
349 | it, | 342 | ModuleDef::Adt(it) => from_hir_fmt(db, it, mod_path), |
350 | match it.definition_source(db).value { | 343 | ModuleDef::Variant(it) => from_hir_fmt(db, it, mod_path), |
351 | ModuleSource::Module(it) => it.short_label(), | 344 | ModuleDef::Const(it) => from_hir_fmt(db, it, mod_path), |
352 | ModuleSource::SourceFile(it) => it.short_label(), | 345 | ModuleDef::Static(it) => from_hir_fmt(db, it, mod_path), |
353 | ModuleSource::BlockExpr(it) => it.short_label(), | 346 | ModuleDef::Trait(it) => from_hir_fmt(db, it, mod_path), |
354 | }, | 347 | ModuleDef::TypeAlias(it) => from_hir_fmt(db, it, mod_path), |
355 | mod_path, | ||
356 | ), | ||
357 | ModuleDef::Function(it) => from_def_source(db, it, mod_path), | ||
358 | ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path), | ||
359 | ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path), | ||
360 | ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path), | ||
361 | ModuleDef::Variant(it) => from_def_source(db, it, mod_path), | ||
362 | ModuleDef::Const(it) => from_def_source(db, it, mod_path), | ||
363 | ModuleDef::Static(it) => from_def_source(db, it, mod_path), | ||
364 | ModuleDef::Trait(it) => from_def_source(db, it, mod_path), | ||
365 | ModuleDef::TypeAlias(it) => from_def_source(db, it, mod_path), | ||
366 | ModuleDef::BuiltinType(it) => famous_defs | 348 | ModuleDef::BuiltinType(it) => famous_defs |
367 | .and_then(|fd| hover_for_builtin(fd, it)) | 349 | .and_then(|fd| hover_for_builtin(fd, it)) |
368 | .or_else(|| Some(Markup::fenced_block(&it.name()))), | 350 | .or_else(|| Some(Markup::fenced_block(&it.name()))), |
369 | }, | 351 | }, |
370 | Definition::Local(it) => hover_for_local(it, db), | 352 | Definition::Local(it) => hover_for_local(it, db), |
371 | Definition::SelfType(impl_def) => { | 353 | Definition::SelfType(impl_def) => { |
372 | impl_def.target_ty(db).as_adt().and_then(|adt| match adt { | 354 | impl_def.target_ty(db).as_adt().and_then(|adt| from_hir_fmt(db, adt, mod_path)) |
373 | Adt::Struct(it) => from_def_source(db, it, mod_path), | ||
374 | Adt::Union(it) => from_def_source(db, it, mod_path), | ||
375 | Adt::Enum(it) => from_def_source(db, it, mod_path), | ||
376 | }) | ||
377 | } | 355 | } |
356 | Definition::GenericParam(it) => from_hir_fmt(db, it, None), | ||
378 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), | 357 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), |
379 | Definition::GenericParam(it) => match it { | ||
380 | GenericParam::TypeParam(it) => Some(Markup::fenced_block(&it.display(db))), | ||
381 | GenericParam::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), | ||
382 | GenericParam::ConstParam(it) => from_def_source(db, it, None), | ||
383 | }, | ||
384 | }; | 358 | }; |
385 | 359 | ||
386 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> | 360 | fn from_hir_fmt<D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> |
387 | where | 361 | where |
388 | D: HasSource<Ast = A> + HasAttrs + Copy, | 362 | D: HasAttrs + HirDisplay, |
389 | A: ShortLabel, | ||
390 | { | 363 | { |
391 | let short_label = def.source(db)?.value.short_label(); | 364 | let label = def.display(db).to_string(); |
392 | from_def_source_labeled(db, def, short_label, mod_path) | 365 | from_def_source_labeled(db, def, Some(label), mod_path) |
393 | } | 366 | } |
394 | 367 | ||
395 | fn from_def_source_labeled<D>( | 368 | fn from_def_source_labeled<D>( |
@@ -438,7 +411,7 @@ fn hover_for_keyword( | |||
438 | if !token.kind().is_keyword() { | 411 | if !token.kind().is_keyword() { |
439 | return None; | 412 | return None; |
440 | } | 413 | } |
441 | let famous_defs = FamousDefs(&sema, sema.scope(&token.parent()).krate()); | 414 | let famous_defs = FamousDefs(&sema, sema.scope(&token.parent()?).krate()); |
442 | // std exposes {}_keyword modules with docstrings on the root to document keywords | 415 | // std exposes {}_keyword modules with docstrings on the root to document keywords |
443 | let keyword_mod = format!("{}_keyword", token.text()); | 416 | let keyword_mod = format!("{}_keyword", token.text()); |
444 | let doc_owner = find_std_module(&famous_defs, &keyword_mod)?; | 417 | let doc_owner = find_std_module(&famous_defs, &keyword_mod)?; |
@@ -670,7 +643,9 @@ fn main() { let foo_test = fo$0o(); } | |||
670 | ``` | 643 | ``` |
671 | 644 | ||
672 | ```rust | 645 | ```rust |
673 | pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str | 646 | pub fn foo<'a, T>(b: &'a T) -> &'a str |
647 | where | ||
648 | T: AsRef<str>, | ||
674 | ``` | 649 | ``` |
675 | "#]], | 650 | "#]], |
676 | ); | 651 | ); |
@@ -878,7 +853,7 @@ fn main() { So$0me(12); } | |||
878 | ``` | 853 | ``` |
879 | 854 | ||
880 | ```rust | 855 | ```rust |
881 | Some | 856 | Some(T) |
882 | ``` | 857 | ``` |
883 | "#]], | 858 | "#]], |
884 | ); | 859 | ); |
@@ -944,7 +919,7 @@ fn main() { | |||
944 | ``` | 919 | ``` |
945 | 920 | ||
946 | ```rust | 921 | ```rust |
947 | Some | 922 | Some(T) |
948 | ``` | 923 | ``` |
949 | 924 | ||
950 | --- | 925 | --- |
@@ -1441,13 +1416,14 @@ fn bar() { fo$0o(); } | |||
1441 | ``` | 1416 | ``` |
1442 | "#]], | 1417 | "#]], |
1443 | ); | 1418 | ); |
1419 | // Top level `pub(crate)` will be displayed as no visibility. | ||
1444 | check( | 1420 | check( |
1445 | r#"pub(crate) async unsafe extern "C" fn foo$0() {}"#, | 1421 | r#"mod m { pub(crate) async unsafe extern "C" fn foo$0() {} }"#, |
1446 | expect![[r#" | 1422 | expect![[r#" |
1447 | *foo* | 1423 | *foo* |
1448 | 1424 | ||
1449 | ```rust | 1425 | ```rust |
1450 | test | 1426 | test::m |
1451 | ``` | 1427 | ``` |
1452 | 1428 | ||
1453 | ```rust | 1429 | ```rust |
@@ -1489,11 +1465,18 @@ extern crate st$0d; | |||
1489 | //! abc123 | 1465 | //! abc123 |
1490 | "#, | 1466 | "#, |
1491 | expect![[r#" | 1467 | expect![[r#" |
1492 | *std* | 1468 | *std* |
1493 | Standard library for this test | 1469 | |
1470 | ```rust | ||
1471 | extern crate std | ||
1472 | ``` | ||
1473 | |||
1474 | --- | ||
1494 | 1475 | ||
1495 | Printed? | 1476 | Standard library for this test |
1496 | abc123 | 1477 | |
1478 | Printed? | ||
1479 | abc123 | ||
1497 | "#]], | 1480 | "#]], |
1498 | ); | 1481 | ); |
1499 | check( | 1482 | check( |
@@ -1507,11 +1490,18 @@ extern crate std as ab$0c; | |||
1507 | //! abc123 | 1490 | //! abc123 |
1508 | "#, | 1491 | "#, |
1509 | expect![[r#" | 1492 | expect![[r#" |
1510 | *abc* | 1493 | *abc* |
1511 | Standard library for this test | 1494 | |
1495 | ```rust | ||
1496 | extern crate std | ||
1497 | ``` | ||
1512 | 1498 | ||
1513 | Printed? | 1499 | --- |
1514 | abc123 | 1500 | |
1501 | Standard library for this test | ||
1502 | |||
1503 | Printed? | ||
1504 | abc123 | ||
1515 | "#]], | 1505 | "#]], |
1516 | ); | 1506 | ); |
1517 | } | 1507 | } |
@@ -2021,7 +2011,7 @@ enum E { | |||
2021 | ``` | 2011 | ``` |
2022 | 2012 | ||
2023 | ```rust | 2013 | ```rust |
2024 | V | 2014 | V { field: i32 } |
2025 | ``` | 2015 | ``` |
2026 | 2016 | ||
2027 | --- | 2017 | --- |
@@ -2417,7 +2407,7 @@ fn main() { let s$0t = S{ f1:Arg(0) }; } | |||
2417 | focus_range: 24..25, | 2407 | focus_range: 24..25, |
2418 | name: "S", | 2408 | name: "S", |
2419 | kind: Struct, | 2409 | kind: Struct, |
2420 | description: "struct S", | 2410 | description: "struct S<T>", |
2421 | }, | 2411 | }, |
2422 | }, | 2412 | }, |
2423 | HoverGotoTypeData { | 2413 | HoverGotoTypeData { |
@@ -2463,7 +2453,7 @@ fn main() { let s$0t = S{ f1: S{ f1: Arg(0) } }; } | |||
2463 | focus_range: 24..25, | 2453 | focus_range: 24..25, |
2464 | name: "S", | 2454 | name: "S", |
2465 | kind: Struct, | 2455 | kind: Struct, |
2466 | description: "struct S", | 2456 | description: "struct S<T>", |
2467 | }, | 2457 | }, |
2468 | }, | 2458 | }, |
2469 | HoverGotoTypeData { | 2459 | HoverGotoTypeData { |
@@ -2605,7 +2595,7 @@ fn main() { let s$0t = foo(); } | |||
2605 | focus_range: 6..9, | 2595 | focus_range: 6..9, |
2606 | name: "Foo", | 2596 | name: "Foo", |
2607 | kind: Trait, | 2597 | kind: Trait, |
2608 | description: "trait Foo", | 2598 | description: "trait Foo<T>", |
2609 | }, | 2599 | }, |
2610 | }, | 2600 | }, |
2611 | HoverGotoTypeData { | 2601 | HoverGotoTypeData { |
@@ -2702,7 +2692,7 @@ fn main() { let s$0t = foo(); } | |||
2702 | focus_range: 6..9, | 2692 | focus_range: 6..9, |
2703 | name: "Foo", | 2693 | name: "Foo", |
2704 | kind: Trait, | 2694 | kind: Trait, |
2705 | description: "trait Foo", | 2695 | description: "trait Foo<T>", |
2706 | }, | 2696 | }, |
2707 | }, | 2697 | }, |
2708 | HoverGotoTypeData { | 2698 | HoverGotoTypeData { |
@@ -2715,7 +2705,7 @@ fn main() { let s$0t = foo(); } | |||
2715 | focus_range: 22..25, | 2705 | focus_range: 22..25, |
2716 | name: "Bar", | 2706 | name: "Bar", |
2717 | kind: Trait, | 2707 | kind: Trait, |
2718 | description: "trait Bar", | 2708 | description: "trait Bar<T>", |
2719 | }, | 2709 | }, |
2720 | }, | 2710 | }, |
2721 | HoverGotoTypeData { | 2711 | HoverGotoTypeData { |
@@ -2819,7 +2809,7 @@ fn foo(ar$0g: &impl Foo + Bar<S>) {} | |||
2819 | focus_range: 19..22, | 2809 | focus_range: 19..22, |
2820 | name: "Bar", | 2810 | name: "Bar", |
2821 | kind: Trait, | 2811 | kind: Trait, |
2822 | description: "trait Bar", | 2812 | description: "trait Bar<T>", |
2823 | }, | 2813 | }, |
2824 | }, | 2814 | }, |
2825 | HoverGotoTypeData { | 2815 | HoverGotoTypeData { |
@@ -2916,7 +2906,7 @@ fn foo(ar$0g: &impl Foo<S>) {} | |||
2916 | focus_range: 6..9, | 2906 | focus_range: 6..9, |
2917 | name: "Foo", | 2907 | name: "Foo", |
2918 | kind: Trait, | 2908 | kind: Trait, |
2919 | description: "trait Foo", | 2909 | description: "trait Foo<T>", |
2920 | }, | 2910 | }, |
2921 | }, | 2911 | }, |
2922 | HoverGotoTypeData { | 2912 | HoverGotoTypeData { |
@@ -2966,7 +2956,7 @@ fn main() { let s$0t = foo(); } | |||
2966 | focus_range: 49..50, | 2956 | focus_range: 49..50, |
2967 | name: "B", | 2957 | name: "B", |
2968 | kind: Struct, | 2958 | kind: Struct, |
2969 | description: "struct B", | 2959 | description: "struct B<T>", |
2970 | }, | 2960 | }, |
2971 | }, | 2961 | }, |
2972 | HoverGotoTypeData { | 2962 | HoverGotoTypeData { |
@@ -3042,7 +3032,7 @@ fn foo(ar$0g: &dyn Foo<S>) {} | |||
3042 | focus_range: 6..9, | 3032 | focus_range: 6..9, |
3043 | name: "Foo", | 3033 | name: "Foo", |
3044 | kind: Trait, | 3034 | kind: Trait, |
3045 | description: "trait Foo", | 3035 | description: "trait Foo<T>", |
3046 | }, | 3036 | }, |
3047 | }, | 3037 | }, |
3048 | HoverGotoTypeData { | 3038 | HoverGotoTypeData { |
@@ -3090,7 +3080,7 @@ fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
3090 | focus_range: 6..15, | 3080 | focus_range: 6..15, |
3091 | name: "ImplTrait", | 3081 | name: "ImplTrait", |
3092 | kind: Trait, | 3082 | kind: Trait, |
3093 | description: "trait ImplTrait", | 3083 | description: "trait ImplTrait<T>", |
3094 | }, | 3084 | }, |
3095 | }, | 3085 | }, |
3096 | HoverGotoTypeData { | 3086 | HoverGotoTypeData { |
@@ -3103,7 +3093,7 @@ fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
3103 | focus_range: 50..51, | 3093 | focus_range: 50..51, |
3104 | name: "B", | 3094 | name: "B", |
3105 | kind: Struct, | 3095 | kind: Struct, |
3106 | description: "struct B", | 3096 | description: "struct B<T>", |
3107 | }, | 3097 | }, |
3108 | }, | 3098 | }, |
3109 | HoverGotoTypeData { | 3099 | HoverGotoTypeData { |
@@ -3116,7 +3106,7 @@ fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
3116 | focus_range: 28..36, | 3106 | focus_range: 28..36, |
3117 | name: "DynTrait", | 3107 | name: "DynTrait", |
3118 | kind: Trait, | 3108 | kind: Trait, |
3119 | description: "trait DynTrait", | 3109 | description: "trait DynTrait<T>", |
3120 | }, | 3110 | }, |
3121 | }, | 3111 | }, |
3122 | HoverGotoTypeData { | 3112 | HoverGotoTypeData { |
@@ -3582,6 +3572,17 @@ mod foo$0; | |||
3582 | "#, | 3572 | "#, |
3583 | expect![[r#" | 3573 | expect![[r#" |
3584 | *foo* | 3574 | *foo* |
3575 | |||
3576 | ```rust | ||
3577 | test | ||
3578 | ``` | ||
3579 | |||
3580 | ```rust | ||
3581 | mod foo | ||
3582 | ``` | ||
3583 | |||
3584 | --- | ||
3585 | |||
3585 | For the horde! | 3586 | For the horde! |
3586 | "#]], | 3587 | "#]], |
3587 | ); | 3588 | ); |
@@ -3606,7 +3607,7 @@ use foo::bar::{self$0}; | |||
3606 | ``` | 3607 | ``` |
3607 | 3608 | ||
3608 | ```rust | 3609 | ```rust |
3609 | pub mod bar | 3610 | mod bar |
3610 | ``` | 3611 | ``` |
3611 | 3612 | ||
3612 | --- | 3613 | --- |
@@ -3657,4 +3658,43 @@ cosnt _: &str$0 = ""; }"#; | |||
3657 | "#]], | 3658 | "#]], |
3658 | ); | 3659 | ); |
3659 | } | 3660 | } |
3661 | |||
3662 | #[test] | ||
3663 | fn hover_macro_expanded_function() { | ||
3664 | check( | ||
3665 | r#" | ||
3666 | struct S<'a, T>(&'a T); | ||
3667 | trait Clone {} | ||
3668 | macro_rules! foo { | ||
3669 | () => { | ||
3670 | fn bar<'t, T: Clone + 't>(s: &mut S<'t, T>, t: u32) -> *mut u32 where | ||
3671 | 't: 't + 't, | ||
3672 | for<'a> T: Clone + 'a | ||
3673 | { 0 as _ } | ||
3674 | }; | ||
3675 | } | ||
3676 | |||
3677 | foo!(); | ||
3678 | |||
3679 | fn main() { | ||
3680 | bar$0; | ||
3681 | } | ||
3682 | "#, | ||
3683 | expect![[r#" | ||
3684 | *bar* | ||
3685 | |||
3686 | ```rust | ||
3687 | test | ||
3688 | ``` | ||
3689 | |||
3690 | ```rust | ||
3691 | fn bar<'t, T>(s: &mut S<'t, T>, t: u32) -> *mut u32 | ||
3692 | where | ||
3693 | T: Clone + 't, | ||
3694 | 't: 't + 't, | ||
3695 | for<'a> T: Clone + 'a, | ||
3696 | ``` | ||
3697 | "#]], | ||
3698 | ) | ||
3699 | } | ||
3660 | } | 3700 | } |