mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 05:15:04 +00:00
return Declaration from classify_name
This commit is contained in:
parent
0b5d0a41fd
commit
83f780eabf
2 changed files with 59 additions and 36 deletions
|
@ -1,13 +1,19 @@
|
||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
use hir::{Either, FromSource};
|
use hir::{Either, FromSource, HasSource};
|
||||||
use ra_db::FileId;
|
use ra_db::FileId;
|
||||||
use ra_syntax::{ast, AstNode, AstPtr};
|
use ra_syntax::{ast, ast::VisibilityOwner, AstNode, AstPtr};
|
||||||
use test_utils::tested_by;
|
use test_utils::tested_by;
|
||||||
|
|
||||||
use crate::db::RootDatabase;
|
use crate::db::RootDatabase;
|
||||||
|
|
||||||
pub enum NameKind {
|
pub(crate) struct Declaration {
|
||||||
|
visibility: Option<ast::Visibility>,
|
||||||
|
container: hir::ModuleSource,
|
||||||
|
pub item: NameKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) enum NameKind {
|
||||||
Macro(hir::MacroDef),
|
Macro(hir::MacroDef),
|
||||||
FieldAccess(hir::StructField),
|
FieldAccess(hir::StructField),
|
||||||
AssocItem(hir::AssocItem),
|
AssocItem(hir::AssocItem),
|
||||||
|
@ -96,7 +102,7 @@ pub(crate) fn classify_name(
|
||||||
db: &RootDatabase,
|
db: &RootDatabase,
|
||||||
file_id: FileId,
|
file_id: FileId,
|
||||||
name: &ast::Name,
|
name: &ast::Name,
|
||||||
) -> Option<NameKind> {
|
) -> Option<Declaration> {
|
||||||
use NameKind::*;
|
use NameKind::*;
|
||||||
|
|
||||||
let parent = name.syntax().parent()?;
|
let parent = name.syntax().parent()?;
|
||||||
|
@ -105,89 +111,106 @@ pub(crate) fn classify_name(
|
||||||
macro_rules! match_ast {
|
macro_rules! match_ast {
|
||||||
(match $node:ident {
|
(match $node:ident {
|
||||||
$( ast::$ast:ident($it:ident) => $res:block, )*
|
$( ast::$ast:ident($it:ident) => $res:block, )*
|
||||||
_ => $catch_all:expr,
|
_ => $catch_all:block,
|
||||||
}) => {{
|
}) => {{
|
||||||
$( if let Some($it) = ast::$ast::cast($node.clone()) $res else )*
|
$( if let Some($it) = ast::$ast::cast($node.clone()) $res else )*
|
||||||
{ $catch_all }
|
$catch_all
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: add ast::MacroCall(it)
|
let container = parent.ancestors().find_map(|n| {
|
||||||
match_ast! {
|
match_ast! {
|
||||||
|
match n {
|
||||||
|
ast::Module(it) => { Some(hir::ModuleSource::Module(it)) },
|
||||||
|
ast::SourceFile(it) => { Some(hir::ModuleSource::SourceFile(it)) },
|
||||||
|
_ => { None },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// FIXME: add ast::MacroCall(it)
|
||||||
|
let (item, visibility) = match_ast! {
|
||||||
match parent {
|
match parent {
|
||||||
ast::BindPat(it) => {
|
ast::BindPat(it) => {
|
||||||
let pat = AstPtr::new(&it);
|
let pat = AstPtr::new(&it);
|
||||||
Some(Pat(pat))
|
(Pat(pat), None)
|
||||||
},
|
},
|
||||||
ast::RecordFieldDef(it) => {
|
ast::RecordFieldDef(it) => {
|
||||||
let src = hir::Source { file_id, ast: hir::FieldSource::Named(it) };
|
let src = hir::Source { file_id, ast: hir::FieldSource::Named(it) };
|
||||||
let field = hir::StructField::from_source(db, src)?;
|
let field = hir::StructField::from_source(db, src)?;
|
||||||
Some(FieldAccess(field))
|
let visibility = match field.parent_def(db) {
|
||||||
|
hir::VariantDef::Struct(s) => s.source(db).ast.visibility(),
|
||||||
|
hir::VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(),
|
||||||
|
};
|
||||||
|
(FieldAccess(field), visibility)
|
||||||
},
|
},
|
||||||
ast::FnDef(it) => {
|
ast::FnDef(it) => {
|
||||||
if parent.parent().and_then(ast::ItemList::cast).is_some() {
|
if parent.parent().and_then(ast::ItemList::cast).is_some() {
|
||||||
let src = hir::Source { file_id, ast: ast::ImplItem::from(it) };
|
let src = hir::Source { file_id, ast: ast::ImplItem::from(it.clone()) };
|
||||||
let item = hir::AssocItem::from_source(db, src)?;
|
let item = hir::AssocItem::from_source(db, src)?;
|
||||||
Some(AssocItem(item))
|
(AssocItem(item), it.visibility())
|
||||||
} else {
|
} else {
|
||||||
let src = hir::Source { file_id, ast: it };
|
let src = hir::Source { file_id, ast: it.clone() };
|
||||||
let def = hir::Function::from_source(db, src)?;
|
let def = hir::Function::from_source(db, src)?;
|
||||||
Some(Def(def.into()))
|
(Def(def.into()), it.visibility())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::ConstDef(it) => {
|
ast::ConstDef(it) => {
|
||||||
if parent.parent().and_then(ast::ItemList::cast).is_some() {
|
if parent.parent().and_then(ast::ItemList::cast).is_some() {
|
||||||
let src = hir::Source { file_id, ast: ast::ImplItem::from(it) };
|
let src = hir::Source { file_id, ast: ast::ImplItem::from(it.clone()) };
|
||||||
let item = hir::AssocItem::from_source(db, src)?;
|
let item = hir::AssocItem::from_source(db, src)?;
|
||||||
Some(AssocItem(item))
|
(AssocItem(item), it.visibility())
|
||||||
} else {
|
} else {
|
||||||
let src = hir::Source { file_id, ast: it };
|
let src = hir::Source { file_id, ast: it.clone() };
|
||||||
let def = hir::Const::from_source(db, src)?;
|
let def = hir::Const::from_source(db, src)?;
|
||||||
Some(Def(def.into()))
|
(Def(def.into()), it.visibility())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::TypeAliasDef(it) => {
|
ast::TypeAliasDef(it) => {
|
||||||
if parent.parent().and_then(ast::ItemList::cast).is_some() {
|
if parent.parent().and_then(ast::ItemList::cast).is_some() {
|
||||||
let src = hir::Source { file_id, ast: ast::ImplItem::from(it) };
|
let src = hir::Source { file_id, ast: ast::ImplItem::from(it.clone()) };
|
||||||
let item = hir::AssocItem::from_source(db, src)?;
|
let item = hir::AssocItem::from_source(db, src)?;
|
||||||
Some(AssocItem(item))
|
(AssocItem(item), it.visibility())
|
||||||
} else {
|
} else {
|
||||||
let src = hir::Source { file_id, ast: it };
|
let src = hir::Source { file_id, ast: it.clone() };
|
||||||
let def = hir::TypeAlias::from_source(db, src)?;
|
let def = hir::TypeAlias::from_source(db, src)?;
|
||||||
Some(Def(def.into()))
|
(Def(def.into()), it.visibility())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::Module(it) => {
|
ast::Module(it) => {
|
||||||
let src = hir::Source { file_id, ast: hir::ModuleSource::Module(it) };
|
let src = hir::Source { file_id, ast: hir::ModuleSource::Module(it.clone()) };
|
||||||
let def = hir::Module::from_definition(db, src)?;
|
let def = hir::Module::from_definition(db, src)?;
|
||||||
Some(Def(def.into()))
|
(Def(def.into()), it.visibility())
|
||||||
},
|
},
|
||||||
ast::StructDef(it) => {
|
ast::StructDef(it) => {
|
||||||
let src = hir::Source { file_id, ast: it };
|
let src = hir::Source { file_id, ast: it.clone() };
|
||||||
let def = hir::Struct::from_source(db, src)?;
|
let def = hir::Struct::from_source(db, src)?;
|
||||||
Some(Def(def.into()))
|
(Def(def.into()), it.visibility())
|
||||||
},
|
},
|
||||||
ast::EnumDef(it) => {
|
ast::EnumDef(it) => {
|
||||||
let src = hir::Source { file_id, ast: it };
|
let src = hir::Source { file_id, ast: it.clone() };
|
||||||
let def = hir::Enum::from_source(db, src)?;
|
let def = hir::Enum::from_source(db, src)?;
|
||||||
Some(Def(def.into()))
|
(Def(def.into()), it.visibility())
|
||||||
},
|
},
|
||||||
ast::TraitDef(it) => {
|
ast::TraitDef(it) => {
|
||||||
let src = hir::Source { file_id, ast: it };
|
let src = hir::Source { file_id, ast: it.clone() };
|
||||||
let def = hir::Trait::from_source(db, src)?;
|
let def = hir::Trait::from_source(db, src)?;
|
||||||
Some(Def(def.into()))
|
(Def(def.into()), it.visibility())
|
||||||
},
|
},
|
||||||
ast::StaticDef(it) => {
|
ast::StaticDef(it) => {
|
||||||
let src = hir::Source { file_id, ast: it };
|
let src = hir::Source { file_id, ast: it.clone() };
|
||||||
let def = hir::Static::from_source(db, src)?;
|
let def = hir::Static::from_source(db, src)?;
|
||||||
Some(Def(def.into()))
|
(Def(def.into()), it.visibility())
|
||||||
},
|
},
|
||||||
ast::EnumVariant(it) => {
|
ast::EnumVariant(it) => {
|
||||||
let src = hir::Source { file_id, ast: it };
|
let src = hir::Source { file_id, ast: it.clone() };
|
||||||
let def = hir::EnumVariant::from_source(db, src)?;
|
let def = hir::EnumVariant::from_source(db, src)?;
|
||||||
Some(Def(def.into()))
|
(Def(def.into()), it.parent_enum().visibility())
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
return None;
|
||||||
},
|
},
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
Some(Declaration { item, container, visibility })
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ pub(crate) fn find_all_refs(
|
||||||
) -> Option<RangeInfo<(hir::SourceAnalyzer, NameKind)>> {
|
) -> Option<RangeInfo<(hir::SourceAnalyzer, NameKind)>> {
|
||||||
if let Some(name) = find_node_at_offset::<ast::Name>(&syntax, position.offset) {
|
if let Some(name) = find_node_at_offset::<ast::Name>(&syntax, position.offset) {
|
||||||
let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name.syntax(), None);
|
let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name.syntax(), None);
|
||||||
let name_kind = classify_name(db, position.file_id, &name)?;
|
let name_kind = classify_name(db, position.file_id, &name)?.item;
|
||||||
let range = name.syntax().text_range();
|
let range = name.syntax().text_range();
|
||||||
return Some(RangeInfo::new(range, (analyzer, name_kind)));
|
return Some(RangeInfo::new(range, (analyzer, name_kind)));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue