10805: ide: dedupe or merge hover actions r=Veykril a=jhgg

fixes #10780 

Co-authored-by: Jake Heinz <jh@discordapp.com>
This commit is contained in:
bors[bot] 2021-11-19 10:59:49 +00:00 committed by GitHub
commit 2507442382
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 20 deletions

View File

@ -11,7 +11,7 @@
base_db::FileRange, base_db::FileRange,
defs::Definition, defs::Definition,
helpers::{pick_best_token, FamousDefs}, helpers::{pick_best_token, FamousDefs},
RootDatabase, FxIndexSet, RootDatabase,
}; };
use itertools::Itertools; use itertools::Itertools;
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T}; use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T};
@ -69,7 +69,7 @@ fn goto_type_from_targets(db: &RootDatabase, targets: Vec<hir::ModuleDef>) -> Se
} }
} }
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct HoverGotoTypeData { pub struct HoverGotoTypeData {
pub mod_path: String, pub mod_path: String,
pub nav: NavigationTarget, pub nav: NavigationTarget,
@ -136,11 +136,12 @@ pub(crate) fn hover(
.flatten() .flatten()
.unique_by(|&(def, _)| def) .unique_by(|&(def, _)| def)
.filter_map(|(def, node)| hover_for_definition(sema, file_id, def, &node, config)) .filter_map(|(def, node)| hover_for_definition(sema, file_id, def, &node, config))
.reduce(|mut acc, HoverResult { markup, actions }| { .reduce(|mut acc: HoverResult, HoverResult { markup, actions }| {
acc.actions.extend(actions); acc.actions.extend(actions);
acc.markup = Markup::from(format!("{}\n---\n{}", acc.markup, markup)); acc.markup = Markup::from(format!("{}\n---\n{}", acc.markup, markup));
acc acc
}); });
if result.is_none() { if result.is_none() {
// fallbacks, show keywords or types // fallbacks, show keywords or types
if let Some(res) = render::keyword(sema, config, &original_token) { if let Some(res) = render::keyword(sema, config, &original_token) {
@ -152,7 +153,10 @@ pub(crate) fn hover(
return res; return res;
} }
} }
result.map(|res| RangeInfo::new(original_token.text_range(), res)) result.map(|mut res: HoverResult| {
res.actions = dedupe_or_merge_hover_actions(res.actions);
RangeInfo::new(original_token.text_range(), res)
})
} }
pub(crate) fn hover_for_definition( pub(crate) fn hover_for_definition(
@ -341,3 +345,43 @@ fn walk_and_push_ty(
} }
}); });
} }
fn dedupe_or_merge_hover_actions(actions: Vec<HoverAction>) -> Vec<HoverAction> {
let mut deduped_actions = Vec::with_capacity(actions.len());
let mut go_to_type_targets = FxIndexSet::default();
let mut seen_implementation = false;
let mut seen_reference = false;
let mut seen_runnable = false;
for action in actions {
match action {
HoverAction::GoToType(targets) => {
go_to_type_targets.extend(targets);
}
HoverAction::Implementation(..) => {
if !seen_implementation {
seen_implementation = true;
deduped_actions.push(action);
}
}
HoverAction::Reference(..) => {
if !seen_reference {
seen_reference = true;
deduped_actions.push(action);
}
}
HoverAction::Runnable(..) => {
if !seen_runnable {
seen_runnable = true;
deduped_actions.push(action);
}
}
};
}
if !go_to_type_targets.is_empty() {
deduped_actions.push(HoverAction::GoToType(go_to_type_targets.into_iter().collect()));
}
deduped_actions
}

View File

@ -173,7 +173,7 @@ fn abc()
--- ---
Outer Outer
"#]], "#]],
); );
} }
@ -1135,6 +1135,39 @@ fn bar() -> bool
); );
} }
#[test]
fn test_hover_multiple_actions() {
check_actions(
r#"
struct Bar;
struct Foo { bar: Bar }
fn foo(Foo { b$0ar }: &Foo) {}
"#,
expect![[r#"
[
GoToType(
[
HoverGotoTypeData {
mod_path: "test::Bar",
nav: NavigationTarget {
file_id: FileId(
0,
),
full_range: 0..11,
focus_range: 7..10,
name: "Bar",
kind: Struct,
description: "struct Bar",
},
},
],
),
]
"#]],
)
}
#[test] #[test]
fn test_hover_through_literal_string_in_builtin_macro() { fn test_hover_through_literal_string_in_builtin_macro() {
check_hover_no_result( check_hover_no_result(
@ -1750,9 +1783,6 @@ fn foo_$0test() {}
cfg: None, cfg: None,
}, },
), ),
GoToType(
[],
),
] ]
"#]], "#]],
); );
@ -2749,21 +2779,21 @@ fn main() {
} }
"#, "#,
expect![[r#" expect![[r#"
*f* *f*
```rust ```rust
f: &i32 f: &i32
``` ```
--- ---
```rust ```rust
test::S test::S
``` ```
```rust ```rust
f: i32 f: i32
``` ```
"#]], "#]],
); );
} }