From 5208c2aa930ae452e062dcdc2563c1bbb67d2e4a Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 19 Jan 2019 21:23:26 +0100 Subject: Sketching the resolver API --- crates/ra_hir/src/expr.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir/src/expr.rs') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index f4a950418..6d124fe2f 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -10,15 +10,15 @@ use ra_syntax::{ }; use crate::{ - Path, Name, Function, - name::AsName, HirDatabase, + Path, Name, HirDatabase, Function, Resolver, + name::AsName, type_ref::{Mutability, TypeRef}, }; use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; pub use self::scope::{ExprScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax}; -mod scope; +pub(crate) mod scope; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ExprId(RawId); @@ -62,6 +62,11 @@ impl Body { pub fn body_expr(&self) -> ExprId { self.body_expr } + + #[allow(unused_variables)] + pub fn resolver_for_expr(&self, expr_id: ExprId) -> Resolver { + unimplemented!() + } } impl Index for Body { -- cgit v1.2.3 From 758bc72873efe36f579236d1abf240d14866fd82 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Wed, 23 Jan 2019 23:08:41 +0100 Subject: Implement methods to build a resolver --- crates/ra_hir/src/expr.rs | 129 +++++++++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 52 deletions(-) (limited to 'crates/ra_hir/src/expr.rs') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 6d124fe2f..c09d3fbf9 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -27,6 +27,9 @@ impl_arena_id!(ExprId); /// The body of an item (function, const etc.). #[derive(Debug, Eq, PartialEq)] pub struct Body { + // TODO: this should be more general, consts & statics also have bodies + /// The Function of the item this body belongs to + owner: Function, exprs: Arena, pats: Arena, /// The patterns for the function's parameters. While the parameter types are @@ -63,12 +66,26 @@ impl Body { self.body_expr } - #[allow(unused_variables)] - pub fn resolver_for_expr(&self, expr_id: ExprId) -> Resolver { - unimplemented!() + pub fn owner(&self) -> Function { + self.owner } } +// needs arbitrary_self_types to be a method... or maybe move to the def? +#[allow(dead_code)] +pub fn resolver_for_expr(body: Arc, db: &impl HirDatabase, expr_id: ExprId) -> Resolver { + let mut r = body.owner.resolver(db); + if !body.params.is_empty() { + r = r.push_function_params(Arc::clone(&body)); + } + let scopes = db.expr_scopes(body.owner); + let scope_chain = scopes.scope_chain_for(expr_id).collect::>(); + for scope in scope_chain.into_iter().rev() { + r = r.push_expr_scope(Arc::clone(&scopes), scope); + } + r +} + impl Index for Body { type Output = Expr; @@ -453,23 +470,29 @@ pub(crate) fn body_hir(db: &impl HirDatabase, func: Function) -> Arc { } struct ExprCollector { + owner: Function, exprs: Arena, pats: Arena, expr_syntax_mapping: FxHashMap, expr_syntax_mapping_back: ArenaMap, pat_syntax_mapping: FxHashMap, pat_syntax_mapping_back: ArenaMap, + params: Vec, + body_expr: Option, } impl ExprCollector { - fn new() -> Self { + fn new(owner: Function) -> Self { ExprCollector { + owner, exprs: Arena::default(), pats: Arena::default(), expr_syntax_mapping: FxHashMap::default(), expr_syntax_mapping_back: ArenaMap::default(), pat_syntax_mapping: FxHashMap::default(), pat_syntax_mapping_back: ArenaMap::default(), + params: Vec::new(), + body_expr: None, } } @@ -907,10 +930,7 @@ impl ExprCollector { }); fields.extend(iter); - Pat::Struct { - path: path, - args: fields, - } + Pat::Struct { path, args: fields } } // TODO: implement @@ -928,12 +948,48 @@ impl ExprCollector { } } - fn into_body_syntax_mapping(self, params: Vec, body_expr: ExprId) -> BodySyntaxMapping { + fn collect_fn_body(&mut self, node: &ast::FnDef) { + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + let self_param = SyntaxNodePtr::new( + self_param + .self_kw() + .expect("self param without self keyword") + .syntax(), + ); + let param_pat = self.alloc_pat( + Pat::Bind { + name: Name::self_param(), + mode: BindingAnnotation::Unannotated, + subpat: None, + }, + self_param, + ); + self.params.push(param_pat); + } + + for param in param_list.params() { + let pat = if let Some(pat) = param.pat() { + pat + } else { + continue; + }; + let param_pat = self.collect_pat(pat); + self.params.push(param_pat); + } + }; + + let body = self.collect_block_opt(node.body()); + self.body_expr = Some(body); + } + + fn into_body_syntax_mapping(self) -> BodySyntaxMapping { let body = Body { + owner: self.owner, exprs: self.exprs, pats: self.pats, - params, - body_expr, + params: self.params, + body_expr: self.body_expr.expect("A body should have been collected"), }; BodySyntaxMapping { body: Arc::new(body), @@ -945,49 +1001,18 @@ impl ExprCollector { } } -pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping { - let mut collector = ExprCollector::new(); - - let params = if let Some(param_list) = node.param_list() { - let mut params = Vec::new(); - - if let Some(self_param) = param_list.self_param() { - let self_param = SyntaxNodePtr::new( - self_param - .self_kw() - .expect("self param without self keyword") - .syntax(), - ); - let param = collector.alloc_pat( - Pat::Bind { - name: Name::self_param(), - mode: BindingAnnotation::Unannotated, - subpat: None, - }, - self_param, - ); - params.push(param); - } +pub(crate) fn body_syntax_mapping(db: &impl HirDatabase, func: Function) -> Arc { + let mut collector = ExprCollector::new(func); - for param in param_list.params() { - let pat = if let Some(pat) = param.pat() { - pat - } else { - continue; - }; - params.push(collector.collect_pat(pat)); - } - params - } else { - Vec::new() - }; + // TODO: consts, etc. + collector.collect_fn_body(&func.source(db).1); - let body = collector.collect_block_opt(node.body()); - collector.into_body_syntax_mapping(params, body) + Arc::new(collector.into_body_syntax_mapping()) } -pub(crate) fn body_syntax_mapping(db: &impl HirDatabase, func: Function) -> Arc { - let (_, fn_def) = func.source(db); - let body_syntax_mapping = collect_fn_body_syntax(&fn_def); - Arc::new(body_syntax_mapping) +#[cfg(test)] +pub(crate) fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> BodySyntaxMapping { + let mut collector = ExprCollector::new(function); + collector.collect_fn_body(node); + collector.into_body_syntax_mapping() } -- cgit v1.2.3 From 6b076f1931d7dc324d7bbbc4c1df9f7c1c1db8b7 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 26 Jan 2019 22:52:04 +0100 Subject: Use new Resolver API in type inference --- crates/ra_hir/src/expr.rs | 3 --- 1 file changed, 3 deletions(-) (limited to 'crates/ra_hir/src/expr.rs') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index c09d3fbf9..503a09f25 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -75,9 +75,6 @@ impl Body { #[allow(dead_code)] pub fn resolver_for_expr(body: Arc, db: &impl HirDatabase, expr_id: ExprId) -> Resolver { let mut r = body.owner.resolver(db); - if !body.params.is_empty() { - r = r.push_function_params(Arc::clone(&body)); - } let scopes = db.expr_scopes(body.owner); let scope_chain = scopes.scope_chain_for(expr_id).collect::>(); for scope in scope_chain.into_iter().rev() { -- cgit v1.2.3 From 33ff7b56ff353410e7bcb7aed27004d4f0a57d8e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 27 Jan 2019 20:50:57 +0100 Subject: Use the new Resolver API in completion --- crates/ra_hir/src/expr.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir/src/expr.rs') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 503a09f25..6c294bf10 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -72,11 +72,23 @@ impl Body { } // needs arbitrary_self_types to be a method... or maybe move to the def? -#[allow(dead_code)] -pub fn resolver_for_expr(body: Arc, db: &impl HirDatabase, expr_id: ExprId) -> Resolver { +pub fn resolver_for_expr( + body: Arc, + db: &impl HirDatabase, + expr_id: ExprId, +) -> Resolver<'static> { + let scopes = db.expr_scopes(body.owner); + resolver_for_scope(body, db, scopes.scope_for(expr_id)) +} + +pub fn resolver_for_scope( + body: Arc, + db: &impl HirDatabase, + scope_id: Option, +) -> Resolver<'static> { let mut r = body.owner.resolver(db); let scopes = db.expr_scopes(body.owner); - let scope_chain = scopes.scope_chain_for(expr_id).collect::>(); + let scope_chain = scopes.scope_chain_for(scope_id).collect::>(); for scope in scope_chain.into_iter().rev() { r = r.push_expr_scope(Arc::clone(&scopes), scope); } -- cgit v1.2.3 From afce8e442639fa9ed954b3659a2d1eccb7d80113 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 29 Jan 2019 20:49:31 +0100 Subject: Use the new Resolver API for goto def --- crates/ra_hir/src/expr.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'crates/ra_hir/src/expr.rs') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 6c294bf10..e78ba889e 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -69,6 +69,10 @@ impl Body { pub fn owner(&self) -> Function { self.owner } + + pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc { + db.body_syntax_mapping(self.owner) + } } // needs arbitrary_self_types to be a method... or maybe move to the def? -- cgit v1.2.3 From d3df80dfe41e4e3ab7644ae576119a264ba0e7f1 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 27 Jan 2019 17:23:49 +0100 Subject: Cleanup --- crates/ra_hir/src/expr.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir/src/expr.rs') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index e78ba889e..f9f702ae2 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -76,11 +76,7 @@ impl Body { } // needs arbitrary_self_types to be a method... or maybe move to the def? -pub fn resolver_for_expr( - body: Arc, - db: &impl HirDatabase, - expr_id: ExprId, -) -> Resolver<'static> { +pub fn resolver_for_expr(body: Arc, db: &impl HirDatabase, expr_id: ExprId) -> Resolver { let scopes = db.expr_scopes(body.owner); resolver_for_scope(body, db, scopes.scope_for(expr_id)) } @@ -89,7 +85,7 @@ pub fn resolver_for_scope( body: Arc, db: &impl HirDatabase, scope_id: Option, -) -> Resolver<'static> { +) -> Resolver { let mut r = body.owner.resolver(db); let scopes = db.expr_scopes(body.owner); let scope_chain = scopes.scope_chain_for(scope_id).collect::>(); -- cgit v1.2.3