Skip to content

Commit 41943f2

Browse files
committed
refactor: Apply PR suggestions
1 parent 743c037 commit 41943f2

File tree

4 files changed

+49
-70
lines changed

4 files changed

+49
-70
lines changed

crates/ide/src/hover.rs

+40-47
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,41 @@ pub struct HoverResult {
7171
pub actions: Vec<HoverAction>,
7272
}
7373

74-
/// Feature: Hover
75-
///
76-
/// Shows additional information, like the type of an expression or the documentation for a definition when "focusing" code.
77-
/// Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
78-
///
79-
/// image::https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif
74+
// Feature: Hover
75+
//
76+
// Shows additional information, like the type of an expression or the documentation for a definition when "focusing" code.
77+
// Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
78+
//
79+
// image::https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif
8080
pub(crate) fn hover(
8181
db: &RootDatabase,
82-
position: FilePosition,
82+
range: FileRange,
8383
config: &HoverConfig,
8484
) -> Option<RangeInfo<HoverResult>> {
8585
let sema = hir::Semantics::new(db);
86-
let file = sema.parse(position.file_id).syntax().clone();
86+
let file = sema.parse(range.file_id).syntax().clone();
87+
88+
// This means we're hovering over a range.
89+
if !range.range.is_empty() {
90+
let expr = find_node_at_range::<ast::Expr>(&file, range.range)?;
91+
let ty = sema.type_of_expr(&expr)?;
92+
93+
if ty.is_unknown() {
94+
return None;
95+
}
96+
97+
let mut res = HoverResult::default();
98+
99+
res.markup = if config.markdown() {
100+
Markup::fenced_block(&ty.display(db))
101+
} else {
102+
ty.display(db).to_string().into()
103+
};
104+
105+
return Some(RangeInfo::new(range.range, res));
106+
}
107+
108+
let position = FilePosition { file_id: range.file_id, offset: range.range.start() };
87109
let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
88110
IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] => 3,
89111
T!['('] | T![')'] => 2,
@@ -197,6 +219,7 @@ pub(crate) fn hover(
197219
} else {
198220
ty.display(db).to_string().into()
199221
};
222+
200223
let range = sema.original_range(&node).range;
201224
Some(RangeInfo::new(range, res))
202225
}
@@ -245,37 +268,6 @@ fn try_hover_for_lint(attr: &ast::Attr, token: &SyntaxToken) -> Option<RangeInfo
245268
))
246269
}
247270

