Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/hover.rs')
-rw-r--r--crates/ide/src/hover.rs82
1 files changed, 55 insertions, 27 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 03b9b36775..958de8930d 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -6,34 +6,34 @@ mod tests;
use std::{iter, ops::Not};
use either::Either;
-use hir::{
- DisplayTarget, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics,
- db::DefDatabase,
-};
+use hir::{DisplayTarget, GenericDef, GenericSubstitution, HasCrate, HasSource, Semantics};
use ide_db::{
- FileRange, FxIndexSet, Ranker, RootDatabase,
+ FileRange, FxIndexSet, MiniCore, Ranker, RootDatabase,
defs::{Definition, IdentClass, NameRefClass, OperatorClass},
famous_defs::FamousDefs,
helpers::pick_best_token,
+ ra_fixture::UpmapFromRaFixture,
};
use itertools::{Itertools, multizip};
-use span::Edition;
+use macros::UpmapFromRaFixture;
+use span::{Edition, TextRange};
use syntax::{
- AstNode,
+ AstNode, AstToken,
SyntaxKind::{self, *},
SyntaxNode, T, ast,
};
use crate::{
- FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, TryToNav,
+ Analysis, FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, TryToNav,
doc_links::token_as_doc_comment,
markdown_remove::remove_markdown,
markup::Markup,
navigation_target::UpmappingResult,
runnables::{runnable_fn, runnable_mod},
};
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct HoverConfig {
+
+#[derive(Clone, Debug)]
+pub struct HoverConfig<'a> {
pub links_in_hover: bool,
pub memory_layout: Option<MemoryLayoutHoverConfig>,
pub documentation: bool,
@@ -44,6 +44,7 @@ pub struct HoverConfig {
pub max_enum_variants_count: Option<usize>,
pub max_subst_ty_len: SubstTyLen,
pub show_drop_glue: bool,
+ pub minicore: MiniCore<'a>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -75,7 +76,7 @@ pub enum HoverDocFormat {
PlainText,
}
-#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Clone, Hash, PartialEq, Eq, UpmapFromRaFixture)]
pub enum HoverAction {
Runnable(Runnable),
Implementation(FilePosition),
@@ -108,14 +109,14 @@ impl HoverAction {
}
}
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash, UpmapFromRaFixture)]
pub struct HoverGotoTypeData {
pub mod_path: String,
pub nav: NavigationTarget,
}
/// Contains the results when hovering over an item
-#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
+#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, UpmapFromRaFixture)]
pub struct HoverResult {
pub markup: Markup,
pub actions: Vec<HoverAction>,
@@ -130,12 +131,11 @@ pub struct HoverResult {
pub(crate) fn hover(
db: &RootDatabase,
frange @ FileRange { file_id, range }: FileRange,
- config: &HoverConfig,
+ config: &HoverConfig<'_>,
) -> Option<RangeInfo<HoverResult>> {
let sema = &hir::Semantics::new(db);
let file = sema.parse_guess_edition(file_id).syntax().clone();
- let edition =
- sema.attach_first_edition(file_id).map(|it| it.edition(db)).unwrap_or(Edition::CURRENT);
+ let edition = sema.attach_first_edition(file_id).edition(db);
let display_target = sema.first_crate(file_id)?.to_display_target(db);
let mut res = if range.is_empty() {
hover_offset(
@@ -161,7 +161,7 @@ fn hover_offset(
sema: &Semantics<'_, RootDatabase>,
FilePosition { file_id, offset }: FilePosition,
file: SyntaxNode,
- config: &HoverConfig,
+ config: &HoverConfig<'_>,
edition: Edition,
display_target: DisplayTarget,
) -> Option<RangeInfo<HoverResult>> {
@@ -219,6 +219,21 @@ fn hover_offset(
return Some(RangeInfo::new(range, res));
}
+ if let Some(literal) = ast::String::cast(original_token.clone())
+ && let Some((analysis, fixture_analysis)) =
+ Analysis::from_ra_fixture(sema, literal.clone(), &literal, config.minicore)
+ {
+ let (virtual_file_id, virtual_offset) = fixture_analysis.map_offset_down(offset)?;
+ return analysis
+ .hover(
+ config,
+ FileRange { file_id: virtual_file_id, range: TextRange::empty(virtual_offset) },
+ )
+ .ok()??
+ .upmap_from_ra_fixture(&fixture_analysis, virtual_file_id, file_id)
+ .ok();
+ }
+
// prefer descending the same token kind in attribute expansions, in normal macros text
// equivalency is more important
let mut descended = sema.descend_into_macros(original_token.clone());
@@ -383,9 +398,9 @@ fn hover_offset(
fn hover_ranged(
sema: &Semantics<'_, RootDatabase>,
- FileRange { range, .. }: FileRange,
+ FileRange { file_id, range }: FileRange,
file: SyntaxNode,
- config: &HoverConfig,
+ config: &HoverConfig<'_>,
edition: Edition,
display_target: DisplayTarget,
) -> Option<RangeInfo<HoverResult>> {
@@ -404,6 +419,20 @@ fn hover_ranged(
{
render::deref_expr(sema, config, prefix_expr, edition, display_target)
}
+ Either::Left(ast::Expr::Literal(literal)) => {
+ if let Some(literal) = ast::String::cast(literal.token())
+ && let Some((analysis, fixture_analysis)) =
+ Analysis::from_ra_fixture(sema, literal.clone(), &literal, config.minicore)
+ {
+ let (virtual_file_id, virtual_range) = fixture_analysis.map_range_down(range)?;
+ return analysis
+ .hover(config, FileRange { file_id: virtual_file_id, range: virtual_range })
+ .ok()??
+ .upmap_from_ra_fixture(&fixture_analysis, virtual_file_id, file_id)
+ .ok();
+ }
+ None
+ }
_ => None,
};
let res =
@@ -426,7 +455,7 @@ pub(crate) fn hover_for_definition(
scope_node: &SyntaxNode,
macro_arm: Option<u32>,
render_extras: bool,
- config: &HoverConfig,
+ config: &HoverConfig<'_>,
edition: Edition,
display_target: DisplayTarget,
) -> HoverResult {
@@ -440,7 +469,7 @@ pub(crate) fn hover_for_definition(
Definition::Local(it) => Some(it.ty(db)),
Definition::GenericParam(hir::GenericParam::ConstParam(it)) => Some(it.ty(db)),
Definition::GenericParam(hir::GenericParam::TypeParam(it)) => Some(it.ty(db)),
- Definition::Field(field) => Some(field.ty(db)),
+ Definition::Field(field) => Some(field.ty(db).to_type(db)),
Definition::TupleField(it) => Some(it.ty(db)),
Definition::Function(it) => Some(it.ty(db)),
Definition::Adt(it) => Some(it.ty(db)),
@@ -489,9 +518,8 @@ fn notable_traits<'db>(
return Vec::new();
}
- db.notable_traits_in_deps(ty.krate(db).into())
- .iter()
- .flat_map(|it| &**it)
+ ty.krate(db)
+ .notable_traits_in_deps(db)
.filter_map(move |&trait_| {
let trait_ = trait_.into();
ty.impls_trait(db, trait_, &[]).then(|| {
@@ -602,7 +630,7 @@ fn goto_type_action_for_def(
let ty = match def {
Definition::Local(it) => Some(it.ty(db)),
- Definition::Field(field) => Some(field.ty(db)),
+ Definition::Field(field) => Some(field.ty(db).to_type(db)),
Definition::TupleField(field) => Some(field.ty(db)),
Definition::Const(it) => Some(it.ty(db)),
Definition::Static(it) => Some(it.ty(db)),
@@ -644,10 +672,10 @@ fn walk_and_push_ty(
} else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
push_new_def(trait_.into());
} else if let Some(tp) = t.as_type_param(db) {
- let sized_trait = LangItem::Sized.resolve_trait(db, t.krate(db).into());
+ let sized_trait = hir::Trait::lang(db, t.krate(db), hir::LangItem::Sized);
tp.trait_bounds(db)
.into_iter()
- .filter(|&it| Some(it.into()) != sized_trait)
+ .filter(|&it| Some(it) != sized_trait)
.for_each(|it| push_new_def(it.into()));
}
});