Remove hover fallback in favor of ranged hover

This commit is contained in:
Lukas Wirth 2023-01-20 16:36:24 +01:00
parent a542bd46bf
commit 4685b97f74
2 changed files with 27 additions and 131 deletions

View File

@ -15,7 +15,7 @@ use ide_db::{
FxIndexSet, RootDatabase,
};
use itertools::Itertools;
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T};
use syntax::{ast, AstNode, SyntaxKind::*, SyntaxNode, T};
use crate::{
doc_links::token_as_doc_comment,
@ -203,14 +203,10 @@ fn hover_simple(
})
});
result
.map(|mut res: HoverResult| {
res.actions = dedupe_or_merge_hover_actions(res.actions);
RangeInfo::new(original_token.text_range(), res)
})
// fallback to type hover if there aren't any other suggestions
// this finds its own range instead of using the closest token's range
.or_else(|| descended().find_map(|token| hover_type_fallback(sema, config, token, token)))
result.map(|mut res: HoverResult| {
res.actions = dedupe_or_merge_hover_actions(res.actions);
RangeInfo::new(original_token.text_range(), res)
})
}
fn hover_ranged(
@ -220,8 +216,11 @@ fn hover_ranged(
config: &HoverConfig,
) -> Option<RangeInfo<HoverResult>> {
// FIXME: make this work in attributes
let expr_or_pat =
file.covering_element(range).ancestors().find_map(Either::<ast::Expr, ast::Pat>::cast)?;
let expr_or_pat = file
.covering_element(range)
.ancestors()
.take_while(|it| ast::MacroCall::can_cast(it.kind()) || !ast::Item::can_cast(it.kind()))
.find_map(Either::<ast::Expr, ast::Pat>::cast)?;
let res = match &expr_or_pat {
Either::Left(ast::Expr::TryExpr(try_expr)) => render::try_expr(sema, config, try_expr),
Either::Left(ast::Expr::PrefixExpr(prefix_expr))
@ -268,39 +267,6 @@ pub(crate) fn hover_for_definition(
})
}
fn hover_type_fallback(
sema: &Semantics<'_, RootDatabase>,
config: &HoverConfig,
token: &SyntaxToken,
original_token: &SyntaxToken,
) -> Option<RangeInfo<HoverResult>> {
let node =
token.parent_ancestors().take_while(|it| !ast::Item::can_cast(it.kind())).find(|n| {
ast::Expr::can_cast(n.kind())
|| ast::Pat::can_cast(n.kind())
|| ast::Type::can_cast(n.kind())
})?;
let expr_or_pat = match_ast! {
match node {
ast::Expr(it) => Either::Left(it),
ast::Pat(it) => Either::Right(it),
// If this node is a MACRO_CALL, it means that `descend_into_macros_many` failed to resolve.
// (e.g expanding a builtin macro). So we give up here.
ast::MacroCall(_it) => return None,
_ => return None,
}
};
let res = render::type_info_of(sema, config, &expr_or_pat)?;
let range = sema
.original_range_opt(&node)
.map(|frange| frange.range)
.unwrap_or_else(|| original_token.text_range());
Some(RangeInfo::new(range, res))
}
fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
fn to_action(nav_target: NavigationTarget) -> HoverAction {
HoverAction::Implementation(FilePosition {

View File

@ -213,25 +213,6 @@ m!(ab$0c);
);
}
#[test]
fn hover_shows_type_of_an_expression() {
check(
r#"
pub fn foo() -> u32 { 1 }
fn main() {
let foo_test = foo()$0;
}
"#,
expect![[r#"
*foo()*
```rust
u32
```
"#]],
);
}
#[test]
fn hover_remove_markdown_if_configured() {
check_hover_no_markdown(
@ -239,12 +220,14 @@ fn hover_remove_markdown_if_configured() {
pub fn foo() -> u32 { 1 }
fn main() {
let foo_test = foo()$0;
let foo_test = foo$0();
}
"#,
expect![[r#"
*foo()*
u32
*foo*
test
pub fn foo() -> u32
"#]],
);
}
@ -304,33 +287,6 @@ fn main() { let foo_test = fo$0o(); }
"#]],
);
// Multiple candidates but results are ambiguous.
check(
r#"
//- /a.rs
pub fn foo() -> u32 { 1 }
//- /b.rs
pub fn foo() -> &str { "" }
//- /c.rs
pub fn foo(a: u32, b: u32) {}
//- /main.rs
mod a;
mod b;
mod c;
fn main() { let foo_test = fo$0o(); }
"#,
expect![[r#"
*foo*
```rust
{unknown}
```
"#]],
);
// Use literal `crate` in path
check(
r#"
@ -1194,33 +1150,19 @@ fn test_hover_through_func_in_macro_recursive() {
macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } }
macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
fn bar() -> u32 { 0 }
fn foo() { let a = id!([0u32, bar($0)] ); }
fn foo() { let a = id!([0u32, bar$0()] ); }
"#,
expect![[r#"
*bar()*
```rust
u32
```
"#]],
);
}
*bar*
#[test]
fn test_hover_through_literal_string_in_macro() {
check(
r#"
macro_rules! arr { ($($tt:tt)*) => { [$($tt)*] } }
fn foo() {
let mastered_for_itunes = "";
let _ = arr!("Tr$0acks", &mastered_for_itunes);
}
"#,
expect![[r#"
*"Tracks"*
```rust
&str
```
"#]],
```rust
test
```
```rust
fn bar() -> u32
```
"#]],
);
}
@ -5655,30 +5597,18 @@ fn main() {
#[test]
fn hover_underscore_type() {
check(
check_hover_no_result(
r#"
fn main() {
let x: _$0 = 0;
}
"#,
expect![[r#"
*_*
```rust
{unknown}
```
"#]],
);
check(
check_hover_no_result(
r#"
fn main() {
let x: (_$0,) = (0,);
}
"#,
expect![[r#"
*_*
```rust
{unknown}
```
"#]],
);
}