248-
/// LSP Extension: Hover over a range
249-
///
250-
/// Gets the type of the expression closest to the selection if the user is hovering inside
251-
/// the selection. If not, it is handled by `handle_hover`.
252-
///
253-
/// https://user-images.githubusercontent.com/22298999/126914293-0ce49a92-545d-4005-a59e-9294fa2330d6.gif
254-
pub(crate) fn hover_range(
255-
db: &RootDatabase,
256-
range: FileRange,
257-
config: &HoverConfig,
258-
) -> Option<RangeInfo<HoverResult>> {
259-
let sema = hir::Semantics::new(db);
260-
let file = sema.parse(range.file_id).syntax().clone();
261-
let expr = find_node_at_range::<ast::Expr>(&file, range.range)?;
262-
let ty = sema.type_of_expr(&expr)?;
263-
264-
if ty.is_unknown() {
265-
return None;
266-
}
267-
268-
let mut res = HoverResult::default();
269-
270-
res.markup = if config.markdown() {
271-
Markup::fenced_block(&ty.display(db))
272-
} else {
273-
ty.display(db).to_string().into()
274-
};
275-
276-
Some(RangeInfo::new(range.range, res))
277-
}
278-
279271
fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
280272
fn to_action(nav_target: NavigationTarget) -> HoverAction {
281273
HoverAction::Implementation(FilePosition {
@@ -565,7 +557,8 @@ fn find_std_module(famous_defs: &FamousDefs, name: &str) -> Option<hir::Module>
565557
#[cfg(test)]
566558
mod tests {
567559
use expect_test::{expect, Expect};
568-
use ide_db::base_db::FileLoader;
560+
use ide_db::base_db::{FileLoader, FileRange};
561+
use syntax::TextRange;
569562

570563
use crate::{fixture, hover::HoverDocFormat, HoverConfig};
571564

@@ -577,7 +570,7 @@ mod tests {
577570
links_in_hover: true,
578571
documentation: Some(HoverDocFormat::Markdown),
579572
},
580-
position,
573+
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
581574
)
582575
.unwrap();
583576
assert!(hover.is_none());
@@ -591,7 +584,7 @@ mod tests {
591584
links_in_hover: true,
592585
documentation: Some(HoverDocFormat::Markdown),
593586
},
594-
position,
587+
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
595588
)
596589
.unwrap()
597590
.unwrap();
@@ -611,7 +604,7 @@ mod tests {
611604
links_in_hover: false,
612605
documentation: Some(HoverDocFormat::Markdown),
613606
},
614-
position,
607+
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
615608
)
616609
.unwrap()
617610
.unwrap();
@@ -631,7 +624,7 @@ mod tests {
631624
links_in_hover: true,
632625
documentation: Some(HoverDocFormat::PlainText),
633626
},
634-
position,
627+
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
635628
)
636629
.unwrap()
637630
.unwrap();
@@ -651,7 +644,7 @@ mod tests {
651644
links_in_hover: true,
652645
documentation: Some(HoverDocFormat::Markdown),
653646
},
654-
position,
647+
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
655648
)
656649
.unwrap()
657650
.unwrap();
@@ -661,7 +654,7 @@ mod tests {
661654
fn check_hover_range(ra_fixture: &str, expect: Expect) {
662655
let (analysis, range) = fixture::range(ra_fixture);
663656
let hover = analysis
664-
.hover_range(
657+
.hover(
665658
&HoverConfig {
666659
links_in_hover: false,
667660
documentation: Some(HoverDocFormat::Markdown),
@@ -676,7 +669,7 @@ mod tests {
676669
fn check_hover_range_no_results(ra_fixture: &str) {
677670
let (analysis, range) = fixture::range(ra_fixture);
678671
let hover = analysis
679-
.hover_range(
672+
.hover(
680673
&HoverConfig {
681674
links_in_hover: false,
682675
documentation: Some(HoverDocFormat::Markdown),

crates/ide/src/lib.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -416,20 +416,11 @@ impl Analysis {
416416

417417
/// Returns a short text describing element at position.
418418
pub fn hover(
419-
&self,
420-
config: &HoverConfig,
421-
position: FilePosition,
422-
) -> Cancellable<Option<RangeInfo<HoverResult>>> {
423-
self.with_db(|db| hover::hover(db, position, config))
424-
}
425-
426-
/// Returns a short text displaying the type of the expression.
427-
pub fn hover_range(
428419
&self,
429420
config: &HoverConfig,
430421
range: FileRange,
431422
) -> Cancellable<Option<RangeInfo<HoverResult>>> {
432-
self.with_db(|db| hover::hover_range(db, range, config))
423+
self.with_db(|db| hover::hover(db, range, config))
433424
}
434425

435426
/// Return URL(s) for the documentation of the symbol under the cursor.

crates/rust-analyzer/src/handlers.rs

+6-13
Original file line numberDiff line numberDiff line change
@@ -874,21 +874,14 @@ pub(crate) fn handle_hover(
874874
) -> Result<Option<lsp_ext::Hover>> {
875875
let _p = profile::span("handle_hover");
876876
let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
877-
let hover_result = match params.position {
878-
PositionOrRange::Position(position) => {
879-
let position = from_proto::file_position(
880-
&snap,
881-
lsp_types::TextDocumentPositionParams::new(params.text_document, position),
882-
)?;
883-
snap.analysis.hover(&snap.config.hover(), position)?
884-
}
885-
PositionOrRange::Range(range) => {
886-
let range = from_proto::file_range(&snap, params.text_document, range)?;
887-
snap.analysis.hover_range(&snap.config.hover(), range)?
888-
}
877+
878+
let range = match params.position {
879+
PositionOrRange::Position(position) => Range::new(position, position),
880+
PositionOrRange::Range(range) => range,
889881
};
890882

891-
let info = match hover_result {
883+
let file_range = from_proto::file_range(&snap, params.text_document, range)?;
884+
let info = match snap.analysis.hover(&snap.config.hover(), file_range)? {
892885
None => return Ok(None),
893886
Some(info) => info,
894887
};

docs/dev/lsp-extensions.md

+2
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,8 @@ interface TestInfo {
662662

663663
**Issue:** https://github.com/microsoft/language-server-protocol/issues/377
664664

665+
**Experimental Server Capability:** { "hoverRange": boolean }
666+
665667
This request build upon the current `textDocument/hover` to show the type of the expression currently selected.
666668

667669
```typescript

0 commit comments

Comments
 (0)