1use crate::TypeContext;
6use crate::{Analyzer, LocationSide};
7use source_map_node::Node;
8use swamp_semantic::ArgumentExpression;
9use swamp_semantic::err::ErrorKind;
10use swamp_types::prelude::*;
11
12pub struct MaybeBorrowMutRefExpression {
13 pub ast_expression: swamp_ast::Expression,
14 pub has_borrow_mutable_reference: Option<Node>,
15}
16
17impl Analyzer<'_> {
18 pub fn analyze_argument(
31 &mut self,
32 fn_parameter: &TypeForParameter,
33 argument_expr: &swamp_ast::Expression,
34 ) -> ArgumentExpression {
35 let context = TypeContext::new_argument(
36 &fn_parameter.resolved_type,
37 false, );
39
40 let ref_checked_argument = self.analyze_maybe_ref_expression(argument_expr);
41
42 if fn_parameter.is_mutable {
43 if ref_checked_argument.has_borrow_mutable_reference.is_none() {
44 let expr = self.create_err(ErrorKind::ArgumentIsNotMutable, &argument_expr.node);
46 return ArgumentExpression::Expression(expr);
47 }
48 let mut_location = self.analyze_to_location(
49 &ref_checked_argument.ast_expression,
50 &context,
51 LocationSide::Rhs,
52 );
53
54 ArgumentExpression::BorrowMutableReference(mut_location)
55 } else {
56 if ref_checked_argument.has_borrow_mutable_reference.is_some() {
57 {
58 let expr =
59 self.create_err(ErrorKind::ParameterIsNotMutable, &argument_expr.node);
60 return ArgumentExpression::Expression(expr);
62 }
63 }
64 let resolved_expr = self.analyze_expression(argument_expr, &context);
65 ArgumentExpression::Expression(resolved_expr)
66 }
67 }
68
69 pub fn analyze_and_verify_parameters(
72 &mut self,
73 node: &swamp_ast::Node,
74 fn_parameters: &[TypeForParameter],
75 arguments: &[swamp_ast::Expression],
76 ) -> Vec<ArgumentExpression> {
77 if fn_parameters.len() != arguments.len() {
78 self.add_err(
79 ErrorKind::WrongNumberOfArguments(fn_parameters.len(), arguments.len()),
80 node,
81 );
82 return vec![];
83 }
84
85 let mut resolved_arguments = Vec::new();
86 for (fn_parameter, argument_expr) in fn_parameters.iter().zip(arguments) {
87 let mut_or_immutable = self.analyze_argument(fn_parameter, argument_expr);
88 resolved_arguments.push(mut_or_immutable);
89 }
90
91 resolved_arguments
92 }
93
94 pub fn analyze_mut_or_immutable_expression(
97 &mut self,
98 expr: &swamp_ast::Expression,
99 context: &TypeContext,
100 location_side: LocationSide,
101 ) -> ArgumentExpression {
102 let maybe_borrow_or_normal_expression = self.analyze_maybe_ref_expression(expr);
103
104 if maybe_borrow_or_normal_expression
105 .has_borrow_mutable_reference
106 .is_some()
107 {
108 ArgumentExpression::BorrowMutableReference(self.analyze_to_location(
109 &maybe_borrow_or_normal_expression.ast_expression,
110 context,
111 location_side,
112 ))
113 } else {
114 ArgumentExpression::Expression(
115 self.analyze_expression(&maybe_borrow_or_normal_expression.ast_expression, context),
116 )
117 }
118 }
119}