1use crate::TypeContext;
6use crate::err::{Error, ErrorKind};
7use crate::{Analyzer, LocationSide};
8use source_map_node::Node;
9use swamp_semantic::{ArgumentExpressionOrLocation, MutOrImmutableExpression};
10use swamp_types::prelude::*;
11
12impl Analyzer<'_> {
13 pub fn analyze_argument(
16 &mut self,
17 fn_parameter: &TypeForParameter,
18 argument_expr: &swamp_ast::MutableOrImmutableExpression,
19 ) -> Result<ArgumentExpressionOrLocation, Error> {
20 let context = TypeContext::new_argument(&fn_parameter.resolved_type);
21
22 let mut_or_immutable = if fn_parameter.is_mutable {
23 if argument_expr.is_mutable.is_none() {
24 return Err(self.create_err(
25 ErrorKind::ArgumentIsNotMutable,
26 &argument_expr.expression.node,
27 ));
28 }
29 let mut_location =
30 self.analyze_to_location(&argument_expr.expression, &context, LocationSide::Rhs)?;
31 ArgumentExpressionOrLocation::Location(mut_location)
32 } else {
33 if argument_expr.is_mutable.is_some() {
34 return Err(self.create_err(
35 ErrorKind::ParameterIsNotMutable,
36 &argument_expr.expression.node,
37 ));
38 }
39 let resolved_expr = self.analyze_expression(&argument_expr.expression, &context)?;
40 ArgumentExpressionOrLocation::Expression(resolved_expr)
41 };
42
43 Ok(mut_or_immutable)
44 }
45
46 pub fn analyze_and_verify_parameters(
49 &mut self,
50 node: &Node,
51 fn_parameters: &[TypeForParameter],
52 arguments: &[swamp_ast::MutableOrImmutableExpression],
53 ) -> Result<Vec<ArgumentExpressionOrLocation>, Error> {
54 if fn_parameters.len() != arguments.len() {
55 return Err(self.create_err_resolved(
56 ErrorKind::WrongNumberOfArguments(fn_parameters.len(), arguments.len()),
57 node,
58 ));
59 }
60
61 let mut resolved_arguments = Vec::new();
62 for (fn_parameter, argument_expr) in fn_parameters.iter().zip(arguments) {
63 let mut_or_immutable = self.analyze_argument(fn_parameter, argument_expr)?;
64 resolved_arguments.push(mut_or_immutable);
65 }
66
67 Ok(resolved_arguments)
68 }
69
70 pub fn analyze_mut_or_immutable_expression(
73 &mut self,
74 expr: &swamp_ast::MutableOrImmutableExpression,
75 context: &TypeContext,
76 location_side: LocationSide,
77 ) -> Result<MutOrImmutableExpression, Error> {
78 let is_mutable = self.to_node_option(Option::from(&expr.is_mutable));
79 let expression_or_location = if is_mutable.is_some() {
80 ArgumentExpressionOrLocation::Location(self.analyze_to_location(
81 &expr.expression,
82 context,
83 location_side,
84 )?)
85 } else {
86 ArgumentExpressionOrLocation::Expression(
87 self.analyze_expression(&expr.expression, context)?,
88 )
89 };
90
91 Ok(MutOrImmutableExpression {
92 expression_or_location,
93 is_mutable,
94 })
95 }
96}