diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 201 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/path.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 7 |
6 files changed, 135 insertions, 93 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 7759a6d4f..7d5257461 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -12,7 +12,7 @@ use ra_syntax::{ | |||
12 | use crate::{ | 12 | use crate::{ |
13 | Path, Name, HirDatabase, Resolver,DefWithBody, Either, | 13 | Path, Name, HirDatabase, Resolver,DefWithBody, Either, |
14 | name::AsName, | 14 | name::AsName, |
15 | ids::MacroDefId, | 15 | ids::{MacroCallLoc,HirFileId}, |
16 | type_ref::{Mutability, TypeRef}, | 16 | type_ref::{Mutability, TypeRef}, |
17 | }; | 17 | }; |
18 | use crate::{path::GenericArgs, ty::primitive::{IntTy, UncertainIntTy, FloatTy, UncertainFloatTy}}; | 18 | use crate::{path::GenericArgs, ty::primitive::{IntTy, UncertainIntTy, FloatTy, UncertainFloatTy}}; |
@@ -479,7 +479,8 @@ impl Pat { | |||
479 | 479 | ||
480 | // Queries | 480 | // Queries |
481 | 481 | ||
482 | pub(crate) struct ExprCollector { | 482 | pub(crate) struct ExprCollector<DB> { |
483 | db: DB, | ||
483 | owner: DefWithBody, | 484 | owner: DefWithBody, |
484 | exprs: Arena<ExprId, Expr>, | 485 | exprs: Arena<ExprId, Expr>, |
485 | pats: Arena<PatId, Pat>, | 486 | pats: Arena<PatId, Pat>, |
@@ -489,20 +490,10 @@ pub(crate) struct ExprCollector { | |||
489 | resolver: Resolver, | 490 | resolver: Resolver, |
490 | } | 491 | } |
491 | 492 | ||
492 | impl ExprCollector{ | 493 | impl<'a, DB> ExprCollector<&'a DB> |
493 | fn new(owner: DefWithBody,resolver:Resolver) -> Self { | 494 | where |
494 | ExprCollector { | 495 | DB: HirDatabase, |
495 | owner, | 496 | { |
496 | resolver, | ||
497 | exprs: Arena::default(), | ||
498 | pats: Arena::default(), | ||
499 | source_map: BodySourceMap::default(), | ||
500 | params: Vec::new(), | ||
501 | body_expr: None, | ||
502 | |||
503 | } | ||
504 | } | ||
505 | |||
506 | fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId { | 497 | fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId { |
507 | let id = self.exprs.alloc(expr); | 498 | let id = self.exprs.alloc(expr); |
508 | self.source_map.expr_map.insert(syntax_ptr, id); | 499 | self.source_map.expr_map.insert(syntax_ptr, id); |
@@ -522,7 +513,7 @@ impl ExprCollector{ | |||
522 | self.exprs.alloc(block) | 513 | self.exprs.alloc(block) |
523 | } | 514 | } |
524 | 515 | ||
525 | fn collect_expr(&mut self, expr: &ast::Expr,db:&impl HirDatabase) -> ExprId { | 516 | fn collect_expr(&mut self, expr: &ast::Expr) -> ExprId { |
526 | let syntax_ptr = SyntaxNodePtr::new(expr.syntax()); | 517 | let syntax_ptr = SyntaxNodePtr::new(expr.syntax()); |
527 | match expr.kind() { | 518 | match expr.kind() { |
528 | ast::ExprKind::IfExpr(e) => { | 519 | ast::ExprKind::IfExpr(e) => { |
@@ -530,15 +521,15 @@ impl ExprCollector{ | |||
530 | // if let -- desugar to match | 521 | // if let -- desugar to match |
531 | let pat = self.collect_pat(pat); | 522 | let pat = self.collect_pat(pat); |
532 | let match_expr = | 523 | let match_expr = |
533 | self.collect_expr_opt(e.condition().expect("checked above").expr(),db); | 524 | self.collect_expr_opt(e.condition().expect("checked above").expr()); |
534 | let then_branch = self.collect_block_opt(e.then_branch(),db); | 525 | let then_branch = self.collect_block_opt(e.then_branch()); |
535 | let else_branch = e | 526 | let else_branch = e |
536 | .else_branch() | 527 | .else_branch() |
537 | .map(|b| match b { | 528 | .map(|b| match b { |
538 | ast::ElseBranch::Block(it) => self.collect_block(it,db), | 529 | ast::ElseBranch::Block(it) => self.collect_block(it), |
539 | ast::ElseBranch::IfExpr(elif) => { | 530 | ast::ElseBranch::IfExpr(elif) => { |
540 | let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap(); | 531 | let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap(); |
541 | self.collect_expr(expr,db) | 532 | self.collect_expr(expr) |
542 | } | 533 | } |
543 | }) | 534 | }) |
544 | .unwrap_or_else(|| self.empty_block()); | 535 | .unwrap_or_else(|| self.empty_block()); |
@@ -549,27 +540,27 @@ impl ExprCollector{ | |||
549 | ]; | 540 | ]; |
550 | self.alloc_expr(Expr::Match { expr: match_expr, arms }, syntax_ptr) | 541 | self.alloc_expr(Expr::Match { expr: match_expr, arms }, syntax_ptr) |
551 | } else { | 542 | } else { |
552 | let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr()),db); | 543 | let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr())); |
553 | let then_branch = self.collect_block_opt(e.then_branch(),db); | 544 | let then_branch = self.collect_block_opt(e.then_branch()); |
554 | let else_branch = e.else_branch().map(|b| match b { | 545 | let else_branch = e.else_branch().map(|b| match b { |
555 | ast::ElseBranch::Block(it) => self.collect_block(it,db), | 546 | ast::ElseBranch::Block(it) => self.collect_block(it), |
556 | ast::ElseBranch::IfExpr(elif) => { | 547 | ast::ElseBranch::IfExpr(elif) => { |
557 | let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap(); | 548 | let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap(); |
558 | self.collect_expr(expr,db) | 549 | self.collect_expr(expr) |
559 | } | 550 | } |
560 | }); | 551 | }); |
561 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) | 552 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) |
562 | } | 553 | } |
563 | } | 554 | } |
564 | ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block(),db), | 555 | ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()), |
565 | ast::ExprKind::LoopExpr(e) => { | 556 | ast::ExprKind::LoopExpr(e) => { |
566 | let body = self.collect_block_opt(e.loop_body(),db); | 557 | let body = self.collect_block_opt(e.loop_body()); |
567 | self.alloc_expr(Expr::Loop { body }, syntax_ptr) | 558 | self.alloc_expr(Expr::Loop { body }, syntax_ptr) |
568 | } | 559 | } |
569 | ast::ExprKind::WhileExpr(e) => { | 560 | ast::ExprKind::WhileExpr(e) => { |
570 | let condition = if let Some(condition) = e.condition() { | 561 | let condition = if let Some(condition) = e.condition() { |
571 | if condition.pat().is_none() { | 562 | if condition.pat().is_none() { |
572 | self.collect_expr_opt(condition.expr(),db) | 563 | self.collect_expr_opt(condition.expr()) |
573 | } else { | 564 | } else { |
574 | // FIXME handle while let | 565 | // FIXME handle while let |
575 | return self.alloc_expr(Expr::Missing, syntax_ptr); | 566 | return self.alloc_expr(Expr::Missing, syntax_ptr); |
@@ -577,28 +568,28 @@ impl ExprCollector{ | |||
577 | } else { | 568 | } else { |
578 | self.exprs.alloc(Expr::Missing) | 569 | self.exprs.alloc(Expr::Missing) |
579 | }; | 570 | }; |
580 | let body = self.collect_block_opt(e.loop_body(),db); | 571 | let body = self.collect_block_opt(e.loop_body()); |
581 | self.alloc_expr(Expr::While { condition, body }, syntax_ptr) | 572 | self.alloc_expr(Expr::While { condition, body }, syntax_ptr) |
582 | } | 573 | } |
583 | ast::ExprKind::ForExpr(e) => { | 574 | ast::ExprKind::ForExpr(e) => { |
584 | let iterable = self.collect_expr_opt(e.iterable(),db); | 575 | let iterable = self.collect_expr_opt(e.iterable()); |
585 | let pat = self.collect_pat_opt(e.pat()); | 576 | let pat = self.collect_pat_opt(e.pat()); |
586 | let body = self.collect_block_opt(e.loop_body(),db); | 577 | let body = self.collect_block_opt(e.loop_body()); |
587 | self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr) | 578 | self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr) |
588 | } | 579 | } |
589 | ast::ExprKind::CallExpr(e) => { | 580 | ast::ExprKind::CallExpr(e) => { |
590 | let callee = self.collect_expr_opt(e.expr(),db); | 581 | let callee = self.collect_expr_opt(e.expr()); |
591 | let args = if let Some(arg_list) = e.arg_list() { | 582 | let args = if let Some(arg_list) = e.arg_list() { |
592 | arg_list.args().map(|e| self.collect_expr(e,db)).collect() | 583 | arg_list.args().map(|e| self.collect_expr(e)).collect() |
593 | } else { | 584 | } else { |
594 | Vec::new() | 585 | Vec::new() |
595 | }; | 586 | }; |
596 | self.alloc_expr(Expr::Call { callee, args }, syntax_ptr) | 587 | self.alloc_expr(Expr::Call { callee, args }, syntax_ptr) |
597 | } | 588 | } |
598 | ast::ExprKind::MethodCallExpr(e) => { | 589 | ast::ExprKind::MethodCallExpr(e) => { |
599 | let receiver = self.collect_expr_opt(e.expr(),db); | 590 | let receiver = self.collect_expr_opt(e.expr()); |
600 | let args = if let Some(arg_list) = e.arg_list() { | 591 | let args = if let Some(arg_list) = e.arg_list() { |
601 | arg_list.args().map(|e| self.collect_expr(e,db)).collect() | 592 | arg_list.args().map(|e| self.collect_expr(e)).collect() |
602 | } else { | 593 | } else { |
603 | Vec::new() | 594 | Vec::new() |
604 | }; | 595 | }; |
@@ -610,17 +601,17 @@ impl ExprCollector{ | |||
610 | ) | 601 | ) |
611 | } | 602 | } |
612 | ast::ExprKind::MatchExpr(e) => { | 603 | ast::ExprKind::MatchExpr(e) => { |
613 | let expr = self.collect_expr_opt(e.expr(),db); | 604 | let expr = self.collect_expr_opt(e.expr()); |
614 | let arms = if let Some(match_arm_list) = e.match_arm_list() { | 605 | let arms = if let Some(match_arm_list) = e.match_arm_list() { |
615 | match_arm_list | 606 | match_arm_list |
616 | .arms() | 607 | .arms() |
617 | .map(|arm| MatchArm { | 608 | .map(|arm| MatchArm { |
618 | pats: arm.pats().map(|p| self.collect_pat(p)).collect(), | 609 | pats: arm.pats().map(|p| self.collect_pat(p)).collect(), |
619 | expr: self.collect_expr_opt(arm.expr(),db), | 610 | expr: self.collect_expr_opt(arm.expr()), |
620 | guard: arm | 611 | guard: arm |
621 | .guard() | 612 | .guard() |
622 | .and_then(|guard| guard.expr()) | 613 | .and_then(|guard| guard.expr()) |
623 | .map(|e| self.collect_expr(e,db)), | 614 | .map(|e| self.collect_expr(e)), |
624 | }) | 615 | }) |
625 | .collect() | 616 | .collect() |
626 | } else { | 617 | } else { |
@@ -638,17 +629,17 @@ impl ExprCollector{ | |||
638 | self.alloc_expr(Expr::Continue, syntax_ptr) | 629 | self.alloc_expr(Expr::Continue, syntax_ptr) |
639 | } | 630 | } |
640 | ast::ExprKind::BreakExpr(e) => { | 631 | ast::ExprKind::BreakExpr(e) => { |
641 | let expr = e.expr().map(|e| self.collect_expr(e,db)); | 632 | let expr = e.expr().map(|e| self.collect_expr(e)); |
642 | self.alloc_expr(Expr::Break { expr }, syntax_ptr) | 633 | self.alloc_expr(Expr::Break { expr }, syntax_ptr) |
643 | } | 634 | } |
644 | ast::ExprKind::ParenExpr(e) => { | 635 | ast::ExprKind::ParenExpr(e) => { |
645 | let inner = self.collect_expr_opt(e.expr(),db); | 636 | let inner = self.collect_expr_opt(e.expr()); |
646 | // make the paren expr point to the inner expression as well | 637 | // make the paren expr point to the inner expression as well |
647 | self.source_map.expr_map.insert(syntax_ptr, inner); | 638 | self.source_map.expr_map.insert(syntax_ptr, inner); |
648 | inner | 639 | inner |
649 | } | 640 | } |
650 | ast::ExprKind::ReturnExpr(e) => { | 641 | ast::ExprKind::ReturnExpr(e) => { |
651 | let expr = e.expr().map(|e| self.collect_expr(e,db)); | 642 | let expr = e.expr().map(|e| self.collect_expr(e)); |
652 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) | 643 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) |
653 | } | 644 | } |
654 | ast::ExprKind::StructLit(e) => { | 645 | ast::ExprKind::StructLit(e) => { |
@@ -663,7 +654,7 @@ impl ExprCollector{ | |||
663 | .map(|nr| nr.as_name()) | 654 | .map(|nr| nr.as_name()) |
664 | .unwrap_or_else(Name::missing), | 655 | .unwrap_or_else(Name::missing), |
665 | expr: if let Some(e) = field.expr() { | 656 | expr: if let Some(e) = field.expr() { |
666 | self.collect_expr(e,db) | 657 | self.collect_expr(e) |
667 | } else if let Some(nr) = field.name_ref() { | 658 | } else if let Some(nr) = field.name_ref() { |
668 | // field shorthand | 659 | // field shorthand |
669 | let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr))); | 660 | let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr))); |
@@ -682,7 +673,7 @@ impl ExprCollector{ | |||
682 | } else { | 673 | } else { |
683 | Vec::new() | 674 | Vec::new() |
684 | }; | 675 | }; |
685 | let spread = e.spread().map(|s| self.collect_expr(s,db)); | 676 | let spread = e.spread().map(|s| self.collect_expr(s)); |
686 | let res = self.alloc_expr(Expr::StructLit { path, fields, spread }, syntax_ptr); | 677 | let res = self.alloc_expr(Expr::StructLit { path, fields, spread }, syntax_ptr); |
687 | for (i, ptr) in field_ptrs.into_iter().enumerate() { | 678 | for (i, ptr) in field_ptrs.into_iter().enumerate() { |
688 | self.source_map.field_map.insert((res, i), ptr); | 679 | self.source_map.field_map.insert((res, i), ptr); |
@@ -690,7 +681,7 @@ impl ExprCollector{ | |||
690 | res | 681 | res |
691 | } | 682 | } |
692 | ast::ExprKind::FieldExpr(e) => { | 683 | ast::ExprKind::FieldExpr(e) => { |
693 | let expr = self.collect_expr_opt(e.expr(),db); | 684 | let expr = self.collect_expr_opt(e.expr()); |
694 | let name = match e.field_access() { | 685 | let name = match e.field_access() { |
695 | Some(kind) => kind.as_name(), | 686 | Some(kind) => kind.as_name(), |
696 | _ => Name::missing(), | 687 | _ => Name::missing(), |
@@ -698,21 +689,21 @@ impl ExprCollector{ | |||
698 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) | 689 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) |
699 | } | 690 | } |
700 | ast::ExprKind::TryExpr(e) => { | 691 | ast::ExprKind::TryExpr(e) => { |
701 | let expr = self.collect_expr_opt(e.expr(),db); | 692 | let expr = self.collect_expr_opt(e.expr()); |
702 | self.alloc_expr(Expr::Try { expr }, syntax_ptr) | 693 | self.alloc_expr(Expr::Try { expr }, syntax_ptr) |
703 | } | 694 | } |
704 | ast::ExprKind::CastExpr(e) => { | 695 | ast::ExprKind::CastExpr(e) => { |
705 | let expr = self.collect_expr_opt(e.expr(),db); | 696 | let expr = self.collect_expr_opt(e.expr()); |
706 | let type_ref = TypeRef::from_ast_opt(e.type_ref()); | 697 | let type_ref = TypeRef::from_ast_opt(e.type_ref()); |
707 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) | 698 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) |
708 | } | 699 | } |
709 | ast::ExprKind::RefExpr(e) => { | 700 | ast::ExprKind::RefExpr(e) => { |
710 | let expr = self.collect_expr_opt(e.expr(),db); | 701 | let expr = self.collect_expr_opt(e.expr()); |
711 | let mutability = Mutability::from_mutable(e.is_mut()); | 702 | let mutability = Mutability::from_mutable(e.is_mut()); |
712 | self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr) | 703 | self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr) |
713 | } | 704 | } |
714 | ast::ExprKind::PrefixExpr(e) => { | 705 | ast::ExprKind::PrefixExpr(e) => { |
715 | let expr = self.collect_expr_opt(e.expr(),db); | 706 | let expr = self.collect_expr_opt(e.expr()); |
716 | if let Some(op) = e.op_kind() { | 707 | if let Some(op) = e.op_kind() { |
717 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) | 708 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) |
718 | } else { | 709 | } else { |
@@ -730,17 +721,17 @@ impl ExprCollector{ | |||
730 | arg_types.push(type_ref); | 721 | arg_types.push(type_ref); |
731 | } | 722 | } |
732 | } | 723 | } |
733 | let body = self.collect_expr_opt(e.body(),db); | 724 | let body = self.collect_expr_opt(e.body()); |
734 | self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) | 725 | self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) |
735 | } | 726 | } |
736 | ast::ExprKind::BinExpr(e) => { | 727 | ast::ExprKind::BinExpr(e) => { |
737 | let lhs = self.collect_expr_opt(e.lhs(),db); | 728 | let lhs = self.collect_expr_opt(e.lhs()); |
738 | let rhs = self.collect_expr_opt(e.rhs(),db); | 729 | let rhs = self.collect_expr_opt(e.rhs()); |
739 | let op = e.op_kind(); | 730 | let op = e.op_kind(); |
740 | self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) | 731 | self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) |
741 | } | 732 | } |
742 | ast::ExprKind::TupleExpr(e) => { | 733 | ast::ExprKind::TupleExpr(e) => { |
743 | let exprs = e.exprs().map(|expr| self.collect_expr(expr,db)).collect(); | 734 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); |
744 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) | 735 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) |
745 | } | 736 | } |
746 | 737 | ||
@@ -749,12 +740,12 @@ impl ExprCollector{ | |||
749 | 740 | ||
750 | match kind { | 741 | match kind { |
751 | ArrayExprKind::ElementList(e) => { | 742 | ArrayExprKind::ElementList(e) => { |
752 | let exprs = e.map(|expr| self.collect_expr(expr,db)).collect(); | 743 | let exprs = e.map(|expr| self.collect_expr(expr)).collect(); |
753 | self.alloc_expr(Expr::Array(Array::ElementList(exprs)), syntax_ptr) | 744 | self.alloc_expr(Expr::Array(Array::ElementList(exprs)), syntax_ptr) |
754 | } | 745 | } |
755 | ArrayExprKind::Repeat { initializer, repeat } => { | 746 | ArrayExprKind::Repeat { initializer, repeat } => { |
756 | let initializer = self.collect_expr_opt(initializer,db); | 747 | let initializer = self.collect_expr_opt(initializer); |
757 | let repeat = self.collect_expr_opt(repeat,db); | 748 | let repeat = self.collect_expr_opt(repeat); |
758 | self.alloc_expr( | 749 | self.alloc_expr( |
759 | Expr::Array(Array::Repeat { initializer, repeat }), | 750 | Expr::Array(Array::Repeat { initializer, repeat }), |
760 | syntax_ptr, | 751 | syntax_ptr, |
@@ -799,52 +790,79 @@ impl ExprCollector{ | |||
799 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 790 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
800 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 791 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
801 | ast::ExprKind::MacroCall(e) => { | 792 | ast::ExprKind::MacroCall(e) => { |
802 | 793 | // very hacky.TODO change to use the macro resolution | |
803 | let name = e.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 794 | let name = e |
804 | 795 | .path() | |
805 | let res = self.resolver.resolve_name(db,&name); | 796 | .and_then(Path::from_ast) |
806 | 797 | .and_then(|path| path.expand_macro_expr()) | |
807 | // match res { | 798 | .unwrap_or_else(Name::missing); |
808 | 799 | ||
809 | // } | 800 | if let Some(macro_id) = self.resolver.resolve_macro_call(&name) { |
810 | 801 | if let Some((module, _)) = self.resolver.module() { | |
811 | // let resolver = Resolver | 802 | // we do this to get the ast_id for the macro call |
812 | 803 | // if we used the ast_id from the macro_id variable | |
813 | self.alloc_expr(Expr::Missing, syntax_ptr) | 804 | // it gives us the ast_id of the defenition site |
814 | }, | 805 | let module = module.mk_module(module.root()); |
806 | let hir_file_id = module.definition_source(self.db).0; | ||
807 | let ast_id = | ||
808 | self.db.ast_id_map(hir_file_id).ast_id(e).with_file_id(hir_file_id); | ||
809 | |||
810 | let call_loc = MacroCallLoc { def: *macro_id, ast_id }; | ||
811 | let call_id = call_loc.id(self.db); | ||
812 | let file_id: HirFileId = call_id.into(); | ||
813 | |||
814 | log::debug!( | ||
815 | "expanded macro ast {}", | ||
816 | self.db.hir_parse(file_id).syntax().debug_dump() | ||
817 | ); | ||
818 | |||
819 | self.db | ||
820 | .hir_parse(file_id) | ||
821 | .syntax() | ||
822 | .descendants() | ||
823 | .find_map(ast::Expr::cast) | ||
824 | .map(|expr| self.collect_expr(expr)) | ||
825 | .unwrap_or(self.alloc_expr(Expr::Missing, syntax_ptr)) | ||
826 | } else { | ||
827 | self.alloc_expr(Expr::Missing, syntax_ptr) | ||
828 | } | ||
829 | } else { | ||
830 | self.alloc_expr(Expr::Missing, syntax_ptr) | ||
831 | } | ||
832 | } | ||
815 | } | 833 | } |
816 | } | 834 | } |
817 | 835 | ||
818 | fn collect_expr_opt(&mut self, expr: Option<&ast::Expr>,db:&impl HirDatabase) -> ExprId { | 836 | fn collect_expr_opt(&mut self, expr: Option<&ast::Expr>) -> ExprId { |
819 | if let Some(expr) = expr { | 837 | if let Some(expr) = expr { |
820 | self.collect_expr(expr,db) | 838 | self.collect_expr(expr) |
821 | } else { | 839 | } else { |
822 | self.exprs.alloc(Expr::Missing) | 840 | self.exprs.alloc(Expr::Missing) |
823 | } | 841 | } |
824 | } | 842 | } |
825 | 843 | ||
826 | fn collect_block(&mut self, block: &ast::Block,db:&impl HirDatabase) -> ExprId { | 844 | fn collect_block(&mut self, block: &ast::Block) -> ExprId { |
827 | let statements = block | 845 | let statements = block |
828 | .statements() | 846 | .statements() |
829 | .map(|s| match s.kind() { | 847 | .map(|s| match s.kind() { |
830 | ast::StmtKind::LetStmt(stmt) => { | 848 | ast::StmtKind::LetStmt(stmt) => { |
831 | let pat = self.collect_pat_opt(stmt.pat()); | 849 | let pat = self.collect_pat_opt(stmt.pat()); |
832 | let type_ref = stmt.ascribed_type().map(TypeRef::from_ast); | 850 | let type_ref = stmt.ascribed_type().map(TypeRef::from_ast); |
833 | let initializer = stmt.initializer().map(|e| self.collect_expr(e,db)); | 851 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
834 | Statement::Let { pat, type_ref, initializer } | 852 | Statement::Let { pat, type_ref, initializer } |
835 | } | 853 | } |
836 | ast::StmtKind::ExprStmt(stmt) => { | 854 | ast::StmtKind::ExprStmt(stmt) => { |
837 | Statement::Expr(self.collect_expr_opt(stmt.expr(),db)) | 855 | Statement::Expr(self.collect_expr_opt(stmt.expr())) |
838 | } | 856 | } |
839 | }) | 857 | }) |
840 | .collect(); | 858 | .collect(); |
841 | let tail = block.expr().map(|e| self.collect_expr(e,db)); | 859 | let tail = block.expr().map(|e| self.collect_expr(e)); |
842 | self.alloc_expr(Expr::Block { statements, tail }, SyntaxNodePtr::new(block.syntax())) | 860 | self.alloc_expr(Expr::Block { statements, tail }, SyntaxNodePtr::new(block.syntax())) |
843 | } | 861 | } |
844 | 862 | ||
845 | fn collect_block_opt(&mut self, block: Option<&ast::Block>,db:&impl HirDatabase) -> ExprId { | 863 | fn collect_block_opt(&mut self, block: Option<&ast::Block>) -> ExprId { |
846 | if let Some(block) = block { | 864 | if let Some(block) = block { |
847 | self.collect_block(block,db) | 865 | self.collect_block(block) |
848 | } else { | 866 | } else { |
849 | self.exprs.alloc(Expr::Missing) | 867 | self.exprs.alloc(Expr::Missing) |
850 | } | 868 | } |
@@ -917,17 +935,17 @@ impl ExprCollector{ | |||
917 | } | 935 | } |
918 | } | 936 | } |
919 | 937 | ||
920 | fn collect_const_body(&mut self, node: &ast::ConstDef,db:&impl HirDatabase) { | 938 | fn collect_const_body(&mut self, node: &ast::ConstDef) { |
921 | let body = self.collect_expr_opt(node.body(),db); | 939 | let body = self.collect_expr_opt(node.body()); |
922 | self.body_expr = Some(body); | 940 | self.body_expr = Some(body); |
923 | } | 941 | } |
924 | 942 | ||
925 | fn collect_static_body(&mut self, node: &ast::StaticDef,db:&impl HirDatabase) { | 943 | fn collect_static_body(&mut self, node: &ast::StaticDef) { |
926 | let body = self.collect_expr_opt(node.body(),db); | 944 | let body = self.collect_expr_opt(node.body()); |
927 | self.body_expr = Some(body); | 945 | self.body_expr = Some(body); |
928 | } | 946 | } |
929 | 947 | ||
930 | fn collect_fn_body(&mut self, node: &ast::FnDef,db:&impl HirDatabase) { | 948 | fn collect_fn_body(&mut self, node: &ast::FnDef) { |
931 | if let Some(param_list) = node.param_list() { | 949 | if let Some(param_list) = node.param_list() { |
932 | if let Some(self_param) = param_list.self_param() { | 950 | if let Some(self_param) = param_list.self_param() { |
933 | let ptr = AstPtr::new(self_param); | 951 | let ptr = AstPtr::new(self_param); |
@@ -953,7 +971,7 @@ impl ExprCollector{ | |||
953 | } | 971 | } |
954 | }; | 972 | }; |
955 | 973 | ||
956 | let body = self.collect_block_opt(node.body(),db); | 974 | let body = self.collect_block_opt(node.body()); |
957 | self.body_expr = Some(body); | 975 | self.body_expr = Some(body); |
958 | } | 976 | } |
959 | 977 | ||
@@ -973,14 +991,21 @@ pub(crate) fn body_with_source_map_query( | |||
973 | db: &impl HirDatabase, | 991 | db: &impl HirDatabase, |
974 | def: DefWithBody, | 992 | def: DefWithBody, |
975 | ) -> (Arc<Body>, Arc<BodySourceMap>) { | 993 | ) -> (Arc<Body>, Arc<BodySourceMap>) { |
976 | 994 | let mut collector = ExprCollector { | |
977 | let mut resolver = def.resolver(db); | 995 | db, |
978 | let mut collector = ExprCollector::new(def,resolver); | 996 | owner: def, |
997 | resolver: def.resolver(db), | ||
998 | exprs: Arena::default(), | ||
999 | pats: Arena::default(), | ||
1000 | source_map: BodySourceMap::default(), | ||
1001 | params: Vec::new(), | ||
1002 | body_expr: None, | ||
1003 | }; | ||
979 | 1004 | ||
980 | match def { | 1005 | match def { |
981 | DefWithBody::Const(ref c) => collector.collect_const_body(&c.source(db).1,db), | 1006 | DefWithBody::Const(ref c) => collector.collect_const_body(&c.source(db).1), |
982 | DefWithBody::Function(ref f) => collector.collect_fn_body(&f.source(db).1,db), | 1007 | DefWithBody::Function(ref f) => collector.collect_fn_body(&f.source(db).1), |
983 | DefWithBody::Static(ref s) => collector.collect_static_body(&s.source(db).1,db), | 1008 | DefWithBody::Static(ref s) => collector.collect_static_body(&s.source(db).1), |
984 | } | 1009 | } |
985 | 1010 | ||
986 | let (body, source_map) = collector.finish(); | 1011 | let (body, source_map) = collector.finish(); |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index c7849c995..a07624a19 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -101,7 +101,7 @@ fn parse_macro( | |||
101 | return Err(format!("Total tokens count exceed limit : count = {}", count)); | 101 | return Err(format!("Total tokens count exceed limit : count = {}", count)); |
102 | } | 102 | } |
103 | 103 | ||
104 | Ok(mbe::token_tree_to_ast_item_list(&tt)) | 104 | Some(mbe::token_tree_to_ast_item_list(&tt)) |
105 | } | 105 | } |
106 | 106 | ||
107 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 107 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index fbfff4fd7..a450d7b84 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -104,6 +104,7 @@ pub struct CrateDefMap { | |||
104 | /// However, do we want to put it as a global variable? | 104 | /// However, do we want to put it as a global variable? |
105 | poison_macros: FxHashSet<MacroDefId>, | 105 | poison_macros: FxHashSet<MacroDefId>, |
106 | 106 | ||
107 | local_macros: FxHashMap<Name, MacroDefId>, | ||
107 | diagnostics: Vec<DefDiagnostic>, | 108 | diagnostics: Vec<DefDiagnostic>, |
108 | } | 109 | } |
109 | 110 | ||
@@ -209,6 +210,7 @@ impl CrateDefMap { | |||
209 | modules, | 210 | modules, |
210 | public_macros: FxHashMap::default(), | 211 | public_macros: FxHashMap::default(), |
211 | poison_macros: FxHashSet::default(), | 212 | poison_macros: FxHashSet::default(), |
213 | local_macros: FxHashMap::default(), | ||
212 | diagnostics: Vec::new(), | 214 | diagnostics: Vec::new(), |
213 | } | 215 | } |
214 | }; | 216 | }; |
@@ -270,6 +272,10 @@ impl CrateDefMap { | |||
270 | (res.resolved_def, res.segment_index) | 272 | (res.resolved_def, res.segment_index) |
271 | } | 273 | } |
272 | 274 | ||
275 | pub(crate) fn find_macro(&self, name: &Name) -> Option<&MacroDefId> { | ||
276 | self.public_macros.get(name).or(self.local_macros.get(name)) | ||
277 | } | ||
278 | |||
273 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change | 279 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change |
274 | // the result. | 280 | // the result. |
275 | fn resolve_path_fp( | 281 | fn resolve_path_fp( |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 4590a5184..762a61604 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -131,6 +131,8 @@ where | |||
131 | fn define_macro(&mut self, name: Name, macro_id: MacroDefId, export: bool) { | 131 | fn define_macro(&mut self, name: Name, macro_id: MacroDefId, export: bool) { |
132 | if export { | 132 | if export { |
133 | self.def_map.public_macros.insert(name.clone(), macro_id); | 133 | self.def_map.public_macros.insert(name.clone(), macro_id); |
134 | } else { | ||
135 | self.def_map.local_macros.insert(name.clone(), macro_id); | ||
134 | } | 136 | } |
135 | self.global_macro_scope.insert(name, macro_id); | 137 | self.global_macro_scope.insert(name, macro_id); |
136 | } | 138 | } |
@@ -517,10 +519,10 @@ where | |||
517 | 519 | ||
518 | // Case 2: try to expand macro_rules from this crate, triggering | 520 | // Case 2: try to expand macro_rules from this crate, triggering |
519 | // recursive item collection. | 521 | // recursive item collection. |
520 | if let Some(¯o_id) = | 522 | if let Some(macro_id) = |
521 | mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) | 523 | mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(&name)) |
522 | { | 524 | { |
523 | let macro_call_id = MacroCallLoc { def: macro_id, ast_id }.id(self.def_collector.db); | 525 | let macro_call_id = MacroCallLoc { def: *macro_id, ast_id }.id(self.def_collector.db); |
524 | 526 | ||
525 | self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_id); | 527 | self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_id); |
526 | return; | 528 | return; |
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index 5449cddfd..1b129c752 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs | |||
@@ -126,6 +126,10 @@ impl Path { | |||
126 | } | 126 | } |
127 | self.segments.first().map(|s| &s.name) | 127 | self.segments.first().map(|s| &s.name) |
128 | } | 128 | } |
129 | |||
130 | pub fn expand_macro_expr(&self) -> Option<Name> { | ||
131 | self.as_ident().and_then(|name| Some(name.clone())) | ||
132 | } | ||
129 | } | 133 | } |
130 | 134 | ||
131 | impl GenericArgs { | 135 | impl GenericArgs { |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index f2c85eb66..1def032f9 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -6,6 +6,7 @@ use rustc_hash::FxHashMap; | |||
6 | use crate::{ | 6 | use crate::{ |
7 | ModuleDef, | 7 | ModuleDef, |
8 | code_model_api::Crate, | 8 | code_model_api::Crate, |
9 | MacroDefId, | ||
9 | db::HirDatabase, | 10 | db::HirDatabase, |
10 | name::{Name, KnownName}, | 11 | name::{Name, KnownName}, |
11 | nameres::{PerNs, CrateDefMap, CrateModuleId}, | 12 | nameres::{PerNs, CrateDefMap, CrateModuleId}, |
@@ -130,6 +131,10 @@ impl Resolver { | |||
130 | resolution | 131 | resolution |
131 | } | 132 | } |
132 | 133 | ||
134 | pub fn resolve_macro_call(&self, name: &Name) -> Option<&MacroDefId> { | ||
135 | self.module().and_then(|(module, _)| module.find_macro(name)) | ||
136 | } | ||
137 | |||
133 | /// Returns the resolved path segments | 138 | /// Returns the resolved path segments |
134 | /// Which may be fully resolved, empty or partially resolved. | 139 | /// Which may be fully resolved, empty or partially resolved. |
135 | pub(crate) fn resolve_path_segments(&self, db: &impl HirDatabase, path: &Path) -> PathResult { | 140 | pub(crate) fn resolve_path_segments(&self, db: &impl HirDatabase, path: &Path) -> PathResult { |
@@ -192,7 +197,7 @@ impl Resolver { | |||
192 | .flatten() | 197 | .flatten() |
193 | } | 198 | } |
194 | 199 | ||
195 | fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { | 200 | pub(crate) fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { |
196 | self.scopes.iter().rev().find_map(|scope| match scope { | 201 | self.scopes.iter().rev().find_map(|scope| match scope { |
197 | Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)), | 202 | Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)), |
198 | 203 | ||