Merge #2368
2368: Use attrs rather than syntax for lang items r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
9da07a07eb
@ -1,13 +1,14 @@
|
|||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
use std::sync::Arc;
|
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::{
|
use crate::{
|
||||||
db::{AstDatabase, DefDatabase, HirDatabase},
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
@ -95,26 +96,27 @@ pub(crate) fn lang_item_query(
|
|||||||
|
|
||||||
fn collect_lang_items(&mut self, db: &(impl DefDatabase + AstDatabase), module: Module) {
|
fn collect_lang_items(&mut self, db: &(impl DefDatabase + AstDatabase), module: Module) {
|
||||||
// Look for impl targets
|
// Look for impl targets
|
||||||
for impl_block in module.impl_blocks(db) {
|
let def_map = db.crate_def_map(module.id.krate);
|
||||||
let src = impl_block.source(db);
|
let module_data = &def_map[module.id.module_id];
|
||||||
if let Some(lang_item_name) = lang_item_name(&src.value) {
|
for &impl_block in module_data.impls.iter() {
|
||||||
self.items
|
self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlock)
|
||||||
.entry(lang_item_name)
|
|
||||||
.or_insert_with(|| LangItemTarget::ImplBlock(impl_block));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for def in module.declarations(db) {
|
for def in module_data.scope.declarations() {
|
||||||
match def {
|
match def {
|
||||||
ModuleDef::Trait(trait_) => {
|
ModuleDefId::TraitId(trait_) => {
|
||||||
self.collect_lang_item(db, trait_, LangItemTarget::Trait)
|
self.collect_lang_item(db, trait_, LangItemTarget::Trait)
|
||||||
}
|
}
|
||||||
ModuleDef::Adt(Adt::Enum(e)) => self.collect_lang_item(db, e, LangItemTarget::Enum),
|
ModuleDefId::AdtId(AdtId::EnumId(e)) => {
|
||||||
ModuleDef::Adt(Adt::Struct(s)) => {
|
self.collect_lang_item(db, e, LangItemTarget::Enum)
|
||||||
|
}
|
||||||
|
ModuleDefId::AdtId(AdtId::StructId(s)) => {
|
||||||
self.collect_lang_item(db, s, LangItemTarget::Struct)
|
self.collect_lang_item(db, s, LangItemTarget::Struct)
|
||||||
}
|
}
|
||||||
ModuleDef::Function(f) => self.collect_lang_item(db, f, LangItemTarget::Function),
|
ModuleDefId::FunctionId(f) => {
|
||||||
ModuleDef::Static(s) => self.collect_lang_item(db, s, LangItemTarget::Static),
|
self.collect_lang_item(db, f, LangItemTarget::Function)
|
||||||
|
}
|
||||||
|
ModuleDefId::StaticId(s) => self.collect_lang_item(db, s, LangItemTarget::Static),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,26 +137,18 @@ fn collect_lang_items_recursive(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_lang_item<T, N>(
|
fn collect_lang_item<T, D>(
|
||||||
&mut self,
|
&mut self,
|
||||||
db: &(impl DefDatabase + AstDatabase),
|
db: &(impl DefDatabase + AstDatabase),
|
||||||
item: T,
|
item: T,
|
||||||
constructor: fn(T) -> LangItemTarget,
|
constructor: fn(D) -> LangItemTarget,
|
||||||
) where
|
) where
|
||||||
T: Copy + HasSource<Ast = N>,
|
T: Into<AttrDefId> + Copy,
|
||||||
N: AttrsOwner,
|
D: From<T>,
|
||||||
{
|
{
|
||||||
let node = item.source(db).value;
|
let attrs = db.attrs(item.into());
|
||||||
if let Some(lang_item_name) = lang_item_name(&node) {
|
if let Some(lang_item_name) = attrs.find_string_value("lang") {
|
||||||
self.items.entry(lang_item_name).or_insert_with(|| constructor(item));
|
self.items.entry(lang_item_name).or_insert_with(|| constructor(D::from(item)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lang_item_name<T: AttrsOwner>(node: &T) -> Option<SmolStr> {
|
|
||||||
node.attrs()
|
|
||||||
.filter_map(|a| a.as_simple_key_value())
|
|
||||||
.filter(|(key, _)| key == "lang")
|
|
||||||
.map(|(_, val)| val)
|
|
||||||
.nth(0)
|
|
||||||
}
|
|
||||||
|
@ -53,28 +53,38 @@ pub(crate) fn attrs_query(db: &impl DefDatabase2, def: AttrDefId) -> 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) => {
|
AttrDefId::EnumVariantId(it) => {
|
||||||
let src = it.parent.child_source(db);
|
let src = it.parent.child_source(db);
|
||||||
let hygiene = Hygiene::new(db, src.file_id);
|
let hygiene = Hygiene::new(db, src.file_id);
|
||||||
Attr::from_attrs_owner(&src.value[it.local_id], &hygiene)
|
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::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::ConstId(it) => attrs_from_loc(it.lookup(db), db),
|
||||||
AttrDefId::FunctionId(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::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 {
|
pub fn has_atom(&self, atom: &str) -> bool {
|
||||||
self.iter().any(|it| it.is_simple_atom(atom))
|
self.iter().any(|it| it.is_simple_atom(atom))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_string_value(&self, key: &str) -> Option<SmolStr> {
|
||||||
|
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)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
@ -489,6 +489,7 @@ pub enum AttrDefId {
|
|||||||
TraitId(TraitId),
|
TraitId(TraitId),
|
||||||
TypeAliasId(TypeAliasId),
|
TypeAliasId(TypeAliasId),
|
||||||
MacroDefId(MacroDefId),
|
MacroDefId(MacroDefId),
|
||||||
|
ImplId(ImplId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_froms!(
|
impl_froms!(
|
||||||
@ -501,7 +502,8 @@ pub enum AttrDefId {
|
|||||||
FunctionId,
|
FunctionId,
|
||||||
TraitId,
|
TraitId,
|
||||||
TypeAliasId,
|
TypeAliasId,
|
||||||
MacroDefId
|
MacroDefId,
|
||||||
|
ImplId
|
||||||
);
|
);
|
||||||
|
|
||||||
trait Intern {
|
trait Intern {
|
||||||
|
Loading…
Reference in New Issue
Block a user