aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/expr.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-01 22:37:59 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-01 22:37:59 +0000
commit4447019f4b5f24728bb7b91b161755ddb373c74c (patch)
treec53ff3531cbbad182e821eb92fa9ad201d2bff0c /crates/ra_hir/src/expr.rs
parent2b5c226e86892113bcab478cdf4c9adaf1e7b2f6 (diff)
parentc5852f422ff45adaa21815c1a15e03b067a56a82 (diff)
Merge #693
693: Name resolution refactoring r=matklad a=flodiebold This is still very WIP, but it's becoming quite big and I want to make sure this isn't going in a completely bad direction :sweat_smile:. I'm not really happy with how the path resolution looks, and I'm not sure `PerNs<Resolution>` is the best return type -- there are 'this cannot happen in the (types/values) namespace' cases everywhere. I also want to unify the `resolver` and `nameres` namespaces once I'm done switching everything to `Resolver`. Also, `Resolver` only has a lifetime because it needs to have a reference to the `ItemMap` during import resolution :confused: The differences in the completion snapshots are almost completely just ordering (except it completes `Self` as well now), so I changed it to sort the completions before snapshotting. Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r--crates/ra_hir/src/expr.rs143
1 files changed, 91 insertions, 52 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index f4a950418..f9f702ae2 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -10,15 +10,15 @@ use ra_syntax::{
10}; 10};
11 11
12use crate::{ 12use crate::{
13 Path, Name, Function, 13 Path, Name, HirDatabase, Function, Resolver,
14 name::AsName, HirDatabase, 14 name::AsName,
15 type_ref::{Mutability, TypeRef}, 15 type_ref::{Mutability, TypeRef},
16}; 16};
17use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; 17use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy};
18 18
19pub use self::scope::{ExprScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax}; 19pub use self::scope::{ExprScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax};
20 20
21mod scope; 21pub(crate) mod scope;
22 22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct ExprId(RawId); 24pub struct ExprId(RawId);
@@ -27,6 +27,9 @@ impl_arena_id!(ExprId);
27/// The body of an item (function, const etc.). 27/// The body of an item (function, const etc.).
28#[derive(Debug, Eq, PartialEq)] 28#[derive(Debug, Eq, PartialEq)]
29pub struct Body { 29pub struct Body {
30 // TODO: this should be more general, consts & statics also have bodies
31 /// The Function of the item this body belongs to
32 owner: Function,
30 exprs: Arena<ExprId, Expr>, 33 exprs: Arena<ExprId, Expr>,
31 pats: Arena<PatId, Pat>, 34 pats: Arena<PatId, Pat>,
32 /// The patterns for the function's parameters. While the parameter types are 35 /// The patterns for the function's parameters. While the parameter types are
@@ -62,6 +65,34 @@ impl Body {
62 pub fn body_expr(&self) -> ExprId { 65 pub fn body_expr(&self) -> ExprId {
63 self.body_expr 66 self.body_expr
64 } 67 }
68
69 pub fn owner(&self) -> Function {
70 self.owner
71 }
72
73 pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> {
74 db.body_syntax_mapping(self.owner)
75 }
76}
77
78// needs arbitrary_self_types to be a method... or maybe move to the def?
79pub fn resolver_for_expr(body: Arc<Body>, db: &impl HirDatabase, expr_id: ExprId) -> Resolver {
80 let scopes = db.expr_scopes(body.owner);
81 resolver_for_scope(body, db, scopes.scope_for(expr_id))
82}
83
84pub fn resolver_for_scope(
85 body: Arc<Body>,
86 db: &impl HirDatabase,
87 scope_id: Option<scope::ScopeId>,
88) -> Resolver {
89 let mut r = body.owner.resolver(db);
90 let scopes = db.expr_scopes(body.owner);
91 let scope_chain = scopes.scope_chain_for(scope_id).collect::<Vec<_>>();
92 for scope in scope_chain.into_iter().rev() {
93 r = r.push_expr_scope(Arc::clone(&scopes), scope);
94 }
95 r
65} 96}
66 97
67impl Index<ExprId> for Body { 98impl Index<ExprId> for Body {
@@ -448,23 +479,29 @@ pub(crate) fn body_hir(db: &impl HirDatabase, func: Function) -> Arc<Body> {
448} 479}
449 480
450struct ExprCollector { 481struct ExprCollector {
482 owner: Function,
451 exprs: Arena<ExprId, Expr>, 483 exprs: Arena<ExprId, Expr>,
452 pats: Arena<PatId, Pat>, 484 pats: Arena<PatId, Pat>,
453 expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>, 485 expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>,
454 expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>, 486 expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>,
455 pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>, 487 pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>,
456 pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>, 488 pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>,
489 params: Vec<PatId>,
490 body_expr: Option<ExprId>,
457} 491}
458 492
459impl ExprCollector { 493impl ExprCollector {
460 fn new() -> Self { 494 fn new(owner: Function) -> Self {
461 ExprCollector { 495 ExprCollector {
496 owner,
462 exprs: Arena::default(), 497 exprs: Arena::default(),
463 pats: Arena::default(), 498 pats: Arena::default(),
464 expr_syntax_mapping: FxHashMap::default(), 499 expr_syntax_mapping: FxHashMap::default(),
465 expr_syntax_mapping_back: ArenaMap::default(), 500 expr_syntax_mapping_back: ArenaMap::default(),
466 pat_syntax_mapping: FxHashMap::default(), 501 pat_syntax_mapping: FxHashMap::default(),
467 pat_syntax_mapping_back: ArenaMap::default(), 502 pat_syntax_mapping_back: ArenaMap::default(),
503 params: Vec::new(),
504 body_expr: None,
468 } 505 }
469 } 506 }
470 507
@@ -902,10 +939,7 @@ impl ExprCollector {
902 }); 939 });
903 fields.extend(iter); 940 fields.extend(iter);
904 941
905 Pat::Struct { 942 Pat::Struct { path, args: fields }
906 path: path,
907 args: fields,
908 }
909 } 943 }
910 944
911 // TODO: implement 945 // TODO: implement
@@ -923,12 +957,48 @@ impl ExprCollector {
923 } 957 }
924 } 958 }
925 959
926 fn into_body_syntax_mapping(self, params: Vec<PatId>, body_expr: ExprId) -> BodySyntaxMapping { 960 fn collect_fn_body(&mut self, node: &ast::FnDef) {
961 if let Some(param_list) = node.param_list() {
962 if let Some(self_param) = param_list.self_param() {
963 let self_param = SyntaxNodePtr::new(
964 self_param
965 .self_kw()
966 .expect("self param without self keyword")
967 .syntax(),
968 );
969 let param_pat = self.alloc_pat(
970 Pat::Bind {
971 name: Name::self_param(),
972 mode: BindingAnnotation::Unannotated,
973 subpat: None,
974 },
975 self_param,
976 );
977 self.params.push(param_pat);
978 }
979
980 for param in param_list.params() {
981 let pat = if let Some(pat) = param.pat() {
982 pat
983 } else {
984 continue;
985 };
986 let param_pat = self.collect_pat(pat);
987 self.params.push(param_pat);
988 }
989 };
990
991 let body = self.collect_block_opt(node.body());
992 self.body_expr = Some(body);
993 }
994
995 fn into_body_syntax_mapping(self) -> BodySyntaxMapping {
927 let body = Body { 996 let body = Body {
997 owner: self.owner,
928 exprs: self.exprs, 998 exprs: self.exprs,
929 pats: self.pats, 999 pats: self.pats,
930 params, 1000 params: self.params,
931 body_expr, 1001 body_expr: self.body_expr.expect("A body should have been collected"),
932 }; 1002 };
933 BodySyntaxMapping { 1003 BodySyntaxMapping {
934 body: Arc::new(body), 1004 body: Arc::new(body),
@@ -940,49 +1010,18 @@ impl ExprCollector {
940 } 1010 }
941} 1011}
942 1012
943pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping { 1013pub(crate) fn body_syntax_mapping(db: &impl HirDatabase, func: Function) -> Arc<BodySyntaxMapping> {
944 let mut collector = ExprCollector::new(); 1014 let mut collector = ExprCollector::new(func);
945
946 let params = if let Some(param_list) = node.param_list() {
947 let mut params = Vec::new();
948
949 if let Some(self_param) = param_list.self_param() {
950 let self_param = SyntaxNodePtr::new(
951 self_param
952 .self_kw()
953 .expect("self param without self keyword")
954 .syntax(),
955 );
956 let param = collector.alloc_pat(
957 Pat::Bind {
958 name: Name::self_param(),
959 mode: BindingAnnotation::Unannotated,
960 subpat: None,
961 },
962 self_param,
963 );
964 params.push(param);
965 }
966 1015
967 for param in param_list.params() { 1016 // TODO: consts, etc.
968 let pat = if let Some(pat) = param.pat() { 1017 collector.collect_fn_body(&func.source(db).1);
969 pat
970 } else {
971 continue;
972 };
973 params.push(collector.collect_pat(pat));
974 }
975 params
976 } else {
977 Vec::new()
978 };
979 1018
980 let body = collector.collect_block_opt(node.body()); 1019 Arc::new(collector.into_body_syntax_mapping())
981 collector.into_body_syntax_mapping(params, body)
982} 1020}
983 1021
984pub(crate) fn body_syntax_mapping(db: &impl HirDatabase, func: Function) -> Arc<BodySyntaxMapping> { 1022#[cfg(test)]
985 let (_, fn_def) = func.source(db); 1023pub(crate) fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> BodySyntaxMapping {
986 let body_syntax_mapping = collect_fn_body_syntax(&fn_def); 1024 let mut collector = ExprCollector::new(function);
987 Arc::new(body_syntax_mapping) 1025 collector.collect_fn_body(node);
1026 collector.into_body_syntax_mapping()
988} 1027}