rust/crates/ra_hir/src/query_definitions.rs

110 lines
3.5 KiB
Rust
Raw Normal View History

2018-11-28 01:42:26 +01:00
use std::{
sync::Arc,
time::Instant,
};
use rustc_hash::FxHashMap;
use ra_syntax::{
AstNode, SyntaxNode, TreeArc,
ast::{self, ModuleItemOwner}
2018-11-28 01:42:26 +01:00
};
2019-01-15 17:15:01 +01:00
use ra_db::SourceRootId;
2018-11-28 01:42:26 +01:00
use crate::{
2019-01-08 13:38:29 +01:00
SourceFileItems, SourceItemId, DefId, HirFileId, ModuleSource,
2019-01-08 18:11:13 +01:00
MacroCallLoc, FnScopes,
2018-12-04 21:44:00 +01:00
db::HirDatabase,
2019-01-06 17:58:10 +01:00
module_tree::ModuleId,
2019-01-06 15:33:27 +01:00
nameres::{InputModuleItems, ItemMap, Resolver},
2018-11-28 01:42:26 +01:00
};
2019-01-15 17:04:49 +01:00
pub(super) fn fn_scopes(db: &impl HirDatabase, def_id: DefId) -> Arc<FnScopes> {
2019-01-15 17:01:59 +01:00
let body = db.body_hir(def_id);
let res = FnScopes::new(body);
2019-01-15 17:04:49 +01:00
Arc::new(res)
2018-11-28 01:42:26 +01:00
}
2019-01-01 21:21:16 +01:00
pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> {
let source_file = db.hir_source_file(file_id);
2019-01-08 09:28:42 +01:00
let res = SourceFileItems::new(file_id, &source_file);
2018-11-28 01:42:26 +01:00
Arc::new(res)
}
2019-01-08 09:28:42 +01:00
pub(super) fn file_item(
db: &impl HirDatabase,
source_item_id: SourceItemId,
) -> TreeArc<SyntaxNode> {
match source_item_id.item_id {
2019-01-08 09:28:42 +01:00
Some(id) => db.file_items(source_item_id.file_id)[id].to_owned(),
None => db
.hir_source_file(source_item_id.file_id)
.syntax()
.to_owned(),
}
2018-11-28 01:42:26 +01:00
}
pub(super) fn input_module_items(
db: &impl HirDatabase,
2019-01-01 19:52:07 +01:00
source_root_id: SourceRootId,
2018-11-28 01:42:26 +01:00
module_id: ModuleId,
2019-01-15 16:13:11 +01:00
) -> Arc<InputModuleItems> {
let module_tree = db.module_tree(source_root_id);
2018-11-28 01:42:26 +01:00
let source = module_id.source(&module_tree);
2019-01-06 17:58:10 +01:00
let file_id = source.file_id;
let source = ModuleSource::from_source_item_id(db, source);
2019-01-01 21:21:16 +01:00
let file_items = db.file_items(file_id);
2019-01-01 19:52:07 +01:00
let fill = |acc: &mut InputModuleItems, items: &mut Iterator<Item = ast::ItemOrMacro>| {
for item in items {
match item {
ast::ItemOrMacro::Item(it) => {
2019-01-01 21:21:16 +01:00
acc.add_item(file_id, &file_items, it);
2019-01-01 19:52:07 +01:00
}
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 {
2019-01-01 21:21:16 +01:00
file_id,
2019-01-01 19:52:07 +01:00
item_id: Some(item_id),
},
};
let id = loc.id(db);
2019-01-01 21:21:16 +01:00
let file_id = HirFileId::from(id);
let file_items = db.file_items(file_id);
2019-01-01 19:52:07 +01:00
//FIXME: expand recursively
2019-01-08 09:28:42 +01:00
for item in db.hir_source_file(file_id).items() {
2019-01-01 21:21:16 +01:00
acc.add_item(file_id, &file_items, item);
2019-01-01 19:52:07 +01:00
}
}
}
2018-11-28 01:42:26 +01:00
}
2019-01-01 19:52:07 +01:00
};
let mut res = InputModuleItems::default();
2019-01-06 17:58:10 +01:00
match source {
2019-01-08 09:28:42 +01:00
ModuleSource::SourceFile(it) => fill(&mut res, &mut it.items_with_macros()),
2019-01-06 17:58:10 +01:00
ModuleSource::Module(it) => {
2019-01-08 09:28:42 +01:00
if let Some(item_list) = it.item_list() {
2019-01-01 19:52:07 +01:00
fill(&mut res, &mut item_list.items_with_macros())
}
2018-11-28 01:42:26 +01:00
}
};
2019-01-15 16:13:11 +01:00
Arc::new(res)
2018-11-28 01:42:26 +01:00
}
2019-01-15 17:15:01 +01:00
pub(super) fn item_map(db: &impl HirDatabase, source_root: SourceRootId) -> Arc<ItemMap> {
2018-11-28 01:42:26 +01:00
let start = Instant::now();
let module_tree = db.module_tree(source_root);
2018-11-28 01:42:26 +01:00
let input = module_tree
.modules()
2019-01-15 16:13:11 +01:00
.map(|id| (id, db.input_module_items(source_root, id)))
.collect::<FxHashMap<_, _>>();
2018-12-09 10:24:52 +01:00
let resolver = Resolver::new(db, &input, source_root, module_tree);
2019-01-15 17:15:01 +01:00
let res = resolver.resolve();
2018-11-28 01:42:26 +01:00
let elapsed = start.elapsed();
log::info!("item_map: {:?}", elapsed);
2019-01-15 17:15:01 +01:00
Arc::new(res)
2018-11-28 01:42:26 +01:00
}