mxmlextrema_mxmlcaot/semantics/
apply_type.rs

1use crate::ns::*;
2
3/// Operation for applying types to a parameterized type across several entities.
4pub struct ApplyType<'a>(pub &'a Database);
5
6impl<'a> ApplyType<'a> {
7    pub fn exec(&mut self, thing: &Entity, type_params: &SharedArray<Entity>, substitute_types: &SharedArray<Entity>) -> Entity {
8        if thing.is::<UnresolvedEntity>() || thing.is::<InvalidationEntity>() {
9            return thing.clone();
10        } else if thing.is::<Type>() {
11            if thing.is::<FunctionType>() {
12                let result_type = thing.result_type().apply_type(self.0, type_params, substitute_types);
13                let mut params: Vec<Rc<SemanticFunctionTypeParameter>> = Vec::new();
14                for param in thing.params().iter() {
15                    params.push(Rc::new(param.apply_type(self.0, type_params, substitute_types)));
16                }
17                return self.0.factory().create_function_type(params, result_type);
18            } else if thing.is::<NullableType>() {
19                let base = &thing.base().apply_type(self.0, type_params, substitute_types);
20                return self.0.factory().create_nullable_type(base);
21            } else if thing.is::<NonNullableType>() {
22                let base = &thing.base().apply_type(self.0, type_params, substitute_types);
23                return self.0.factory().create_non_nullable_type(base);
24            } else if thing.is::<TupleType>() {
25                let el: Vec<Entity> = thing.element_types().iter().map(|t| t.apply_type(self.0, type_params, substitute_types)).collect();
26                return self.0.factory().create_tuple_type(el);
27            } else if thing.is::<TypeAfterSubstitution>() {
28                let new_substitute_types: SharedArray<Entity> = thing.substitute_types().iter().map(|t| t.apply_type(self.0, type_params, substitute_types)).collect();
29                return self.0.factory().create_type_after_substitution(&thing.origin(), &new_substitute_types);
30            } else if thing.is::<TypeParameterType>() {
31                let i = type_params.index_of(&thing);
32                if let Some(i) = i {
33                    return substitute_types.get(i).unwrap();
34                }
35            }
36            return thing.clone();
37        } else if thing.is::<VariableSlot>() {
38            self.0.factory().create_variable_slot_after_substitution(thing, type_params, substitute_types)
39        } else if thing.is::<VirtualSlot>() {
40            self.0.factory().create_virtual_slot_after_substitution(thing, type_params, substitute_types)
41        } else if thing.is::<MethodSlot>() {
42            self.0.factory().create_method_slot_after_substitution(thing, type_params, substitute_types)
43        } else {
44            panic!()
45        }
46    }
47}