use hir::{HasSource, Semantics};
use ide_db::{
base_db::FileRange,
- defs::Definition,
+ defs::{Definition, IdentClass},
helpers::{pick_best_token, FamousDefs},
FxIndexSet, RootDatabase,
};
let descended = sema.descend_into_macros(original_token.clone());
// FIXME: Definition should include known lints and the like instead of having this special case here
- if let Some(res) = descended.iter().find_map(|token| {
+ let hovered_lint = descended.iter().find_map(|token| {
let attr = token.ancestors().find_map(ast::Attr::cast)?;
render::try_for_lint(&attr, token)
- }) {
+ });
+ if let Some(res) = hovered_lint {
return Some(RangeInfo::new(original_token.text_range(), res));
}
.iter()
.filter_map(|token| {
let node = token.parent()?;
- let defs = Definition::from_token(sema, token);
- Some(defs.into_iter().zip(iter::once(node).cycle()))
+ let class = IdentClass::classify_token(sema, token)?;
+ Some(class.definitions().into_iter().zip(iter::once(node).cycle()))
})
.flatten()
.unique_by(|&(def, _)| def)
if result.is_none() {
// fallbacks, show keywords or types
- if let Some(res) = render::keyword(sema, config, &original_token) {
+
+ let res = descended.iter().find_map(|token| render::keyword(sema, config, &token));
+ if let Some(res) = res {
return Some(RangeInfo::new(original_token.text_range(), res));
}
- if let res @ Some(_) =
- descended.iter().find_map(|token| hover_type_fallback(sema, config, token))
- {
+ let res = descended
+ .iter()
+ .find_map(|token| hover_type_fallback(sema, config, token, &original_token));
+ if let res @ Some(_) = res {
return res;
}
}
sema: &Semantics<RootDatabase>,
config: &HoverConfig,
) -> Option<RangeInfo<HoverResult>> {
+ // FIXME: make this work in attributes
let expr_or_pat = file.covering_element(range).ancestors().find_map(|it| {
match_ast! {
match it {
sema: &Semantics<RootDatabase>,
config: &HoverConfig,
token: &SyntaxToken,
+ original_token: &SyntaxToken,
) -> Option<RangeInfo<HoverResult>> {
let node = token
.ancestors()
};
let res = render::type_info(sema, config, &expr_or_pat)?;
- let range = sema.original_range(&node).range;
+ let range = sema
+ .original_range_opt(&node)
+ .map(|frange| frange.range)
+ .unwrap_or_else(|| original_token.text_range());
Some(RangeInfo::new(range, res))
}
} else if let Some(trait_) = t.as_dyn_trait() {
push_new_def(trait_.into());
} else if let Some(traits) = t.as_impl_traits(db) {
- traits.into_iter().for_each(|it| push_new_def(it.into()));
+ traits.for_each(|it| push_new_def(it.into()));
} else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
push_new_def(trait_.into());
}