From b67295134bf5c518b39bc88abbe1bc5b9d7d3baf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 31 Oct 2018 10:56:31 +0300 Subject: Move FnDescriptors to analyzer --- crates/ra_analysis/src/completion.rs | 5 +- crates/ra_analysis/src/db.rs | 9 +- crates/ra_analysis/src/descriptors/function/imp.rs | 26 ++ crates/ra_analysis/src/descriptors/function/mod.rs | 83 ++++ .../ra_analysis/src/descriptors/function/scope.rs | 435 +++++++++++++++++++++ crates/ra_analysis/src/descriptors/mod.rs | 88 ++--- crates/ra_analysis/src/descriptors/module/imp.rs | 19 +- crates/ra_analysis/src/descriptors/module/mod.rs | 28 +- crates/ra_analysis/src/descriptors/module/scope.rs | 6 +- crates/ra_analysis/src/imp.rs | 5 +- crates/ra_analysis/src/lib.rs | 2 +- crates/ra_analysis/src/syntax_ptr.rs | 1 + 12 files changed, 610 insertions(+), 97 deletions(-) create mode 100644 crates/ra_analysis/src/descriptors/function/imp.rs create mode 100644 crates/ra_analysis/src/descriptors/function/mod.rs create mode 100644 crates/ra_analysis/src/descriptors/function/scope.rs (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/completion.rs b/crates/ra_analysis/src/completion.rs index 0141d132e..869ab5afb 100644 --- a/crates/ra_analysis/src/completion.rs +++ b/crates/ra_analysis/src/completion.rs @@ -1,14 +1,15 @@ use ra_editor::{CompletionItem, find_node_at_offset}; use ra_syntax::{ AtomEdit, File, TextUnit, AstNode, - ast::{self, ModuleItemOwner, AstChildren}, + ast, }; use crate::{ FileId, Cancelable, input::FilesDatabase, db::{self, SyntaxDatabase}, - descriptors::module::{ModulesDatabase, ModuleTree, ModuleId, scope::ModuleScope}, + descriptors::DescriptorDatabase, + descriptors::module::{ModuleTree, ModuleId}, }; pub(crate) fn resolve_based_completion(db: &db::RootDatabase, file_id: FileId, offset: TextUnit) -> Cancelable>> { diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index e7a5d5e2f..fe6587f20 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs @@ -9,7 +9,10 @@ use salsa; use crate::{ db, Cancelable, Canceled, - descriptors::module::{SubmodulesQuery, ModuleTreeQuery, ModulesDatabase, ModuleScopeQuery}, + descriptors::{ + DescriptorDatabase, SubmodulesQuery, ModuleTreeQuery, ModuleScopeQuery, + FnSyntaxQuery, FnScopesQuery + }, symbol_index::SymbolIndex, syntax_ptr::{SyntaxPtrDatabase, ResolveSyntaxPtrQuery}, FileId, @@ -63,10 +66,12 @@ salsa::database_storage! { fn file_lines() for FileLinesQuery; fn file_symbols() for FileSymbolsQuery; } - impl ModulesDatabase { + impl DescriptorDatabase { fn module_tree() for ModuleTreeQuery; fn module_descriptor() for SubmodulesQuery; fn module_scope() for ModuleScopeQuery; + fn fn_syntax() for FnSyntaxQuery; + fn fn_scopes() for FnScopesQuery; } impl SyntaxPtrDatabase { fn resolve_syntax_ptr() for ResolveSyntaxPtrQuery; diff --git a/crates/ra_analysis/src/descriptors/function/imp.rs b/crates/ra_analysis/src/descriptors/function/imp.rs new file mode 100644 index 000000000..0a006f733 --- /dev/null +++ b/crates/ra_analysis/src/descriptors/function/imp.rs @@ -0,0 +1,26 @@ +use std::sync::Arc; + +use ra_syntax::{ + ast::{AstNode, FnDef, FnDefNode}, +}; + +use crate::{ + descriptors::{ + DescriptorDatabase, + function::{FnId, FnScopes}, + }, +}; + +/// Resolve `FnId` to the corresponding `SyntaxNode` +/// TODO: this should return something more type-safe then `SyntaxNode` +pub(crate) fn fn_syntax(db: &impl DescriptorDatabase, fn_id: FnId) -> FnDefNode { + let syntax = db.resolve_syntax_ptr(fn_id.0); + let fn_def = FnDef::cast(syntax.borrowed()).unwrap(); + FnDefNode::new(fn_def) +} + +pub(crate) fn fn_scopes(db: &impl DescriptorDatabase, fn_id: FnId) -> Arc { + let syntax = db.fn_syntax(fn_id); + let res = FnScopes::new(syntax.ast()); + Arc::new(res) +} diff --git a/crates/ra_analysis/src/descriptors/function/mod.rs b/crates/ra_analysis/src/descriptors/function/mod.rs new file mode 100644 index 000000000..687413ddc --- /dev/null +++ b/crates/ra_analysis/src/descriptors/function/mod.rs @@ -0,0 +1,83 @@ +pub(super) mod imp; +mod scope; + +use ra_syntax::{ + ast::{self, AstNode, NameOwner} +}; + +use crate::{ + FileId, + syntax_ptr::SyntaxPtr +}; + +pub(crate) use self::scope::FnScopes; + + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct FnId(SyntaxPtr); + +impl FnId { + pub(crate) fn new(file_id: FileId, fn_def: ast::FnDef) -> FnId { + let ptr = SyntaxPtr::new(file_id, fn_def.syntax()); + FnId(ptr) + } +} + + +#[derive(Debug, Clone)] +pub struct FnDescriptor { + pub name: String, + pub label: String, + pub ret_type: Option, + pub params: Vec, +} + +impl FnDescriptor { + pub fn new(node: ast::FnDef) -> Option { + let name = node.name()?.text().to_string(); + + // Strip the body out for the label. + let label: String = if let Some(body) = node.body() { + let body_range = body.syntax().range(); + let label: String = node + .syntax() + .children() + .filter(|child| !child.range().is_subrange(&body_range)) + .map(|node| node.text().to_string()) + .collect(); + label + } else { + node.syntax().text().to_string() + }; + + let params = FnDescriptor::param_list(node); + let ret_type = node.ret_type().map(|r| r.syntax().text().to_string()); + + Some(FnDescriptor { + name, + ret_type, + params, + label, + }) + } + + fn param_list(node: ast::FnDef) -> Vec { + let mut res = vec![]; + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + res.push(self_param.syntax().text().to_string()) + } + + // Maybe use param.pat here? See if we can just extract the name? + //res.extend(param_list.params().map(|p| p.syntax().text().to_string())); + res.extend( + param_list + .params() + .filter_map(|p| p.pat()) + .map(|pat| pat.syntax().text().to_string()), + ); + } + res + } +} + diff --git a/crates/ra_analysis/src/descriptors/function/scope.rs b/crates/ra_analysis/src/descriptors/function/scope.rs new file mode 100644 index 000000000..5333a0a3b --- /dev/null +++ b/crates/ra_analysis/src/descriptors/function/scope.rs @@ -0,0 +1,435 @@ +use rustc_hash::FxHashMap; + +use ra_syntax::{ + algo::generate, + ast::{self, ArgListOwner, LoopBodyOwner, NameOwner}, + AstNode, SmolStr, SyntaxNodeRef, +}; + +use crate::syntax_ptr::LocalSyntaxPtr; + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub(crate) struct ScopeId(u32); + +#[derive(Debug, PartialEq, Eq)] +pub struct FnScopes { + pub(crate) self_param: Option, + scopes: Vec, + scope_for: FxHashMap, +} + +#[derive(Debug, PartialEq, Eq)] +pub struct ScopeEntry { + name: SmolStr, + ptr: LocalSyntaxPtr, +} + +#[derive(Debug, PartialEq, Eq)] +struct ScopeData { + parent: Option, + entries: Vec, +} + +impl FnScopes { + pub(crate) fn new(fn_def: ast::FnDef) -> FnScopes { + let mut scopes = FnScopes { + self_param: fn_def + .param_list() + .and_then(|it| it.self_param()) + .map(|it| LocalSyntaxPtr::new(it.syntax())), + scopes: Vec::new(), + scope_for: FxHashMap::default(), + }; + let root = scopes.root_scope(); + scopes.add_params_bindings(root, fn_def.param_list()); + if let Some(body) = fn_def.body() { + compute_block_scopes(body, &mut scopes, root) + } + scopes + } + pub(crate) fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { + &self.get(scope).entries + } + pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator + 'a { + generate(self.scope_for(node), move |&scope| { + self.get(scope).parent + }) + } + fn root_scope(&mut self) -> ScopeId { + let res = ScopeId(self.scopes.len() as u32); + self.scopes.push(ScopeData { + parent: None, + entries: vec![], + }); + res + } + fn new_scope(&mut self, parent: ScopeId) -> ScopeId { + let res = ScopeId(self.scopes.len() as u32); + self.scopes.push(ScopeData { + parent: Some(parent), + entries: vec![], + }); + res + } + fn add_bindings(&mut self, scope: ScopeId, pat: ast::Pat) { + let entries = pat + .syntax() + .descendants() + .filter_map(ast::BindPat::cast) + .filter_map(ScopeEntry::new); + self.get_mut(scope).entries.extend(entries); + } + fn add_params_bindings(&mut self, scope: ScopeId, params: Option) { + params + .into_iter() + .flat_map(|it| it.params()) + .filter_map(|it| it.pat()) + .for_each(|it| self.add_bindings(scope, it)); + } + fn set_scope(&mut self, node: SyntaxNodeRef, scope: ScopeId) { + self.scope_for.insert(LocalSyntaxPtr::new(node), scope); + } + fn scope_for(&self, node: SyntaxNodeRef) -> Option { + node.ancestors() + .map(LocalSyntaxPtr::new) + .filter_map(|it| self.scope_for.get(&it).map(|&scope| scope)) + .next() + } + fn get(&self, scope: ScopeId) -> &ScopeData { + &self.scopes[scope.0 as usize] + } + fn get_mut(&mut self, scope: ScopeId) -> &mut ScopeData { + &mut self.scopes[scope.0 as usize] + } +} + +impl ScopeEntry { + fn new(pat: ast::BindPat) -> Option { + let name = pat.name()?; + let res = ScopeEntry { + name: name.text(), + ptr: LocalSyntaxPtr::new(pat.syntax()), + }; + Some(res) + } + pub(crate) fn name(&self) -> &SmolStr { + &self.name + } + pub(crate) fn ptr(&self) -> LocalSyntaxPtr { + self.ptr + } +} + +fn compute_block_scopes(block: ast::Block, scopes: &mut FnScopes, mut scope: ScopeId) { + for stmt in block.statements() { + match stmt { + ast::Stmt::LetStmt(stmt) => { + if let Some(expr) = stmt.initializer() { + scopes.set_scope(expr.syntax(), scope); + compute_expr_scopes(expr, scopes, scope); + } + scope = scopes.new_scope(scope); + if let Some(pat) = stmt.pat() { + scopes.add_bindings(scope, pat); + } + } + ast::Stmt::ExprStmt(expr_stmt) => { + if let Some(expr) = expr_stmt.expr() { + scopes.set_scope(expr.syntax(), scope); + compute_expr_scopes(expr, scopes, scope); + } + } + } + } + if let Some(expr) = block.expr() { + scopes.set_scope(expr.syntax(), scope); + compute_expr_scopes(expr, scopes, scope); + } +} + +fn compute_expr_scopes(expr: ast::Expr, scopes: &mut FnScopes, scope: ScopeId) { + match expr { + ast::Expr::IfExpr(e) => { + let cond_scope = e + .condition() + .and_then(|cond| compute_cond_scopes(cond, scopes, scope)); + if let Some(block) = e.then_branch() { + compute_block_scopes(block, scopes, cond_scope.unwrap_or(scope)); + } + if let Some(block) = e.else_branch() { + compute_block_scopes(block, scopes, scope); + } + } + ast::Expr::BlockExpr(e) => { + if let Some(block) = e.block() { + compute_block_scopes(block, scopes, scope); + } + } + ast::Expr::LoopExpr(e) => { + if let Some(block) = e.loop_body() { + compute_block_scopes(block, scopes, scope); + } + } + ast::Expr::WhileExpr(e) => { + let cond_scope = e + .condition() + .and_then(|cond| compute_cond_scopes(cond, scopes, scope)); + if let Some(block) = e.loop_body() { + compute_block_scopes(block, scopes, cond_scope.unwrap_or(scope)); + } + } + ast::Expr::ForExpr(e) => { + if let Some(expr) = e.iterable() { + compute_expr_scopes(expr, scopes, scope); + } + let mut scope = scope; + if let Some(pat) = e.pat() { + scope = scopes.new_scope(scope); + scopes.add_bindings(scope, pat); + } + if let Some(block) = e.loop_body() { + compute_block_scopes(block, scopes, scope); + } + } + ast::Expr::LambdaExpr(e) => { + let scope = scopes.new_scope(scope); + scopes.add_params_bindings(scope, e.param_list()); + if let Some(body) = e.body() { + scopes.set_scope(body.syntax(), scope); + compute_expr_scopes(body, scopes, scope); + } + } + ast::Expr::CallExpr(e) => { + compute_call_scopes(e.expr(), e.arg_list(), scopes, scope); + } + ast::Expr::MethodCallExpr(e) => { + compute_call_scopes(e.expr(), e.arg_list(), scopes, scope); + } + ast::Expr::MatchExpr(e) => { + if let Some(expr) = e.expr() { + compute_expr_scopes(expr, scopes, scope); + } + for arm in e.match_arm_list().into_iter().flat_map(|it| it.arms()) { + let scope = scopes.new_scope(scope); + for pat in arm.pats() { + scopes.add_bindings(scope, pat); + } + if let Some(expr) = arm.expr() { + compute_expr_scopes(expr, scopes, scope); + } + } + } + _ => expr + .syntax() + .children() + .filter_map(ast::Expr::cast) + .for_each(|expr| compute_expr_scopes(expr, scopes, scope)), + }; + + fn compute_call_scopes( + receiver: Option, + arg_list: Option, + scopes: &mut FnScopes, + scope: ScopeId, + ) { + arg_list + .into_iter() + .flat_map(|it| it.args()) + .chain(receiver) + .for_each(|expr| compute_expr_scopes(expr, scopes, scope)); + } + + fn compute_cond_scopes( + cond: ast::Condition, + scopes: &mut FnScopes, + scope: ScopeId, + ) -> Option { + if let Some(expr) = cond.expr() { + compute_expr_scopes(expr, scopes, scope); + } + if let Some(pat) = cond.pat() { + let s = scopes.new_scope(scope); + scopes.add_bindings(s, pat); + Some(s) + } else { + None + } + } +} + +pub fn resolve_local_name<'a>( + name_ref: ast::NameRef, + scopes: &'a FnScopes, +) -> Option<&'a ScopeEntry> { + use rustc_hash::FxHashSet; + + let mut shadowed = FxHashSet::default(); + let ret = scopes + .scope_chain(name_ref.syntax()) + .flat_map(|scope| scopes.entries(scope).iter()) + .filter(|entry| shadowed.insert(entry.name())) + .filter(|entry| entry.name() == &name_ref.text()) + .nth(0); + ret +} + +#[cfg(test)] +mod tests { + use ra_syntax::File; + use test_utils::extract_offset; + use ra_editor::{find_node_at_offset}; + + use super::*; + + + fn do_check(code: &str, expected: &[&str]) { + let (off, code) = extract_offset(code); + let code = { + let mut buf = String::new(); + let off = u32::from(off) as usize; + buf.push_str(&code[..off]); + buf.push_str("marker"); + buf.push_str(&code[off..]); + buf + }; + let file = File::parse(&code); + let marker: ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); + let fn_def: ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); + let scopes = FnScopes::new(fn_def); + let actual = scopes + .scope_chain(marker.syntax()) + .flat_map(|scope| scopes.entries(scope)) + .map(|it| it.name()) + .collect::>(); + assert_eq!(actual.as_slice(), expected); + } + + #[test] + fn test_lambda_scope() { + do_check( + r" + fn quux(foo: i32) { + let f = |bar, baz: i32| { + <|> + }; + }", + &["bar", "baz", "foo"], + ); + } + + #[test] + fn test_call_scope() { + do_check( + r" + fn quux() { + f(|x| <|> ); + }", + &["x"], + ); + } + + #[test] + fn test_metod_call_scope() { + do_check( + r" + fn quux() { + z.f(|x| <|> ); + }", + &["x"], + ); + } + + #[test] + fn test_loop_scope() { + do_check( + r" + fn quux() { + loop { + let x = (); + <|> + }; + }", + &["x"], + ); + } + + #[test] + fn test_match() { + do_check( + r" + fn quux() { + match () { + Some(x) => { + <|> + } + }; + }", + &["x"], + ); + } + + #[test] + fn test_shadow_variable() { + do_check( + r" + fn foo(x: String) { + let x : &str = &x<|>; + }", + &["x"], + ); + } + + fn do_check_local_name(code: &str, expected_offset: u32) { + let (off, code) = extract_offset(code); + let file = File::parse(&code); + let fn_def: ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); + let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); + + let scopes = FnScopes::new(fn_def); + + let local_name_entry = resolve_local_name(name_ref, &scopes).unwrap(); + let local_name = local_name_entry.ptr().resolve(&file); + let expected_name = + find_node_at_offset::(file.syntax(), expected_offset.into()).unwrap(); + assert_eq!(local_name.range(), expected_name.syntax().range()); + } + + #[test] + fn test_resolve_local_name() { + do_check_local_name( + r#" + fn foo(x: i32, y: u32) { + { + let z = x * 2; + } + { + let t = x<|> * 3; + } + }"#, + 21, + ); + } + + #[test] + fn test_resolve_local_name_declaration() { + do_check_local_name( + r#" + fn foo(x: String) { + let x : &str = &x<|>; + }"#, + 21, + ); + } + + #[test] + fn test_resolve_local_name_shadow() { + do_check_local_name( + r" + fn foo(x: String) { + let x : &str = &x; + x<|> + }", + 46, + ); + } +} diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index 0220f7d5d..0c4991757 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs @@ -1,62 +1,46 @@ pub(crate) mod module; +pub(crate) mod function; + +use std::sync::Arc; use ra_syntax::{ - ast::{self, AstNode, NameOwner}, + SmolStr, + ast::{FnDefNode}, }; -#[derive(Debug, Clone)] -pub struct FnDescriptor { - pub name: String, - pub label: String, - pub ret_type: Option, - pub params: Vec, -} - -impl FnDescriptor { - pub fn new(node: ast::FnDef) -> Option { - let name = node.name()?.text().to_string(); - - // Strip the body out for the label. - let label: String = if let Some(body) = node.body() { - let body_range = body.syntax().range(); - let label: String = node - .syntax() - .children() - .filter(|child| !child.range().is_subrange(&body_range)) - .map(|node| node.text().to_string()) - .collect(); - label - } else { - node.syntax().text().to_string() - }; - - let params = FnDescriptor::param_list(node); - let ret_type = node.ret_type().map(|r| r.syntax().text().to_string()); - - Some(FnDescriptor { - name, - ret_type, - params, - label, - }) - } +use crate::{ + FileId, Cancelable, + db::SyntaxDatabase, + descriptors::module::{ModuleTree, ModuleId, ModuleScope}, + descriptors::function::{FnId, FnScopes}, + input::SourceRootId, + syntax_ptr::SyntaxPtrDatabase, +}; - fn param_list(node: ast::FnDef) -> Vec { - let mut res = vec![]; - if let Some(param_list) = node.param_list() { - if let Some(self_param) = param_list.self_param() { - res.push(self_param.syntax().text().to_string()) - } - // Maybe use param.pat here? See if we can just extract the name? - //res.extend(param_list.params().map(|p| p.syntax().text().to_string())); - res.extend( - param_list - .params() - .filter_map(|p| p.pat()) - .map(|pat| pat.syntax().text().to_string()), - ); +salsa::query_group! { + pub(crate) trait DescriptorDatabase: SyntaxDatabase + SyntaxPtrDatabase { + fn module_tree(source_root_id: SourceRootId) -> Cancelable> { + type ModuleTreeQuery; + use fn module::imp::module_tree; + } + fn submodules(file_id: FileId) -> Cancelable>> { + type SubmodulesQuery; + use fn module::imp::submodules; + } + fn module_scope(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable> { + type ModuleScopeQuery; + use fn module::imp::module_scope; + } + fn fn_syntax(fn_id: FnId) -> FnDefNode { + type FnSyntaxQuery; + // Don't retain syntax trees in memory + storage volatile; + use fn function::imp::fn_syntax; + } + fn fn_scopes(fn_id: FnId) -> Arc { + type FnScopesQuery; + use fn function::imp::fn_scopes; } - res } } diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs index 5fdaad137..dae3a356d 100644 --- a/crates/ra_analysis/src/descriptors/module/imp.rs +++ b/crates/ra_analysis/src/descriptors/module/imp.rs @@ -10,14 +10,15 @@ use ra_syntax::{ use crate::{ FileId, Cancelable, FileResolverImp, db, input::{SourceRoot, SourceRootId}, + descriptors::DescriptorDatabase, }; use super::{ - ModuleData, ModuleTree, ModuleId, LinkId, LinkData, Problem, ModulesDatabase, ModuleScope + ModuleData, ModuleTree, ModuleId, LinkId, LinkData, Problem, ModuleScope }; -pub(super) fn submodules(db: &impl ModulesDatabase, file_id: FileId) -> Cancelable>> { +pub(crate) fn submodules(db: &impl DescriptorDatabase, file_id: FileId) -> Cancelable>> { db::check_canceled(db)?; let file = db.file_syntax(file_id); let root = file.ast(); @@ -25,7 +26,7 @@ pub(super) fn submodules(db: &impl ModulesDatabase, file_id: FileId) -> Cancelab Ok(Arc::new(submodules)) } -pub(super) fn modules(root: ast::Root<'_>) -> impl Iterator)> { +pub(crate) fn modules(root: ast::Root<'_>) -> impl Iterator)> { root.modules().filter_map(|module| { let name = module.name()?.text(); if !module.has_semi() { @@ -35,8 +36,8 @@ pub(super) fn modules(root: ast::Root<'_>) -> impl Iterator Cancelable> { @@ -47,8 +48,8 @@ pub(super) fn module_scope( Ok(Arc::new(res)) } -pub(super) fn module_tree( - db: &impl ModulesDatabase, +pub(crate) fn module_tree( + db: &impl DescriptorDatabase, source_root: SourceRootId, ) -> Cancelable> { db::check_canceled(db)?; @@ -64,7 +65,7 @@ pub struct Submodule { fn create_module_tree<'a>( - db: &impl ModulesDatabase, + db: &impl DescriptorDatabase, source_root: SourceRootId, ) -> Cancelable { let mut tree = ModuleTree { @@ -88,7 +89,7 @@ fn create_module_tree<'a>( } fn build_subtree( - db: &impl ModulesDatabase, + db: &impl DescriptorDatabase, source_root: &SourceRoot, tree: &mut ModuleTree, visited: &mut FxHashSet, diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 9e5d73f94..667553f74 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -1,37 +1,13 @@ -mod imp; +pub(super) mod imp; pub(crate) mod scope; -use std::sync::Arc; - use relative_path::RelativePathBuf; use ra_syntax::{ast::{self, NameOwner, AstNode}, SmolStr, SyntaxNode}; -use crate::{ - FileId, Cancelable, - db::SyntaxDatabase, - input::SourceRootId, -}; +use crate::FileId; pub(crate) use self::scope::ModuleScope; -salsa::query_group! { - pub(crate) trait ModulesDatabase: SyntaxDatabase { - fn module_tree(source_root_id: SourceRootId) -> Cancelable> { - type ModuleTreeQuery; - use fn imp::module_tree; - } - fn submodules(file_id: FileId) -> Cancelable>> { - type SubmodulesQuery; - use fn imp::submodules; - } - fn module_scope(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable> { - type ModuleScopeQuery; - use fn imp::module_scope; - } - } -} - - #[derive(Debug, PartialEq, Eq, Hash)] pub(crate) struct ModuleTree { mods: Vec, diff --git a/crates/ra_analysis/src/descriptors/module/scope.rs b/crates/ra_analysis/src/descriptors/module/scope.rs index da58ddce0..0f8f325ab 100644 --- a/crates/ra_analysis/src/descriptors/module/scope.rs +++ b/crates/ra_analysis/src/descriptors/module/scope.rs @@ -2,8 +2,8 @@ use ra_syntax::{ - ast::{self, AstChildren, ModuleItemOwner}, - File, AstNode, SmolStr, SyntaxNode, SyntaxNodeRef, + ast::{self, ModuleItemOwner}, + File, AstNode, SmolStr, }; use crate::syntax_ptr::LocalSyntaxPtr; @@ -99,7 +99,7 @@ fn collect_imports(tree: ast::UseTree, acc: &mut Vec) { #[cfg(test)] mod tests { use super::*; - use ra_syntax::{ast::ModuleItemOwner, File}; + use ra_syntax::{File}; fn do_check(code: &str, expected: &[&str]) { let file = File::parse(&code); diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index efb3182a6..49b693ae8 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -21,8 +21,9 @@ use crate::{ self, SyntaxDatabase, FileSyntaxQuery, }, input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE}, - descriptors::module::{ModulesDatabase, ModuleTree, Problem}, - descriptors::{FnDescriptor}, + descriptors::DescriptorDatabase, + descriptors::module::{ModuleTree, Problem}, + descriptors::function::{FnDescriptor}, symbol_index::SymbolIndex, CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position, Query, SourceChange, SourceFileEdit, Cancelable, diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 363c72c0b..a77c9a5fa 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -29,7 +29,7 @@ use crate::{ }; pub use crate::{ - descriptors::FnDescriptor, + descriptors::function::FnDescriptor, input::{FileId, FileResolver, CrateGraph, CrateId} }; pub use ra_editor::{ diff --git a/crates/ra_analysis/src/syntax_ptr.rs b/crates/ra_analysis/src/syntax_ptr.rs index adbff4806..aee214318 100644 --- a/crates/ra_analysis/src/syntax_ptr.rs +++ b/crates/ra_analysis/src/syntax_ptr.rs @@ -12,6 +12,7 @@ salsa::query_group! { pub(crate) trait SyntaxPtrDatabase: SyntaxDatabase { fn resolve_syntax_ptr(ptr: SyntaxPtr) -> SyntaxNode { type ResolveSyntaxPtrQuery; + // Don't retain syntax trees in memory storage volatile; } } -- cgit v1.2.3