move query definitions

This commit is contained in:
Aleksey Kladov 2018-11-27 23:33:36 +03:00
parent 90bc832b22
commit b7049ea543
10 changed files with 229 additions and 196 deletions

View file

@ -10,7 +10,7 @@ use crate::{
hir,
symbol_index::SymbolIndex,
syntax_ptr::SyntaxPtr,
loc2id::{IdMaps, IdDatabase},
loc2id::{IdMaps},
Cancelable, Canceled, FileId,
};
@ -77,7 +77,14 @@ impl salsa::ParallelDatabase for RootDatabase {
}
}
impl IdDatabase for RootDatabase {
pub(crate) trait BaseDatabase: salsa::Database {
fn id_maps(&self) -> &IdMaps;
fn check_canceled(&self) -> Cancelable<()> {
check_canceled(self)
}
}
impl BaseDatabase for RootDatabase {
fn id_maps(&self) -> &IdMaps {
&self.id_maps
}
@ -136,7 +143,7 @@ salsa::database_storage! {
}
salsa::query_group! {
pub(crate) trait SyntaxDatabase: crate::input::FilesDatabase {
pub(crate) trait SyntaxDatabase: crate::input::FilesDatabase + BaseDatabase {
fn file_syntax(file_id: FileId) -> SourceFileNode {
type FileSyntaxQuery;
}

View file

@ -8,56 +8,59 @@ use ra_syntax::{
use crate::{
FileId,
db::SyntaxDatabase,
hir::query_definitions,
hir::function::{FnId, FnScopes},
hir::module::{
ModuleId, ModuleTree, ModuleSource,
nameres::{ItemMap, InputModuleItems, FileItems, FileItemId}
},
input::SourceRootId,
loc2id::{IdDatabase},
Cancelable,
};
salsa::query_group! {
pub(crate) trait HirDatabase: SyntaxDatabase + IdDatabase {
fn fn_scopes(fn_id: FnId) -> Arc<FnScopes> {
type FnScopesQuery;
use fn crate::hir::function::imp::fn_scopes;
}
fn file_items(file_id: FileId) -> Arc<FileItems> {
type FileItemsQuery;
storage dependencies;
use fn crate::hir::module::nameres::file_items;
}
pub(crate) trait HirDatabase: SyntaxDatabase {
fn fn_scopes(fn_id: FnId) -> Arc<FnScopes> {
type FnScopesQuery;
use fn query_definitions::fn_scopes;
}
fn fn_syntax(fn_id: FnId) -> FnDefNode {
type FnSyntaxQuery;
// Don't retain syntax trees in memory
storage dependencies;
use fn query_definitions::fn_syntax;
}
fn file_item(file_id: FileId, file_item_id: FileItemId) -> SyntaxNode {
type FileItemQuery;
storage dependencies;
use fn crate::hir::module::nameres::file_item;
}
fn file_items(file_id: FileId) -> Arc<FileItems> {
type FileItemsQuery;
storage dependencies;
use fn query_definitions::file_items;
}
fn input_module_items(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<InputModuleItems>> {
type InputModuleItemsQuery;
use fn crate::hir::module::nameres::input_module_items;
}
fn item_map(source_root_id: SourceRootId) -> Cancelable<Arc<ItemMap>> {
type ItemMapQuery;
use fn crate::hir::module::nameres::item_map;
}
fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> {
type ModuleTreeQuery;
use fn crate::hir::module::imp::module_tree;
}
fn fn_syntax(fn_id: FnId) -> FnDefNode {
type FnSyntaxQuery;
// Don't retain syntax trees in memory
storage dependencies;
use fn crate::hir::function::imp::fn_syntax;
}
fn submodules(source: ModuleSource) -> Cancelable<Arc<Vec<crate::hir::module::imp::Submodule>>> {
type SubmodulesQuery;
use fn crate::hir::module::imp::submodules;
}
fn file_item(file_id: FileId, file_item_id: FileItemId) -> SyntaxNode {
type FileItemQuery;
storage dependencies;
use fn query_definitions::file_item;
}
fn submodules(source: ModuleSource) -> Cancelable<Arc<Vec<crate::hir::module::imp::Submodule>>> {
type SubmodulesQuery;
use fn query_definitions::submodules;
}
fn input_module_items(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<InputModuleItems>> {
type InputModuleItemsQuery;
use fn query_definitions::input_module_items;
}
fn item_map(source_root_id: SourceRootId) -> Cancelable<Arc<ItemMap>> {
type ItemMapQuery;
use fn query_definitions::item_map;
}
fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> {
type ModuleTreeQuery;
use fn crate::hir::module::imp::module_tree;
}
}
}

View file

@ -1,21 +0,0 @@
use std::sync::Arc;
use ra_syntax::ast::{AstNode, FnDef, FnDefNode};
use crate::hir::{
function::{FnId, FnScopes},
HirDatabase,
};
/// Resolve `FnId` to the corresponding `SyntaxNode`
pub(crate) fn fn_syntax(db: &impl HirDatabase, fn_id: FnId) -> FnDefNode {
let ptr = db.id_maps().fn_ptr(fn_id);
let syntax = db.resolve_syntax_ptr(ptr);
FnDef::cast(syntax.borrowed()).unwrap().owned()
}
pub(crate) fn fn_scopes(db: &impl HirDatabase, fn_id: FnId) -> Arc<FnScopes> {
let syntax = db.fn_syntax(fn_id);
let res = FnScopes::new(syntax.borrowed());
Arc::new(res)
}

View file

@ -1,4 +1,3 @@
pub(super) mod imp;
mod scope;
use std::{
@ -14,14 +13,13 @@ use ra_syntax::{
use crate::{
hir::HirDatabase,
syntax_ptr::SyntaxPtr, FileId,
loc2id::IdDatabase,
};
pub(crate) use self::scope::{resolve_local_name, FnScopes};
pub(crate) use crate::loc2id::FnId;
impl FnId {
pub(crate) fn get(db: &impl IdDatabase, file_id: FileId, fn_def: ast::FnDef) -> FnId {
pub(crate) fn get(db: &impl HirDatabase, file_id: FileId, fn_def: ast::FnDef) -> FnId {
let ptr = SyntaxPtr::new(file_id, fn_def.syntax());
db.id_maps().fn_id(ptr)
}

View file

@ -9,6 +9,7 @@ pub(crate) mod function;
pub(crate) mod module;
pub(crate) mod db;
mod path;
mod query_definitions;
use ra_syntax::{
ast::{self, AstNode},

View file

@ -15,7 +15,7 @@ use crate::{
};
use super::{
LinkData, LinkId, ModuleData, ModuleId, ModuleSource, ModuleSourceNode,
LinkData, LinkId, ModuleData, ModuleId, ModuleSource,
ModuleTree, Problem,
};
@ -34,39 +34,6 @@ impl Submodule {
}
}
pub(crate) fn submodules(
db: &impl HirDatabase,
source: ModuleSource,
) -> Cancelable<Arc<Vec<Submodule>>> {
db::check_canceled(db)?;
let file_id = source.file_id();
let submodules = match source.resolve(db) {
ModuleSourceNode::SourceFile(it) => collect_submodules(file_id, it.borrowed()),
ModuleSourceNode::Module(it) => it
.borrowed()
.item_list()
.map(|it| collect_submodules(file_id, it))
.unwrap_or_else(Vec::new),
};
return Ok(Arc::new(submodules));
fn collect_submodules<'a>(
file_id: FileId,
root: impl ast::ModuleItemOwner<'a>,
) -> Vec<Submodule> {
modules(root)
.map(|(name, m)| {
if m.has_semi() {
Submodule::Declaration(name)
} else {
let src = ModuleSource::new_inline(file_id, m);
Submodule::Definition(name, src)
}
})
.collect()
}
}
pub(crate) fn modules<'a>(
root: impl ast::ModuleItemOwner<'a>,
) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> {

View file

@ -196,7 +196,7 @@ pub(crate) struct ModuleTree {
}
impl ModuleTree {
fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a {
pub(in crate::hir) fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a {
self.mods.iter().map(|(id, _)| id)
}
@ -224,7 +224,7 @@ pub(crate) enum ModuleSource {
/// An owned syntax node for a module. Unlike `ModuleSource`,
/// this holds onto the AST for the whole file.
enum ModuleSourceNode {
pub(crate) enum ModuleSourceNode {
SourceFile(ast::SourceFileNode),
Module(ast::ModuleNode),
}
@ -244,7 +244,7 @@ pub enum Problem {
}
impl ModuleId {
fn source(self, tree: &ModuleTree) -> ModuleSource {
pub(in crate::hir) fn source(self, tree: &ModuleTree) -> ModuleSource {
tree.mods[self].source
}
fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
@ -318,7 +318,7 @@ pub(crate) struct ModuleData {
}
impl ModuleSource {
fn new_inline(file_id: FileId, module: ast::Module) -> ModuleSource {
pub(crate) fn new_inline(file_id: FileId, module: ast::Module) -> ModuleSource {
assert!(!module.has_semi());
let ptr = SyntaxPtr::new(file_id, module.syntax());
ModuleSource::Module(ptr)
@ -338,7 +338,7 @@ impl ModuleSource {
}
}
fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode {
pub(crate) fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode {
match self {
ModuleSource::SourceFile(file_id) => {
let syntax = db.file_syntax(file_id);

View file

@ -16,7 +16,6 @@
//! structure itself is modified.
use std::{
sync::Arc,
time::Instant,
ops::Index,
};
@ -25,7 +24,7 @@ use rustc_hash::FxHashMap;
use ra_syntax::{
SyntaxNode, SyntaxNodeRef, TextRange,
SmolStr, SyntaxKind::{self, *},
ast::{self, ModuleItemOwner, AstNode}
ast::{self, AstNode}
};
use crate::{
@ -34,7 +33,7 @@ use crate::{
hir::{
Path, PathKind,
HirDatabase,
module::{ModuleId, ModuleTree, ModuleSourceNode},
module::{ModuleId, ModuleTree},
},
input::SourceRootId,
arena::{Arena, Id}
@ -51,7 +50,7 @@ pub(crate) struct FileItems {
}
impl FileItems {
fn alloc(&mut self, item: SyntaxNode) -> FileItemId {
pub(crate) fn alloc(&mut self, item: SyntaxNode) -> FileItemId {
self.arena.alloc(item)
}
fn id_of(&self, item: SyntaxNodeRef) -> FileItemId {
@ -71,29 +70,6 @@ impl Index<FileItemId> for FileItems {
}
}
pub(crate) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<FileItems> {
let source_file = db.file_syntax(file_id);
let source_file = source_file.borrowed();
let mut res = FileItems::default();
source_file
.syntax()
.descendants()
.filter_map(ast::ModuleItem::cast)
.map(|it| it.syntax().owned())
.for_each(|it| {
res.alloc(it);
});
Arc::new(res)
}
pub(crate) fn file_item(
db: &impl HirDatabase,
file_id: FileId,
file_item_id: FileItemId,
) -> SyntaxNode {
db.file_items(file_id)[file_item_id].clone()
}
/// Item map is the result of the name resolution. Item map contains, for each
/// module, the set of visible items.
#[derive(Default, Debug, PartialEq, Eq)]
@ -167,58 +143,6 @@ enum ImportKind {
Named(NamedImport),
}
pub(crate) fn input_module_items(
db: &impl HirDatabase,
source_root: SourceRootId,
module_id: ModuleId,
) -> Cancelable<Arc<InputModuleItems>> {
let module_tree = db.module_tree(source_root)?;
let source = module_id.source(&module_tree);
let file_items = db.file_items(source.file_id());
let res = match source.resolve(db) {
ModuleSourceNode::SourceFile(it) => {
let items = it.borrowed().items();
InputModuleItems::new(&file_items, items)
}
ModuleSourceNode::Module(it) => {
let items = it
.borrowed()
.item_list()
.into_iter()
.flat_map(|it| it.items());
InputModuleItems::new(&file_items, items)
}
};
Ok(Arc::new(res))
}
pub(crate) fn item_map(
db: &impl HirDatabase,
source_root: SourceRootId,
) -> Cancelable<Arc<ItemMap>> {
let start = Instant::now();
let module_tree = db.module_tree(source_root)?;
let input = module_tree
.modules()
.map(|id| {
let items = db.input_module_items(source_root, id)?;
Ok((id, items))
})
.collect::<Cancelable<FxHashMap<_, _>>>()?;
let mut resolver = Resolver {
db: db,
input: &input,
source_root,
module_tree,
result: ItemMap::default(),
};
resolver.resolve()?;
let res = resolver.result;
let elapsed = start.elapsed();
log::info!("item_map: {:?}", elapsed);
Ok(Arc::new(res))
}
/// Resolution is basically `DefId` atm, but it should account for stuff like
/// multiple namespaces, ambiguity and errors.
#[derive(Debug, Clone, PartialEq, Eq)]
@ -242,7 +166,7 @@ pub(crate) struct Resolution {
// }
impl InputModuleItems {
fn new<'a>(
pub(in crate::hir) fn new<'a>(
file_items: &FileItems,
items: impl Iterator<Item = ast::ModuleItem<'a>>,
) -> InputModuleItems {
@ -306,19 +230,19 @@ impl ModuleItem {
}
}
struct Resolver<'a, DB> {
db: &'a DB,
input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>,
source_root: SourceRootId,
module_tree: Arc<ModuleTree>,
result: ItemMap,
pub(in crate::hir) struct Resolver<'a, DB> {
pub db: &'a DB,
pub input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>,
pub source_root: SourceRootId,
pub module_tree: Arc<ModuleTree>,
pub result: ItemMap,
}
impl<'a, DB> Resolver<'a, DB>
where
DB: HirDatabase,
{
fn resolve(&mut self) -> Cancelable<()> {
pub(in crate::hir) fn resolve(mut self) -> Cancelable<ItemMap> {
for (&module_id, items) in self.input.iter() {
self.populate_module(module_id, items)
}
@ -327,7 +251,7 @@ where
crate::db::check_canceled(self.db)?;
self.resolve_imports(module_id);
}
Ok(())
Ok(self.result)
}
fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) {

View file

@ -0,0 +1,158 @@
use std::{
sync::Arc,
time::Instant,
};
use rustc_hash::FxHashMap;
use ra_syntax::{
AstNode, SyntaxNode, SmolStr,
ast::{self, FnDef, FnDefNode, NameOwner, ModuleItemOwner}
};
use crate::{
FileId, Cancelable,
hir::{
db::HirDatabase,
function::{FnId, FnScopes},
module::{
ModuleSource, ModuleSourceNode, ModuleId,
imp::Submodule,
nameres::{FileItems, FileItemId, InputModuleItems, ItemMap, Resolver},
},
},
input::SourceRootId,
};
/// Resolve `FnId` to the corresponding `SyntaxNode`
pub(super) fn fn_syntax(db: &impl HirDatabase, fn_id: FnId) -> FnDefNode {
let ptr = db.id_maps().fn_ptr(fn_id);
let syntax = db.resolve_syntax_ptr(ptr);
FnDef::cast(syntax.borrowed()).unwrap().owned()
}
pub(super) fn fn_scopes(db: &impl HirDatabase, fn_id: FnId) -> Arc<FnScopes> {
let syntax = db.fn_syntax(fn_id);
let res = FnScopes::new(syntax.borrowed());
Arc::new(res)
}
pub(super) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<FileItems> {
let source_file = db.file_syntax(file_id);
let source_file = source_file.borrowed();
let mut res = FileItems::default();
source_file
.syntax()
.descendants()
.filter_map(ast::ModuleItem::cast)
.map(|it| it.syntax().owned())
.for_each(|it| {
res.alloc(it);
});
Arc::new(res)
}
pub(super) fn file_item(
db: &impl HirDatabase,
file_id: FileId,
file_item_id: FileItemId,
) -> SyntaxNode {
db.file_items(file_id)[file_item_id].clone()
}
pub(crate) fn submodules(
db: &impl HirDatabase,
source: ModuleSource,
) -> Cancelable<Arc<Vec<Submodule>>> {
db.check_canceled()?;
let file_id = source.file_id();
let submodules = match source.resolve(db) {
ModuleSourceNode::SourceFile(it) => collect_submodules(file_id, it.borrowed()),
ModuleSourceNode::Module(it) => it
.borrowed()
.item_list()
.map(|it| collect_submodules(file_id, it))
.unwrap_or_else(Vec::new),
};
return Ok(Arc::new(submodules));
fn collect_submodules<'a>(
file_id: FileId,
root: impl ast::ModuleItemOwner<'a>,
) -> Vec<Submodule> {
modules(root)
.map(|(name, m)| {
if m.has_semi() {
Submodule::Declaration(name)
} else {
let src = ModuleSource::new_inline(file_id, m);
Submodule::Definition(name, src)
}
})
.collect()
}
}
pub(crate) fn modules<'a>(
root: impl ast::ModuleItemOwner<'a>,
) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> {
root.items()
.filter_map(|item| match item {
ast::ModuleItem::Module(m) => Some(m),
_ => None,
})
.filter_map(|module| {
let name = module.name()?.text();
Some((name, module))
})
}
pub(super) fn input_module_items(
db: &impl HirDatabase,
source_root: SourceRootId,
module_id: ModuleId,
) -> Cancelable<Arc<InputModuleItems>> {
let module_tree = db.module_tree(source_root)?;
let source = module_id.source(&module_tree);
let file_items = db.file_items(source.file_id());
let res = match source.resolve(db) {
ModuleSourceNode::SourceFile(it) => {
let items = it.borrowed().items();
InputModuleItems::new(&file_items, items)
}
ModuleSourceNode::Module(it) => {
let items = it
.borrowed()
.item_list()
.into_iter()
.flat_map(|it| it.items());
InputModuleItems::new(&file_items, items)
}
};
Ok(Arc::new(res))
}
pub(super) fn item_map(
db: &impl HirDatabase,
source_root: SourceRootId,
) -> Cancelable<Arc<ItemMap>> {
let start = Instant::now();
let module_tree = db.module_tree(source_root)?;
let input = module_tree
.modules()
.map(|id| {
let items = db.input_module_items(source_root, id)?;
Ok((id, items))
})
.collect::<Cancelable<FxHashMap<_, _>>>()?;
let resolver = Resolver {
db: db,
input: &input,
source_root,
module_tree,
result: ItemMap::default(),
};
let res = resolver.resolve()?;
let elapsed = start.elapsed();
log::info!("item_map: {:?}", elapsed);
Ok(Arc::new(res))
}

View file

@ -109,10 +109,6 @@ pub(crate) enum DefLoc {
},
}
pub(crate) trait IdDatabase: salsa::Database {
fn id_maps(&self) -> &IdMaps;
}
#[derive(Debug, Default, Clone)]
pub(crate) struct IdMaps {
inner: Arc<IdMapsInner>,