From 835173d065dbe1fdd7369ea49336c0b785be8cb8 Mon Sep 17 00:00:00 2001 From: Ekaterina Babshukova Date: Sat, 12 Oct 2019 20:30:53 +0300 Subject: replace trait by a bunch of functions --- .../ra_ide_api/src/references/name_definition.rs | 104 +++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 crates/ra_ide_api/src/references/name_definition.rs (limited to 'crates/ra_ide_api/src/references/name_definition.rs') diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide_api/src/references/name_definition.rs new file mode 100644 index 000000000..19702eba0 --- /dev/null +++ b/crates/ra_ide_api/src/references/name_definition.rs @@ -0,0 +1,104 @@ +use hir::{ + db::AstDatabase, Adt, AssocItem, DefWithBody, FromSource, HasSource, HirFileId, MacroDef, + Module, ModuleDef, StructField, Ty, VariantDef, +}; +use ra_syntax::{ast, ast::VisibilityOwner, match_ast, AstNode, AstPtr}; + +use crate::db::RootDatabase; + +#[derive(Debug, PartialEq, Eq)] +pub enum NameKind { + Macro(MacroDef), + Field(StructField), + AssocItem(AssocItem), + Def(ModuleDef), + SelfType(Ty), + Pat((DefWithBody, AstPtr)), + SelfParam(AstPtr), + GenericParam(u32), +} + +#[derive(PartialEq, Eq)] +pub(crate) struct NameDefinition { + pub visibility: Option, + pub container: Module, + pub item: NameKind, +} + +pub(super) fn from_pat( + db: &RootDatabase, + file_id: HirFileId, + pat: AstPtr, +) -> Option { + let root = db.parse_or_expand(file_id)?; + let def = pat.to_node(&root).syntax().ancestors().find_map(|node| { + match_ast! { + match node { + ast::FnDef(it) => { + let src = hir::Source { file_id, ast: it }; + Some(hir::Function::from_source(db, src)?.into()) + }, + ast::ConstDef(it) => { + let src = hir::Source { file_id, ast: it }; + Some(hir::Const::from_source(db, src)?.into()) + }, + ast::StaticDef(it) => { + let src = hir::Source { file_id, ast: it }; + Some(hir::Static::from_source(db, src)?.into()) + }, + _ => None, + } + } + })?; + let item = NameKind::Pat((def, pat)); + let container = def.module(db); + Some(NameDefinition { item, container, visibility: None }) +} + +pub(super) fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinition { + let container = item.module(db); + let visibility = match item { + AssocItem::Function(f) => f.source(db).ast.visibility(), + AssocItem::Const(c) => c.source(db).ast.visibility(), + AssocItem::TypeAlias(a) => a.source(db).ast.visibility(), + }; + let item = NameKind::AssocItem(item); + NameDefinition { item, container, visibility } +} + +pub(super) fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDefinition { + let item = NameKind::Field(field); + let parent = field.parent_def(db); + let container = parent.module(db); + let visibility = match parent { + VariantDef::Struct(s) => s.source(db).ast.visibility(), + VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(), + }; + NameDefinition { item, container, visibility } +} + +pub(super) fn from_module_def(db: &RootDatabase, def: ModuleDef) -> NameDefinition { + let item = NameKind::Def(def); + let (container, visibility) = match def { + ModuleDef::Module(it) => { + let container = it.parent(db).or_else(|| Some(it)).unwrap(); + let visibility = it.declaration_source(db).and_then(|s| s.ast.visibility()); + (container, visibility) + } + ModuleDef::EnumVariant(it) => { + let container = it.module(db); + let visibility = it.source(db).ast.parent_enum().visibility(); + (container, visibility) + } + ModuleDef::Function(it) => (it.module(db), it.source(db).ast.visibility()), + ModuleDef::Const(it) => (it.module(db), it.source(db).ast.visibility()), + ModuleDef::Static(it) => (it.module(db), it.source(db).ast.visibility()), + ModuleDef::Trait(it) => (it.module(db), it.source(db).ast.visibility()), + ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).ast.visibility()), + ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).ast.visibility()), + ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).ast.visibility()), + ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).ast.visibility()), + ModuleDef::BuiltinType(..) => unreachable!(), + }; + NameDefinition { item, container, visibility } +} -- cgit v1.2.3