swamp_script_analyzer/
types.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5
6use crate::Analyzer;
7use crate::err::Error;
8use swamp_script_types::{Signature, Type, TypeForParameter};
9
10impl Analyzer<'_> {
11    /// # Errors
12    ///
13    pub fn analyze_map_type(
14        &mut self,
15        ast_key_type: &swamp_script_ast::Type,
16        ast_value_type: &swamp_script_ast::Type,
17    ) -> Result<(Type, Type), Error> {
18        // TODO: Check for an existing map type with exact same type
19
20        let key_type = self.analyze_type(ast_key_type)?;
21        let value_type = self.analyze_type(ast_value_type)?;
22
23        Ok((key_type, value_type))
24    }
25
26    /// # Errors
27    ///
28    pub fn analyze_slice_type(&mut self, ast_type: &swamp_script_ast::Type) -> Result<Type, Error> {
29        self.analyze_type(ast_type)
30    }
31
32    /// # Errors
33    ///
34    pub fn analyze_type(&mut self, ast_type: &swamp_script_ast::Type) -> Result<Type, Error> {
35        let resolved = match ast_type {
36            swamp_script_ast::Type::AnonymousStruct(ast_struct) => {
37                let struct_ref = self.analyze_anonymous_struct_type(ast_struct)?;
38                Type::AnonymousStruct(struct_ref.into())
39            }
40            swamp_script_ast::Type::Slice(ast_type) => {
41                Type::Vec(Box::from(self.analyze_slice_type(ast_type)?))
42            }
43            swamp_script_ast::Type::SlicePair(key_type, value_type) => {
44                let (key_type, value_type) = self.analyze_map_type(key_type, value_type)?;
45                Type::Map(Box::from(key_type), Box::from(value_type))
46            }
47            swamp_script_ast::Type::Tuple(types) => Type::Tuple(self.analyze_types(types)?),
48            swamp_script_ast::Type::Generic(base_type, generic_types) => {
49                let base_type = self.analyze_type(base_type)?;
50                Type::Generic(Box::new(base_type), self.analyze_types(generic_types)?)
51            }
52            swamp_script_ast::Type::Named(ast_type_reference) => {
53                self.analyze_named_type(ast_type_reference)?
54            }
55            swamp_script_ast::Type::Optional(inner_type_ast, _node) => {
56                let inner_resolved_type = self.analyze_type(inner_type_ast)?;
57                Type::Optional(Box::from(inner_resolved_type))
58            }
59            swamp_script_ast::Type::Function(parameters, return_type) => {
60                let parameter_types = self.analyze_param_types(parameters)?;
61
62                let resolved_return_type = self.analyze_type(return_type)?;
63                Type::Function(Signature {
64                    parameters: parameter_types,
65                    return_type: Box::new(resolved_return_type),
66                })
67            }
68        };
69
70        Ok(resolved)
71    }
72
73    pub(crate) fn analyze_types(
74        &mut self,
75        types: &[swamp_script_ast::Type],
76    ) -> Result<Vec<Type>, Error> {
77        let mut resolved_types = Vec::new();
78        for some_type in types {
79            resolved_types.push(self.analyze_type(some_type)?);
80        }
81        Ok(resolved_types)
82    }
83
84    fn analyze_param_types(
85        &mut self,
86        type_for_parameters: &Vec<swamp_script_ast::TypeForParameter>,
87    ) -> Result<Vec<TypeForParameter>, Error> {
88        let mut vec = Vec::new();
89        for x in type_for_parameters {
90            vec.push(TypeForParameter {
91                name: String::new(),
92                resolved_type: self.analyze_type(&x.ast_type)?,
93                is_mutable: x.is_mutable,
94                node: None,
95            });
96        }
97
98        Ok(vec)
99    }
100}