Skip to main content

rib/
expr.rs

1use crate::call_type::CallType;
2use crate::inferred_type::DefaultType;
3use crate::parser::block::block;
4use crate::parser::type_name::TypeName;
5use crate::rib_source_span::SourceSpan;
6use crate::rib_type_error::RibTypeErrorInternal;
7use crate::type_inference as ti;
8use crate::wit_type::WitType;
9use crate::{
10    from_string, text, type_checker, type_inference, ComponentDependency, ComponentDependencyKey,
11    CustomInstanceSpec, DynamicParsedFunctionName, GlobalVariableTypeSpec, InferredType,
12    InstanceIdentifier, VariableId,
13};
14use crate::{IntoValueAndType, ValueAndType};
15use bigdecimal::{BigDecimal, ToPrimitive};
16use combine::parser::char::spaces;
17use combine::stream::position;
18use combine::Parser;
19use combine::{eof, EasyParser};
20use serde::{Deserialize, Serialize, Serializer};
21use serde_json::Value;
22use std::collections::VecDeque;
23use std::fmt::Display;
24use std::ops::Deref;
25use std::sync::Arc;
26
27#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
28pub enum Expr {
29    Let {
30        variable_id: VariableId,
31        type_annotation: Option<TypeName>,
32        expr: Box<Expr>,
33        inferred_type: InferredType,
34        source_span: SourceSpan,
35    },
36    SelectField {
37        expr: Box<Expr>,
38        field: String,
39        type_annotation: Option<TypeName>,
40        inferred_type: InferredType,
41        source_span: SourceSpan,
42    },
43    SelectIndex {
44        expr: Box<Expr>,
45        index: Box<Expr>,
46        type_annotation: Option<TypeName>,
47        inferred_type: InferredType,
48        source_span: SourceSpan,
49    },
50    Sequence {
51        exprs: Vec<Expr>,
52        type_annotation: Option<TypeName>,
53        inferred_type: InferredType,
54        source_span: SourceSpan,
55    },
56    Range {
57        range: Range,
58        type_annotation: Option<TypeName>,
59        inferred_type: InferredType,
60        source_span: SourceSpan,
61    },
62    Record {
63        exprs: Vec<(String, Box<Expr>)>,
64        type_annotation: Option<TypeName>,
65        inferred_type: InferredType,
66        source_span: SourceSpan,
67    },
68    Tuple {
69        exprs: Vec<Expr>,
70        type_annotation: Option<TypeName>,
71        inferred_type: InferredType,
72        source_span: SourceSpan,
73    },
74    Literal {
75        value: String,
76        type_annotation: Option<TypeName>,
77        inferred_type: InferredType,
78        source_span: SourceSpan,
79    },
80    Number {
81        number: Number,
82        type_annotation: Option<TypeName>,
83        inferred_type: InferredType,
84        source_span: SourceSpan,
85    },
86    Flags {
87        flags: Vec<String>,
88        type_annotation: Option<TypeName>,
89        inferred_type: InferredType,
90        source_span: SourceSpan,
91    },
92    Identifier {
93        variable_id: VariableId,
94        type_annotation: Option<TypeName>,
95        inferred_type: InferredType,
96        source_span: SourceSpan,
97    },
98    Boolean {
99        value: bool,
100        type_annotation: Option<TypeName>,
101        inferred_type: InferredType,
102        source_span: SourceSpan,
103    },
104    Concat {
105        exprs: Vec<Expr>,
106        type_annotation: Option<TypeName>,
107        inferred_type: InferredType,
108        source_span: SourceSpan,
109    },
110    ExprBlock {
111        exprs: Vec<Expr>,
112        type_annotation: Option<TypeName>,
113        inferred_type: InferredType,
114        source_span: SourceSpan,
115    },
116    Not {
117        expr: Box<Expr>,
118        inferred_type: InferredType,
119        type_annotation: Option<TypeName>,
120        source_span: SourceSpan,
121    },
122    GreaterThan {
123        lhs: Box<Expr>,
124        rhs: Box<Expr>,
125        type_annotation: Option<TypeName>,
126        inferred_type: InferredType,
127        source_span: SourceSpan,
128    },
129    And {
130        lhs: Box<Expr>,
131        rhs: Box<Expr>,
132        type_annotation: Option<TypeName>,
133        inferred_type: InferredType,
134        source_span: SourceSpan,
135    },
136    Or {
137        lhs: Box<Expr>,
138        rhs: Box<Expr>,
139        type_annotation: Option<TypeName>,
140        inferred_type: InferredType,
141        source_span: SourceSpan,
142    },
143    GreaterThanOrEqualTo {
144        lhs: Box<Expr>,
145        rhs: Box<Expr>,
146        type_annotation: Option<TypeName>,
147        inferred_type: InferredType,
148        source_span: SourceSpan,
149    },
150    LessThanOrEqualTo {
151        lhs: Box<Expr>,
152        rhs: Box<Expr>,
153        type_annotation: Option<TypeName>,
154        inferred_type: InferredType,
155        source_span: SourceSpan,
156    },
157    Plus {
158        lhs: Box<Expr>,
159        rhs: Box<Expr>,
160        type_annotation: Option<TypeName>,
161        inferred_type: InferredType,
162        source_span: SourceSpan,
163    },
164    Multiply {
165        lhs: Box<Expr>,
166        rhs: Box<Expr>,
167        type_annotation: Option<TypeName>,
168        inferred_type: InferredType,
169        source_span: SourceSpan,
170    },
171    Minus {
172        lhs: Box<Expr>,
173        rhs: Box<Expr>,
174        type_annotation: Option<TypeName>,
175        inferred_type: InferredType,
176        source_span: SourceSpan,
177    },
178    Divide {
179        lhs: Box<Expr>,
180        rhs: Box<Expr>,
181        type_annotation: Option<TypeName>,
182        inferred_type: InferredType,
183        source_span: SourceSpan,
184    },
185    EqualTo {
186        lhs: Box<Expr>,
187        rhs: Box<Expr>,
188        type_annotation: Option<TypeName>,
189        inferred_type: InferredType,
190        source_span: SourceSpan,
191    },
192    LessThan {
193        lhs: Box<Expr>,
194        rhs: Box<Expr>,
195        type_annotation: Option<TypeName>,
196        inferred_type: InferredType,
197        source_span: SourceSpan,
198    },
199    Cond {
200        cond: Box<Expr>,
201        lhs: Box<Expr>,
202        rhs: Box<Expr>,
203        type_annotation: Option<TypeName>,
204        inferred_type: InferredType,
205        source_span: SourceSpan,
206    },
207    PatternMatch {
208        predicate: Box<Expr>,
209        match_arms: Vec<MatchArm>,
210        type_annotation: Option<TypeName>,
211        inferred_type: InferredType,
212        source_span: SourceSpan,
213    },
214    Option {
215        expr: Option<Box<Expr>>,
216        type_annotation: Option<TypeName>,
217        inferred_type: InferredType,
218        source_span: SourceSpan,
219    },
220    Result {
221        expr: Result<Box<Expr>, Box<Expr>>,
222        type_annotation: Option<TypeName>,
223        inferred_type: InferredType,
224        source_span: SourceSpan,
225    },
226    // `instance("my-worker")` is parsed as Expr::Call { "instance", vec!["my-worker"] }.
227    // During function call inference phase, the type of this `Expr::Call` will be `Expr::Call { InstanceCreation,.. }
228    // with inferred-type as `InstanceType`. This way any variables attached to the instance creation
229    // will be having the `InstanceType`.
230    Call {
231        call_type: CallType,
232        args: Vec<Expr>,
233        type_annotation: Option<TypeName>,
234        inferred_type: InferredType,
235        source_span: SourceSpan,
236    },
237    // Any calls such as `my-worker-variable-expr.function_name()` will be parsed as Expr::Invoke
238    // such that `my-worker-variable-expr` (lhs) will be of the type `InferredType::InstanceType`. `lhs` will
239    // be `Expr::Call { InstanceCreation }` with type `InferredType::InstanceType`.
240    // As part of a separate type inference phase this will be converted back to `Expr::Call` with fully
241    // qualified function names (the complex version) which further takes part in all other type inference phases.
242    InvokeMethodLazy {
243        lhs: Box<Expr>,
244        method: String,
245        args: Vec<Expr>,
246        type_annotation: Option<TypeName>,
247        inferred_type: InferredType,
248        source_span: SourceSpan,
249    },
250    Unwrap {
251        expr: Box<Expr>,
252        inferred_type: InferredType,
253        type_annotation: Option<TypeName>,
254        source_span: SourceSpan,
255    },
256    Throw {
257        message: String,
258        inferred_type: InferredType,
259        type_annotation: Option<TypeName>,
260        source_span: SourceSpan,
261    },
262    GetTag {
263        expr: Box<Expr>,
264        inferred_type: InferredType,
265        type_annotation: Option<TypeName>,
266        source_span: SourceSpan,
267    },
268    ListComprehension {
269        iterated_variable: VariableId,
270        iterable_expr: Box<Expr>,
271        yield_expr: Box<Expr>,
272        type_annotation: Option<TypeName>,
273        inferred_type: InferredType,
274        source_span: SourceSpan,
275    },
276    ListReduce {
277        reduce_variable: VariableId,
278        iterated_variable: VariableId,
279        iterable_expr: Box<Expr>,
280        type_annotation: Option<TypeName>,
281        yield_expr: Box<Expr>,
282        init_value_expr: Box<Expr>,
283        inferred_type: InferredType,
284        source_span: SourceSpan,
285    },
286    Length {
287        expr: Box<Expr>,
288        inferred_type: InferredType,
289        type_annotation: Option<TypeName>,
290        source_span: SourceSpan,
291    },
292
293    GenerateWorkerName {
294        inferred_type: InferredType,
295        type_annotation: Option<TypeName>,
296        source_span: SourceSpan,
297        variable_id: Option<VariableId>,
298    },
299}
300
301impl Expr {
302    pub fn as_record(&self) -> Option<Vec<(String, Expr)>> {
303        match self {
304            Expr::Record { exprs: fields, .. } => Some(
305                fields
306                    .iter()
307                    .map(|(k, v)| (k.clone(), v.deref().clone()))
308                    .collect::<Vec<_>>(),
309            ),
310            _ => None,
311        }
312    }
313    /// Parse a text directly as Rib expression
314    /// Example of a Rib expression:
315    ///
316    /// ```rib
317    ///   let shopping-cart-worker = instance("my-worker");
318    ///   let result = shopping-cart-worker.add-to-cart({product-name: "apple", quantity: 2});
319    ///
320    ///   match result {
321    ///     ok(id) => "product-id-${id}",
322    ///     err(error_msg) => "Error: ${error_msg}"
323    ///   }
324    /// ```
325    ///
326    /// Rib supports conditional calls, function calls, pattern-matching,
327    /// string interpolation (see error_message above) etc.
328    ///
329    pub fn from_text(input: &str) -> Result<Expr, String> {
330        if input.trim().ends_with(';') {
331            return Err("unexpected `;` at the end of rib expression. \nnote: `;` is used to separate expressions, but it should not appear after the last expression (which is the return value)".to_string());
332        }
333
334        spaces()
335            .with(block().skip(eof()))
336            .easy_parse(position::Stream::new(input))
337            .map(|t| t.0)
338            .map_err(|err| format!("{err}"))
339    }
340
341    pub fn lookup(&self, source_span: &SourceSpan) -> Option<Expr> {
342        let mut expr = self.clone();
343        find_expr(&mut expr, source_span)
344    }
345
346    pub fn is_literal(&self) -> bool {
347        matches!(self, Expr::Literal { .. })
348    }
349
350    pub fn is_block(&self) -> bool {
351        matches!(self, Expr::ExprBlock { .. })
352    }
353
354    pub fn is_number(&self) -> bool {
355        matches!(self, Expr::Number { .. })
356    }
357
358    pub fn is_record(&self) -> bool {
359        matches!(self, Expr::Record { .. })
360    }
361
362    pub fn is_result(&self) -> bool {
363        matches!(self, Expr::Result { .. })
364    }
365
366    pub fn is_option(&self) -> bool {
367        matches!(self, Expr::Option { .. })
368    }
369
370    pub fn is_tuple(&self) -> bool {
371        matches!(self, Expr::Tuple { .. })
372    }
373
374    pub fn is_list(&self) -> bool {
375        matches!(self, Expr::Sequence { .. })
376    }
377
378    pub fn is_flags(&self) -> bool {
379        matches!(self, Expr::Flags { .. })
380    }
381
382    pub fn is_identifier(&self) -> bool {
383        matches!(self, Expr::Identifier { .. })
384    }
385
386    pub fn is_select_field(&self) -> bool {
387        matches!(self, Expr::SelectField { .. })
388    }
389
390    pub fn is_if_else(&self) -> bool {
391        matches!(self, Expr::Cond { .. })
392    }
393
394    pub fn is_function_call(&self) -> bool {
395        matches!(self, Expr::Call { .. })
396    }
397
398    pub fn is_match_expr(&self) -> bool {
399        matches!(self, Expr::PatternMatch { .. })
400    }
401
402    pub fn is_boolean(&self) -> bool {
403        matches!(self, Expr::Boolean { .. })
404    }
405
406    pub fn is_comparison(&self) -> bool {
407        matches!(
408            self,
409            Expr::GreaterThan { .. }
410                | Expr::GreaterThanOrEqualTo { .. }
411                | Expr::LessThanOrEqualTo { .. }
412                | Expr::EqualTo { .. }
413                | Expr::LessThan { .. }
414        )
415    }
416
417    pub fn is_concat(&self) -> bool {
418        matches!(self, Expr::Concat { .. })
419    }
420
421    pub fn is_multiple(&self) -> bool {
422        matches!(self, Expr::ExprBlock { .. })
423    }
424
425    pub fn inbuilt_variant(&self) -> Option<(String, Option<Expr>)> {
426        match self {
427            Expr::Option {
428                expr: Some(expr), ..
429            } => Some(("some".to_string(), Some(expr.deref().clone()))),
430            Expr::Option { expr: None, .. } => Some(("some".to_string(), None)),
431            Expr::Result { expr: Ok(expr), .. } => {
432                Some(("ok".to_string(), Some(expr.deref().clone())))
433            }
434            Expr::Result {
435                expr: Err(expr), ..
436            } => Some(("err".to_string(), Some(expr.deref().clone()))),
437            _ => None,
438        }
439    }
440    pub fn unwrap(&self) -> Self {
441        Expr::Unwrap {
442            expr: Box::new(self.clone()),
443            inferred_type: InferredType::unknown(),
444            source_span: SourceSpan::default(),
445            type_annotation: None,
446        }
447    }
448
449    pub fn length(expr: Expr) -> Self {
450        Expr::Length {
451            expr: Box::new(expr),
452            inferred_type: InferredType::u64(),
453            source_span: SourceSpan::default(),
454            type_annotation: None,
455        }
456    }
457
458    pub fn boolean(value: bool) -> Self {
459        Expr::Boolean {
460            value,
461            inferred_type: InferredType::bool(),
462            source_span: SourceSpan::default(),
463            type_annotation: None,
464        }
465    }
466
467    pub fn and(left: Expr, right: Expr) -> Self {
468        Expr::And {
469            lhs: Box::new(left),
470            rhs: Box::new(right),
471            inferred_type: InferredType::bool(),
472            source_span: SourceSpan::default(),
473            type_annotation: None,
474        }
475    }
476
477    pub fn throw(message: impl AsRef<str>) -> Self {
478        Expr::Throw {
479            message: message.as_ref().to_string(),
480            inferred_type: InferredType::unknown(),
481            source_span: SourceSpan::default(),
482            type_annotation: None,
483        }
484    }
485
486    pub fn generate_worker_name(variable_id: Option<VariableId>) -> Self {
487        Expr::GenerateWorkerName {
488            inferred_type: InferredType::string(),
489            type_annotation: None,
490            source_span: SourceSpan::default(),
491            variable_id,
492        }
493    }
494
495    pub fn plus(left: Expr, right: Expr) -> Self {
496        Expr::Plus {
497            lhs: Box::new(left),
498            rhs: Box::new(right),
499            inferred_type: InferredType::unknown(),
500            source_span: SourceSpan::default(),
501            type_annotation: None,
502        }
503    }
504
505    pub fn minus(left: Expr, right: Expr) -> Self {
506        Expr::Minus {
507            lhs: Box::new(left),
508            rhs: Box::new(right),
509            inferred_type: InferredType::unknown(),
510            source_span: SourceSpan::default(),
511            type_annotation: None,
512        }
513    }
514
515    pub fn divide(left: Expr, right: Expr) -> Self {
516        Expr::Divide {
517            lhs: Box::new(left),
518            rhs: Box::new(right),
519            inferred_type: InferredType::unknown(),
520            source_span: SourceSpan::default(),
521            type_annotation: None,
522        }
523    }
524
525    pub fn multiply(left: Expr, right: Expr) -> Self {
526        Expr::Multiply {
527            lhs: Box::new(left),
528            rhs: Box::new(right),
529            inferred_type: InferredType::unknown(),
530            source_span: SourceSpan::default(),
531            type_annotation: None,
532        }
533    }
534
535    pub fn and_combine(conditions: Vec<Expr>) -> Option<Expr> {
536        let mut cond: Option<Expr> = None;
537
538        for i in conditions {
539            let left = Box::new(cond.clone().unwrap_or(Expr::boolean(true)));
540            cond = Some(Expr::And {
541                lhs: left,
542                rhs: Box::new(i),
543                inferred_type: InferredType::bool(),
544                source_span: SourceSpan::default(),
545                type_annotation: None,
546            });
547        }
548
549        cond
550    }
551
552    pub fn call_worker_function(
553        dynamic_parsed_fn_name: DynamicParsedFunctionName,
554        module_identifier: Option<InstanceIdentifier>,
555        args: Vec<Expr>,
556        component_info: Option<ComponentDependencyKey>,
557    ) -> Self {
558        Expr::Call {
559            call_type: CallType::Function {
560                function_name: dynamic_parsed_fn_name,
561                instance_identifier: module_identifier.map(Box::new),
562                component_info,
563            },
564            args,
565            inferred_type: InferredType::unknown(),
566            source_span: SourceSpan::default(),
567            type_annotation: None,
568        }
569    }
570
571    pub fn call(call_type: CallType, args: Vec<Expr>) -> Self {
572        Expr::Call {
573            call_type,
574            args,
575            inferred_type: InferredType::unknown(),
576            source_span: SourceSpan::default(),
577            type_annotation: None,
578        }
579    }
580
581    pub fn invoke_worker_function(lhs: Expr, function_name: String, args: Vec<Expr>) -> Self {
582        Expr::InvokeMethodLazy {
583            lhs: Box::new(lhs),
584            method: function_name,
585            args,
586            inferred_type: InferredType::unknown(),
587            source_span: SourceSpan::default(),
588            type_annotation: None,
589        }
590    }
591
592    pub fn concat(expressions: Vec<Expr>) -> Self {
593        Expr::Concat {
594            exprs: expressions,
595            inferred_type: InferredType::string(),
596            source_span: SourceSpan::default(),
597            type_annotation: None,
598        }
599    }
600
601    pub fn cond(cond: Expr, lhs: Expr, rhs: Expr) -> Self {
602        Expr::Cond {
603            cond: Box::new(cond),
604            lhs: Box::new(lhs),
605            rhs: Box::new(rhs),
606            inferred_type: InferredType::unknown(),
607            source_span: SourceSpan::default(),
608            type_annotation: None,
609        }
610    }
611
612    pub fn equal_to(left: Expr, right: Expr) -> Self {
613        Expr::EqualTo {
614            lhs: Box::new(left),
615            rhs: Box::new(right),
616            inferred_type: InferredType::bool(),
617            source_span: SourceSpan::default(),
618            type_annotation: None,
619        }
620    }
621
622    pub fn err(expr: Expr, type_annotation: Option<TypeName>) -> Self {
623        let inferred_type = expr.inferred_type();
624        Expr::Result {
625            expr: Err(Box::new(expr)),
626            type_annotation,
627            inferred_type: InferredType::result(Some(InferredType::unknown()), Some(inferred_type)),
628            source_span: SourceSpan::default(),
629        }
630    }
631
632    pub fn flags(flags: Vec<String>) -> Self {
633        Expr::Flags {
634            flags: flags.clone(),
635            inferred_type: InferredType::flags(flags),
636            source_span: SourceSpan::default(),
637            type_annotation: None,
638        }
639    }
640
641    pub fn greater_than(left: Expr, right: Expr) -> Self {
642        Expr::GreaterThan {
643            lhs: Box::new(left),
644            rhs: Box::new(right),
645            inferred_type: InferredType::bool(),
646            source_span: SourceSpan::default(),
647            type_annotation: None,
648        }
649    }
650
651    pub fn greater_than_or_equal_to(left: Expr, right: Expr) -> Self {
652        Expr::GreaterThanOrEqualTo {
653            lhs: Box::new(left),
654            rhs: Box::new(right),
655            inferred_type: InferredType::bool(),
656            source_span: SourceSpan::default(),
657            type_annotation: None,
658        }
659    }
660
661    // An identifier by default is global until name-binding phase is run
662    pub fn identifier_global(name: impl AsRef<str>, type_annotation: Option<TypeName>) -> Self {
663        Expr::Identifier {
664            variable_id: VariableId::global(name.as_ref().to_string()),
665            type_annotation,
666            inferred_type: InferredType::unknown(),
667            source_span: SourceSpan::default(),
668        }
669    }
670
671    pub fn identifier_local(
672        name: impl AsRef<str>,
673        id: u32,
674        type_annotation: Option<TypeName>,
675    ) -> Self {
676        Expr::Identifier {
677            variable_id: VariableId::local(name.as_ref(), id),
678            type_annotation,
679            inferred_type: InferredType::unknown(),
680            source_span: SourceSpan::default(),
681        }
682    }
683
684    pub fn identifier_with_variable_id(
685        variable_id: VariableId,
686        type_annotation: Option<TypeName>,
687    ) -> Self {
688        Expr::Identifier {
689            variable_id,
690            type_annotation,
691            inferred_type: InferredType::unknown(),
692            source_span: SourceSpan::default(),
693        }
694    }
695
696    pub fn less_than(left: Expr, right: Expr) -> Self {
697        Expr::LessThan {
698            lhs: Box::new(left),
699            rhs: Box::new(right),
700            inferred_type: InferredType::bool(),
701            source_span: SourceSpan::default(),
702            type_annotation: None,
703        }
704    }
705
706    pub fn less_than_or_equal_to(left: Expr, right: Expr) -> Self {
707        Expr::LessThanOrEqualTo {
708            lhs: Box::new(left),
709            rhs: Box::new(right),
710            inferred_type: InferredType::bool(),
711            source_span: SourceSpan::default(),
712            type_annotation: None,
713        }
714    }
715
716    pub fn range(from: Expr, to: Expr) -> Self {
717        Expr::Range {
718            range: Range::Range {
719                from: Box::new(from.clone()),
720                to: Box::new(to.clone()),
721            },
722            inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
723            source_span: SourceSpan::default(),
724            type_annotation: None,
725        }
726    }
727
728    pub fn range_from(from: Expr) -> Self {
729        Expr::Range {
730            range: Range::RangeFrom {
731                from: Box::new(from.clone()),
732            },
733            inferred_type: InferredType::range(from.inferred_type(), None),
734            source_span: SourceSpan::default(),
735            type_annotation: None,
736        }
737    }
738
739    pub fn range_inclusive(from: Expr, to: Expr) -> Self {
740        Expr::Range {
741            range: Range::RangeInclusive {
742                from: Box::new(from.clone()),
743                to: Box::new(to.clone()),
744            },
745            inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
746            source_span: SourceSpan::default(),
747            type_annotation: None,
748        }
749    }
750
751    pub fn let_binding(
752        name: impl AsRef<str>,
753        expr: Expr,
754        type_annotation: Option<TypeName>,
755    ) -> Self {
756        Expr::Let {
757            variable_id: VariableId::global(name.as_ref().to_string()),
758            type_annotation,
759            expr: Box::new(expr),
760            source_span: SourceSpan::default(),
761            inferred_type: InferredType::tuple(vec![]),
762        }
763    }
764
765    pub fn let_binding_with_variable_id(
766        variable_id: VariableId,
767        expr: Expr,
768        type_annotation: Option<TypeName>,
769    ) -> Self {
770        Expr::Let {
771            variable_id,
772            type_annotation,
773            expr: Box::new(expr),
774            source_span: SourceSpan::default(),
775            inferred_type: InferredType::tuple(vec![]),
776        }
777    }
778
779    pub fn typed_list_reduce(
780        reduce_variable: VariableId,
781        iterated_variable: VariableId,
782        iterable_expr: Expr,
783        init_value_expr: Expr,
784        yield_expr: Expr,
785        inferred_type: InferredType,
786    ) -> Self {
787        Expr::ListReduce {
788            reduce_variable,
789            iterated_variable,
790            iterable_expr: Box::new(iterable_expr),
791            yield_expr: Box::new(yield_expr),
792            init_value_expr: Box::new(init_value_expr),
793            inferred_type,
794            source_span: SourceSpan::default(),
795            type_annotation: None,
796        }
797    }
798
799    pub fn list_reduce(
800        reduce_variable: VariableId,
801        iterated_variable: VariableId,
802        iterable_expr: Expr,
803        init_value_expr: Expr,
804        yield_expr: Expr,
805    ) -> Self {
806        Expr::typed_list_reduce(
807            reduce_variable,
808            iterated_variable,
809            iterable_expr,
810            init_value_expr,
811            yield_expr,
812            InferredType::unknown(),
813        )
814    }
815
816    pub fn list_comprehension_typed(
817        iterated_variable: VariableId,
818        iterable_expr: Expr,
819        yield_expr: Expr,
820        inferred_type: InferredType,
821    ) -> Self {
822        Expr::ListComprehension {
823            iterated_variable,
824            iterable_expr: Box::new(iterable_expr),
825            yield_expr: Box::new(yield_expr),
826            inferred_type,
827            source_span: SourceSpan::default(),
828            type_annotation: None,
829        }
830    }
831
832    pub fn list_comprehension(
833        variable_id: VariableId,
834        iterable_expr: Expr,
835        yield_expr: Expr,
836    ) -> Self {
837        Expr::list_comprehension_typed(
838            variable_id,
839            iterable_expr,
840            yield_expr,
841            InferredType::list(InferredType::unknown()),
842        )
843    }
844
845    pub fn literal(value: impl AsRef<str>) -> Self {
846        let default_type = DefaultType::String;
847
848        Expr::Literal {
849            value: value.as_ref().to_string(),
850            inferred_type: InferredType::from(&default_type),
851            source_span: SourceSpan::default(),
852            type_annotation: None,
853        }
854    }
855
856    pub fn empty_expr() -> Self {
857        Expr::literal("")
858    }
859
860    pub fn expr_block(expressions: Vec<Expr>) -> Self {
861        let inferred_type = expressions
862            .last()
863            .map_or(InferredType::unknown(), |e| e.inferred_type());
864
865        Expr::ExprBlock {
866            exprs: expressions,
867            inferred_type,
868            source_span: SourceSpan::default(),
869            type_annotation: None,
870        }
871    }
872
873    #[allow(clippy::should_implement_trait)]
874    pub fn not(expr: Expr) -> Self {
875        Expr::Not {
876            expr: Box::new(expr),
877            inferred_type: InferredType::bool(),
878            source_span: SourceSpan::default(),
879            type_annotation: None,
880        }
881    }
882
883    pub fn ok(expr: Expr, type_annotation: Option<TypeName>) -> Self {
884        let inferred_type = expr.inferred_type();
885
886        Expr::Result {
887            expr: Ok(Box::new(expr)),
888            type_annotation,
889            inferred_type: InferredType::result(Some(inferred_type), Some(InferredType::unknown())),
890            source_span: SourceSpan::default(),
891        }
892    }
893
894    pub fn option(expr: Option<Expr>) -> Self {
895        let inferred_type = match &expr {
896            Some(expr) => expr.inferred_type(),
897            None => InferredType::unknown(),
898        };
899
900        Expr::Option {
901            expr: expr.map(Box::new),
902            type_annotation: None,
903            inferred_type: InferredType::option(inferred_type),
904            source_span: SourceSpan::default(),
905        }
906    }
907
908    pub fn or(left: Expr, right: Expr) -> Self {
909        Expr::Or {
910            lhs: Box::new(left),
911            rhs: Box::new(right),
912            inferred_type: InferredType::bool(),
913            source_span: SourceSpan::default(),
914            type_annotation: None,
915        }
916    }
917
918    pub fn pattern_match(expr: Expr, match_arms: Vec<MatchArm>) -> Self {
919        Expr::PatternMatch {
920            predicate: Box::new(expr),
921            match_arms,
922            inferred_type: InferredType::unknown(),
923            source_span: SourceSpan::default(),
924            type_annotation: None,
925        }
926    }
927
928    pub fn record(expressions: Vec<(String, Expr)>) -> Self {
929        let inferred_type = InferredType::record(
930            expressions
931                .iter()
932                .map(|(field_name, expr)| (field_name.to_string(), expr.inferred_type()))
933                .collect(),
934        );
935
936        Expr::Record {
937            exprs: expressions
938                .into_iter()
939                .map(|(field_name, expr)| (field_name, Box::new(expr)))
940                .collect(),
941            inferred_type,
942            source_span: SourceSpan::default(),
943            type_annotation: None,
944        }
945    }
946
947    pub fn select_field(
948        expr: Expr,
949        field: impl AsRef<str>,
950        type_annotation: Option<TypeName>,
951    ) -> Self {
952        Expr::SelectField {
953            expr: Box::new(expr),
954            field: field.as_ref().to_string(),
955            type_annotation,
956            inferred_type: InferredType::unknown(),
957            source_span: SourceSpan::default(),
958        }
959    }
960
961    pub fn select_index(expr: Expr, index: Expr) -> Self {
962        Expr::SelectIndex {
963            expr: Box::new(expr),
964            index: Box::new(index),
965            type_annotation: None,
966            inferred_type: InferredType::unknown(),
967            source_span: SourceSpan::default(),
968        }
969    }
970
971    pub fn get_tag(expr: Expr) -> Self {
972        Expr::GetTag {
973            expr: Box::new(expr),
974            inferred_type: InferredType::unknown(),
975            source_span: SourceSpan::default(),
976            type_annotation: None,
977        }
978    }
979
980    pub fn tuple(expressions: Vec<Expr>) -> Self {
981        let inferred_type = InferredType::tuple(
982            expressions
983                .iter()
984                .map(|expr| expr.inferred_type())
985                .collect(),
986        );
987
988        Expr::Tuple {
989            exprs: expressions,
990            inferred_type,
991            source_span: SourceSpan::default(),
992            type_annotation: None,
993        }
994    }
995
996    pub fn sequence(expressions: Vec<Expr>, type_annotation: Option<TypeName>) -> Self {
997        let inferred_type = InferredType::list(
998            expressions
999                .first()
1000                .map_or(InferredType::unknown(), |x| x.inferred_type()),
1001        );
1002
1003        Expr::Sequence {
1004            exprs: expressions,
1005            type_annotation,
1006            inferred_type,
1007            source_span: SourceSpan::default(),
1008        }
1009    }
1010
1011    pub fn inferred_type_mut(&mut self) -> &mut InferredType {
1012        match self {
1013            Expr::Let { inferred_type, .. }
1014            | Expr::SelectField { inferred_type, .. }
1015            | Expr::SelectIndex { inferred_type, .. }
1016            | Expr::Sequence { inferred_type, .. }
1017            | Expr::Record { inferred_type, .. }
1018            | Expr::Tuple { inferred_type, .. }
1019            | Expr::Literal { inferred_type, .. }
1020            | Expr::Number { inferred_type, .. }
1021            | Expr::Flags { inferred_type, .. }
1022            | Expr::Identifier { inferred_type, .. }
1023            | Expr::Boolean { inferred_type, .. }
1024            | Expr::Concat { inferred_type, .. }
1025            | Expr::ExprBlock { inferred_type, .. }
1026            | Expr::Not { inferred_type, .. }
1027            | Expr::GreaterThan { inferred_type, .. }
1028            | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1029            | Expr::LessThanOrEqualTo { inferred_type, .. }
1030            | Expr::EqualTo { inferred_type, .. }
1031            | Expr::Plus { inferred_type, .. }
1032            | Expr::Minus { inferred_type, .. }
1033            | Expr::Divide { inferred_type, .. }
1034            | Expr::Multiply { inferred_type, .. }
1035            | Expr::LessThan { inferred_type, .. }
1036            | Expr::Cond { inferred_type, .. }
1037            | Expr::PatternMatch { inferred_type, .. }
1038            | Expr::Option { inferred_type, .. }
1039            | Expr::Result { inferred_type, .. }
1040            | Expr::Unwrap { inferred_type, .. }
1041            | Expr::Throw { inferred_type, .. }
1042            | Expr::GetTag { inferred_type, .. }
1043            | Expr::And { inferred_type, .. }
1044            | Expr::Or { inferred_type, .. }
1045            | Expr::ListComprehension { inferred_type, .. }
1046            | Expr::ListReduce { inferred_type, .. }
1047            | Expr::Call { inferred_type, .. }
1048            | Expr::Range { inferred_type, .. }
1049            | Expr::InvokeMethodLazy { inferred_type, .. }
1050            | Expr::Length { inferred_type, .. }
1051            | Expr::GenerateWorkerName { inferred_type, .. } => &mut *inferred_type,
1052        }
1053    }
1054
1055    pub fn inferred_type(&self) -> InferredType {
1056        match self {
1057            Expr::Let { inferred_type, .. }
1058            | Expr::SelectField { inferred_type, .. }
1059            | Expr::SelectIndex { inferred_type, .. }
1060            | Expr::Sequence { inferred_type, .. }
1061            | Expr::Record { inferred_type, .. }
1062            | Expr::Tuple { inferred_type, .. }
1063            | Expr::Literal { inferred_type, .. }
1064            | Expr::Number { inferred_type, .. }
1065            | Expr::Flags { inferred_type, .. }
1066            | Expr::Identifier { inferred_type, .. }
1067            | Expr::Boolean { inferred_type, .. }
1068            | Expr::Concat { inferred_type, .. }
1069            | Expr::ExprBlock { inferred_type, .. }
1070            | Expr::Not { inferred_type, .. }
1071            | Expr::GreaterThan { inferred_type, .. }
1072            | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1073            | Expr::LessThanOrEqualTo { inferred_type, .. }
1074            | Expr::EqualTo { inferred_type, .. }
1075            | Expr::Plus { inferred_type, .. }
1076            | Expr::Minus { inferred_type, .. }
1077            | Expr::Divide { inferred_type, .. }
1078            | Expr::Multiply { inferred_type, .. }
1079            | Expr::LessThan { inferred_type, .. }
1080            | Expr::Cond { inferred_type, .. }
1081            | Expr::PatternMatch { inferred_type, .. }
1082            | Expr::Option { inferred_type, .. }
1083            | Expr::Result { inferred_type, .. }
1084            | Expr::Unwrap { inferred_type, .. }
1085            | Expr::Throw { inferred_type, .. }
1086            | Expr::GetTag { inferred_type, .. }
1087            | Expr::And { inferred_type, .. }
1088            | Expr::Or { inferred_type, .. }
1089            | Expr::ListComprehension { inferred_type, .. }
1090            | Expr::ListReduce { inferred_type, .. }
1091            | Expr::Call { inferred_type, .. }
1092            | Expr::Range { inferred_type, .. }
1093            | Expr::InvokeMethodLazy { inferred_type, .. }
1094            | Expr::Length { inferred_type, .. }
1095            | Expr::GenerateWorkerName { inferred_type, .. } => inferred_type.clone(),
1096        }
1097    }
1098
1099    pub fn infer_types(
1100        &mut self,
1101        component_dependency: &ComponentDependency,
1102        global_variable_type_spec: &Vec<GlobalVariableTypeSpec>,
1103        custom_instance_spec: &[CustomInstanceSpec],
1104    ) -> Result<(), RibTypeErrorInternal> {
1105        let component = Arc::new(component_dependency.clone());
1106
1107        let (mut arena, mut types, root) = {
1108            let _p = crate::profile::Scope::new("type inference: lower to expr arena");
1109
1110            crate::expr_arena::lower(self)
1111        };
1112
1113        {
1114            let _p = crate::profile::Scope::new(
1115                "type inference: run_initial_binding_and_instance_phases",
1116            );
1117            ti::run_initial_binding_and_instance_phases(
1118                root,
1119                &mut arena,
1120                &mut types,
1121                component.clone(),
1122                global_variable_type_spec.as_slice(),
1123                custom_instance_spec,
1124            )?;
1125
1126            ti::infer_variants_lowered(root, &mut arena, &mut types, component.as_ref());
1127            ti::infer_enums(root, &mut arena, &mut types, component.as_ref());
1128            ti::bind_instance_types(root, &arena, &mut types);
1129        }
1130
1131        {
1132            let _p = crate::profile::Scope::new(
1133                "type inference: fixpoint - resolve function calls and instance bindings",
1134            );
1135
1136            ti::type_inference_fix_point(
1137                |root, arena, types| -> Result<(), RibTypeErrorInternal> {
1138                    ti::bind_instance_types(root, arena, types);
1139                    ti::infer_function_invokes(root, arena, types, component.as_ref())
1140                },
1141                root,
1142                &mut arena,
1143                &mut types,
1144            )?;
1145        }
1146
1147        {
1148            let _p = crate::profile::Scope::new("type inference: infer_function_call_types");
1149
1150            ti::infer_function_call_types(
1151                root,
1152                &arena,
1153                &mut types,
1154                component.as_ref(),
1155                custom_instance_spec,
1156            )
1157            .map_err(RibTypeErrorInternal::from)?;
1158        }
1159
1160        {
1161            let _p = crate::profile::Scope::new(
1162                "type inference: fixpoint - main scan for type inference",
1163            );
1164
1165            ti::type_inference_fix_point(
1166                |root, arena, types| -> Result<(), RibTypeErrorInternal> {
1167                    ti::infer_all_identifiers(root, arena, types);
1168                    ti::push_types_down(root, arena, types)?;
1169                    ti::infer_all_identifiers(root, arena, types);
1170                    ti::pull_types_up(root, arena, types, component.as_ref())?;
1171                    ti::infer_global_inputs(root, arena, types);
1172                    ti::infer_function_call_types(
1173                        root,
1174                        arena,
1175                        types,
1176                        component.as_ref(),
1177                        custom_instance_spec,
1178                    )
1179                    .map_err(RibTypeErrorInternal::from)?;
1180                    Ok(())
1181                },
1182                root,
1183                &mut arena,
1184                &mut types,
1185            )?;
1186        }
1187
1188        {
1189            let _p = crate::profile::Scope::new(
1190                "type inference: sync_embedded_worker_exprs_from_calls + bind_instance_types",
1191            );
1192
1193            ti::sync_embedded_worker_exprs_from_calls(root, &arena, &mut types);
1194            ti::bind_instance_types(root, &arena, &mut types);
1195        }
1196
1197        {
1198            let _p = crate::profile::Scope::new("type inference: type check");
1199            type_checker::checker::type_check(root, &arena, &mut types, component.as_ref())?;
1200        }
1201
1202        {
1203            let _p = crate::profile::Scope::new("type inference: unify types");
1204            type_inference::unify_types(root, &arena, &mut types)?;
1205        }
1206
1207        {
1208            let _p = crate::profile::Scope::new("type inference: rebuild_expr");
1209            *self = crate::expr_arena::rebuild_expr(root, &arena, &types);
1210        }
1211
1212        Ok(())
1213    }
1214
1215    pub fn merge_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1216        let mut expr_copied = self.clone();
1217        expr_copied.add_infer_type_mut(new_inferred_type);
1218        expr_copied
1219    }
1220
1221    pub fn add_infer_type_mut(&mut self, new_inferred_type: InferredType) {
1222        match self {
1223            Expr::Identifier { inferred_type, .. }
1224            | Expr::Let { inferred_type, .. }
1225            | Expr::SelectField { inferred_type, .. }
1226            | Expr::SelectIndex { inferred_type, .. }
1227            | Expr::Sequence { inferred_type, .. }
1228            | Expr::Record { inferred_type, .. }
1229            | Expr::Tuple { inferred_type, .. }
1230            | Expr::Literal { inferred_type, .. }
1231            | Expr::Number { inferred_type, .. }
1232            | Expr::Flags { inferred_type, .. }
1233            | Expr::Boolean { inferred_type, .. }
1234            | Expr::Concat { inferred_type, .. }
1235            | Expr::ExprBlock { inferred_type, .. }
1236            | Expr::Not { inferred_type, .. }
1237            | Expr::GreaterThan { inferred_type, .. }
1238            | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1239            | Expr::LessThanOrEqualTo { inferred_type, .. }
1240            | Expr::EqualTo { inferred_type, .. }
1241            | Expr::Plus { inferred_type, .. }
1242            | Expr::Minus { inferred_type, .. }
1243            | Expr::Divide { inferred_type, .. }
1244            | Expr::Multiply { inferred_type, .. }
1245            | Expr::LessThan { inferred_type, .. }
1246            | Expr::Cond { inferred_type, .. }
1247            | Expr::PatternMatch { inferred_type, .. }
1248            | Expr::Option { inferred_type, .. }
1249            | Expr::Result { inferred_type, .. }
1250            | Expr::Unwrap { inferred_type, .. }
1251            | Expr::Throw { inferred_type, .. }
1252            | Expr::GetTag { inferred_type, .. }
1253            | Expr::And { inferred_type, .. }
1254            | Expr::Or { inferred_type, .. }
1255            | Expr::ListComprehension { inferred_type, .. }
1256            | Expr::ListReduce { inferred_type, .. }
1257            | Expr::InvokeMethodLazy { inferred_type, .. }
1258            | Expr::Range { inferred_type, .. }
1259            | Expr::Length { inferred_type, .. }
1260            | Expr::GenerateWorkerName { inferred_type, .. }
1261            | Expr::Call { inferred_type, .. } => {
1262                if !new_inferred_type.is_unknown() {
1263                    *inferred_type = inferred_type.merge(new_inferred_type);
1264                }
1265            }
1266        }
1267    }
1268
1269    pub fn reset_type(&mut self) {
1270        type_inference::reset_type_info(self);
1271    }
1272
1273    pub fn source_span(&self) -> SourceSpan {
1274        match self {
1275            Expr::Identifier { source_span, .. }
1276            | Expr::Let { source_span, .. }
1277            | Expr::SelectField { source_span, .. }
1278            | Expr::SelectIndex { source_span, .. }
1279            | Expr::Sequence { source_span, .. }
1280            | Expr::Record { source_span, .. }
1281            | Expr::Tuple { source_span, .. }
1282            | Expr::Literal { source_span, .. }
1283            | Expr::Number { source_span, .. }
1284            | Expr::Flags { source_span, .. }
1285            | Expr::Boolean { source_span, .. }
1286            | Expr::Concat { source_span, .. }
1287            | Expr::ExprBlock { source_span, .. }
1288            | Expr::Not { source_span, .. }
1289            | Expr::GreaterThan { source_span, .. }
1290            | Expr::GreaterThanOrEqualTo { source_span, .. }
1291            | Expr::LessThanOrEqualTo { source_span, .. }
1292            | Expr::EqualTo { source_span, .. }
1293            | Expr::LessThan { source_span, .. }
1294            | Expr::Plus { source_span, .. }
1295            | Expr::Minus { source_span, .. }
1296            | Expr::Divide { source_span, .. }
1297            | Expr::Multiply { source_span, .. }
1298            | Expr::Cond { source_span, .. }
1299            | Expr::PatternMatch { source_span, .. }
1300            | Expr::Option { source_span, .. }
1301            | Expr::Result { source_span, .. }
1302            | Expr::Unwrap { source_span, .. }
1303            | Expr::Throw { source_span, .. }
1304            | Expr::And { source_span, .. }
1305            | Expr::Or { source_span, .. }
1306            | Expr::GetTag { source_span, .. }
1307            | Expr::ListComprehension { source_span, .. }
1308            | Expr::ListReduce { source_span, .. }
1309            | Expr::InvokeMethodLazy { source_span, .. }
1310            | Expr::Range { source_span, .. }
1311            | Expr::Length { source_span, .. }
1312            | Expr::Call { source_span, .. }
1313            | Expr::GenerateWorkerName { source_span, .. } => source_span.clone(),
1314        }
1315    }
1316
1317    pub fn type_annotation(&self) -> &Option<TypeName> {
1318        match self {
1319            Expr::Identifier {
1320                type_annotation, ..
1321            }
1322            | Expr::Let {
1323                type_annotation, ..
1324            }
1325            | Expr::SelectField {
1326                type_annotation, ..
1327            }
1328            | Expr::SelectIndex {
1329                type_annotation, ..
1330            }
1331            | Expr::Sequence {
1332                type_annotation, ..
1333            }
1334            | Expr::Record {
1335                type_annotation, ..
1336            }
1337            | Expr::Tuple {
1338                type_annotation, ..
1339            }
1340            | Expr::Literal {
1341                type_annotation, ..
1342            }
1343            | Expr::Number {
1344                type_annotation, ..
1345            }
1346            | Expr::Flags {
1347                type_annotation, ..
1348            }
1349            | Expr::Boolean {
1350                type_annotation, ..
1351            }
1352            | Expr::Concat {
1353                type_annotation, ..
1354            }
1355            | Expr::ExprBlock {
1356                type_annotation, ..
1357            }
1358            | Expr::Not {
1359                type_annotation, ..
1360            }
1361            | Expr::GreaterThan {
1362                type_annotation, ..
1363            }
1364            | Expr::GreaterThanOrEqualTo {
1365                type_annotation, ..
1366            }
1367            | Expr::LessThanOrEqualTo {
1368                type_annotation, ..
1369            }
1370            | Expr::EqualTo {
1371                type_annotation, ..
1372            }
1373            | Expr::LessThan {
1374                type_annotation, ..
1375            }
1376            | Expr::Plus {
1377                type_annotation, ..
1378            }
1379            | Expr::Minus {
1380                type_annotation, ..
1381            }
1382            | Expr::Divide {
1383                type_annotation, ..
1384            }
1385            | Expr::Multiply {
1386                type_annotation, ..
1387            }
1388            | Expr::Cond {
1389                type_annotation, ..
1390            }
1391            | Expr::PatternMatch {
1392                type_annotation, ..
1393            }
1394            | Expr::Option {
1395                type_annotation, ..
1396            }
1397            | Expr::Result {
1398                type_annotation, ..
1399            }
1400            | Expr::Unwrap {
1401                type_annotation, ..
1402            }
1403            | Expr::Throw {
1404                type_annotation, ..
1405            }
1406            | Expr::And {
1407                type_annotation, ..
1408            }
1409            | Expr::Or {
1410                type_annotation, ..
1411            }
1412            | Expr::GetTag {
1413                type_annotation, ..
1414            }
1415            | Expr::ListComprehension {
1416                type_annotation, ..
1417            }
1418            | Expr::ListReduce {
1419                type_annotation, ..
1420            }
1421            | Expr::InvokeMethodLazy {
1422                type_annotation, ..
1423            }
1424            | Expr::Range {
1425                type_annotation, ..
1426            }
1427            | Expr::Length {
1428                type_annotation, ..
1429            }
1430            | Expr::GenerateWorkerName {
1431                type_annotation, ..
1432            }
1433            | Expr::Call {
1434                type_annotation, ..
1435            } => type_annotation,
1436        }
1437    }
1438
1439    pub fn with_type_annotation_opt(&self, type_annotation: Option<TypeName>) -> Expr {
1440        if let Some(type_annotation) = type_annotation {
1441            self.with_type_annotation(type_annotation)
1442        } else {
1443            self.clone()
1444        }
1445    }
1446
1447    pub fn with_type_annotation(&self, type_annotation: TypeName) -> Expr {
1448        let mut expr_copied = self.clone();
1449        expr_copied.with_type_annotation_mut(type_annotation);
1450        expr_copied
1451    }
1452
1453    pub fn with_type_annotation_mut(&mut self, type_annotation: TypeName) {
1454        let new_type_annotation = type_annotation;
1455
1456        match self {
1457            Expr::Identifier {
1458                type_annotation, ..
1459            }
1460            | Expr::Let {
1461                type_annotation, ..
1462            }
1463            | Expr::SelectField {
1464                type_annotation, ..
1465            }
1466            | Expr::SelectIndex {
1467                type_annotation, ..
1468            }
1469            | Expr::Sequence {
1470                type_annotation, ..
1471            }
1472            | Expr::Record {
1473                type_annotation, ..
1474            }
1475            | Expr::Tuple {
1476                type_annotation, ..
1477            }
1478            | Expr::Literal {
1479                type_annotation, ..
1480            }
1481            | Expr::Number {
1482                type_annotation, ..
1483            }
1484            | Expr::Flags {
1485                type_annotation, ..
1486            }
1487            | Expr::Boolean {
1488                type_annotation, ..
1489            }
1490            | Expr::Concat {
1491                type_annotation, ..
1492            }
1493            | Expr::ExprBlock {
1494                type_annotation, ..
1495            }
1496            | Expr::Not {
1497                type_annotation, ..
1498            }
1499            | Expr::GreaterThan {
1500                type_annotation, ..
1501            }
1502            | Expr::GreaterThanOrEqualTo {
1503                type_annotation, ..
1504            }
1505            | Expr::LessThanOrEqualTo {
1506                type_annotation, ..
1507            }
1508            | Expr::EqualTo {
1509                type_annotation, ..
1510            }
1511            | Expr::LessThan {
1512                type_annotation, ..
1513            }
1514            | Expr::Plus {
1515                type_annotation, ..
1516            }
1517            | Expr::Minus {
1518                type_annotation, ..
1519            }
1520            | Expr::Divide {
1521                type_annotation, ..
1522            }
1523            | Expr::Multiply {
1524                type_annotation, ..
1525            }
1526            | Expr::Cond {
1527                type_annotation, ..
1528            }
1529            | Expr::PatternMatch {
1530                type_annotation, ..
1531            }
1532            | Expr::Option {
1533                type_annotation, ..
1534            }
1535            | Expr::Result {
1536                type_annotation, ..
1537            }
1538            | Expr::Unwrap {
1539                type_annotation, ..
1540            }
1541            | Expr::Throw {
1542                type_annotation, ..
1543            }
1544            | Expr::And {
1545                type_annotation, ..
1546            }
1547            | Expr::Or {
1548                type_annotation, ..
1549            }
1550            | Expr::GetTag {
1551                type_annotation, ..
1552            }
1553            | Expr::Range {
1554                type_annotation, ..
1555            }
1556            | Expr::ListComprehension {
1557                type_annotation, ..
1558            }
1559            | Expr::ListReduce {
1560                type_annotation, ..
1561            }
1562            | Expr::InvokeMethodLazy {
1563                type_annotation, ..
1564            }
1565            | Expr::Length {
1566                type_annotation, ..
1567            }
1568            | Expr::GenerateWorkerName {
1569                type_annotation, ..
1570            }
1571            | Expr::Call {
1572                type_annotation, ..
1573            } => {
1574                *type_annotation = Some(new_type_annotation);
1575            }
1576        }
1577    }
1578
1579    pub fn with_source_span(&self, new_source_span: SourceSpan) -> Expr {
1580        let mut expr_copied = self.clone();
1581        expr_copied.with_source_span_mut(new_source_span);
1582        expr_copied
1583    }
1584
1585    pub fn with_source_span_mut(&mut self, new_source_span: SourceSpan) {
1586        match self {
1587            Expr::Identifier { source_span, .. }
1588            | Expr::Let { source_span, .. }
1589            | Expr::SelectField { source_span, .. }
1590            | Expr::SelectIndex { source_span, .. }
1591            | Expr::Sequence { source_span, .. }
1592            | Expr::Number { source_span, .. }
1593            | Expr::Record { source_span, .. }
1594            | Expr::Tuple { source_span, .. }
1595            | Expr::Literal { source_span, .. }
1596            | Expr::Flags { source_span, .. }
1597            | Expr::Boolean { source_span, .. }
1598            | Expr::Concat { source_span, .. }
1599            | Expr::ExprBlock { source_span, .. }
1600            | Expr::Not { source_span, .. }
1601            | Expr::GreaterThan { source_span, .. }
1602            | Expr::GreaterThanOrEqualTo { source_span, .. }
1603            | Expr::LessThanOrEqualTo { source_span, .. }
1604            | Expr::EqualTo { source_span, .. }
1605            | Expr::LessThan { source_span, .. }
1606            | Expr::Plus { source_span, .. }
1607            | Expr::Minus { source_span, .. }
1608            | Expr::Divide { source_span, .. }
1609            | Expr::Multiply { source_span, .. }
1610            | Expr::Cond { source_span, .. }
1611            | Expr::PatternMatch { source_span, .. }
1612            | Expr::Option { source_span, .. }
1613            | Expr::Result { source_span, .. }
1614            | Expr::Unwrap { source_span, .. }
1615            | Expr::Throw { source_span, .. }
1616            | Expr::And { source_span, .. }
1617            | Expr::Or { source_span, .. }
1618            | Expr::GetTag { source_span, .. }
1619            | Expr::Range { source_span, .. }
1620            | Expr::ListComprehension { source_span, .. }
1621            | Expr::ListReduce { source_span, .. }
1622            | Expr::InvokeMethodLazy { source_span, .. }
1623            | Expr::Length { source_span, .. }
1624            | Expr::GenerateWorkerName { source_span, .. }
1625            | Expr::Call { source_span, .. } => {
1626                *source_span = new_source_span;
1627            }
1628        }
1629    }
1630
1631    pub fn with_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1632        let mut expr_copied = self.clone();
1633        expr_copied.with_inferred_type_mut(new_inferred_type);
1634        expr_copied
1635    }
1636
1637    // `with_inferred_type` overrides the existing inferred_type and returns a new expr
1638    // This is different to `merge_inferred_type` where it tries to combine the new inferred type with the existing one.
1639    pub fn with_inferred_type_mut(&mut self, new_inferred_type: InferredType) {
1640        match self {
1641            Expr::Identifier { inferred_type, .. }
1642            | Expr::Let { inferred_type, .. }
1643            | Expr::SelectField { inferred_type, .. }
1644            | Expr::SelectIndex { inferred_type, .. }
1645            | Expr::Sequence { inferred_type, .. }
1646            | Expr::Record { inferred_type, .. }
1647            | Expr::Tuple { inferred_type, .. }
1648            | Expr::Literal { inferred_type, .. }
1649            | Expr::Number { inferred_type, .. }
1650            | Expr::Flags { inferred_type, .. }
1651            | Expr::Boolean { inferred_type, .. }
1652            | Expr::Concat { inferred_type, .. }
1653            | Expr::ExprBlock { inferred_type, .. }
1654            | Expr::Not { inferred_type, .. }
1655            | Expr::GreaterThan { inferred_type, .. }
1656            | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1657            | Expr::LessThanOrEqualTo { inferred_type, .. }
1658            | Expr::EqualTo { inferred_type, .. }
1659            | Expr::LessThan { inferred_type, .. }
1660            | Expr::Plus { inferred_type, .. }
1661            | Expr::Minus { inferred_type, .. }
1662            | Expr::Divide { inferred_type, .. }
1663            | Expr::Multiply { inferred_type, .. }
1664            | Expr::Cond { inferred_type, .. }
1665            | Expr::PatternMatch { inferred_type, .. }
1666            | Expr::Option { inferred_type, .. }
1667            | Expr::Result { inferred_type, .. }
1668            | Expr::Unwrap { inferred_type, .. }
1669            | Expr::Throw { inferred_type, .. }
1670            | Expr::And { inferred_type, .. }
1671            | Expr::Or { inferred_type, .. }
1672            | Expr::GetTag { inferred_type, .. }
1673            | Expr::ListComprehension { inferred_type, .. }
1674            | Expr::ListReduce { inferred_type, .. }
1675            | Expr::InvokeMethodLazy { inferred_type, .. }
1676            | Expr::Range { inferred_type, .. }
1677            | Expr::Length { inferred_type, .. }
1678            | Expr::GenerateWorkerName { inferred_type, .. }
1679            | Expr::Call { inferred_type, .. } => {
1680                *inferred_type = new_inferred_type;
1681            }
1682        }
1683    }
1684
1685    pub fn visit_expr_nodes_lazy<'a>(&'a mut self, queue: &mut VecDeque<&'a mut Expr>) {
1686        type_inference::collect_children_mut(self, queue);
1687    }
1688
1689    pub fn number_inferred(
1690        big_decimal: BigDecimal,
1691        type_annotation: Option<TypeName>,
1692        inferred_type: InferredType,
1693    ) -> Expr {
1694        Expr::Number {
1695            number: Number { value: big_decimal },
1696            type_annotation,
1697            inferred_type,
1698            source_span: SourceSpan::default(),
1699        }
1700    }
1701
1702    pub fn number(big_decimal: BigDecimal) -> Expr {
1703        let default_type = DefaultType::from(&big_decimal);
1704        let inferred_type = InferredType::from(&default_type);
1705
1706        Expr::number_inferred(big_decimal, None, inferred_type)
1707    }
1708}
1709
1710#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
1711pub enum Range {
1712    Range { from: Box<Expr>, to: Box<Expr> },
1713    RangeInclusive { from: Box<Expr>, to: Box<Expr> },
1714    RangeFrom { from: Box<Expr> },
1715}
1716
1717impl Range {
1718    pub fn from(&self) -> Option<&Expr> {
1719        match self {
1720            Range::Range { from, .. } => Some(from),
1721            Range::RangeInclusive { from, .. } => Some(from),
1722            Range::RangeFrom { from } => Some(from),
1723        }
1724    }
1725
1726    pub fn to(&self) -> Option<&Expr> {
1727        match self {
1728            Range::Range { to, .. } => Some(to),
1729            Range::RangeInclusive { to, .. } => Some(to),
1730            Range::RangeFrom { .. } => None,
1731        }
1732    }
1733
1734    pub fn inclusive(&self) -> bool {
1735        matches!(self, Range::RangeInclusive { .. })
1736    }
1737
1738    pub fn get_exprs_mut(&mut self) -> Vec<&mut Box<Expr>> {
1739        match self {
1740            Range::Range { from, to } => vec![from, to],
1741            Range::RangeInclusive { from, to } => vec![from, to],
1742            Range::RangeFrom { from } => vec![from],
1743        }
1744    }
1745
1746    pub fn get_exprs(&self) -> Vec<&Expr> {
1747        match self {
1748            Range::Range { from, to } => vec![from.as_ref(), to.as_ref()],
1749            Range::RangeInclusive { from, to } => vec![from.as_ref(), to.as_ref()],
1750            Range::RangeFrom { from } => vec![from.as_ref()],
1751        }
1752    }
1753}
1754
1755#[derive(Debug, Hash, Clone, PartialEq, Ord, PartialOrd)]
1756pub struct Number {
1757    pub value: BigDecimal,
1758}
1759
1760impl Eq for Number {}
1761
1762impl Number {
1763    pub fn to_val(&self, analysed_type: &WitType) -> Option<ValueAndType> {
1764        match analysed_type {
1765            WitType::F64(_) => self.value.to_f64().map(|v| v.into_value_and_type()),
1766            WitType::U64(_) => self.value.to_u64().map(|v| v.into_value_and_type()),
1767            WitType::F32(_) => self.value.to_f32().map(|v| v.into_value_and_type()),
1768            WitType::U32(_) => self.value.to_u32().map(|v| v.into_value_and_type()),
1769            WitType::S32(_) => self.value.to_i32().map(|v| v.into_value_and_type()),
1770            WitType::S64(_) => self.value.to_i64().map(|v| v.into_value_and_type()),
1771            WitType::U8(_) => self.value.to_u8().map(|v| v.into_value_and_type()),
1772            WitType::S8(_) => self.value.to_i8().map(|v| v.into_value_and_type()),
1773            WitType::U16(_) => self.value.to_u16().map(|v| v.into_value_and_type()),
1774            WitType::S16(_) => self.value.to_i16().map(|v| v.into_value_and_type()),
1775            _ => None,
1776        }
1777    }
1778}
1779
1780impl Display for Number {
1781    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1782        write!(f, "{}", self.value)
1783    }
1784}
1785
1786#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1787pub struct MatchArm {
1788    pub arm_pattern: ArmPattern,
1789    pub arm_resolution_expr: Box<Expr>,
1790}
1791
1792impl MatchArm {
1793    pub fn new(arm_pattern: ArmPattern, arm_resolution: Expr) -> MatchArm {
1794        MatchArm {
1795            arm_pattern,
1796            arm_resolution_expr: Box::new(arm_resolution),
1797        }
1798    }
1799}
1800
1801#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1802pub enum ArmPattern {
1803    WildCard,
1804    As(String, Box<ArmPattern>),
1805    Constructor(String, Vec<ArmPattern>),
1806    TupleConstructor(Vec<ArmPattern>),
1807    RecordConstructor(Vec<(String, ArmPattern)>),
1808    ListConstructor(Vec<ArmPattern>),
1809    Literal(Box<Expr>),
1810}
1811
1812impl ArmPattern {
1813    pub fn is_wildcard(&self) -> bool {
1814        matches!(self, ArmPattern::WildCard)
1815    }
1816
1817    pub fn is_literal_identifier(&self) -> bool {
1818        matches!(self, ArmPattern::Literal(expr) if expr.is_identifier())
1819    }
1820
1821    pub fn constructor(name: &str, patterns: Vec<ArmPattern>) -> ArmPattern {
1822        ArmPattern::Constructor(name.to_string(), patterns)
1823    }
1824
1825    pub fn literal(expr: Expr) -> ArmPattern {
1826        ArmPattern::Literal(Box::new(expr))
1827    }
1828
1829    pub fn get_expr_literals_mut(&mut self) -> Vec<&mut Box<Expr>> {
1830        match self {
1831            ArmPattern::Literal(expr) => vec![expr],
1832            ArmPattern::As(_, pattern) => pattern.get_expr_literals_mut(),
1833            ArmPattern::Constructor(_, patterns) => {
1834                let mut result = vec![];
1835                for pattern in patterns {
1836                    result.extend(pattern.get_expr_literals_mut());
1837                }
1838                result
1839            }
1840            ArmPattern::TupleConstructor(patterns) => {
1841                let mut result = vec![];
1842                for pattern in patterns {
1843                    result.extend(pattern.get_expr_literals_mut());
1844                }
1845                result
1846            }
1847            ArmPattern::RecordConstructor(patterns) => {
1848                let mut result = vec![];
1849                for (_, pattern) in patterns {
1850                    result.extend(pattern.get_expr_literals_mut());
1851                }
1852                result
1853            }
1854            ArmPattern::ListConstructor(patterns) => {
1855                let mut result = vec![];
1856                for pattern in patterns {
1857                    result.extend(pattern.get_expr_literals_mut());
1858                }
1859                result
1860            }
1861            ArmPattern::WildCard => vec![],
1862        }
1863    }
1864
1865    pub fn get_expr_literals(&self) -> Vec<&Expr> {
1866        match self {
1867            ArmPattern::Literal(expr) => vec![expr.as_ref()],
1868            ArmPattern::As(_, pattern) => pattern.get_expr_literals(),
1869            ArmPattern::Constructor(_, patterns) => {
1870                let mut result = vec![];
1871                for pattern in patterns {
1872                    result.extend(pattern.get_expr_literals());
1873                }
1874                result
1875            }
1876            ArmPattern::TupleConstructor(patterns) => {
1877                let mut result = vec![];
1878                for pattern in patterns {
1879                    result.extend(pattern.get_expr_literals());
1880                }
1881                result
1882            }
1883            ArmPattern::RecordConstructor(patterns) => {
1884                let mut result = vec![];
1885                for (_, pattern) in patterns {
1886                    result.extend(pattern.get_expr_literals());
1887                }
1888                result
1889            }
1890            ArmPattern::ListConstructor(patterns) => {
1891                let mut result = vec![];
1892                for pattern in patterns {
1893                    result.extend(pattern.get_expr_literals());
1894                }
1895                result
1896            }
1897            ArmPattern::WildCard => vec![],
1898        }
1899    }
1900    // Helper to construct ok(v). Cannot be used if there is nested constructors such as ok(some(v)))
1901    pub fn ok(binding_variable: &str) -> ArmPattern {
1902        ArmPattern::Literal(Box::new(Expr::Result {
1903            expr: Ok(Box::new(Expr::Identifier {
1904                variable_id: VariableId::global(binding_variable.to_string()),
1905                type_annotation: None,
1906                inferred_type: InferredType::unknown(),
1907                source_span: SourceSpan::default(),
1908            })),
1909            type_annotation: None,
1910            inferred_type: InferredType::result(
1911                Some(InferredType::unknown()),
1912                Some(InferredType::unknown()),
1913            ),
1914            source_span: SourceSpan::default(),
1915        }))
1916    }
1917
1918    // Helper to construct err(v). Cannot be used if there is nested constructors such as err(some(v)))
1919    pub fn err(binding_variable: &str) -> ArmPattern {
1920        ArmPattern::Literal(Box::new(Expr::Result {
1921            expr: Err(Box::new(Expr::Identifier {
1922                variable_id: VariableId::global(binding_variable.to_string()),
1923                type_annotation: None,
1924                inferred_type: InferredType::unknown(),
1925                source_span: SourceSpan::default(),
1926            })),
1927            type_annotation: None,
1928            inferred_type: InferredType::result(
1929                Some(InferredType::unknown()),
1930                Some(InferredType::unknown()),
1931            ),
1932            source_span: SourceSpan::default(),
1933        }))
1934    }
1935
1936    // Helper to construct some(v). Cannot be used if there is nested constructors such as some(ok(v)))
1937    pub fn some(binding_variable: &str) -> ArmPattern {
1938        ArmPattern::Literal(Box::new(Expr::Option {
1939            expr: Some(Box::new(Expr::Identifier {
1940                variable_id: VariableId::local_with_no_id(binding_variable),
1941                type_annotation: None,
1942                inferred_type: InferredType::unknown(),
1943                source_span: SourceSpan::default(),
1944            })),
1945            type_annotation: None,
1946            inferred_type: InferredType::unknown(),
1947            source_span: SourceSpan::default(),
1948        }))
1949    }
1950
1951    pub fn none() -> ArmPattern {
1952        ArmPattern::Literal(Box::new(Expr::Option {
1953            expr: None,
1954            type_annotation: None,
1955            inferred_type: InferredType::unknown(),
1956            source_span: SourceSpan::default(),
1957        }))
1958    }
1959
1960    pub fn identifier(binding_variable: &str) -> ArmPattern {
1961        ArmPattern::Literal(Box::new(Expr::Identifier {
1962            variable_id: VariableId::global(binding_variable.to_string()),
1963            type_annotation: None,
1964            inferred_type: InferredType::unknown(),
1965            source_span: SourceSpan::default(),
1966        }))
1967    }
1968    pub fn custom_constructor(name: &str, args: Vec<ArmPattern>) -> ArmPattern {
1969        ArmPattern::Constructor(name.to_string(), args)
1970    }
1971}
1972
1973impl Display for Expr {
1974    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1975        write!(f, "{}", text::to_string(self).unwrap())
1976    }
1977}
1978
1979impl Display for ArmPattern {
1980    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1981        write!(f, "{}", text::to_string_arm_pattern(self).unwrap())
1982    }
1983}
1984
1985impl<'de> Deserialize<'de> for Expr {
1986    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1987    where
1988        D: serde::Deserializer<'de>,
1989    {
1990        let value = Value::deserialize(deserializer)?;
1991        match value {
1992            Value::String(expr_string) => match from_string(expr_string.as_str()) {
1993                Ok(expr) => Ok(expr),
1994                Err(message) => Err(serde::de::Error::custom(message.to_string())),
1995            },
1996
1997            e => Err(serde::de::Error::custom(format!(
1998                "Failed to deserialize expression {e}"
1999            ))),
2000        }
2001    }
2002}
2003
2004impl Serialize for Expr {
2005    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2006    where
2007        S: Serializer,
2008    {
2009        match text::to_string(self) {
2010            Ok(value) => Value::serialize(&Value::String(value), serializer),
2011            Err(error) => Err(serde::ser::Error::custom(error.to_string())),
2012        }
2013    }
2014}
2015
2016fn find_expr(expr: &mut Expr, source_span: &SourceSpan) -> Option<Expr> {
2017    let mut expr = expr.clone();
2018    let mut found = None;
2019
2020    type_inference::visit_post_order_rev_mut(&mut expr, &mut |current| {
2021        if found.is_none() {
2022            let span = current.source_span();
2023            if source_span.eq(&span) {
2024                found = Some(current.clone());
2025            }
2026        }
2027    });
2028
2029    found
2030}