Classify name takes const patterns into account
This commit is contained in:
parent
9ef6359950
commit
209eb32796
6 changed files with 44 additions and 23 deletions
|
@ -30,7 +30,9 @@ pub(crate) fn goto_definition(
|
||||||
reference_definition(&sema, &name_ref).to_vec()
|
reference_definition(&sema, &name_ref).to_vec()
|
||||||
},
|
},
|
||||||
ast::Name(name) => {
|
ast::Name(name) => {
|
||||||
name_definition(&sema, &name)?
|
let def = classify_name(&sema, &name)?.definition();
|
||||||
|
let nav = def.try_to_nav(sema.db)?;
|
||||||
|
vec![nav]
|
||||||
},
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
|
@ -88,15 +90,6 @@ pub(crate) fn reference_definition(
|
||||||
Approximate(navs)
|
Approximate(navs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name_definition(
|
|
||||||
sema: &Semantics<RootDatabase>,
|
|
||||||
name: &ast::Name,
|
|
||||||
) -> Option<Vec<NavigationTarget>> {
|
|
||||||
let def = classify_name(sema, name)?;
|
|
||||||
let nav = def.try_to_nav(sema.db)?;
|
|
||||||
Some(vec![nav])
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::{assert_eq_text, covers};
|
use test_utils::{assert_eq_text, covers};
|
||||||
|
|
|
@ -156,7 +156,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
|
||||||
classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d))
|
classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d))
|
||||||
},
|
},
|
||||||
ast::Name(name) => {
|
ast::Name(name) => {
|
||||||
classify_name(&sema, &name).map(|d| (name.syntax().clone(), d))
|
classify_name(&sema, &name).map(|d| (name.syntax().clone(), d.definition()))
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -761,13 +761,13 @@ fn func(foo: i32) { if true { <|>foo; }; }
|
||||||
fn test_hover_through_literal_string_in_builtin_macro() {
|
fn test_hover_through_literal_string_in_builtin_macro() {
|
||||||
check_hover_no_result(
|
check_hover_no_result(
|
||||||
r#"
|
r#"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
macro_rules! assert {
|
macro_rules! assert {
|
||||||
($cond:expr) => {{ /* compiler built-in */ }};
|
($cond:expr) => {{ /* compiler built-in */ }};
|
||||||
($cond:expr,) => {{ /* compiler built-in */ }};
|
($cond:expr,) => {{ /* compiler built-in */ }};
|
||||||
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
|
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo() {
|
fn foo() {
|
||||||
assert!("hel<|>lo");
|
assert!("hel<|>lo");
|
||||||
|
|
|
@ -155,7 +155,7 @@ fn find_name(
|
||||||
opt_name: Option<ast::Name>,
|
opt_name: Option<ast::Name>,
|
||||||
) -> Option<RangeInfo<(String, NameDefinition)>> {
|
) -> Option<RangeInfo<(String, NameDefinition)>> {
|
||||||
if let Some(name) = opt_name {
|
if let Some(name) = opt_name {
|
||||||
let def = classify_name(sema, &name)?;
|
let def = classify_name(sema, &name)?.definition();
|
||||||
let range = name.syntax().text_range();
|
let range = name.syntax().text_range();
|
||||||
return Some(RangeInfo::new(range, (name.text().to_string(), def)));
|
return Some(RangeInfo::new(range, (name.text().to_string(), def)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ mod tests;
|
||||||
|
|
||||||
use hir::{Name, Semantics};
|
use hir::{Name, Semantics};
|
||||||
use ra_ide_db::{
|
use ra_ide_db::{
|
||||||
defs::{classify_name, NameDefinition},
|
defs::{classify_name, NameClass, NameDefinition},
|
||||||
RootDatabase,
|
RootDatabase,
|
||||||
};
|
};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
|
@ -169,7 +169,7 @@ fn highlight_element(
|
||||||
let name = element.into_node().and_then(ast::Name::cast).unwrap();
|
let name = element.into_node().and_then(ast::Name::cast).unwrap();
|
||||||
let name_kind = classify_name(sema, &name);
|
let name_kind = classify_name(sema, &name);
|
||||||
|
|
||||||
if let Some(NameDefinition::Local(local)) = &name_kind {
|
if let Some(NameClass::NameDefinition(NameDefinition::Local(local))) = &name_kind {
|
||||||
if let Some(name) = local.name(db) {
|
if let Some(name) = local.name(db) {
|
||||||
let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
|
let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
|
||||||
*shadow_count += 1;
|
*shadow_count += 1;
|
||||||
|
@ -177,11 +177,13 @@ fn highlight_element(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let h = match name_kind {
|
match name_kind {
|
||||||
Some(name_kind) => highlight_name(db, name_kind),
|
Some(NameClass::NameDefinition(def)) => {
|
||||||
None => highlight_name_by_syntax(name),
|
highlight_name(db, def) | HighlightModifier::Definition
|
||||||
};
|
}
|
||||||
h | HighlightModifier::Definition
|
Some(NameClass::ConstReference(def)) => highlight_name(db, def),
|
||||||
|
None => highlight_name_by_syntax(name) | HighlightModifier::Definition,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Highlight references like the definitions they resolve to
|
// Highlight references like the definitions they resolve to
|
||||||
|
|
|
@ -68,7 +68,32 @@ impl NameDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameDefinition> {
|
pub enum NameClass {
|
||||||
|
NameDefinition(NameDefinition),
|
||||||
|
/// `None` in `if let None = Some(82) {}`
|
||||||
|
ConstReference(NameDefinition),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NameClass {
|
||||||
|
pub fn into_definition(self) -> Option<NameDefinition> {
|
||||||
|
match self {
|
||||||
|
NameClass::NameDefinition(it) => Some(it),
|
||||||
|
NameClass::ConstReference(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn definition(self) -> NameDefinition {
|
||||||
|
match self {
|
||||||
|
NameClass::NameDefinition(it) | NameClass::ConstReference(it) => it,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> {
|
||||||
|
classify_name_inner(sema, name).map(NameClass::NameDefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameDefinition> {
|
||||||
let _p = profile("classify_name");
|
let _p = profile("classify_name");
|
||||||
let parent = name.syntax().parent()?;
|
let parent = name.syntax().parent()?;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ impl<'a> ImportsLocator<'a> {
|
||||||
} else {
|
} else {
|
||||||
candidate_node
|
candidate_node
|
||||||
};
|
};
|
||||||
classify_name(&self.sema, &ast::Name::cast(candidate_name_node)?)
|
let name = ast::Name::cast(candidate_name_node)?;
|
||||||
|
classify_name(&self.sema, &name)?.into_definition()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue