This commit is contained in:
Aleksey Kladov 2018-08-27 21:02:47 +03:00
parent aaca7d003b
commit 7f4b07a907
2 changed files with 16 additions and 20 deletions

View file

@ -8,7 +8,7 @@ use libsyntax2::{
use { use {
AtomEdit, find_node_at_offset, AtomEdit, find_node_at_offset,
scope::{FnScopes, compute_scopes}, scope::FnScopes,
}; };
#[derive(Debug)] #[derive(Debug)]
@ -25,7 +25,7 @@ pub fn scope_completion(file: &File, offset: TextUnit) -> Option<Vec<CompletionI
}; };
let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), offset)?; let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), offset)?;
let fn_def = ancestors(name_ref.syntax()).filter_map(ast::FnDef::cast).next()?; let fn_def = ancestors(name_ref.syntax()).filter_map(ast::FnDef::cast).next()?;
let scopes = compute_scopes(fn_def); let scopes = FnScopes::new(fn_def);
Some(complete(name_ref, &scopes)) Some(complete(name_ref, &scopes))
} }

View file

@ -9,20 +9,6 @@ use libsyntax2::{
algo::{ancestors, generate, walk::preorder} algo::{ancestors, generate, walk::preorder}
}; };
pub fn compute_scopes(fn_def: ast::FnDef) -> FnScopes {
let mut scopes = FnScopes::new();
let root = scopes.root_scope();
fn_def.param_list().into_iter()
.flat_map(|it| it.params())
.filter_map(|it| it.pat())
.for_each(|it| scopes.add_bindings(root, it));
if let Some(body) = fn_def.body() {
compute_block_scopes(body, &mut scopes, root)
}
scopes
}
fn compute_block_scopes(block: ast::Block, scopes: &mut FnScopes, mut scope: ScopeId) { fn compute_block_scopes(block: ast::Block, scopes: &mut FnScopes, mut scope: ScopeId) {
for stmt in block.statements() { for stmt in block.statements() {
match stmt { match stmt {
@ -106,11 +92,21 @@ pub struct FnScopes {
} }
impl FnScopes { impl FnScopes {
fn new() -> FnScopes { pub fn new(fn_def: ast::FnDef) -> FnScopes {
FnScopes { let mut scopes = FnScopes {
scopes: vec![], scopes: Vec::new(),
scope_for: HashMap::new(), scope_for: HashMap::new()
};
let root = scopes.root_scope();
fn_def.param_list().into_iter()
.flat_map(|it| it.params())
.filter_map(|it| it.pat())
.for_each(|it| scopes.add_bindings(root, it));
if let Some(body) = fn_def.body() {
compute_block_scopes(body, &mut scopes, root)
} }
scopes
} }
pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] {
&self.scopes[scope].entries &self.scopes[scope].entries