From 1a9986496387544c048475765ac64e83518437af Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Nov 2019 12:01:56 +0300 Subject: Use attrs rather than syntax for lang items --- crates/ra_hir/src/lang_item.rs | 56 +++++++++++++++++++----------------------- crates/ra_hir_def/src/attr.rs | 24 ++++++++++++------ crates/ra_hir_def/src/lib.rs | 4 ++- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs index 89fd85f59..55f0c3a13 100644 --- a/crates/ra_hir/src/lang_item.rs +++ b/crates/ra_hir/src/lang_item.rs @@ -1,13 +1,14 @@ //! FIXME: write short doc here -use rustc_hash::FxHashMap; use std::sync::Arc; -use ra_syntax::{ast::AttrsOwner, SmolStr}; +use hir_def::{AdtId, AttrDefId, ModuleDefId}; +use ra_syntax::SmolStr; +use rustc_hash::FxHashMap; use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, - Adt, Crate, Enum, Function, HasSource, ImplBlock, Module, ModuleDef, Static, Struct, Trait, + Crate, Enum, Function, ImplBlock, Module, Static, Struct, Trait, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -95,26 +96,27 @@ impl LangItems { fn collect_lang_items(&mut self, db: &(impl DefDatabase + AstDatabase), module: Module) { // Look for impl targets - for impl_block in module.impl_blocks(db) { - let src = impl_block.source(db); - if let Some(lang_item_name) = lang_item_name(&src.value) { - self.items - .entry(lang_item_name) - .or_insert_with(|| LangItemTarget::ImplBlock(impl_block)); - } + let def_map = db.crate_def_map(module.id.krate); + let module_data = &def_map[module.id.module_id]; + for &impl_block in module_data.impls.iter() { + self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlock) } - for def in module.declarations(db) { + for def in module_data.scope.declarations() { match def { - ModuleDef::Trait(trait_) => { + ModuleDefId::TraitId(trait_) => { self.collect_lang_item(db, trait_, LangItemTarget::Trait) } - ModuleDef::Adt(Adt::Enum(e)) => self.collect_lang_item(db, e, LangItemTarget::Enum), - ModuleDef::Adt(Adt::Struct(s)) => { + ModuleDefId::AdtId(AdtId::EnumId(e)) => { + self.collect_lang_item(db, e, LangItemTarget::Enum) + } + ModuleDefId::AdtId(AdtId::StructId(s)) => { self.collect_lang_item(db, s, LangItemTarget::Struct) } - ModuleDef::Function(f) => self.collect_lang_item(db, f, LangItemTarget::Function), - ModuleDef::Static(s) => self.collect_lang_item(db, s, LangItemTarget::Static), + ModuleDefId::FunctionId(f) => { + self.collect_lang_item(db, f, LangItemTarget::Function) + } + ModuleDefId::StaticId(s) => self.collect_lang_item(db, s, LangItemTarget::Static), _ => {} } } @@ -135,26 +137,18 @@ impl LangItems { } } - fn collect_lang_item( + fn collect_lang_item( &mut self, db: &(impl DefDatabase + AstDatabase), item: T, - constructor: fn(T) -> LangItemTarget, + constructor: fn(D) -> LangItemTarget, ) where - T: Copy + HasSource, - N: AttrsOwner, + T: Into + Copy, + D: From, { - let node = item.source(db).value; - if let Some(lang_item_name) = lang_item_name(&node) { - self.items.entry(lang_item_name).or_insert_with(|| constructor(item)); + let attrs = db.attrs(item.into()); + if let Some(lang_item_name) = attrs.find_string_value("lang") { + self.items.entry(lang_item_name).or_insert_with(|| constructor(D::from(item))); } } } - -fn lang_item_name(node: &T) -> Option { - node.attrs() - .filter_map(|a| a.as_simple_key_value()) - .filter(|(key, _)| key == "lang") - .map(|(_, val)| val) - .nth(0) -} diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index ce397f6b0..eee5e44bf 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -53,28 +53,38 @@ impl Attrs { } } } - AttrDefId::AdtId(it) => match it { - AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), - AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), - AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), - }, AttrDefId::EnumVariantId(it) => { let src = it.parent.child_source(db); let hygiene = Hygiene::new(db, src.file_id); Attr::from_attrs_owner(&src.value[it.local_id], &hygiene) } + AttrDefId::AdtId(it) => match it { + AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), + AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), + }, AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), + AttrDefId::ImplId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), - AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db), - AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), } } pub fn has_atom(&self, atom: &str) -> bool { self.iter().any(|it| it.is_simple_atom(atom)) } + + pub fn find_string_value(&self, key: &str) -> Option { + self.iter().filter(|attr| attr.is_simple_atom(key)).find_map(|attr| { + match attr.input.as_ref()? { + AttrInput::Literal(it) => Some(it.clone()), + _ => None, + } + }) + } } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 1bcdf9b78..20d4deadb 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -489,6 +489,7 @@ pub enum AttrDefId { TraitId(TraitId), TypeAliasId(TypeAliasId), MacroDefId(MacroDefId), + ImplId(ImplId), } impl_froms!( @@ -501,7 +502,8 @@ impl_froms!( FunctionId, TraitId, TypeAliasId, - MacroDefId + MacroDefId, + ImplId ); trait Intern { -- cgit v1.2.3