Create a mapping from blocks to inner items
This commit is contained in:
parent
52fe50a97b
commit
c5ed2284b5
@ -69,13 +69,12 @@ impl GenericParamsId {
|
||||
pub struct ItemTree {
|
||||
top_level: SmallVec<[ModItem; 1]>,
|
||||
attrs: FxHashMap<AttrOwner, RawAttrs>,
|
||||
inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>,
|
||||
|
||||
data: Option<Box<ItemTreeData>>,
|
||||
}
|
||||
|
||||
impl ItemTree {
|
||||
pub fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
|
||||
pub(crate) fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
|
||||
let _p = profile::span("item_tree_query").detail(|| format!("{:?}", file_id));
|
||||
let syntax = if let Some(node) = db.parse_or_expand(file_id) {
|
||||
node
|
||||
@ -117,12 +116,7 @@ impl ItemTree {
|
||||
}
|
||||
|
||||
fn empty() -> Self {
|
||||
Self {
|
||||
top_level: Default::default(),
|
||||
attrs: Default::default(),
|
||||
inner_items: Default::default(),
|
||||
data: Default::default(),
|
||||
}
|
||||
Self { top_level: Default::default(), attrs: Default::default(), data: Default::default() }
|
||||
}
|
||||
|
||||
fn shrink_to_fit(&mut self) {
|
||||
@ -147,6 +141,7 @@ impl ItemTree {
|
||||
macro_defs,
|
||||
vis,
|
||||
generics,
|
||||
inner_items,
|
||||
} = &mut **data;
|
||||
|
||||
imports.shrink_to_fit();
|
||||
@ -169,6 +164,8 @@ impl ItemTree {
|
||||
|
||||
vis.arena.shrink_to_fit();
|
||||
generics.arena.shrink_to_fit();
|
||||
|
||||
inner_items.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,16 +188,11 @@ impl ItemTree {
|
||||
self.raw_attrs(of).clone().filter(db, krate)
|
||||
}
|
||||
|
||||
/// Returns the lowered inner items that `ast` corresponds to.
|
||||
///
|
||||
/// Most AST items are lowered to a single `ModItem`, but some (eg. `use` items) may be lowered
|
||||
/// to multiple items in the `ItemTree`.
|
||||
pub fn inner_items(&self, ast: FileAstId<ast::Item>) -> &[ModItem] {
|
||||
&self.inner_items[&ast]
|
||||
}
|
||||
|
||||
pub fn all_inner_items(&self) -> impl Iterator<Item = ModItem> + '_ {
|
||||
self.inner_items.values().flatten().copied()
|
||||
match &self.data {
|
||||
Some(data) => Some(data.inner_items.values().flatten().copied()).into_iter().flatten(),
|
||||
None => None.into_iter().flatten(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn source<S: ItemTreeNode>(&self, db: &dyn DefDatabase, of: ItemTreeId<S>) -> S::Source {
|
||||
@ -297,6 +289,8 @@ struct ItemTreeData {
|
||||
|
||||
vis: ItemVisibilities,
|
||||
generics: GenericParamsStorage,
|
||||
|
||||
inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||
|
@ -6,7 +6,7 @@ use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, name::known, HirFileId}
|
||||
use smallvec::SmallVec;
|
||||
use syntax::{
|
||||
ast::{self, ModuleItemOwner},
|
||||
SyntaxNode,
|
||||
SyntaxNode, WalkEvent,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@ -150,14 +150,29 @@ impl Ctx {
|
||||
|
||||
fn collect_inner_items(&mut self, container: &SyntaxNode) {
|
||||
let forced_vis = self.forced_visibility.take();
|
||||
let mut inner_items = mem::take(&mut self.tree.inner_items);
|
||||
inner_items.extend(container.descendants().skip(1).filter_map(ast::Item::cast).filter_map(
|
||||
|item| {
|
||||
let ast_id = self.source_ast_id_map.ast_id(&item);
|
||||
Some((ast_id, self.lower_mod_item(&item, true)?.0))
|
||||
},
|
||||
));
|
||||
self.tree.inner_items = inner_items;
|
||||
|
||||
let mut current_block = None;
|
||||
for event in container.preorder().skip(1) {
|
||||
if let WalkEvent::Enter(node) = event {
|
||||
match_ast! {
|
||||
match node {
|
||||
ast::BlockExpr(block) => {
|
||||
current_block = Some(self.source_ast_id_map.ast_id(&block));
|
||||
},
|
||||
ast::Item(item) => {
|
||||
let mod_items = self.lower_mod_item(&item, true);
|
||||
if let (Some(mod_items), Some(block)) = (mod_items, current_block) {
|
||||
if !mod_items.0.is_empty() {
|
||||
self.data().inner_items.entry(block).or_default().extend(mod_items.0.iter().copied());
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.forced_visibility = forced_vis;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user