Use ItemTree for crate root attr_query collection
This commit is contained in:
parent
1aadd9da92
commit
5f9a5825e0
@ -19,8 +19,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
intern::Interned,
|
intern::Interned,
|
||||||
item_tree::{Fields, ItemTreeId, ItemTreeNode},
|
item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeNode},
|
||||||
nameres::ModuleSource,
|
nameres::{ModuleOrigin, ModuleSource},
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
src::{HasChildSource, HasSource},
|
src::{HasChildSource, HasSource},
|
||||||
AdtId, AttrDefId, EnumId, GenericParamId, LocalEnumVariantId, LocalFieldId, Lookup, MacroId,
|
AdtId, AttrDefId, EnumId, GenericParamId, LocalEnumVariantId, LocalFieldId, Lookup, MacroId,
|
||||||
@ -201,6 +201,7 @@ pub(crate) fn variants_attrs_query(
|
|||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
e: EnumId,
|
e: EnumId,
|
||||||
) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>> {
|
) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>> {
|
||||||
|
// FIXME: There should be some proper form of mapping between item tree enum variant ids and hir enum variant ids
|
||||||
let mut res = ArenaMap::default();
|
let mut res = ArenaMap::default();
|
||||||
|
|
||||||
let loc = e.lookup(db);
|
let loc = e.lookup(db);
|
||||||
@ -226,6 +227,7 @@ pub(crate) fn fields_attrs_query(
|
|||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
v: VariantId,
|
v: VariantId,
|
||||||
) -> Arc<ArenaMap<LocalFieldId, Attrs>> {
|
) -> Arc<ArenaMap<LocalFieldId, Attrs>> {
|
||||||
|
// FIXME: There should be some proper form of mapping between item tree field ids and hir field ids
|
||||||
let mut res = ArenaMap::default();
|
let mut res = ArenaMap::default();
|
||||||
|
|
||||||
let crate_graph = db.crate_graph();
|
let crate_graph = db.crate_graph();
|
||||||
@ -295,11 +297,14 @@ pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
|
|||||||
|
|
||||||
impl Attrs {
|
impl Attrs {
|
||||||
pub fn cfg(&self) -> Option<CfgExpr> {
|
pub fn cfg(&self) -> Option<CfgExpr> {
|
||||||
let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse).collect::<Vec<_>>();
|
let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse);
|
||||||
match cfgs.len() {
|
let first = cfgs.next()?;
|
||||||
0 => None,
|
match cfgs.next() {
|
||||||
1 => Some(cfgs.pop().unwrap()),
|
Some(second) => {
|
||||||
_ => Some(CfgExpr::All(cfgs)),
|
let cfgs = [first, second].into_iter().chain(cfgs);
|
||||||
|
Some(CfgExpr::All(cfgs.collect()))
|
||||||
|
}
|
||||||
|
None => Some(first),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> bool {
|
pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> bool {
|
||||||
@ -367,25 +372,37 @@ pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Self {
|
|||||||
AttrDefId::ModuleId(module) => {
|
AttrDefId::ModuleId(module) => {
|
||||||
let def_map = module.def_map(db);
|
let def_map = module.def_map(db);
|
||||||
let mod_data = &def_map[module.local_id];
|
let mod_data = &def_map[module.local_id];
|
||||||
match mod_data.declaration_source(db) {
|
|
||||||
Some(it) => {
|
match mod_data.origin {
|
||||||
|
// FIXME: We should be able to leverage the item tree instead of parsing declaration here
|
||||||
|
// but we don't save the module's item tree id anywhere
|
||||||
|
ModuleOrigin::File { definition, declaration, .. } => {
|
||||||
|
let value = declaration.to_node(db.upcast());
|
||||||
|
let it = InFile { file_id: declaration.file_id, value };
|
||||||
let raw_attrs = RawAttrs::from_attrs_owner(
|
let raw_attrs = RawAttrs::from_attrs_owner(
|
||||||
db,
|
db,
|
||||||
it.as_ref().map(|it| it as &dyn ast::HasAttrs),
|
it.as_ref().map(|it| it as &dyn ast::HasAttrs),
|
||||||
);
|
);
|
||||||
match mod_data.definition_source(db) {
|
let tree = db.file_item_tree(definition.into());
|
||||||
InFile { file_id, value: ModuleSource::SourceFile(file) } => raw_attrs
|
raw_attrs.merge(tree.raw_attrs(AttrOwner::TopLevel).clone())
|
||||||
.merge(RawAttrs::from_attrs_owner(db, InFile::new(file_id, &file))),
|
|
||||||
_ => raw_attrs,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => RawAttrs::from_attrs_owner(
|
ModuleOrigin::CrateRoot { definition } => {
|
||||||
|
let tree = db.file_item_tree(definition.into());
|
||||||
|
tree.raw_attrs(AttrOwner::TopLevel).clone()
|
||||||
|
}
|
||||||
|
// FIXME: We should be able to leverage the item tree instead of parsing here
|
||||||
|
// but we don't save the module's item tree id anywhere
|
||||||
|
ModuleOrigin::Inline { definition } => RawAttrs::from_attrs_owner(
|
||||||
db,
|
db,
|
||||||
mod_data.definition_source(db).as_ref().map(|src| match src {
|
InFile::new(definition.file_id, definition.to_node(db.upcast()))
|
||||||
ModuleSource::SourceFile(file) => file as &dyn ast::HasAttrs,
|
.as_ref()
|
||||||
ModuleSource::Module(module) => module as &dyn ast::HasAttrs,
|
.map(|it| it as &dyn ast::HasAttrs),
|
||||||
ModuleSource::BlockExpr(block) => block as &dyn ast::HasAttrs,
|
),
|
||||||
}),
|
ModuleOrigin::BlockExpr { block } => RawAttrs::from_attrs_owner(
|
||||||
|
db,
|
||||||
|
InFile::new(block.file_id, block.to_node(db.upcast()))
|
||||||
|
.as_ref()
|
||||||
|
.map(|it| it as &dyn ast::HasAttrs),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user