mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 05:15:04 +00:00
move query definitions
This commit is contained in:
parent
90bc832b22
commit
b7049ea543
10 changed files with 229 additions and 196 deletions
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
hir,
|
hir,
|
||||||
symbol_index::SymbolIndex,
|
symbol_index::SymbolIndex,
|
||||||
syntax_ptr::SyntaxPtr,
|
syntax_ptr::SyntaxPtr,
|
||||||
loc2id::{IdMaps, IdDatabase},
|
loc2id::{IdMaps},
|
||||||
Cancelable, Canceled, FileId,
|
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 {
|
fn id_maps(&self) -> &IdMaps {
|
||||||
&self.id_maps
|
&self.id_maps
|
||||||
}
|
}
|
||||||
|
@ -136,7 +143,7 @@ salsa::database_storage! {
|
||||||
}
|
}
|
||||||
|
|
||||||
salsa::query_group! {
|
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 {
|
fn file_syntax(file_id: FileId) -> SourceFileNode {
|
||||||
type FileSyntaxQuery;
|
type FileSyntaxQuery;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,56 +8,59 @@ use ra_syntax::{
|
||||||
use crate::{
|
use crate::{
|
||||||
FileId,
|
FileId,
|
||||||
db::SyntaxDatabase,
|
db::SyntaxDatabase,
|
||||||
|
hir::query_definitions,
|
||||||
hir::function::{FnId, FnScopes},
|
hir::function::{FnId, FnScopes},
|
||||||
hir::module::{
|
hir::module::{
|
||||||
ModuleId, ModuleTree, ModuleSource,
|
ModuleId, ModuleTree, ModuleSource,
|
||||||
nameres::{ItemMap, InputModuleItems, FileItems, FileItemId}
|
nameres::{ItemMap, InputModuleItems, FileItems, FileItemId}
|
||||||
},
|
},
|
||||||
input::SourceRootId,
|
input::SourceRootId,
|
||||||
loc2id::{IdDatabase},
|
|
||||||
Cancelable,
|
Cancelable,
|
||||||
};
|
};
|
||||||
|
|
||||||
salsa::query_group! {
|
salsa::query_group! {
|
||||||
pub(crate) trait HirDatabase: SyntaxDatabase + IdDatabase {
|
|
||||||
|
pub(crate) trait HirDatabase: SyntaxDatabase {
|
||||||
fn fn_scopes(fn_id: FnId) -> Arc<FnScopes> {
|
fn fn_scopes(fn_id: FnId) -> Arc<FnScopes> {
|
||||||
type FnScopesQuery;
|
type FnScopesQuery;
|
||||||
use fn crate::hir::function::imp::fn_scopes;
|
use fn query_definitions::fn_scopes;
|
||||||
}
|
|
||||||
|
|
||||||
fn file_items(file_id: FileId) -> Arc<FileItems> {
|
|
||||||
type FileItemsQuery;
|
|
||||||
storage dependencies;
|
|
||||||
use fn crate::hir::module::nameres::file_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_item(file_id: FileId, file_item_id: FileItemId) -> SyntaxNode {
|
|
||||||
type FileItemQuery;
|
|
||||||
storage dependencies;
|
|
||||||
use fn crate::hir::module::nameres::file_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
fn fn_syntax(fn_id: FnId) -> FnDefNode {
|
||||||
type FnSyntaxQuery;
|
type FnSyntaxQuery;
|
||||||
// Don't retain syntax trees in memory
|
// Don't retain syntax trees in memory
|
||||||
storage dependencies;
|
storage dependencies;
|
||||||
use fn crate::hir::function::imp::fn_syntax;
|
use fn query_definitions::fn_syntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn file_items(file_id: FileId) -> Arc<FileItems> {
|
||||||
|
type FileItemsQuery;
|
||||||
|
storage dependencies;
|
||||||
|
use fn query_definitions::file_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
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>>> {
|
fn submodules(source: ModuleSource) -> Cancelable<Arc<Vec<crate::hir::module::imp::Submodule>>> {
|
||||||
type SubmodulesQuery;
|
type SubmodulesQuery;
|
||||||
use fn crate::hir::module::imp::submodules;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
pub(super) mod imp;
|
|
||||||
mod scope;
|
mod scope;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -14,14 +13,13 @@ use ra_syntax::{
|
||||||
use crate::{
|
use crate::{
|
||||||
hir::HirDatabase,
|
hir::HirDatabase,
|
||||||
syntax_ptr::SyntaxPtr, FileId,
|
syntax_ptr::SyntaxPtr, FileId,
|
||||||
loc2id::IdDatabase,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) use self::scope::{resolve_local_name, FnScopes};
|
pub(crate) use self::scope::{resolve_local_name, FnScopes};
|
||||||
pub(crate) use crate::loc2id::FnId;
|
pub(crate) use crate::loc2id::FnId;
|
||||||
|
|
||||||
impl 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());
|
let ptr = SyntaxPtr::new(file_id, fn_def.syntax());
|
||||||
db.id_maps().fn_id(ptr)
|
db.id_maps().fn_id(ptr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub(crate) mod function;
|
||||||
pub(crate) mod module;
|
pub(crate) mod module;
|
||||||
pub(crate) mod db;
|
pub(crate) mod db;
|
||||||
mod path;
|
mod path;
|
||||||
|
mod query_definitions;
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
LinkData, LinkId, ModuleData, ModuleId, ModuleSource, ModuleSourceNode,
|
LinkData, LinkId, ModuleData, ModuleId, ModuleSource,
|
||||||
ModuleTree, Problem,
|
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>(
|
pub(crate) fn modules<'a>(
|
||||||
root: impl ast::ModuleItemOwner<'a>,
|
root: impl ast::ModuleItemOwner<'a>,
|
||||||
) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> {
|
) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> {
|
||||||
|
|
|
@ -196,7 +196,7 @@ pub(crate) struct ModuleTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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)
|
self.mods.iter().map(|(id, _)| id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ pub(crate) enum ModuleSource {
|
||||||
|
|
||||||
/// An owned syntax node for a module. Unlike `ModuleSource`,
|
/// An owned syntax node for a module. Unlike `ModuleSource`,
|
||||||
/// this holds onto the AST for the whole file.
|
/// this holds onto the AST for the whole file.
|
||||||
enum ModuleSourceNode {
|
pub(crate) enum ModuleSourceNode {
|
||||||
SourceFile(ast::SourceFileNode),
|
SourceFile(ast::SourceFileNode),
|
||||||
Module(ast::ModuleNode),
|
Module(ast::ModuleNode),
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ pub enum Problem {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleId {
|
impl ModuleId {
|
||||||
fn source(self, tree: &ModuleTree) -> ModuleSource {
|
pub(in crate::hir) fn source(self, tree: &ModuleTree) -> ModuleSource {
|
||||||
tree.mods[self].source
|
tree.mods[self].source
|
||||||
}
|
}
|
||||||
fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
|
fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
|
||||||
|
@ -318,7 +318,7 @@ pub(crate) struct ModuleData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleSource {
|
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());
|
assert!(!module.has_semi());
|
||||||
let ptr = SyntaxPtr::new(file_id, module.syntax());
|
let ptr = SyntaxPtr::new(file_id, module.syntax());
|
||||||
ModuleSource::Module(ptr)
|
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 {
|
match self {
|
||||||
ModuleSource::SourceFile(file_id) => {
|
ModuleSource::SourceFile(file_id) => {
|
||||||
let syntax = db.file_syntax(file_id);
|
let syntax = db.file_syntax(file_id);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
//! structure itself is modified.
|
//! structure itself is modified.
|
||||||
use std::{
|
use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Instant,
|
|
||||||
ops::Index,
|
ops::Index,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ use rustc_hash::FxHashMap;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
SyntaxNode, SyntaxNodeRef, TextRange,
|
SyntaxNode, SyntaxNodeRef, TextRange,
|
||||||
SmolStr, SyntaxKind::{self, *},
|
SmolStr, SyntaxKind::{self, *},
|
||||||
ast::{self, ModuleItemOwner, AstNode}
|
ast::{self, AstNode}
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -34,7 +33,7 @@ use crate::{
|
||||||
hir::{
|
hir::{
|
||||||
Path, PathKind,
|
Path, PathKind,
|
||||||
HirDatabase,
|
HirDatabase,
|
||||||
module::{ModuleId, ModuleTree, ModuleSourceNode},
|
module::{ModuleId, ModuleTree},
|
||||||
},
|
},
|
||||||
input::SourceRootId,
|
input::SourceRootId,
|
||||||
arena::{Arena, Id}
|
arena::{Arena, Id}
|
||||||
|
@ -51,7 +50,7 @@ pub(crate) struct FileItems {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileItems {
|
impl FileItems {
|
||||||
fn alloc(&mut self, item: SyntaxNode) -> FileItemId {
|
pub(crate) fn alloc(&mut self, item: SyntaxNode) -> FileItemId {
|
||||||
self.arena.alloc(item)
|
self.arena.alloc(item)
|
||||||
}
|
}
|
||||||
fn id_of(&self, item: SyntaxNodeRef) -> FileItemId {
|
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
|
/// Item map is the result of the name resolution. Item map contains, for each
|
||||||
/// module, the set of visible items.
|
/// module, the set of visible items.
|
||||||
#[derive(Default, Debug, PartialEq, Eq)]
|
#[derive(Default, Debug, PartialEq, Eq)]
|
||||||
|
@ -167,58 +143,6 @@ enum ImportKind {
|
||||||
Named(NamedImport),
|
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
|
/// Resolution is basically `DefId` atm, but it should account for stuff like
|
||||||
/// multiple namespaces, ambiguity and errors.
|
/// multiple namespaces, ambiguity and errors.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
@ -242,7 +166,7 @@ pub(crate) struct Resolution {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
impl InputModuleItems {
|
impl InputModuleItems {
|
||||||
fn new<'a>(
|
pub(in crate::hir) fn new<'a>(
|
||||||
file_items: &FileItems,
|
file_items: &FileItems,
|
||||||
items: impl Iterator<Item = ast::ModuleItem<'a>>,
|
items: impl Iterator<Item = ast::ModuleItem<'a>>,
|
||||||
) -> InputModuleItems {
|
) -> InputModuleItems {
|
||||||
|
@ -306,19 +230,19 @@ impl ModuleItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Resolver<'a, DB> {
|
pub(in crate::hir) struct Resolver<'a, DB> {
|
||||||
db: &'a DB,
|
pub db: &'a DB,
|
||||||
input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>,
|
pub input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>,
|
||||||
source_root: SourceRootId,
|
pub source_root: SourceRootId,
|
||||||
module_tree: Arc<ModuleTree>,
|
pub module_tree: Arc<ModuleTree>,
|
||||||
result: ItemMap,
|
pub result: ItemMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, DB> Resolver<'a, DB>
|
impl<'a, DB> Resolver<'a, DB>
|
||||||
where
|
where
|
||||||
DB: HirDatabase,
|
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() {
|
for (&module_id, items) in self.input.iter() {
|
||||||
self.populate_module(module_id, items)
|
self.populate_module(module_id, items)
|
||||||
}
|
}
|
||||||
|
@ -327,7 +251,7 @@ where
|
||||||
crate::db::check_canceled(self.db)?;
|
crate::db::check_canceled(self.db)?;
|
||||||
self.resolve_imports(module_id);
|
self.resolve_imports(module_id);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(self.result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) {
|
fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) {
|
||||||
|
|
158
crates/ra_analysis/src/hir/query_definitions.rs
Normal file
158
crates/ra_analysis/src/hir/query_definitions.rs
Normal 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))
|
||||||
|
}
|
|
@ -109,10 +109,6 @@ pub(crate) enum DefLoc {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait IdDatabase: salsa::Database {
|
|
||||||
fn id_maps(&self) -> &IdMaps;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub(crate) struct IdMaps {
|
pub(crate) struct IdMaps {
|
||||||
inner: Arc<IdMapsInner>,
|
inner: Arc<IdMapsInner>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue