add items from macros to modules

This commit is contained in:
Aleksey Kladov 2019-01-01 21:52:07 +03:00
parent 4a3f76d3bb
commit 756e878158
3 changed files with 67 additions and 12 deletions

View file

@ -91,6 +91,7 @@ salsa::database_storage! {
fn library_symbols() for symbol_index::LibrarySymbolsQuery;
}
impl hir::db::HirDatabase {
fn m_source_file() for hir::db::MSourceFileQuery;
fn expand_macro_invocation() for hir::db::ExpandMacroCallQuery;
fn module_tree() for hir::db::ModuleTreeQuery;
fn fn_scopes() for hir::db::FnScopesQuery;

View file

@ -12,6 +12,7 @@ use ra_db::{SourceRootId, FileId, Cancelable,};
use crate::{
SourceFileItems, SourceItemId, DefKind, Function, DefId, Name, AsName, MFileId,
macros::MacroCallLoc,
db::HirDatabase,
function::FnScopes,
module::{
@ -123,25 +124,48 @@ pub(crate) fn modules<'a>(
pub(super) fn input_module_items(
db: &impl HirDatabase,
source_root: SourceRootId,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Cancelable<Arc<InputModuleItems>> {
let module_tree = db.module_tree(source_root)?;
let module_tree = db.module_tree(source_root_id)?;
let source = module_id.source(&module_tree);
let mfile_id = source.file_id().into();
let file_items = db.file_items(mfile_id);
let res = match source.resolve(db) {
ModuleSourceNode::SourceFile(it) => {
let items = it.borrowed().items();
InputModuleItems::new(mfile_id, &file_items, items)
let fill = |acc: &mut InputModuleItems, items: &mut Iterator<Item = ast::ItemOrMacro>| {
for item in items {
match item {
ast::ItemOrMacro::Item(it) => {
acc.add_item(mfile_id, &file_items, it);
}
ast::ItemOrMacro::Macro(macro_call) => {
let item_id = file_items.id_of_unchecked(macro_call.syntax());
let loc = MacroCallLoc {
source_root_id,
module_id,
source_item_id: SourceItemId {
mfile_id,
item_id: Some(item_id),
},
};
let id = loc.id(db);
let mfile_id = MFileId::Macro(id);
let file_items = db.file_items(mfile_id);
//FIXME: expand recursively
for item in db.m_source_file(mfile_id).borrowed().items() {
acc.add_item(mfile_id, &file_items, item);
}
}
}
}
};
let mut res = InputModuleItems::default();
match source.resolve(db) {
ModuleSourceNode::SourceFile(it) => fill(&mut res, &mut it.borrowed().items_with_macros()),
ModuleSourceNode::Module(it) => {
let items = it
.borrowed()
.item_list()
.into_iter()
.flat_map(|it| it.items());
InputModuleItems::new(mfile_id, &file_items, items)
if let Some(item_list) = it.borrowed().item_list() {
fill(&mut res, &mut item_list.items_with_macros())
}
}
};
Ok(Arc::new(res))

View file

@ -48,10 +48,40 @@ pub trait FnDefOwner<'a>: AstNode<'a> {
}
}
// ModuleItem
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ItemOrMacro<'a> {
Item(ModuleItem<'a>),
Macro(MacroCall<'a>),
}
impl<'a> AstNode<'a> for ItemOrMacro<'a> {
fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
let res = if let Some(item) = ModuleItem::cast(syntax) {
ItemOrMacro::Item(item)
} else if let Some(macro_call) = MacroCall::cast(syntax) {
ItemOrMacro::Macro(macro_call)
} else {
return None;
};
Some(res)
}
fn syntax(self) -> SyntaxNodeRef<'a> {
match self {
ItemOrMacro::Item(it) => it.syntax(),
ItemOrMacro::Macro(it) => it.syntax(),
}
}
}
pub trait ModuleItemOwner<'a>: AstNode<'a> {
fn items(self) -> AstChildren<'a, ModuleItem<'a>> {
children(self)
}
fn items_with_macros(self) -> AstChildren<'a, ItemOrMacro<'a>> {
children(self)
}
}
pub trait TypeParamsOwner<'a>: AstNode<'a> {