diff options
Diffstat (limited to 'crates/ra_ide/src/hover.rs')
-rw-r--r-- | crates/ra_ide/src/hover.rs | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index d372ca758..51e320128 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -6,6 +6,8 @@ use ra_syntax::{ | |||
6 | algo::find_covering_element, | 6 | algo::find_covering_element, |
7 | ast::{self, DocCommentsOwner}, | 7 | ast::{self, DocCommentsOwner}, |
8 | match_ast, AstNode, | 8 | match_ast, AstNode, |
9 | SyntaxKind::*, | ||
10 | SyntaxToken, TokenAtOffset, | ||
9 | }; | 11 | }; |
10 | 12 | ||
11 | use crate::{ | 13 | use crate::{ |
@@ -156,7 +158,7 @@ fn hover_text_from_name_kind( | |||
156 | 158 | ||
157 | pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> { | 159 | pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> { |
158 | let file = db.parse_or_expand(position.file_id.into())?; | 160 | let file = db.parse_or_expand(position.file_id.into())?; |
159 | let token = file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?; | 161 | let token = pick_best(file.token_at_offset(position.offset))?; |
160 | let token = descend_into_macros(db, position.file_id, token); | 162 | let token = descend_into_macros(db, position.file_id, token); |
161 | 163 | ||
162 | let mut res = HoverResult::new(); | 164 | let mut res = HoverResult::new(); |
@@ -218,6 +220,18 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
218 | Some(RangeInfo::new(range, res)) | 220 | Some(RangeInfo::new(range, res)) |
219 | } | 221 | } |
220 | 222 | ||
223 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | ||
224 | return tokens.max_by_key(priority); | ||
225 | fn priority(n: &SyntaxToken) -> usize { | ||
226 | match n.kind() { | ||
227 | IDENT | INT_NUMBER => 3, | ||
228 | L_PAREN | R_PAREN => 2, | ||
229 | kind if kind.is_trivia() => 0, | ||
230 | _ => 1, | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | |||
221 | pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { | 235 | pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { |
222 | let parse = db.parse(frange.file_id); | 236 | let parse = db.parse(frange.file_id); |
223 | let leaf_node = find_covering_element(parse.tree().syntax(), frange.range); | 237 | let leaf_node = find_covering_element(parse.tree().syntax(), frange.range); |
@@ -505,6 +519,13 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
505 | } | 519 | } |
506 | 520 | ||
507 | #[test] | 521 | #[test] |
522 | fn hover_for_param_edge() { | ||
523 | let (analysis, position) = single_file_with_position("fn func(<|>foo: i32) {}"); | ||
524 | let hover = analysis.hover(position).unwrap().unwrap(); | ||
525 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); | ||
526 | } | ||
527 | |||
528 | #[test] | ||
508 | fn test_type_of_for_function() { | 529 | fn test_type_of_for_function() { |
509 | let (analysis, range) = single_file_with_range( | 530 | let (analysis, range) = single_file_with_range( |
510 | " | 531 | " |