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; fn library_symbols() for symbol_index::LibrarySymbolsQuery;
} }
impl hir::db::HirDatabase { impl hir::db::HirDatabase {
fn m_source_file() for hir::db::MSourceFileQuery;
fn expand_macro_invocation() for hir::db::ExpandMacroCallQuery; fn expand_macro_invocation() for hir::db::ExpandMacroCallQuery;
fn module_tree() for hir::db::ModuleTreeQuery; fn module_tree() for hir::db::ModuleTreeQuery;
fn fn_scopes() for hir::db::FnScopesQuery; fn fn_scopes() for hir::db::FnScopesQuery;

View file

@ -12,6 +12,7 @@ use ra_db::{SourceRootId, FileId, Cancelable,};
use crate::{ use crate::{
SourceFileItems, SourceItemId, DefKind, Function, DefId, Name, AsName, MFileId, SourceFileItems, SourceItemId, DefKind, Function, DefId, Name, AsName, MFileId,
macros::MacroCallLoc,
db::HirDatabase, db::HirDatabase,
function::FnScopes, function::FnScopes,
module::{ module::{
@ -123,25 +124,48 @@ pub(crate) fn modules<'a>(
pub(super) fn input_module_items( pub(super) fn input_module_items(
db: &impl HirDatabase, db: &impl HirDatabase,
source_root: SourceRootId, source_root_id: SourceRootId,
module_id: ModuleId, module_id: ModuleId,
) -> Cancelable<Arc<InputModuleItems>> { ) -> 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 source = module_id.source(&module_tree);
let mfile_id = source.file_id().into(); let mfile_id = source.file_id().into();
let file_items = db.file_items(mfile_id); let file_items = db.file_items(mfile_id);
let res = match source.resolve(db) { let fill = |acc: &mut InputModuleItems, items: &mut Iterator<Item = ast::ItemOrMacro>| {
ModuleSourceNode::SourceFile(it) => { for item in items {
let items = it.borrowed().items(); match item {
InputModuleItems::new(mfile_id, &file_items, items) 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) => { ModuleSourceNode::Module(it) => {
let items = it if let Some(item_list) = it.borrowed().item_list() {
.borrowed() fill(&mut res, &mut item_list.items_with_macros())
.item_list() }
.into_iter()
.flat_map(|it| it.items());
InputModuleItems::new(mfile_id, &file_items, items)
} }
}; };
Ok(Arc::new(res)) 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> { pub trait ModuleItemOwner<'a>: AstNode<'a> {
fn items(self) -> AstChildren<'a, ModuleItem<'a>> { fn items(self) -> AstChildren<'a, ModuleItem<'a>> {
children(self) children(self)
} }
fn items_with_macros(self) -> AstChildren<'a, ItemOrMacro<'a>> {
children(self)
}
} }
pub trait TypeParamsOwner<'a>: AstNode<'a> { pub trait TypeParamsOwner<'a>: AstNode<'a> {