Add ModuleScope as a query

This is a first step towards queryifing completion and resolve.

Some code currently duplicates ra_editor: the plan is to move all
completion from ra_editor, but it'll take more than one commit.
This commit is contained in:
Aleksey Kladov 2018-10-31 02:08:54 +03:00
parent d10214581e
commit fbbee53722
8 changed files with 223 additions and 22 deletions

View file

@ -1,40 +1,51 @@
use ra_editor::{CompletionItem, find_node_at_offset, complete_module_items};
use ra_editor::{CompletionItem, find_node_at_offset};
use ra_syntax::{
AtomEdit, File, TextUnit, AstNode,
ast::{self, ModuleItemOwner},
ast::{self, ModuleItemOwner, AstChildren},
};
use crate::{
FileId, Cancelable,
input::FilesDatabase,
db::{self, SyntaxDatabase},
descriptors::module::{ModulesDatabase, ModuleTree, ModuleId},
descriptors::module::{ModulesDatabase, ModuleTree, ModuleId, scope::ModuleScope},
};
pub(crate) fn resolve_based_completion(db: &db::RootDatabase, file_id: FileId, offset: TextUnit) -> Cancelable<Option<Vec<CompletionItem>>> {
let source_root_id = db.file_source_root(file_id);
let file = db.file_syntax(file_id);
let module_tree = db.module_tree(source_root_id)?;
let module_id = match module_tree.any_module_for_file(file_id) {
None => return Ok(None),
Some(it) => it,
};
let file = {
let edit = AtomEdit::insert(offset, "intellijRulezz".to_string());
file.reparse(&edit)
};
let target_file = match find_target_module(&module_tree, file_id, &file, offset) {
let target_module_id = match find_target_module(&module_tree, module_id, &file, offset) {
None => return Ok(None),
Some(target_module) => {
let file_id = target_module.file_id(&module_tree);
db.file_syntax(file_id)
}
Some(it) => it,
};
let mut res = Vec::new();
complete_module_items(target_file.ast().items(), None, &mut res);
let module_scope = db.module_scope(source_root_id, target_module_id)?;
let res: Vec<_> = module_scope
.entries()
.iter()
.map(|entry| CompletionItem {
label: entry.name().to_string(),
lookup: None,
snippet: None,
})
.collect();
Ok(Some(res))
}
pub(crate) fn find_target_module(module_tree: &ModuleTree, file_id: FileId, file: &File, offset: TextUnit) -> Option<ModuleId> {
pub(crate) fn find_target_module(module_tree: &ModuleTree, module_id: ModuleId, file: &File, offset: TextUnit) -> Option<ModuleId> {
let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), offset)?;
let mut crate_path = crate_path(name_ref)?;
let module_id = module_tree.any_module_for_file(file_id)?;
crate_path.pop();
let mut target_module = module_id.root(&module_tree);
for name in crate_path {