mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Merge #3367
3367: Fix highlighting of const patterns r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
c692e07b4f
13 changed files with 143 additions and 70 deletions
|
@ -17,8 +17,8 @@ use crate::{
|
|||
db::HirDatabase,
|
||||
source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer},
|
||||
source_binder::{ChildContainer, SourceBinder},
|
||||
Function, HirFileId, InFile, Local, MacroDef, Module, Name, Origin, Path, PathResolution,
|
||||
ScopeDef, StructField, Trait, Type, TypeParam, VariantDef,
|
||||
Function, HirFileId, InFile, Local, MacroDef, Module, ModuleDef, Name, Origin, Path,
|
||||
PathResolution, ScopeDef, StructField, Trait, Type, TypeParam, VariantDef,
|
||||
};
|
||||
use hir_expand::ExpansionInfo;
|
||||
use ra_prof::profile;
|
||||
|
@ -129,6 +129,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
|||
self.analyze(path.syntax()).resolve_path(self.db, path)
|
||||
}
|
||||
|
||||
pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> {
|
||||
self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat)
|
||||
}
|
||||
|
||||
// FIXME: use this instead?
|
||||
// pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>;
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ use either::Either;
|
|||
use hir_def::{
|
||||
body::{
|
||||
scope::{ExprScopes, ScopeId},
|
||||
BodySourceMap,
|
||||
Body, BodySourceMap,
|
||||
},
|
||||
expr::{ExprId, PatId},
|
||||
expr::{ExprId, Pat, PatId},
|
||||
resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
|
||||
AsMacroCall, DefWithBodyId,
|
||||
};
|
||||
|
@ -25,8 +25,8 @@ use ra_syntax::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, Path, Static, Struct,
|
||||
Trait, Type, TypeAlias, TypeParam,
|
||||
db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, ModuleDef, Path, Static,
|
||||
Struct, Trait, Type, TypeAlias, TypeParam,
|
||||
};
|
||||
|
||||
/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
|
||||
|
@ -35,6 +35,7 @@ use crate::{
|
|||
pub(crate) struct SourceAnalyzer {
|
||||
file_id: HirFileId,
|
||||
pub(crate) resolver: Resolver,
|
||||
body: Option<Arc<Body>>,
|
||||
body_source_map: Option<Arc<BodySourceMap>>,
|
||||
infer: Option<Arc<InferenceResult>>,
|
||||
scopes: Option<Arc<ExprScopes>>,
|
||||
|
@ -66,7 +67,7 @@ impl SourceAnalyzer {
|
|||
node: InFile<&SyntaxNode>,
|
||||
offset: Option<TextUnit>,
|
||||
) -> SourceAnalyzer {
|
||||
let (_body, source_map) = db.body_with_source_map(def);
|
||||
let (body, source_map) = db.body_with_source_map(def);
|
||||
let scopes = db.expr_scopes(def);
|
||||
let scope = match offset {
|
||||
None => scope_for(&scopes, &source_map, node),
|
||||
|
@ -75,6 +76,7 @@ impl SourceAnalyzer {
|
|||
let resolver = resolver_for_scope(db, def, scope);
|
||||
SourceAnalyzer {
|
||||
resolver,
|
||||
body: Some(body),
|
||||
body_source_map: Some(source_map),
|
||||
infer: Some(db.infer(def)),
|
||||
scopes: Some(scopes),
|
||||
|
@ -88,6 +90,7 @@ impl SourceAnalyzer {
|
|||
) -> SourceAnalyzer {
|
||||
SourceAnalyzer {
|
||||
resolver,
|
||||
body: None,
|
||||
body_source_map: None,
|
||||
infer: None,
|
||||
scopes: None,
|
||||
|
@ -197,6 +200,24 @@ impl SourceAnalyzer {
|
|||
self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into())
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_bind_pat_to_const(
|
||||
&self,
|
||||
db: &impl HirDatabase,
|
||||
pat: &ast::BindPat,
|
||||
) -> Option<ModuleDef> {
|
||||
let pat_id = self.pat_id(&pat.clone().into())?;
|
||||
let body = self.body.as_ref()?;
|
||||
let path = match &body[pat_id] {
|
||||
Pat::Path(path) => path,
|
||||
_ => return None,
|
||||
};
|
||||
let res = resolve_hir_path(db, &self.resolver, &path)?;
|
||||
match res {
|
||||
PathResolution::Def(def) => Some(def),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_path(
|
||||
&self,
|
||||
db: &impl HirDatabase,
|
||||
|
|
|
@ -30,7 +30,9 @@ pub(crate) fn goto_definition(
|
|||
reference_definition(&sema, &name_ref).to_vec()
|
||||
},
|
||||
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,
|
||||
}
|
||||
|
@ -88,15 +90,6 @@ pub(crate) fn reference_definition(
|
|||
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)]
|
||||
mod tests {
|
||||
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))
|
||||
},
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ fn find_name(
|
|||
opt_name: Option<ast::Name>,
|
||||
) -> Option<RangeInfo<(String, NameDefinition)>> {
|
||||
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();
|
||||
return Some(RangeInfo::new(range, (name.text().to_string(), def)));
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
body { margin: 0; }
|
||||
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
|
||||
|
||||
|
||||
.lifetime { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -27,14 +27,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
.control { font-style: italic; }
|
||||
</style>
|
||||
<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span>
|
||||
<span class="keyword">struct</span> <span class="struct">Foo</span> {
|
||||
<span class="keyword">pub</span> <span class="field">x</span>: <span class="builtin_type">i32</span>,
|
||||
<span class="keyword">pub</span> <span class="field">y</span>: <span class="builtin_type">i32</span>,
|
||||
<span class="keyword">struct</span> <span class="struct declaration">Foo</span> {
|
||||
<span class="keyword">pub</span> <span class="field declaration">x</span>: <span class="builtin_type">i32</span>,
|
||||
<span class="keyword">pub</span> <span class="field declaration">y</span>: <span class="builtin_type">i32</span>,
|
||||
}
|
||||
|
||||
<span class="keyword">fn</span> <span class="function">foo</span><<span class="type_param">T</span>>() -> <span class="type_param">T</span> {
|
||||
<span class="macro">unimplemented</span><span class="macro">!</span>();
|
||||
<span class="function">foo</span>::<<span class="builtin_type">i32</span>>();
|
||||
<span class="keyword">fn</span> <span class="function declaration">foo</span><<span class="lifetime declaration">'a</span>, <span class="type_param declaration">T</span>>() -> <span class="type_param">T</span> {
|
||||
<span class="function">foo</span>::<<span class="lifetime">'a</span>, <span class="builtin_type">i32</span>>()
|
||||
}
|
||||
|
||||
<span class="macro">macro_rules</span><span class="macro">!</span> def_fn {
|
||||
|
@ -42,33 +41,40 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
}
|
||||
|
||||
<span class="macro">def_fn</span><span class="macro">!</span> {
|
||||
<span class="keyword">fn</span> <span class="function">bar</span>() -> <span class="builtin_type">u32</span> {
|
||||
<span class="keyword">fn</span> <span class="function declaration">bar</span>() -> <span class="builtin_type">u32</span> {
|
||||
<span class="numeric_literal">100</span>
|
||||
}
|
||||
}
|
||||
|
||||
<span class="comment">// comment</span>
|
||||
<span class="keyword">fn</span> <span class="function">main</span>() {
|
||||
<span class="keyword">fn</span> <span class="function declaration">main</span>() {
|
||||
<span class="macro">println</span><span class="macro">!</span>(<span class="string_literal">"Hello, {}!"</span>, <span class="numeric_literal">92</span>);
|
||||
|
||||
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable mutable">vec</span> = Vec::new();
|
||||
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">vec</span> = Vec::new();
|
||||
<span class="keyword control">if</span> <span class="keyword">true</span> {
|
||||
<span class="keyword">let</span> <span class="variable">x</span> = <span class="numeric_literal">92</span>;
|
||||
<span class="keyword">let</span> <span class="variable declaration">x</span> = <span class="numeric_literal">92</span>;
|
||||
<span class="variable mutable">vec</span>.push(<span class="struct">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="numeric_literal">1</span> });
|
||||
}
|
||||
<span class="keyword unsafe">unsafe</span> { <span class="variable mutable">vec</span>.set_len(<span class="numeric_literal">0</span>); }
|
||||
|
||||
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable mutable">x</span> = <span class="numeric_literal">42</span>;
|
||||
<span class="keyword">let</span> <span class="variable mutable">y</span> = &<span class="keyword">mut</span> <span class="variable mutable">x</span>;
|
||||
<span class="keyword">let</span> <span class="variable">z</span> = &<span class="variable mutable">y</span>;
|
||||
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">x</span> = <span class="numeric_literal">42</span>;
|
||||
<span class="keyword">let</span> <span class="variable declaration mutable">y</span> = &<span class="keyword">mut</span> <span class="variable mutable">x</span>;
|
||||
<span class="keyword">let</span> <span class="variable declaration">z</span> = &<span class="variable mutable">y</span>;
|
||||
|
||||
<span class="variable mutable">y</span>;
|
||||
}
|
||||
|
||||
<span class="keyword">enum</span> <span class="enum">E</span><<span class="type_param">X</span>> {
|
||||
<span class="enum_variant">V</span>(<span class="type_param">X</span>)
|
||||
<span class="keyword">enum</span> <span class="enum declaration">Option</span><<span class="type_param declaration">T</span>> {
|
||||
<span class="enum_variant declaration">Some</span>(<span class="type_param">T</span>),
|
||||
<span class="enum_variant declaration">None</span>,
|
||||
}
|
||||
<span class="keyword">use</span> <span class="enum">Option</span>::*;
|
||||
|
||||
<span class="keyword">impl</span><<span class="type_param">X</span>> <span class="enum">E</span><<span class="type_param">X</span>> {
|
||||
<span class="keyword">fn</span> <span class="function">new</span><<span class="type_param">T</span>>() -> <span class="enum">E</span><<span class="type_param">T</span>> {}
|
||||
<span class="keyword">impl</span><<span class="type_param declaration">T</span>> <span class="enum">Option</span><<span class="type_param">T</span>> {
|
||||
<span class="keyword">fn</span> <span class="function declaration">and</span><<span class="type_param declaration">U</span>>(<span class="keyword">self</span>, <span class="variable declaration">other</span>: <span class="enum">Option</span><<span class="type_param">U</span>>) -> <span class="enum">Option</span><(<span class="type_param">T</span>, <span class="type_param">U</span>)> {
|
||||
<span class="keyword control">match</span> <span class="variable">other</span> {
|
||||
<span class="enum_variant">None</span> => <span class="macro">unimplemented</span><span class="macro">!</span>(),
|
||||
<span class="variable declaration">Nope</span> => <span class="variable">Nope</span>,
|
||||
}
|
||||
}
|
||||
}</code></pre>
|
|
@ -3,7 +3,7 @@
|
|||
body { margin: 0; }
|
||||
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
|
||||
|
||||
|
||||
.lifetime { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -26,15 +26,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
.keyword.unsafe { color: #BC8383; font-weight: bold; }
|
||||
.control { font-style: italic; }
|
||||
</style>
|
||||
<pre><code><span class="keyword">fn</span> <span class="function">main</span>() {
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>;
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="2705725358298919760" style="color: hsl(17,51%,74%);">x</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string();
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="3365759661443752373" style="color: hsl(127,76%,66%);">y</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string();
|
||||
<pre><code><span class="keyword">fn</span> <span class="function declaration">main</span>() {
|
||||
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>;
|
||||
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="2705725358298919760" style="color: hsl(17,51%,74%);">x</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string();
|
||||
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="3365759661443752373" style="color: hsl(127,76%,66%);">y</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string();
|
||||
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span> = <span class="string_literal">"other color please!"</span>;
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="6717528807933952652" style="color: hsl(85,49%,84%);">y</span> = <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span>.to_string();
|
||||
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span> = <span class="string_literal">"other color please!"</span>;
|
||||
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="6717528807933952652" style="color: hsl(85,49%,84%);">y</span> = <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span>.to_string();
|
||||
}
|
||||
|
||||
<span class="keyword">fn</span> <span class="function">bar</span>() {
|
||||
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable mutable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>;
|
||||
<span class="keyword">fn</span> <span class="function declaration">bar</span>() {
|
||||
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>;
|
||||
}</code></pre>
|
|
@ -7,7 +7,7 @@ mod tests;
|
|||
|
||||
use hir::{Name, Semantics};
|
||||
use ra_ide_db::{
|
||||
defs::{classify_name, NameDefinition},
|
||||
defs::{classify_name, NameClass, NameDefinition},
|
||||
RootDatabase,
|
||||
};
|
||||
use ra_prof::profile;
|
||||
|
@ -169,7 +169,7 @@ fn highlight_element(
|
|||
let name = element.into_node().and_then(ast::Name::cast).unwrap();
|
||||
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) {
|
||||
let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
|
||||
*shadow_count += 1;
|
||||
|
@ -177,11 +177,13 @@ fn highlight_element(
|
|||
}
|
||||
};
|
||||
|
||||
let h = match name_kind {
|
||||
Some(name_kind) => highlight_name(db, name_kind),
|
||||
None => highlight_name_by_syntax(name),
|
||||
};
|
||||
h | HighlightModifier::Definition
|
||||
match name_kind {
|
||||
Some(NameClass::NameDefinition(def)) => {
|
||||
highlight_name(db, def) | 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
|
||||
|
@ -212,8 +214,13 @@ fn highlight_element(
|
|||
INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(),
|
||||
BYTE => HighlightTag::ByteLiteral.into(),
|
||||
CHAR => HighlightTag::CharLiteral.into(),
|
||||
// FIXME: set Declaration for decls
|
||||
LIFETIME => HighlightTag::Lifetime.into(),
|
||||
LIFETIME => {
|
||||
let h = Highlight::new(HighlightTag::Lifetime);
|
||||
dbg!(match element.parent().map(|it| it.kind()) {
|
||||
Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition,
|
||||
_ => h,
|
||||
})
|
||||
}
|
||||
|
||||
k if k.is_keyword() => {
|
||||
let h = Highlight::new(HighlightTag::Keyword);
|
||||
|
|
|
@ -80,7 +80,7 @@ const STYLE: &str = "
|
|||
body { margin: 0; }
|
||||
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
|
||||
|
||||
|
||||
.lifetime { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
|
|
@ -90,8 +90,12 @@ impl fmt::Display for HighlightTag {
|
|||
}
|
||||
|
||||
impl HighlightModifier {
|
||||
const ALL: &'static [HighlightModifier] =
|
||||
&[HighlightModifier::Mutable, HighlightModifier::Unsafe, HighlightModifier::Control];
|
||||
const ALL: &'static [HighlightModifier] = &[
|
||||
HighlightModifier::Control,
|
||||
HighlightModifier::Definition,
|
||||
HighlightModifier::Mutable,
|
||||
HighlightModifier::Unsafe,
|
||||
];
|
||||
|
||||
fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
|
|
|
@ -17,9 +17,8 @@ struct Foo {
|
|||
pub y: i32,
|
||||
}
|
||||
|
||||
fn foo<T>() -> T {
|
||||
unimplemented!();
|
||||
foo::<i32>();
|
||||
fn foo<'a, T>() -> T {
|
||||
foo::<'a, i32>()
|
||||
}
|
||||
|
||||
macro_rules! def_fn {
|
||||
|
@ -50,12 +49,19 @@ fn main() {
|
|||
y;
|
||||
}
|
||||
|
||||
enum E<X> {
|
||||
V(X)
|
||||
enum Option<T> {
|
||||
Some(T),
|
||||
None,
|
||||
}
|
||||
use Option::*;
|
||||
|
||||
impl<X> E<X> {
|
||||
fn new<T>() -> E<T> {}
|
||||
impl<T> Option<T> {
|
||||
fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
|
||||
match other {
|
||||
None => unimplemented!(),
|
||||
Nope => Nope,
|
||||
}
|
||||
}
|
||||
}
|
||||
"#
|
||||
.trim(),
|
||||
|
@ -123,5 +129,5 @@ fn test_ranges() {
|
|||
.highlight_range(FileRange { file_id, range: TextRange::offset_len(82.into(), 1.into()) })
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(&highlights[0].highlight.to_string(), "field");
|
||||
assert_eq!(&highlights[0].highlight.to_string(), "field.declaration");
|
||||
}
|
||||
|
|
|
@ -68,7 +68,38 @@ 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> {
|
||||
if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) {
|
||||
if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
|
||||
return Some(NameClass::ConstReference(NameDefinition::ModuleDef(def)));
|
||||
}
|
||||
}
|
||||
|
||||
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 parent = name.syntax().parent()?;
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ impl<'a> ImportsLocator<'a> {
|
|||
} else {
|
||||
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
Add a link
Reference in a new issue