aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/body
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/body')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs86
1 files changed, 62 insertions, 24 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 0caedd8d8..443b057ab 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -3,8 +3,9 @@
3 3
4use either::Either; 4use either::Either;
5use hir_expand::{ 5use hir_expand::{
6 hygiene::Hygiene,
6 name::{name, AsName, Name}, 7 name::{name, AsName, Name},
7 MacroDefId, MacroDefKind, 8 HirFileId, MacroDefId, MacroDefKind,
8}; 9};
9use ra_arena::Arena; 10use ra_arena::Arena;
10use ra_syntax::{ 11use ra_syntax::{
@@ -26,7 +27,7 @@ use crate::{
26 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, 27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
27 }, 28 },
28 item_scope::BuiltinShadowMode, 29 item_scope::BuiltinShadowMode,
29 path::GenericArgs, 30 path::{GenericArgs, Path},
30 type_ref::{Mutability, TypeRef}, 31 type_ref::{Mutability, TypeRef},
31 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, 32 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId,
32 StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, 33 StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
@@ -35,6 +36,23 @@ use crate::{
35use super::{ExprSource, PatSource}; 36use super::{ExprSource, PatSource};
36use ast::AstChildren; 37use ast::AstChildren;
37 38
39pub(crate) struct LowerCtx {
40 hygiene: Hygiene,
41}
42
43impl LowerCtx {
44 pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self {
45 LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) }
46 }
47 pub fn with_hygiene(hygiene: &Hygiene) -> Self {
48 LowerCtx { hygiene: hygiene.clone() }
49 }
50
51 pub fn lower_path(&self, ast: ast::Path) -> Option<Path> {
52 Path::from_src(ast, &self.hygiene)
53 }
54}
55
38pub(super) fn lower( 56pub(super) fn lower(
39 db: &dyn DefDatabase, 57 db: &dyn DefDatabase,
40 def: DefWithBodyId, 58 def: DefWithBodyId,
@@ -42,10 +60,13 @@ pub(super) fn lower(
42 params: Option<ast::ParamList>, 60 params: Option<ast::ParamList>,
43 body: Option<ast::Expr>, 61 body: Option<ast::Expr>,
44) -> (Body, BodySourceMap) { 62) -> (Body, BodySourceMap) {
63 let ctx = LowerCtx::new(db, expander.current_file_id.clone());
64
45 ExprCollector { 65 ExprCollector {
46 db, 66 db,
47 def, 67 def,
48 expander, 68 expander,
69 ctx,
49 source_map: BodySourceMap::default(), 70 source_map: BodySourceMap::default(),
50 body: Body { 71 body: Body {
51 exprs: Arena::default(), 72 exprs: Arena::default(),
@@ -62,7 +83,7 @@ struct ExprCollector<'a> {
62 db: &'a dyn DefDatabase, 83 db: &'a dyn DefDatabase,
63 def: DefWithBodyId, 84 def: DefWithBodyId,
64 expander: Expander, 85 expander: Expander,
65 86 ctx: LowerCtx,
66 body: Body, 87 body: Body,
67 source_map: BodySourceMap, 88 source_map: BodySourceMap,
68} 89}
@@ -141,6 +162,9 @@ impl ExprCollector<'_> {
141 162
142 fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { 163 fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
143 let syntax_ptr = AstPtr::new(&expr); 164 let syntax_ptr = AstPtr::new(&expr);
165 if !self.expander.is_cfg_enabled(&expr) {
166 return self.missing_expr();
167 }
144 match expr { 168 match expr {
145 ast::Expr::IfExpr(e) => { 169 ast::Expr::IfExpr(e) => {
146 let then_branch = self.collect_block_opt(e.then_branch()); 170 let then_branch = self.collect_block_opt(e.then_branch());
@@ -178,10 +202,16 @@ impl ExprCollector<'_> {
178 202
179 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) 203 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
180 } 204 }
181 ast::Expr::TryBlockExpr(e) => { 205 ast::Expr::EffectExpr(e) => match e.effect() {
182 let body = self.collect_block_opt(e.body()); 206 ast::Effect::Try(_) => {
183 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) 207 let body = self.collect_block_opt(e.block_expr());
184 } 208 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr)
209 }
210 // FIXME: we need to record these effects somewhere...
211 ast::Effect::Async(_) | ast::Effect::Label(_) | ast::Effect::Unsafe(_) => {
212 self.collect_block_opt(e.block_expr())
213 }
214 },
185 ast::Expr::BlockExpr(e) => self.collect_block(e), 215 ast::Expr::BlockExpr(e) => self.collect_block(e),
186 ast::Expr::LoopExpr(e) => { 216 ast::Expr::LoopExpr(e) => {
187 let body = self.collect_block_opt(e.loop_body()); 217 let body = self.collect_block_opt(e.loop_body());
@@ -237,7 +267,8 @@ impl ExprCollector<'_> {
237 Vec::new() 267 Vec::new()
238 }; 268 };
239 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); 269 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
240 let generic_args = e.type_arg_list().and_then(GenericArgs::from_ast); 270 let generic_args =
271 e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it));
241 self.alloc_expr( 272 self.alloc_expr(
242 Expr::MethodCall { receiver, method_name, args, generic_args }, 273 Expr::MethodCall { receiver, method_name, args, generic_args },
243 syntax_ptr, 274 syntax_ptr,
@@ -297,8 +328,7 @@ impl ExprCollector<'_> {
297 .fields() 328 .fields()
298 .inspect(|field| field_ptrs.push(AstPtr::new(field))) 329 .inspect(|field| field_ptrs.push(AstPtr::new(field)))
299 .filter_map(|field| { 330 .filter_map(|field| {
300 let attrs = self.expander.parse_attrs(&field); 331 if !self.expander.is_cfg_enabled(&field) {
301 if !self.expander.is_cfg_enabled(&attrs) {
302 return None; 332 return None;
303 } 333 }
304 let name = field.field_name()?.as_name(); 334 let name = field.field_name()?.as_name();
@@ -343,7 +373,7 @@ impl ExprCollector<'_> {
343 } 373 }
344 ast::Expr::CastExpr(e) => { 374 ast::Expr::CastExpr(e) => {
345 let expr = self.collect_expr_opt(e.expr()); 375 let expr = self.collect_expr_opt(e.expr());
346 let type_ref = TypeRef::from_ast_opt(e.type_ref()); 376 let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref());
347 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) 377 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
348 } 378 }
349 ast::Expr::RefExpr(e) => { 379 ast::Expr::RefExpr(e) => {
@@ -365,12 +395,16 @@ impl ExprCollector<'_> {
365 if let Some(pl) = e.param_list() { 395 if let Some(pl) = e.param_list() {
366 for param in pl.params() { 396 for param in pl.params() {
367 let pat = self.collect_pat_opt(param.pat()); 397 let pat = self.collect_pat_opt(param.pat());
368 let type_ref = param.ascribed_type().map(TypeRef::from_ast); 398 let type_ref =
399 param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it));
369 args.push(pat); 400 args.push(pat);
370 arg_types.push(type_ref); 401 arg_types.push(type_ref);
371 } 402 }
372 } 403 }
373 let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast); 404 let ret_type = e
405 .ret_type()
406 .and_then(|r| r.type_ref())
407 .map(|it| TypeRef::from_ast(&self.ctx, it));
374 let body = self.collect_expr_opt(e.body()); 408 let body = self.collect_expr_opt(e.body());
375 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) 409 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
376 } 410 }
@@ -430,6 +464,7 @@ impl ExprCollector<'_> {
430 krate: Some(self.expander.module.krate), 464 krate: Some(self.expander.module.krate),
431 ast_id: Some(self.expander.ast_id(&e)), 465 ast_id: Some(self.expander.ast_id(&e)),
432 kind: MacroDefKind::Declarative, 466 kind: MacroDefKind::Declarative,
467 local_inner: false,
433 }; 468 };
434 self.body.item_scope.define_legacy_macro(name, mac); 469 self.body.item_scope.define_legacy_macro(name, mac);
435 470
@@ -464,19 +499,15 @@ impl ExprCollector<'_> {
464 } 499 }
465 } 500 }
466 501
467 fn collect_block(&mut self, expr: ast::BlockExpr) -> ExprId { 502 fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
468 let syntax_node_ptr = AstPtr::new(&expr.clone().into()); 503 let syntax_node_ptr = AstPtr::new(&block.clone().into());
469 let block = match expr.block() {
470 Some(block) => block,
471 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
472 };
473 self.collect_block_items(&block); 504 self.collect_block_items(&block);
474 let statements = block 505 let statements = block
475 .statements() 506 .statements()
476 .map(|s| match s { 507 .map(|s| match s {
477 ast::Stmt::LetStmt(stmt) => { 508 ast::Stmt::LetStmt(stmt) => {
478 let pat = self.collect_pat_opt(stmt.pat()); 509 let pat = self.collect_pat_opt(stmt.pat());
479 let type_ref = stmt.ascribed_type().map(TypeRef::from_ast); 510 let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it));
480 let initializer = stmt.initializer().map(|e| self.collect_expr(e)); 511 let initializer = stmt.initializer().map(|e| self.collect_expr(e));
481 Statement::Let { pat, type_ref, initializer } 512 Statement::Let { pat, type_ref, initializer }
482 } 513 }
@@ -487,7 +518,7 @@ impl ExprCollector<'_> {
487 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 518 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
488 } 519 }
489 520
490 fn collect_block_items(&mut self, block: &ast::Block) { 521 fn collect_block_items(&mut self, block: &ast::BlockExpr) {
491 let container = ContainerId::DefWithBodyId(self.def); 522 let container = ContainerId::DefWithBodyId(self.def);
492 for item in block.items() { 523 for item in block.items() {
493 let (def, name): (ModuleDefId, Option<ast::Name>) = match item { 524 let (def, name): (ModuleDefId, Option<ast::Name>) = match item {
@@ -542,9 +573,16 @@ impl ExprCollector<'_> {
542 self.body.item_scope.define_def(def); 573 self.body.item_scope.define_def(def);
543 if let Some(name) = name { 574 if let Some(name) = name {
544 let vis = crate::visibility::Visibility::Public; // FIXME determine correctly 575 let vis = crate::visibility::Visibility::Public; // FIXME determine correctly
545 self.body 576 let has_constructor = match def {
546 .item_scope 577 ModuleDefId::AdtId(AdtId::StructId(s)) => {
547 .push_res(name.as_name(), crate::per_ns::PerNs::from_def(def, vis)); 578 self.db.struct_data(s).variant_data.kind() != StructKind::Record
579 }
580 _ => true,
581 };
582 self.body.item_scope.push_res(
583 name.as_name(),
584 crate::per_ns::PerNs::from_def(def, vis, has_constructor),
585 );
548 } 586 }
549 } 587 }
550 } 588 }