use super::*; impl TopLevelComposer { pub fn make_primitives() -> (PrimitiveStore, Unifier) { let mut unifier = Unifier::new(); let int32 = unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(0), fields: HashMap::new().into(), params: HashMap::new().into(), }); let int64 = unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(1), fields: HashMap::new().into(), params: HashMap::new().into(), }); let float = unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(2), fields: HashMap::new().into(), params: HashMap::new().into(), }); let bool = unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(3), fields: HashMap::new().into(), params: HashMap::new().into(), }); let none = unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(4), fields: HashMap::new().into(), params: HashMap::new().into(), }); let primitives = PrimitiveStore { int32, int64, float, bool, none }; crate::typecheck::magic_methods::set_primitives_magic_methods(&primitives, &mut unifier); (primitives, unifier) } /// already include the definition_id of itself inside the ancestors vector /// when first regitering, the type_vars, fields, methods, ancestors are invalid pub fn make_top_level_class_def( index: usize, resolver: Option>>, name: &str, ) -> TopLevelDef { TopLevelDef::Class { name: name.to_string(), object_id: DefinitionId(index), type_vars: Default::default(), fields: Default::default(), methods: Default::default(), ancestors: Default::default(), resolver, } } /// when first registering, the type is a invalid value pub fn make_top_level_function_def( name: String, ty: Type, resolver: Option>>, ) -> TopLevelDef { TopLevelDef::Function { name, signature: ty, var_id: Default::default(), instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver, } } pub fn make_class_method_name(mut class_name: String, method_name: &str) -> String { class_name.push_str(method_name); class_name } pub fn get_class_method_def_info( class_methods_def: &[(String, Type, DefinitionId)], method_name: &str, ) -> Result<(Type, DefinitionId), String> { for (name, ty, def_id) in class_methods_def { if name == method_name { return Ok((*ty, *def_id)); } } Err(format!("no method {} in the current class", method_name)) } /// get all base class def id of a class, including itself pub fn get_all_base( child: DefinitionId, temp_def_list: &[Arc>], ) -> Vec { let mut result: Vec = Vec::new(); let child_def = temp_def_list.get(child.0).unwrap(); let child_def = child_def.read(); let child_def = child_def.deref(); if let TopLevelDef::Class { ancestors, .. } = child_def { for a in ancestors { if let TypeAnnotation::CustomClassKind { id, .. } = a { if *id != child { result.extend(Self::get_all_base(*id, temp_def_list)); } } else { unreachable!("must be class type annotation type") } } } else { unreachable!("this function should only be called with class def id as parameter") } result.push(child); result } }