1use la_arena::{Arena, Idx};
16use std::collections::HashMap;
17use std::fmt;
18
19use crate::call_type::{CallType, InstanceCreationType, InstanceIdentifier};
20use crate::expr::{ArmPattern, Expr, MatchArm, Number, Range};
21use crate::parser::type_name::TypeName;
22use crate::rib_source_span::SourceSpan;
23use crate::{InferredType, VariableId};
24
25pub type ExprId = Idx<ExprNode>;
31
32pub type ArmPatternId = Idx<ArmPatternNode>;
34
35#[derive(Debug, Clone)]
42pub struct ExprNode {
43 pub kind: ExprKind,
44 pub source_span: SourceSpan,
45 pub type_annotation: Option<TypeName>,
46}
47
48#[derive(Debug, Clone)]
52pub enum ExprKind {
53 Let {
54 variable_id: VariableId,
55 expr: ExprId,
56 },
57 SelectField {
58 expr: ExprId,
59 field: String,
60 },
61 SelectIndex {
62 expr: ExprId,
63 index: ExprId,
64 },
65 Sequence {
66 exprs: Vec<ExprId>,
67 },
68 Range {
69 range: RangeKind,
70 },
71 Record {
72 fields: Vec<(String, ExprId)>,
73 },
74 Tuple {
75 exprs: Vec<ExprId>,
76 },
77 Literal {
78 value: String,
79 },
80 Number {
81 number: Number,
82 },
83 Flags {
84 flags: Vec<String>,
85 },
86 Identifier {
87 variable_id: VariableId,
88 },
89 Boolean {
90 value: bool,
91 },
92 Concat {
93 exprs: Vec<ExprId>,
94 },
95 ExprBlock {
96 exprs: Vec<ExprId>,
97 },
98 Not {
99 expr: ExprId,
100 },
101 GreaterThan {
102 lhs: ExprId,
103 rhs: ExprId,
104 },
105 GreaterThanOrEqualTo {
106 lhs: ExprId,
107 rhs: ExprId,
108 },
109 LessThanOrEqualTo {
110 lhs: ExprId,
111 rhs: ExprId,
112 },
113 EqualTo {
114 lhs: ExprId,
115 rhs: ExprId,
116 },
117 LessThan {
118 lhs: ExprId,
119 rhs: ExprId,
120 },
121 And {
122 lhs: ExprId,
123 rhs: ExprId,
124 },
125 Or {
126 lhs: ExprId,
127 rhs: ExprId,
128 },
129 Plus {
130 lhs: ExprId,
131 rhs: ExprId,
132 },
133 Minus {
134 lhs: ExprId,
135 rhs: ExprId,
136 },
137 Multiply {
138 lhs: ExprId,
139 rhs: ExprId,
140 },
141 Divide {
142 lhs: ExprId,
143 rhs: ExprId,
144 },
145 Cond {
146 cond: ExprId,
147 lhs: ExprId,
148 rhs: ExprId,
149 },
150 PatternMatch {
151 predicate: ExprId,
152 match_arms: Vec<MatchArmNode>,
153 },
154 Option {
155 expr: Option<ExprId>,
156 },
157 Result {
158 expr: ResultExprKind,
159 },
160 Call {
161 call_type: CallTypeNode,
162 args: Vec<ExprId>,
163 },
164 InvokeMethodLazy {
165 lhs: ExprId,
166 method: String,
167 args: Vec<ExprId>,
168 },
169 Unwrap {
170 expr: ExprId,
171 },
172 Throw {
173 message: String,
174 },
175 GetTag {
176 expr: ExprId,
177 },
178 ListComprehension {
179 iterated_variable: VariableId,
180 iterable_expr: ExprId,
181 yield_expr: ExprId,
182 },
183 ListReduce {
184 reduce_variable: VariableId,
185 iterated_variable: VariableId,
186 iterable_expr: ExprId,
187 init_value_expr: ExprId,
188 yield_expr: ExprId,
189 },
190 Length {
191 expr: ExprId,
192 },
193 GenerateWorkerName {
194 variable_id: Option<VariableId>,
195 },
196}
197
198#[derive(Debug, Clone)]
200pub enum RangeKind {
201 Range { from: ExprId, to: ExprId },
202 RangeInclusive { from: ExprId, to: ExprId },
203 RangeFrom { from: ExprId },
204}
205
206#[derive(Debug, Clone)]
208pub enum ResultExprKind {
209 Ok(ExprId),
210 Err(ExprId),
211}
212
213#[derive(Debug, Clone)]
217pub enum CallTypeNode {
218 Function {
219 component_info: Option<crate::ComponentDependencyKey>,
220 instance_identifier: Option<InstanceIdentifierNode>,
221 function_name: crate::DynamicParsedFunctionName,
222 },
223 VariantConstructor(String),
224 EnumConstructor(String),
225 InstanceCreation(InstanceCreationNode),
226}
227
228impl CallTypeNode {
229 pub fn is_resource_method(&self) -> bool {
231 match self {
232 CallTypeNode::Function { function_name, .. } => function_name
233 .to_parsed_function_name()
234 .function
235 .resource_method_name()
236 .is_some(),
237 _ => false,
238 }
239 }
240}
241
242impl fmt::Display for CallTypeNode {
243 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
244 match self {
245 CallTypeNode::Function { function_name, .. } => write!(f, "{function_name}"),
246 CallTypeNode::VariantConstructor(name) => write!(f, "{name}"),
247 CallTypeNode::EnumConstructor(name) => write!(f, "{name}"),
248 CallTypeNode::InstanceCreation(InstanceCreationNode::WitWorker { .. }) => {
249 write!(f, "instance")
250 }
251 CallTypeNode::InstanceCreation(InstanceCreationNode::WitResource {
252 resource_name,
253 ..
254 }) => write!(f, "{}", resource_name.resource_name),
255 }
256 }
257}
258
259#[derive(Debug, Clone)]
260pub enum InstanceIdentifierNode {
261 WitWorker {
262 variable_id: Option<VariableId>,
263 worker_name: Option<ExprId>,
264 },
265 WitResource {
266 variable_id: Option<VariableId>,
267 worker_name: Option<ExprId>,
268 resource_name: String,
269 },
270}
271
272#[derive(Debug, Clone)]
273pub enum InstanceCreationNode {
274 WitWorker {
275 component_info: Option<crate::ComponentDependencyKey>,
276 worker_name: Option<ExprId>,
277 },
278 WitResource {
279 component_info: Option<crate::ComponentDependencyKey>,
280 module: Option<InstanceIdentifierNode>,
281 resource_name: crate::FullyQualifiedResourceConstructor,
282 },
283}
284
285#[derive(Debug, Clone)]
286pub struct MatchArmNode {
287 pub arm_pattern: ArmPatternId,
288 pub arm_resolution_expr: ExprId,
289}
290
291#[derive(Debug, Clone)]
292pub enum ArmPatternNode {
293 WildCard,
294 As(String, ArmPatternId),
295 Constructor(String, Vec<ArmPatternId>),
296 TupleConstructor(Vec<ArmPatternId>),
297 RecordConstructor(Vec<(String, ArmPatternId)>),
298 ListConstructor(Vec<ArmPatternId>),
299 Literal(ExprId),
302}
303
304#[derive(Debug, Clone)]
305pub struct TypeTable {
306 types: HashMap<ExprId, InferredType>,
307}
308
309impl TypeTable {
310 pub fn new() -> Self {
311 TypeTable {
312 types: HashMap::new(),
313 }
314 }
315
316 pub fn get(&self, id: ExprId) -> &InferredType {
317 self.types
318 .get(&id)
319 .expect("TypeTable: ExprId not found — was it allocated in this arena?")
320 }
321
322 pub fn get_opt(&self, id: ExprId) -> Option<&InferredType> {
323 self.types.get(&id)
324 }
325
326 pub fn set(&mut self, id: ExprId, ty: InferredType) {
327 self.types.insert(id, ty);
328 }
329
330 pub fn snapshot(&self) -> Vec<(ExprId, InferredType)> {
334 self.types.iter().map(|(k, v)| (*k, v.clone())).collect()
335 }
336
337 pub fn same_as(&self, other: &TypeTable) -> bool {
340 if self.types.len() != other.types.len() {
341 return false;
342 }
343 self.types
344 .iter()
345 .all(|(id, ty)| other.types.get(id) == Some(ty))
346 }
347
348 pub fn same_as_snapshot(&self, snapshot: &[(ExprId, InferredType)]) -> bool {
350 if self.types.len() != snapshot.len() {
351 return false;
352 }
353 snapshot
354 .iter()
355 .all(|(id, ty)| self.types.get(id) == Some(ty))
356 }
357}
358
359impl Default for TypeTable {
360 fn default() -> Self {
361 TypeTable::new()
362 }
363}
364
365#[derive(Debug, Default)]
372pub struct ExprArena {
373 pub exprs: Arena<ExprNode>,
374 pub patterns: Arena<ArmPatternNode>,
375}
376
377impl ExprArena {
378 pub fn new() -> Self {
379 ExprArena::default()
380 }
381
382 pub fn alloc_expr(&mut self, node: ExprNode) -> ExprId {
384 self.exprs.alloc(node)
385 }
386
387 pub fn alloc_pattern(&mut self, node: ArmPatternNode) -> ArmPatternId {
389 self.patterns.alloc(node)
390 }
391
392 pub fn expr(&self, id: ExprId) -> &ExprNode {
394 &self.exprs[id]
395 }
396
397 pub fn expr_mut(&mut self, id: ExprId) -> &mut ExprNode {
401 &mut self.exprs[id]
402 }
403
404 pub fn pattern(&self, id: ArmPatternId) -> &ArmPatternNode {
406 &self.patterns[id]
407 }
408
409 pub fn pattern_mut(&mut self, id: ArmPatternId) -> &mut ArmPatternNode {
411 &mut self.patterns[id]
412 }
413}
414
415pub fn lower(expr: &Expr) -> (ExprArena, TypeTable, ExprId) {
423 let mut arena = ExprArena::new();
424 let mut types = TypeTable::new();
425 let root = lower_expr(expr, &mut arena, &mut types);
426 (arena, types, root)
427}
428
429pub fn lower_into(arena: &mut ExprArena, types: &mut TypeTable, expr: &Expr) -> ExprId {
433 lower_expr(expr, arena, types)
434}
435
436pub fn rebuild_expr(id: ExprId, arena: &ExprArena, types: &TypeTable) -> Expr {
445 let node = arena.expr(id);
446 let inferred = types
447 .get_opt(id)
448 .cloned()
449 .unwrap_or_else(InferredType::unknown);
450 let span = node.source_span.clone();
451 let annotation = node.type_annotation.clone();
452
453 match &node.kind.clone() {
454 ExprKind::Let {
455 variable_id,
456 expr: rhs_id,
457 } => Expr::Let {
458 variable_id: variable_id.clone(),
459 type_annotation: annotation,
460 expr: Box::new(rebuild_expr(*rhs_id, arena, types)),
461 inferred_type: inferred,
462 source_span: span,
463 },
464 ExprKind::SelectField {
465 expr: inner_id,
466 field,
467 } => Expr::SelectField {
468 expr: Box::new(rebuild_expr(*inner_id, arena, types)),
469 field: field.clone(),
470 type_annotation: annotation,
471 inferred_type: inferred,
472 source_span: span,
473 },
474 ExprKind::SelectIndex {
475 expr: e_id,
476 index: i_id,
477 } => Expr::SelectIndex {
478 expr: Box::new(rebuild_expr(*e_id, arena, types)),
479 index: Box::new(rebuild_expr(*i_id, arena, types)),
480 type_annotation: annotation,
481 inferred_type: inferred,
482 source_span: span,
483 },
484 ExprKind::Sequence { exprs } => Expr::Sequence {
485 exprs: exprs
486 .iter()
487 .map(|&e| rebuild_expr(e, arena, types))
488 .collect(),
489 type_annotation: annotation,
490 inferred_type: inferred,
491 source_span: span,
492 },
493 ExprKind::Tuple { exprs } => Expr::Tuple {
494 exprs: exprs
495 .iter()
496 .map(|&e| rebuild_expr(e, arena, types))
497 .collect(),
498 type_annotation: annotation,
499 inferred_type: inferred,
500 source_span: span,
501 },
502 ExprKind::Concat { exprs } => Expr::Concat {
503 exprs: exprs
504 .iter()
505 .map(|&e| rebuild_expr(e, arena, types))
506 .collect(),
507 type_annotation: annotation,
508 inferred_type: inferred,
509 source_span: span,
510 },
511 ExprKind::ExprBlock { exprs } => Expr::ExprBlock {
512 exprs: exprs
513 .iter()
514 .map(|&e| rebuild_expr(e, arena, types))
515 .collect(),
516 type_annotation: annotation,
517 inferred_type: inferred,
518 source_span: span,
519 },
520 ExprKind::Record { fields } => Expr::Record {
521 exprs: fields
522 .iter()
523 .map(|(name, e)| (name.clone(), Box::new(rebuild_expr(*e, arena, types))))
524 .collect(),
525 type_annotation: annotation,
526 inferred_type: inferred,
527 source_span: span,
528 },
529 ExprKind::Range { range } => {
530 let range_val = match range {
531 RangeKind::Range { from, to } => crate::expr::Range::Range {
532 from: Box::new(rebuild_expr(*from, arena, types)),
533 to: Box::new(rebuild_expr(*to, arena, types)),
534 },
535 RangeKind::RangeInclusive { from, to } => crate::expr::Range::RangeInclusive {
536 from: Box::new(rebuild_expr(*from, arena, types)),
537 to: Box::new(rebuild_expr(*to, arena, types)),
538 },
539 RangeKind::RangeFrom { from } => crate::expr::Range::RangeFrom {
540 from: Box::new(rebuild_expr(*from, arena, types)),
541 },
542 };
543 Expr::Range {
544 range: range_val,
545 type_annotation: annotation,
546 inferred_type: inferred,
547 source_span: span,
548 }
549 }
550 ExprKind::Literal { value } => Expr::Literal {
551 value: value.clone(),
552 type_annotation: annotation,
553 inferred_type: inferred,
554 source_span: span,
555 },
556 ExprKind::Number { number } => Expr::Number {
557 number: number.clone(),
558 type_annotation: annotation,
559 inferred_type: inferred,
560 source_span: span,
561 },
562 ExprKind::Flags { flags } => Expr::Flags {
563 flags: flags.clone(),
564 type_annotation: annotation,
565 inferred_type: inferred,
566 source_span: span,
567 },
568 ExprKind::Identifier { variable_id } => Expr::Identifier {
569 variable_id: variable_id.clone(),
570 type_annotation: annotation,
571 inferred_type: inferred,
572 source_span: span,
573 },
574 ExprKind::Boolean { value } => Expr::Boolean {
575 value: *value,
576 type_annotation: annotation,
577 inferred_type: inferred,
578 source_span: span,
579 },
580 ExprKind::Not { expr: inner } => Expr::Not {
581 expr: Box::new(rebuild_expr(*inner, arena, types)),
582 type_annotation: annotation,
583 inferred_type: inferred,
584 source_span: span,
585 },
586 ExprKind::Length { expr: inner } => Expr::Length {
587 expr: Box::new(rebuild_expr(*inner, arena, types)),
588 type_annotation: annotation,
589 inferred_type: inferred,
590 source_span: span,
591 },
592 ExprKind::Unwrap { expr: inner } => Expr::Unwrap {
593 expr: Box::new(rebuild_expr(*inner, arena, types)),
594 type_annotation: annotation,
595 inferred_type: inferred,
596 source_span: span,
597 },
598 ExprKind::GetTag { expr: inner } => Expr::GetTag {
599 expr: Box::new(rebuild_expr(*inner, arena, types)),
600 type_annotation: annotation,
601 inferred_type: inferred,
602 source_span: span,
603 },
604 ExprKind::GreaterThan { lhs, rhs } => Expr::GreaterThan {
605 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
606 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
607 type_annotation: annotation,
608 inferred_type: inferred,
609 source_span: span,
610 },
611 ExprKind::GreaterThanOrEqualTo { lhs, rhs } => Expr::GreaterThanOrEqualTo {
612 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
613 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
614 type_annotation: annotation,
615 inferred_type: inferred,
616 source_span: span,
617 },
618 ExprKind::LessThanOrEqualTo { lhs, rhs } => Expr::LessThanOrEqualTo {
619 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
620 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
621 type_annotation: annotation,
622 inferred_type: inferred,
623 source_span: span,
624 },
625 ExprKind::EqualTo { lhs, rhs } => Expr::EqualTo {
626 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
627 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
628 type_annotation: annotation,
629 inferred_type: inferred,
630 source_span: span,
631 },
632 ExprKind::LessThan { lhs, rhs } => Expr::LessThan {
633 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
634 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
635 type_annotation: annotation,
636 inferred_type: inferred,
637 source_span: span,
638 },
639 ExprKind::And { lhs, rhs } => Expr::And {
640 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
641 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
642 type_annotation: annotation,
643 inferred_type: inferred,
644 source_span: span,
645 },
646 ExprKind::Or { lhs, rhs } => Expr::Or {
647 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
648 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
649 type_annotation: annotation,
650 inferred_type: inferred,
651 source_span: span,
652 },
653 ExprKind::Plus { lhs, rhs } => Expr::Plus {
654 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
655 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
656 type_annotation: annotation,
657 inferred_type: inferred,
658 source_span: span,
659 },
660 ExprKind::Minus { lhs, rhs } => Expr::Minus {
661 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
662 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
663 type_annotation: annotation,
664 inferred_type: inferred,
665 source_span: span,
666 },
667 ExprKind::Multiply { lhs, rhs } => Expr::Multiply {
668 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
669 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
670 type_annotation: annotation,
671 inferred_type: inferred,
672 source_span: span,
673 },
674 ExprKind::Divide { lhs, rhs } => Expr::Divide {
675 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
676 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
677 type_annotation: annotation,
678 inferred_type: inferred,
679 source_span: span,
680 },
681 ExprKind::Cond { cond, lhs, rhs } => Expr::Cond {
682 cond: Box::new(rebuild_expr(*cond, arena, types)),
683 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
684 rhs: Box::new(rebuild_expr(*rhs, arena, types)),
685 type_annotation: annotation,
686 inferred_type: inferred,
687 source_span: span,
688 },
689 ExprKind::PatternMatch {
690 predicate,
691 match_arms,
692 } => Expr::PatternMatch {
693 predicate: Box::new(rebuild_expr(*predicate, arena, types)),
694 match_arms: match_arms
695 .iter()
696 .map(|arm| crate::expr::MatchArm {
697 arm_pattern: rebuild_arm_pattern(arm.arm_pattern, arena, types),
698 arm_resolution_expr: Box::new(rebuild_expr(
699 arm.arm_resolution_expr,
700 arena,
701 types,
702 )),
703 })
704 .collect(),
705 type_annotation: annotation,
706 inferred_type: inferred,
707 source_span: span,
708 },
709 ExprKind::Option { expr: None } => Expr::Option {
710 expr: None,
711 type_annotation: annotation,
712 inferred_type: inferred,
713 source_span: span,
714 },
715 ExprKind::Option { expr: Some(inner) } => Expr::Option {
716 expr: Some(Box::new(rebuild_expr(*inner, arena, types))),
717 type_annotation: annotation,
718 inferred_type: inferred,
719 source_span: span,
720 },
721 ExprKind::Result {
722 expr: ResultExprKind::Ok(inner),
723 } => Expr::Result {
724 expr: Ok(Box::new(rebuild_expr(*inner, arena, types))),
725 type_annotation: annotation,
726 inferred_type: inferred,
727 source_span: span,
728 },
729 ExprKind::Result {
730 expr: ResultExprKind::Err(inner),
731 } => Expr::Result {
732 expr: Err(Box::new(rebuild_expr(*inner, arena, types))),
733 type_annotation: annotation,
734 inferred_type: inferred,
735 source_span: span,
736 },
737 ExprKind::Call { call_type, args } => {
738 let old_call_type = rebuild_call_type(call_type, arena, types);
739 Expr::Call {
740 call_type: old_call_type,
741 args: args
742 .iter()
743 .map(|&a| rebuild_expr(a, arena, types))
744 .collect(),
745 type_annotation: annotation,
746 inferred_type: inferred,
747 source_span: span,
748 }
749 }
750 ExprKind::InvokeMethodLazy { lhs, method, args } => Expr::InvokeMethodLazy {
751 lhs: Box::new(rebuild_expr(*lhs, arena, types)),
752 method: method.clone(),
753 args: args
754 .iter()
755 .map(|&a| rebuild_expr(a, arena, types))
756 .collect(),
757 type_annotation: annotation,
758 inferred_type: inferred,
759 source_span: span,
760 },
761 ExprKind::Throw { message } => Expr::Throw {
762 message: message.clone(),
763 type_annotation: annotation,
764 inferred_type: inferred,
765 source_span: span,
766 },
767 ExprKind::ListComprehension {
768 iterated_variable,
769 iterable_expr,
770 yield_expr,
771 } => Expr::ListComprehension {
772 iterated_variable: iterated_variable.clone(),
773 iterable_expr: Box::new(rebuild_expr(*iterable_expr, arena, types)),
774 yield_expr: Box::new(rebuild_expr(*yield_expr, arena, types)),
775 type_annotation: annotation,
776 inferred_type: inferred,
777 source_span: span,
778 },
779 ExprKind::ListReduce {
780 reduce_variable,
781 iterated_variable,
782 iterable_expr,
783 init_value_expr,
784 yield_expr,
785 } => Expr::ListReduce {
786 reduce_variable: reduce_variable.clone(),
787 iterated_variable: iterated_variable.clone(),
788 iterable_expr: Box::new(rebuild_expr(*iterable_expr, arena, types)),
789 init_value_expr: Box::new(rebuild_expr(*init_value_expr, arena, types)),
790 yield_expr: Box::new(rebuild_expr(*yield_expr, arena, types)),
791 type_annotation: annotation,
792 inferred_type: inferred,
793 source_span: span,
794 },
795 ExprKind::GenerateWorkerName { variable_id } => Expr::GenerateWorkerName {
796 variable_id: variable_id.clone(),
797 type_annotation: annotation,
798 inferred_type: inferred,
799 source_span: span,
800 },
801 }
802}
803
804pub(crate) fn rebuild_arm_pattern(
805 pat_id: ArmPatternId,
806 arena: &ExprArena,
807 types: &TypeTable,
808) -> crate::expr::ArmPattern {
809 match arena.pattern(pat_id) {
810 ArmPatternNode::WildCard => crate::expr::ArmPattern::WildCard,
811 ArmPatternNode::As(name, inner) => {
812 let inner = *inner;
813 crate::expr::ArmPattern::As(
814 name.clone(),
815 Box::new(rebuild_arm_pattern(inner, arena, types)),
816 )
817 }
818 ArmPatternNode::Literal(expr_id) => {
819 crate::expr::ArmPattern::Literal(Box::new(rebuild_expr(*expr_id, arena, types)))
820 }
821 ArmPatternNode::Constructor(name, children) => {
822 let children = children.clone();
823 crate::expr::ArmPattern::Constructor(
824 name.clone(),
825 children
826 .iter()
827 .map(|&c| rebuild_arm_pattern(c, arena, types))
828 .collect(),
829 )
830 }
831 ArmPatternNode::TupleConstructor(children) => {
832 let children = children.clone();
833 crate::expr::ArmPattern::TupleConstructor(
834 children
835 .iter()
836 .map(|&c| rebuild_arm_pattern(c, arena, types))
837 .collect(),
838 )
839 }
840 ArmPatternNode::ListConstructor(children) => {
841 let children = children.clone();
842 crate::expr::ArmPattern::ListConstructor(
843 children
844 .iter()
845 .map(|&c| rebuild_arm_pattern(c, arena, types))
846 .collect(),
847 )
848 }
849 ArmPatternNode::RecordConstructor(fields) => {
850 let fields = fields.clone();
851 crate::expr::ArmPattern::RecordConstructor(
852 fields
853 .iter()
854 .map(|(name, c)| (name.clone(), rebuild_arm_pattern(*c, arena, types)))
855 .collect(),
856 )
857 }
858 }
859}
860
861pub(crate) fn rebuild_call_type(
862 call_type: &CallTypeNode,
863 arena: &ExprArena,
864 types: &TypeTable,
865) -> crate::call_type::CallType {
866 use crate::call_type::{CallType, InstanceCreationType};
867 match call_type {
868 CallTypeNode::Function {
869 component_info,
870 instance_identifier,
871 function_name,
872 } => CallType::Function {
873 component_info: component_info.clone(),
874 instance_identifier: instance_identifier
875 .as_ref()
876 .map(|ii| Box::new(rebuild_instance_identifier(ii, arena, types))),
877 function_name: function_name.clone(),
878 },
879 CallTypeNode::VariantConstructor(name) => CallType::VariantConstructor(name.clone()),
880 CallTypeNode::EnumConstructor(name) => CallType::EnumConstructor(name.clone()),
881 CallTypeNode::InstanceCreation(creation) => {
882 let ict = match creation {
883 InstanceCreationNode::WitWorker {
884 component_info,
885 worker_name,
886 } => InstanceCreationType::WitWorker {
887 component_info: component_info.clone(),
888 worker_name: worker_name
889 .map(|wn_id| Box::new(rebuild_expr(wn_id, arena, types))),
890 },
891 InstanceCreationNode::WitResource {
892 component_info,
893 module,
894 resource_name,
895 } => InstanceCreationType::WitResource {
896 component_info: component_info.clone(),
897 module: module
898 .as_ref()
899 .map(|m| rebuild_instance_identifier(m, arena, types)),
900 resource_name: resource_name.clone(),
901 },
902 };
903 CallType::InstanceCreation(ict)
904 }
905 }
906}
907
908fn rebuild_instance_identifier(
909 ii: &InstanceIdentifierNode,
910 arena: &ExprArena,
911 types: &TypeTable,
912) -> crate::call_type::InstanceIdentifier {
913 use crate::call_type::InstanceIdentifier;
914 match ii {
915 InstanceIdentifierNode::WitWorker {
916 variable_id,
917 worker_name,
918 } => InstanceIdentifier::WitWorker {
919 variable_id: variable_id.clone(),
920 worker_name: worker_name.map(|wn_id| Box::new(rebuild_expr(wn_id, arena, types))),
921 },
922 InstanceIdentifierNode::WitResource {
923 variable_id,
924 worker_name,
925 resource_name,
926 } => InstanceIdentifier::WitResource {
927 variable_id: variable_id.clone(),
928 worker_name: worker_name.map(|wn_id| Box::new(rebuild_expr(wn_id, arena, types))),
929 resource_name: resource_name.clone(),
930 },
931 }
932}
933
934fn lower_expr(expr: &Expr, arena: &mut ExprArena, types: &mut TypeTable) -> ExprId {
935 let (kind, span, annotation, inferred) = match expr {
936 Expr::Let {
937 variable_id,
938 type_annotation,
939 expr,
940 inferred_type,
941 source_span,
942 } => {
943 let child = lower_expr(expr, arena, types);
944 (
945 ExprKind::Let {
946 variable_id: variable_id.clone(),
947 expr: child,
948 },
949 source_span.clone(),
950 type_annotation.clone(),
951 inferred_type.clone(),
952 )
953 }
954
955 Expr::SelectField {
956 expr,
957 field,
958 type_annotation,
959 inferred_type,
960 source_span,
961 } => {
962 let child = lower_expr(expr, arena, types);
963 (
964 ExprKind::SelectField {
965 expr: child,
966 field: field.clone(),
967 },
968 source_span.clone(),
969 type_annotation.clone(),
970 inferred_type.clone(),
971 )
972 }
973
974 Expr::SelectIndex {
975 expr,
976 index,
977 type_annotation,
978 inferred_type,
979 source_span,
980 } => {
981 let e = lower_expr(expr, arena, types);
982 let i = lower_expr(index, arena, types);
983 (
984 ExprKind::SelectIndex { expr: e, index: i },
985 source_span.clone(),
986 type_annotation.clone(),
987 inferred_type.clone(),
988 )
989 }
990
991 Expr::Sequence {
992 exprs,
993 type_annotation,
994 inferred_type,
995 source_span,
996 } => {
997 let ids = exprs.iter().map(|e| lower_expr(e, arena, types)).collect();
998 (
999 ExprKind::Sequence { exprs: ids },
1000 source_span.clone(),
1001 type_annotation.clone(),
1002 inferred_type.clone(),
1003 )
1004 }
1005
1006 Expr::Range {
1007 range,
1008 type_annotation,
1009 inferred_type,
1010 source_span,
1011 } => {
1012 let range_kind = lower_range(range, arena, types);
1013 (
1014 ExprKind::Range { range: range_kind },
1015 source_span.clone(),
1016 type_annotation.clone(),
1017 inferred_type.clone(),
1018 )
1019 }
1020
1021 Expr::Record {
1022 exprs,
1023 type_annotation,
1024 inferred_type,
1025 source_span,
1026 } => {
1027 let fields = exprs
1028 .iter()
1029 .map(|(name, e)| (name.clone(), lower_expr(e, arena, types)))
1030 .collect();
1031 (
1032 ExprKind::Record { fields },
1033 source_span.clone(),
1034 type_annotation.clone(),
1035 inferred_type.clone(),
1036 )
1037 }
1038
1039 Expr::Tuple {
1040 exprs,
1041 type_annotation,
1042 inferred_type,
1043 source_span,
1044 } => {
1045 let ids = exprs.iter().map(|e| lower_expr(e, arena, types)).collect();
1046 (
1047 ExprKind::Tuple { exprs: ids },
1048 source_span.clone(),
1049 type_annotation.clone(),
1050 inferred_type.clone(),
1051 )
1052 }
1053
1054 Expr::Literal {
1055 value,
1056 type_annotation,
1057 inferred_type,
1058 source_span,
1059 } => (
1060 ExprKind::Literal {
1061 value: value.clone(),
1062 },
1063 source_span.clone(),
1064 type_annotation.clone(),
1065 inferred_type.clone(),
1066 ),
1067
1068 Expr::Number {
1069 number,
1070 type_annotation,
1071 inferred_type,
1072 source_span,
1073 } => (
1074 ExprKind::Number {
1075 number: number.clone(),
1076 },
1077 source_span.clone(),
1078 type_annotation.clone(),
1079 inferred_type.clone(),
1080 ),
1081
1082 Expr::Flags {
1083 flags,
1084 type_annotation,
1085 inferred_type,
1086 source_span,
1087 } => (
1088 ExprKind::Flags {
1089 flags: flags.clone(),
1090 },
1091 source_span.clone(),
1092 type_annotation.clone(),
1093 inferred_type.clone(),
1094 ),
1095
1096 Expr::Identifier {
1097 variable_id,
1098 type_annotation,
1099 inferred_type,
1100 source_span,
1101 } => (
1102 ExprKind::Identifier {
1103 variable_id: variable_id.clone(),
1104 },
1105 source_span.clone(),
1106 type_annotation.clone(),
1107 inferred_type.clone(),
1108 ),
1109
1110 Expr::Boolean {
1111 value,
1112 type_annotation,
1113 inferred_type,
1114 source_span,
1115 } => (
1116 ExprKind::Boolean { value: *value },
1117 source_span.clone(),
1118 type_annotation.clone(),
1119 inferred_type.clone(),
1120 ),
1121
1122 Expr::Concat {
1123 exprs,
1124 type_annotation,
1125 inferred_type,
1126 source_span,
1127 } => {
1128 let ids = exprs.iter().map(|e| lower_expr(e, arena, types)).collect();
1129 (
1130 ExprKind::Concat { exprs: ids },
1131 source_span.clone(),
1132 type_annotation.clone(),
1133 inferred_type.clone(),
1134 )
1135 }
1136
1137 Expr::ExprBlock {
1138 exprs,
1139 type_annotation,
1140 inferred_type,
1141 source_span,
1142 } => {
1143 let ids = exprs.iter().map(|e| lower_expr(e, arena, types)).collect();
1144 (
1145 ExprKind::ExprBlock { exprs: ids },
1146 source_span.clone(),
1147 type_annotation.clone(),
1148 inferred_type.clone(),
1149 )
1150 }
1151
1152 Expr::Not {
1153 expr,
1154 type_annotation,
1155 inferred_type,
1156 source_span,
1157 } => {
1158 let child = lower_expr(expr, arena, types);
1159 (
1160 ExprKind::Not { expr: child },
1161 source_span.clone(),
1162 type_annotation.clone(),
1163 inferred_type.clone(),
1164 )
1165 }
1166
1167 Expr::GreaterThan {
1168 lhs,
1169 rhs,
1170 type_annotation,
1171 inferred_type,
1172 source_span,
1173 } => {
1174 let l = lower_expr(lhs, arena, types);
1175 let r = lower_expr(rhs, arena, types);
1176 (
1177 ExprKind::GreaterThan { lhs: l, rhs: r },
1178 source_span.clone(),
1179 type_annotation.clone(),
1180 inferred_type.clone(),
1181 )
1182 }
1183
1184 Expr::GreaterThanOrEqualTo {
1185 lhs,
1186 rhs,
1187 type_annotation,
1188 inferred_type,
1189 source_span,
1190 } => {
1191 let l = lower_expr(lhs, arena, types);
1192 let r = lower_expr(rhs, arena, types);
1193 (
1194 ExprKind::GreaterThanOrEqualTo { lhs: l, rhs: r },
1195 source_span.clone(),
1196 type_annotation.clone(),
1197 inferred_type.clone(),
1198 )
1199 }
1200
1201 Expr::LessThanOrEqualTo {
1202 lhs,
1203 rhs,
1204 type_annotation,
1205 inferred_type,
1206 source_span,
1207 } => {
1208 let l = lower_expr(lhs, arena, types);
1209 let r = lower_expr(rhs, arena, types);
1210 (
1211 ExprKind::LessThanOrEqualTo { lhs: l, rhs: r },
1212 source_span.clone(),
1213 type_annotation.clone(),
1214 inferred_type.clone(),
1215 )
1216 }
1217
1218 Expr::EqualTo {
1219 lhs,
1220 rhs,
1221 type_annotation,
1222 inferred_type,
1223 source_span,
1224 } => {
1225 let l = lower_expr(lhs, arena, types);
1226 let r = lower_expr(rhs, arena, types);
1227 (
1228 ExprKind::EqualTo { lhs: l, rhs: r },
1229 source_span.clone(),
1230 type_annotation.clone(),
1231 inferred_type.clone(),
1232 )
1233 }
1234
1235 Expr::LessThan {
1236 lhs,
1237 rhs,
1238 type_annotation,
1239 inferred_type,
1240 source_span,
1241 } => {
1242 let l = lower_expr(lhs, arena, types);
1243 let r = lower_expr(rhs, arena, types);
1244 (
1245 ExprKind::LessThan { lhs: l, rhs: r },
1246 source_span.clone(),
1247 type_annotation.clone(),
1248 inferred_type.clone(),
1249 )
1250 }
1251
1252 Expr::And {
1253 lhs,
1254 rhs,
1255 type_annotation,
1256 inferred_type,
1257 source_span,
1258 } => {
1259 let l = lower_expr(lhs, arena, types);
1260 let r = lower_expr(rhs, arena, types);
1261 (
1262 ExprKind::And { lhs: l, rhs: r },
1263 source_span.clone(),
1264 type_annotation.clone(),
1265 inferred_type.clone(),
1266 )
1267 }
1268
1269 Expr::Or {
1270 lhs,
1271 rhs,
1272 type_annotation,
1273 inferred_type,
1274 source_span,
1275 } => {
1276 let l = lower_expr(lhs, arena, types);
1277 let r = lower_expr(rhs, arena, types);
1278 (
1279 ExprKind::Or { lhs: l, rhs: r },
1280 source_span.clone(),
1281 type_annotation.clone(),
1282 inferred_type.clone(),
1283 )
1284 }
1285
1286 Expr::Plus {
1287 lhs,
1288 rhs,
1289 type_annotation,
1290 inferred_type,
1291 source_span,
1292 } => {
1293 let l = lower_expr(lhs, arena, types);
1294 let r = lower_expr(rhs, arena, types);
1295 (
1296 ExprKind::Plus { lhs: l, rhs: r },
1297 source_span.clone(),
1298 type_annotation.clone(),
1299 inferred_type.clone(),
1300 )
1301 }
1302
1303 Expr::Minus {
1304 lhs,
1305 rhs,
1306 type_annotation,
1307 inferred_type,
1308 source_span,
1309 } => {
1310 let l = lower_expr(lhs, arena, types);
1311 let r = lower_expr(rhs, arena, types);
1312 (
1313 ExprKind::Minus { lhs: l, rhs: r },
1314 source_span.clone(),
1315 type_annotation.clone(),
1316 inferred_type.clone(),
1317 )
1318 }
1319
1320 Expr::Multiply {
1321 lhs,
1322 rhs,
1323 type_annotation,
1324 inferred_type,
1325 source_span,
1326 } => {
1327 let l = lower_expr(lhs, arena, types);
1328 let r = lower_expr(rhs, arena, types);
1329 (
1330 ExprKind::Multiply { lhs: l, rhs: r },
1331 source_span.clone(),
1332 type_annotation.clone(),
1333 inferred_type.clone(),
1334 )
1335 }
1336
1337 Expr::Divide {
1338 lhs,
1339 rhs,
1340 type_annotation,
1341 inferred_type,
1342 source_span,
1343 } => {
1344 let l = lower_expr(lhs, arena, types);
1345 let r = lower_expr(rhs, arena, types);
1346 (
1347 ExprKind::Divide { lhs: l, rhs: r },
1348 source_span.clone(),
1349 type_annotation.clone(),
1350 inferred_type.clone(),
1351 )
1352 }
1353
1354 Expr::Cond {
1355 cond,
1356 lhs,
1357 rhs,
1358 type_annotation,
1359 inferred_type,
1360 source_span,
1361 } => {
1362 let c = lower_expr(cond, arena, types);
1363 let l = lower_expr(lhs, arena, types);
1364 let r = lower_expr(rhs, arena, types);
1365 (
1366 ExprKind::Cond {
1367 cond: c,
1368 lhs: l,
1369 rhs: r,
1370 },
1371 source_span.clone(),
1372 type_annotation.clone(),
1373 inferred_type.clone(),
1374 )
1375 }
1376
1377 Expr::PatternMatch {
1378 predicate,
1379 match_arms,
1380 type_annotation,
1381 inferred_type,
1382 source_span,
1383 } => {
1384 let pred = lower_expr(predicate, arena, types);
1385 let arms = match_arms
1386 .iter()
1387 .map(|arm| lower_match_arm(arm, arena, types))
1388 .collect();
1389 (
1390 ExprKind::PatternMatch {
1391 predicate: pred,
1392 match_arms: arms,
1393 },
1394 source_span.clone(),
1395 type_annotation.clone(),
1396 inferred_type.clone(),
1397 )
1398 }
1399
1400 Expr::Option {
1401 expr,
1402 type_annotation,
1403 inferred_type,
1404 source_span,
1405 } => {
1406 let child = expr.as_ref().map(|e| lower_expr(e, arena, types));
1407 (
1408 ExprKind::Option { expr: child },
1409 source_span.clone(),
1410 type_annotation.clone(),
1411 inferred_type.clone(),
1412 )
1413 }
1414
1415 Expr::Result {
1416 expr,
1417 type_annotation,
1418 inferred_type,
1419 source_span,
1420 } => {
1421 let kind = match expr {
1422 Ok(e) => ResultExprKind::Ok(lower_expr(e, arena, types)),
1423 Err(e) => ResultExprKind::Err(lower_expr(e, arena, types)),
1424 };
1425 (
1426 ExprKind::Result { expr: kind },
1427 source_span.clone(),
1428 type_annotation.clone(),
1429 inferred_type.clone(),
1430 )
1431 }
1432
1433 Expr::Call {
1434 call_type,
1435 args,
1436 type_annotation,
1437 inferred_type,
1438 source_span,
1439 } => {
1440 let call_node = lower_call_type(call_type, arena, types);
1441 let arg_ids = args.iter().map(|a| lower_expr(a, arena, types)).collect();
1442 (
1443 ExprKind::Call {
1444 call_type: call_node,
1445 args: arg_ids,
1446 },
1447 source_span.clone(),
1448 type_annotation.clone(),
1449 inferred_type.clone(),
1450 )
1451 }
1452
1453 Expr::InvokeMethodLazy {
1454 lhs,
1455 method,
1456 args,
1457 type_annotation,
1458 inferred_type,
1459 source_span,
1460 } => {
1461 let lhs_id = lower_expr(lhs, arena, types);
1462 let arg_ids = args.iter().map(|a| lower_expr(a, arena, types)).collect();
1463 (
1464 ExprKind::InvokeMethodLazy {
1465 lhs: lhs_id,
1466 method: method.clone(),
1467 args: arg_ids,
1468 },
1469 source_span.clone(),
1470 type_annotation.clone(),
1471 inferred_type.clone(),
1472 )
1473 }
1474
1475 Expr::Unwrap {
1476 expr,
1477 type_annotation,
1478 inferred_type,
1479 source_span,
1480 } => {
1481 let child = lower_expr(expr, arena, types);
1482 (
1483 ExprKind::Unwrap { expr: child },
1484 source_span.clone(),
1485 type_annotation.clone(),
1486 inferred_type.clone(),
1487 )
1488 }
1489
1490 Expr::Throw {
1491 message,
1492 type_annotation,
1493 inferred_type,
1494 source_span,
1495 } => (
1496 ExprKind::Throw {
1497 message: message.clone(),
1498 },
1499 source_span.clone(),
1500 type_annotation.clone(),
1501 inferred_type.clone(),
1502 ),
1503
1504 Expr::GetTag {
1505 expr,
1506 type_annotation,
1507 inferred_type,
1508 source_span,
1509 } => {
1510 let child = lower_expr(expr, arena, types);
1511 (
1512 ExprKind::GetTag { expr: child },
1513 source_span.clone(),
1514 type_annotation.clone(),
1515 inferred_type.clone(),
1516 )
1517 }
1518
1519 Expr::ListComprehension {
1520 iterated_variable,
1521 iterable_expr,
1522 yield_expr,
1523 type_annotation,
1524 inferred_type,
1525 source_span,
1526 } => {
1527 let iterable = lower_expr(iterable_expr, arena, types);
1528 let yield_ = lower_expr(yield_expr, arena, types);
1529 (
1530 ExprKind::ListComprehension {
1531 iterated_variable: iterated_variable.clone(),
1532 iterable_expr: iterable,
1533 yield_expr: yield_,
1534 },
1535 source_span.clone(),
1536 type_annotation.clone(),
1537 inferred_type.clone(),
1538 )
1539 }
1540
1541 Expr::ListReduce {
1542 reduce_variable,
1543 iterated_variable,
1544 iterable_expr,
1545 init_value_expr,
1546 yield_expr,
1547 type_annotation,
1548 inferred_type,
1549 source_span,
1550 } => {
1551 let iterable = lower_expr(iterable_expr, arena, types);
1552 let init = lower_expr(init_value_expr, arena, types);
1553 let yield_ = lower_expr(yield_expr, arena, types);
1554 (
1555 ExprKind::ListReduce {
1556 reduce_variable: reduce_variable.clone(),
1557 iterated_variable: iterated_variable.clone(),
1558 iterable_expr: iterable,
1559 init_value_expr: init,
1560 yield_expr: yield_,
1561 },
1562 source_span.clone(),
1563 type_annotation.clone(),
1564 inferred_type.clone(),
1565 )
1566 }
1567
1568 Expr::Length {
1569 expr,
1570 type_annotation,
1571 inferred_type,
1572 source_span,
1573 } => {
1574 let child = lower_expr(expr, arena, types);
1575 (
1576 ExprKind::Length { expr: child },
1577 source_span.clone(),
1578 type_annotation.clone(),
1579 inferred_type.clone(),
1580 )
1581 }
1582
1583 Expr::GenerateWorkerName {
1584 variable_id,
1585 type_annotation,
1586 inferred_type,
1587 source_span,
1588 } => (
1589 ExprKind::GenerateWorkerName {
1590 variable_id: variable_id.clone(),
1591 },
1592 source_span.clone(),
1593 type_annotation.clone(),
1594 inferred_type.clone(),
1595 ),
1596 };
1597
1598 let id = arena.alloc_expr(ExprNode {
1599 kind,
1600 source_span: span,
1601 type_annotation: annotation,
1602 });
1603 types.set(id, inferred);
1604 id
1605}
1606
1607fn lower_range(range: &Range, arena: &mut ExprArena, types: &mut TypeTable) -> RangeKind {
1608 match range {
1609 Range::Range { from, to } => RangeKind::Range {
1610 from: lower_expr(from, arena, types),
1611 to: lower_expr(to, arena, types),
1612 },
1613 Range::RangeInclusive { from, to } => RangeKind::RangeInclusive {
1614 from: lower_expr(from, arena, types),
1615 to: lower_expr(to, arena, types),
1616 },
1617 Range::RangeFrom { from } => RangeKind::RangeFrom {
1618 from: lower_expr(from, arena, types),
1619 },
1620 }
1621}
1622
1623fn lower_match_arm(arm: &MatchArm, arena: &mut ExprArena, types: &mut TypeTable) -> MatchArmNode {
1624 let pattern_id = lower_arm_pattern(&arm.arm_pattern, arena, types);
1625 let resolution_id = lower_expr(&arm.arm_resolution_expr, arena, types);
1626 MatchArmNode {
1627 arm_pattern: pattern_id,
1628 arm_resolution_expr: resolution_id,
1629 }
1630}
1631
1632fn lower_arm_pattern(
1633 pattern: &ArmPattern,
1634 arena: &mut ExprArena,
1635 types: &mut TypeTable,
1636) -> ArmPatternId {
1637 let node = match pattern {
1638 ArmPattern::WildCard => ArmPatternNode::WildCard,
1639
1640 ArmPattern::As(name, inner) => {
1641 let inner_id = lower_arm_pattern(inner, arena, types);
1642 ArmPatternNode::As(name.clone(), inner_id)
1643 }
1644
1645 ArmPattern::Constructor(name, patterns) => {
1646 let ids = patterns
1647 .iter()
1648 .map(|p| lower_arm_pattern(p, arena, types))
1649 .collect();
1650 ArmPatternNode::Constructor(name.clone(), ids)
1651 }
1652
1653 ArmPattern::TupleConstructor(patterns) => {
1654 let ids = patterns
1655 .iter()
1656 .map(|p| lower_arm_pattern(p, arena, types))
1657 .collect();
1658 ArmPatternNode::TupleConstructor(ids)
1659 }
1660
1661 ArmPattern::RecordConstructor(fields) => {
1662 let pairs = fields
1663 .iter()
1664 .map(|(name, p)| (name.clone(), lower_arm_pattern(p, arena, types)))
1665 .collect();
1666 ArmPatternNode::RecordConstructor(pairs)
1667 }
1668
1669 ArmPattern::ListConstructor(patterns) => {
1670 let ids = patterns
1671 .iter()
1672 .map(|p| lower_arm_pattern(p, arena, types))
1673 .collect();
1674 ArmPatternNode::ListConstructor(ids)
1675 }
1676
1677 ArmPattern::Literal(expr) => {
1678 let expr_id = lower_expr(expr, arena, types);
1679 ArmPatternNode::Literal(expr_id)
1680 }
1681 };
1682
1683 arena.alloc_pattern(node)
1684}
1685
1686fn lower_call_type(
1687 call_type: &CallType,
1688 arena: &mut ExprArena,
1689 types: &mut TypeTable,
1690) -> CallTypeNode {
1691 match call_type {
1692 CallType::Function {
1693 component_info,
1694 instance_identifier,
1695 function_name,
1696 } => CallTypeNode::Function {
1697 component_info: component_info.clone(),
1698 instance_identifier: instance_identifier
1699 .as_ref()
1700 .map(|ii| lower_instance_identifier(ii, arena, types)),
1701 function_name: function_name.clone(),
1702 },
1703
1704 CallType::VariantConstructor(name) => CallTypeNode::VariantConstructor(name.clone()),
1705 CallType::EnumConstructor(name) => CallTypeNode::EnumConstructor(name.clone()),
1706
1707 CallType::InstanceCreation(creation) => {
1708 CallTypeNode::InstanceCreation(lower_instance_creation(creation, arena, types))
1709 }
1710 }
1711}
1712
1713fn lower_instance_identifier(
1714 ii: &InstanceIdentifier,
1715 arena: &mut ExprArena,
1716 types: &mut TypeTable,
1717) -> InstanceIdentifierNode {
1718 match ii {
1719 InstanceIdentifier::WitWorker {
1720 variable_id,
1721 worker_name,
1722 } => InstanceIdentifierNode::WitWorker {
1723 variable_id: variable_id.clone(),
1724 worker_name: worker_name
1725 .as_ref()
1726 .map(|wn| lower_expr(wn.as_ref(), arena, types)),
1727 },
1728 InstanceIdentifier::WitResource {
1729 variable_id,
1730 worker_name,
1731 resource_name,
1732 } => InstanceIdentifierNode::WitResource {
1733 variable_id: variable_id.clone(),
1734 worker_name: worker_name
1735 .as_ref()
1736 .map(|wn| lower_expr(wn.as_ref(), arena, types)),
1737 resource_name: resource_name.clone(),
1738 },
1739 }
1740}
1741
1742fn lower_instance_creation(
1743 creation: &InstanceCreationType,
1744 arena: &mut ExprArena,
1745 types: &mut TypeTable,
1746) -> InstanceCreationNode {
1747 match creation {
1748 InstanceCreationType::WitWorker {
1749 component_info,
1750 worker_name,
1751 } => InstanceCreationNode::WitWorker {
1752 component_info: component_info.clone(),
1753 worker_name: worker_name
1754 .as_ref()
1755 .map(|wn| lower_expr(wn.as_ref(), arena, types)),
1756 },
1757 InstanceCreationType::WitResource {
1758 component_info,
1759 module,
1760 resource_name,
1761 } => InstanceCreationNode::WitResource {
1762 component_info: component_info.clone(),
1763 module: module
1764 .as_ref()
1765 .map(|m| lower_instance_identifier(m, arena, types)),
1766 resource_name: resource_name.clone(),
1767 },
1768 }
1769}
1770
1771#[cfg(test)]
1776mod tests {
1777 use test_r::test;
1778
1779 use super::*;
1780 use crate::Expr;
1781
1782 #[test]
1783 fn test_lower_literal() {
1784 let expr = Expr::from_text(r#""hello""#).unwrap();
1785 let (arena, types, root) = lower(&expr);
1786 let node = arena.expr(root);
1787 assert!(matches!(node.kind, ExprKind::Literal { .. }));
1788 assert!(types.get_opt(root).is_some());
1790 }
1791
1792 #[test]
1793 fn test_lower_let_binding() {
1794 let expr = Expr::from_text("let x = 1; x").unwrap();
1795 let (arena, types, root) = lower(&expr);
1796 let node = arena.expr(root);
1798 assert!(matches!(node.kind, ExprKind::ExprBlock { .. }));
1799 for (id, _) in arena.exprs.iter() {
1801 assert!(types.get_opt(id).is_some(), "missing type for expr node");
1802 }
1803 }
1804
1805 #[test]
1806 fn test_lower_pattern_match() {
1807 let src = r#"
1808 let x = some("hello");
1809 match x {
1810 some(v) => v,
1811 none => "default"
1812 }
1813 "#;
1814 let expr = Expr::from_text(src).unwrap();
1815 let (arena, types, root) = lower(&expr);
1816 for (id, _) in arena.exprs.iter() {
1818 assert!(types.get_opt(id).is_some());
1819 }
1820 assert!(arena.patterns.iter().count() > 0);
1822 let _ = root;
1823 }
1824
1825 #[test]
1826 fn test_type_table_snapshot_and_same_as() {
1827 let expr = Expr::from_text(r#"1 + 2"#).unwrap();
1828 let (_arena, types, _root) = lower(&expr);
1829 let snap = types.snapshot();
1830 let mut reconstructed = TypeTable::new();
1832 for (id, ty) in snap {
1833 reconstructed.set(id, ty);
1834 }
1835 assert!(types.same_as(&reconstructed));
1836 }
1837
1838 #[test]
1839 fn test_node_count_matches() {
1840 let expr = Expr::from_text(r#"1"#).unwrap();
1842 let (arena, types, _root) = lower(&expr);
1843 assert_eq!(arena.exprs.iter().count(), types.snapshot().len());
1844 }
1845}