swamp_analyzer/
call.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use 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    /// # Errors
14    ///
15    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    /// # Errors
47    ///
48    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    /// # Errors
71    ///
72    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}