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,
defs::Definition,
helpers::{pick_best_token, FamousDefs},
RootDatabase,
FxIndexSet, RootDatabase,
};
use itertools::Itertools;
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 mod_path: String,
pub nav: NavigationTarget,
@ -136,11 +136,12 @@ pub(crate) fn hover(
.flatten()
.unique_by(|&(def, _)| def)
.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.markup = Markup::from(format!("{}\n---\n{}", acc.markup, markup));
acc
});
if result.is_none() {
// fallbacks, show keywords or types
if let Some(res) = render::keyword(sema, config, &original_token) {
@ -152,7 +153,10 @@ pub(crate) fn hover(
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(
@ -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
"#]],
"#]],
);
}
@ -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]
fn test_hover_through_literal_string_in_builtin_macro() {
check_hover_no_result(
@ -1750,9 +1783,6 @@ fn foo_$0test() {}
cfg: None,
},
),
GoToType(
[],
),
]
"#]],
);
@ -2749,21 +2779,21 @@ fn main() {
}
"#,
expect![[r#"
*f*
*f*
```rust
f: &i32
```
---
```rust
f: &i32
```
---
```rust
test::S
```
```rust
test::S
```
```rust
f: i32
```
"#]],
```rust
f: i32
```
"#]],
);
}