diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_def/src/body | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir_def/src/body')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 108 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/scope.rs | 10 |
2 files changed, 96 insertions, 22 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 331736cb2..5323af097 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -1,14 +1,13 @@ | |||
1 | //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` | 1 | //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` |
2 | //! representation. | 2 | //! representation. |
3 | 3 | ||
4 | use hir_expand::{ | 4 | use either::Either; |
5 | either::Either, | 5 | |
6 | name::{self, AsName, Name}, | 6 | use hir_expand::name::{name, AsName, Name}; |
7 | }; | ||
8 | use ra_arena::Arena; | 7 | use ra_arena::Arena; |
9 | use ra_syntax::{ | 8 | use ra_syntax::{ |
10 | ast::{ | 9 | ast::{ |
11 | self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, | 10 | self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner, |
12 | TypeAscriptionOwner, | 11 | TypeAscriptionOwner, |
13 | }, | 12 | }, |
14 | AstNode, AstPtr, | 13 | AstNode, AstPtr, |
@@ -26,23 +25,28 @@ use crate::{ | |||
26 | path::GenericArgs, | 25 | path::GenericArgs, |
27 | path::Path, | 26 | path::Path, |
28 | type_ref::{Mutability, TypeRef}, | 27 | type_ref::{Mutability, TypeRef}, |
28 | ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc, | ||
29 | StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | pub(super) fn lower( | 32 | pub(super) fn lower( |
32 | db: &impl DefDatabase, | 33 | db: &impl DefDatabase, |
34 | def: DefWithBodyId, | ||
33 | expander: Expander, | 35 | expander: Expander, |
34 | params: Option<ast::ParamList>, | 36 | params: Option<ast::ParamList>, |
35 | body: Option<ast::Expr>, | 37 | body: Option<ast::Expr>, |
36 | ) -> (Body, BodySourceMap) { | 38 | ) -> (Body, BodySourceMap) { |
37 | ExprCollector { | 39 | ExprCollector { |
38 | expander, | ||
39 | db, | 40 | db, |
41 | def, | ||
42 | expander, | ||
40 | source_map: BodySourceMap::default(), | 43 | source_map: BodySourceMap::default(), |
41 | body: Body { | 44 | body: Body { |
42 | exprs: Arena::default(), | 45 | exprs: Arena::default(), |
43 | pats: Arena::default(), | 46 | pats: Arena::default(), |
44 | params: Vec::new(), | 47 | params: Vec::new(), |
45 | body_expr: ExprId::dummy(), | 48 | body_expr: ExprId::dummy(), |
49 | item_scope: Default::default(), | ||
46 | }, | 50 | }, |
47 | } | 51 | } |
48 | .collect(params, body) | 52 | .collect(params, body) |
@@ -50,6 +54,7 @@ pub(super) fn lower( | |||
50 | 54 | ||
51 | struct ExprCollector<DB> { | 55 | struct ExprCollector<DB> { |
52 | db: DB, | 56 | db: DB, |
57 | def: DefWithBodyId, | ||
53 | expander: Expander, | 58 | expander: Expander, |
54 | 59 | ||
55 | body: Body, | 60 | body: Body, |
@@ -70,11 +75,11 @@ where | |||
70 | let ptr = AstPtr::new(&self_param); | 75 | let ptr = AstPtr::new(&self_param); |
71 | let param_pat = self.alloc_pat( | 76 | let param_pat = self.alloc_pat( |
72 | Pat::Bind { | 77 | Pat::Bind { |
73 | name: name::SELF_PARAM, | 78 | name: name![self], |
74 | mode: BindingAnnotation::Unannotated, | 79 | mode: BindingAnnotation::Unannotated, |
75 | subpat: None, | 80 | subpat: None, |
76 | }, | 81 | }, |
77 | Either::B(ptr), | 82 | Either::Right(ptr), |
78 | ); | 83 | ); |
79 | self.body.params.push(param_pat); | 84 | self.body.params.push(param_pat); |
80 | } | 85 | } |
@@ -94,7 +99,7 @@ where | |||
94 | } | 99 | } |
95 | 100 | ||
96 | fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { | 101 | fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { |
97 | let ptr = Either::A(ptr); | 102 | let ptr = Either::Left(ptr); |
98 | let id = self.body.exprs.alloc(expr); | 103 | let id = self.body.exprs.alloc(expr); |
99 | let src = self.expander.to_source(ptr); | 104 | let src = self.expander.to_source(ptr); |
100 | self.source_map.expr_map.insert(src, id); | 105 | self.source_map.expr_map.insert(src, id); |
@@ -107,7 +112,7 @@ where | |||
107 | self.body.exprs.alloc(expr) | 112 | self.body.exprs.alloc(expr) |
108 | } | 113 | } |
109 | fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr<ast::RecordField>) -> ExprId { | 114 | fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr<ast::RecordField>) -> ExprId { |
110 | let ptr = Either::B(ptr); | 115 | let ptr = Either::Right(ptr); |
111 | let id = self.body.exprs.alloc(expr); | 116 | let id = self.body.exprs.alloc(expr); |
112 | let src = self.expander.to_source(ptr); | 117 | let src = self.expander.to_source(ptr); |
113 | self.source_map.expr_map.insert(src, id); | 118 | self.source_map.expr_map.insert(src, id); |
@@ -277,7 +282,7 @@ where | |||
277 | ast::Expr::ParenExpr(e) => { | 282 | ast::Expr::ParenExpr(e) => { |
278 | let inner = self.collect_expr_opt(e.expr()); | 283 | let inner = self.collect_expr_opt(e.expr()); |
279 | // make the paren expr point to the inner expression as well | 284 | // make the paren expr point to the inner expression as well |
280 | let src = self.expander.to_source(Either::A(syntax_ptr)); | 285 | let src = self.expander.to_source(Either::Left(syntax_ptr)); |
281 | self.source_map.expr_map.insert(src, inner); | 286 | self.source_map.expr_map.insert(src, inner); |
282 | inner | 287 | inner |
283 | } | 288 | } |
@@ -367,8 +372,9 @@ where | |||
367 | arg_types.push(type_ref); | 372 | arg_types.push(type_ref); |
368 | } | 373 | } |
369 | } | 374 | } |
375 | let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast); | ||
370 | let body = self.collect_expr_opt(e.body()); | 376 | let body = self.collect_expr_opt(e.body()); |
371 | self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) | 377 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) |
372 | } | 378 | } |
373 | ast::Expr::BinExpr(e) => { | 379 | ast::Expr::BinExpr(e) => { |
374 | let lhs = self.collect_expr_opt(e.lhs()); | 380 | let lhs = self.collect_expr_opt(e.lhs()); |
@@ -429,10 +435,17 @@ where | |||
429 | let index = self.collect_expr_opt(e.index()); | 435 | let index = self.collect_expr_opt(e.index()); |
430 | self.alloc_expr(Expr::Index { base, index }, syntax_ptr) | 436 | self.alloc_expr(Expr::Index { base, index }, syntax_ptr) |
431 | } | 437 | } |
432 | 438 | ast::Expr::RangeExpr(e) => { | |
433 | // FIXME implement HIR for these: | 439 | let lhs = e.start().map(|lhs| self.collect_expr(lhs)); |
434 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 440 | let rhs = e.end().map(|rhs| self.collect_expr(rhs)); |
435 | ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 441 | match e.op_kind() { |
442 | Some(range_type) => { | ||
443 | self.alloc_expr(Expr::Range { lhs, rhs, range_type }, syntax_ptr) | ||
444 | } | ||
445 | None => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
446 | } | ||
447 | } | ||
448 | // FIXME expand to statements in statement position | ||
436 | ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { | 449 | ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { |
437 | Some((mark, expansion)) => { | 450 | Some((mark, expansion)) => { |
438 | let id = self.collect_expr(expansion); | 451 | let id = self.collect_expr(expansion); |
@@ -441,6 +454,9 @@ where | |||
441 | } | 454 | } |
442 | None => self.alloc_expr(Expr::Missing, syntax_ptr), | 455 | None => self.alloc_expr(Expr::Missing, syntax_ptr), |
443 | }, | 456 | }, |
457 | |||
458 | // FIXME implement HIR for these: | ||
459 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
444 | } | 460 | } |
445 | } | 461 | } |
446 | 462 | ||
@@ -458,6 +474,7 @@ where | |||
458 | Some(block) => block, | 474 | Some(block) => block, |
459 | None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), | 475 | None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), |
460 | }; | 476 | }; |
477 | self.collect_block_items(&block); | ||
461 | let statements = block | 478 | let statements = block |
462 | .statements() | 479 | .statements() |
463 | .map(|s| match s { | 480 | .map(|s| match s { |
@@ -474,6 +491,63 @@ where | |||
474 | self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) | 491 | self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) |
475 | } | 492 | } |
476 | 493 | ||
494 | fn collect_block_items(&mut self, block: &ast::Block) { | ||
495 | let container = ContainerId::DefWithBodyId(self.def); | ||
496 | for item in block.items() { | ||
497 | let (def, name): (ModuleDefId, Option<ast::Name>) = match item { | ||
498 | ast::ModuleItem::FnDef(def) => { | ||
499 | let ast_id = self.expander.ast_id(&def); | ||
500 | ( | ||
501 | FunctionLoc { container: container.into(), ast_id }.intern(self.db).into(), | ||
502 | def.name(), | ||
503 | ) | ||
504 | } | ||
505 | ast::ModuleItem::TypeAliasDef(def) => { | ||
506 | let ast_id = self.expander.ast_id(&def); | ||
507 | ( | ||
508 | TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into(), | ||
509 | def.name(), | ||
510 | ) | ||
511 | } | ||
512 | ast::ModuleItem::ConstDef(def) => { | ||
513 | let ast_id = self.expander.ast_id(&def); | ||
514 | ( | ||
515 | ConstLoc { container: container.into(), ast_id }.intern(self.db).into(), | ||
516 | def.name(), | ||
517 | ) | ||
518 | } | ||
519 | ast::ModuleItem::StaticDef(def) => { | ||
520 | let ast_id = self.expander.ast_id(&def); | ||
521 | (StaticLoc { container, ast_id }.intern(self.db).into(), def.name()) | ||
522 | } | ||
523 | ast::ModuleItem::StructDef(def) => { | ||
524 | let ast_id = self.expander.ast_id(&def); | ||
525 | (StructLoc { container, ast_id }.intern(self.db).into(), def.name()) | ||
526 | } | ||
527 | ast::ModuleItem::EnumDef(def) => { | ||
528 | let ast_id = self.expander.ast_id(&def); | ||
529 | (EnumLoc { container, ast_id }.intern(self.db).into(), def.name()) | ||
530 | } | ||
531 | ast::ModuleItem::UnionDef(def) => { | ||
532 | let ast_id = self.expander.ast_id(&def); | ||
533 | (UnionLoc { container, ast_id }.intern(self.db).into(), def.name()) | ||
534 | } | ||
535 | ast::ModuleItem::TraitDef(def) => { | ||
536 | let ast_id = self.expander.ast_id(&def); | ||
537 | (TraitLoc { container, ast_id }.intern(self.db).into(), def.name()) | ||
538 | } | ||
539 | ast::ModuleItem::ImplBlock(_) | ||
540 | | ast::ModuleItem::UseItem(_) | ||
541 | | ast::ModuleItem::ExternCrateItem(_) | ||
542 | | ast::ModuleItem::Module(_) => continue, | ||
543 | }; | ||
544 | self.body.item_scope.define_def(def); | ||
545 | if let Some(name) = name { | ||
546 | self.body.item_scope.push_res(name.as_name(), def.into()); | ||
547 | } | ||
548 | } | ||
549 | } | ||
550 | |||
477 | fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { | 551 | fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { |
478 | if let Some(block) = expr { | 552 | if let Some(block) = expr { |
479 | self.collect_block(block) | 553 | self.collect_block(block) |
@@ -541,7 +615,7 @@ where | |||
541 | ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing, | 615 | ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing, |
542 | }; | 616 | }; |
543 | let ptr = AstPtr::new(&pat); | 617 | let ptr = AstPtr::new(&pat); |
544 | self.alloc_pat(pattern, Either::A(ptr)) | 618 | self.alloc_pat(pattern, Either::Left(ptr)) |
545 | } | 619 | } |
546 | 620 | ||
547 | fn collect_pat_opt(&mut self, pat: Option<ast::Pat>) -> PatId { | 621 | fn collect_pat_opt(&mut self, pat: Option<ast::Pat>) -> PatId { |
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index 625aa39dd..a63552327 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs | |||
@@ -171,7 +171,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope | |||
171 | 171 | ||
172 | #[cfg(test)] | 172 | #[cfg(test)] |
173 | mod tests { | 173 | mod tests { |
174 | use hir_expand::{name::AsName, Source}; | 174 | use hir_expand::{name::AsName, InFile}; |
175 | use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; | 175 | use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; |
176 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; | 176 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; |
177 | use test_utils::{assert_eq_text, covers, extract_offset}; | 177 | use test_utils::{assert_eq_text, covers, extract_offset}; |
@@ -183,8 +183,8 @@ mod tests { | |||
183 | let crate_def_map = db.crate_def_map(krate); | 183 | let crate_def_map = db.crate_def_map(krate); |
184 | 184 | ||
185 | let module = crate_def_map.modules_for_file(file_id).next().unwrap(); | 185 | let module = crate_def_map.modules_for_file(file_id).next().unwrap(); |
186 | let (_, res) = crate_def_map[module].scope.entries().next().unwrap(); | 186 | let (_, def) = crate_def_map[module].scope.entries().next().unwrap(); |
187 | match res.def.take_values().unwrap() { | 187 | match def.take_values().unwrap() { |
188 | ModuleDefId::FunctionId(it) => it, | 188 | ModuleDefId::FunctionId(it) => it, |
189 | _ => panic!(), | 189 | _ => panic!(), |
190 | } | 190 | } |
@@ -211,7 +211,7 @@ mod tests { | |||
211 | let (_body, source_map) = db.body_with_source_map(function.into()); | 211 | let (_body, source_map) = db.body_with_source_map(function.into()); |
212 | 212 | ||
213 | let expr_id = source_map | 213 | let expr_id = source_map |
214 | .node_expr(Source { file_id: file_id.into(), value: &marker.into() }) | 214 | .node_expr(InFile { file_id: file_id.into(), value: &marker.into() }) |
215 | .unwrap(); | 215 | .unwrap(); |
216 | let scope = scopes.scope_for(expr_id); | 216 | let scope = scopes.scope_for(expr_id); |
217 | 217 | ||
@@ -318,7 +318,7 @@ mod tests { | |||
318 | let expr_scope = { | 318 | let expr_scope = { |
319 | let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); | 319 | let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); |
320 | let expr_id = | 320 | let expr_id = |
321 | source_map.node_expr(Source { file_id: file_id.into(), value: &expr_ast }).unwrap(); | 321 | source_map.node_expr(InFile { file_id: file_id.into(), value: &expr_ast }).unwrap(); |
322 | scopes.scope_for(expr_id).unwrap() | 322 | scopes.scope_for(expr_id).unwrap() |
323 | }; | 323 | }; |
324 | 324 | ||