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