From a10ab81ee7b2a8a25e94b5ae864a2f390906c21a Mon Sep 17 00:00:00 2001 From: ychenfo Date: Mon, 13 Sep 2021 01:18:21 +0800 Subject: [PATCH] toplevel composer: add ast to class methods, suppress warning --- nac3core/src/toplevel/composer.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/nac3core/src/toplevel/composer.rs b/nac3core/src/toplevel/composer.rs index 722c87c11..e11f17b19 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -1,8 +1,9 @@ use super::*; +type DefAst = (Arc>, Option>); pub struct TopLevelComposer { // list of top level definitions, same as top level context - pub definition_ast_list: Vec<(Arc>, Option>)>, + pub definition_ast_list: Vec, // start as a primitive unifier, will add more top_level defs inside pub unifier: Unifier, // primitive store @@ -69,7 +70,7 @@ impl TopLevelComposer { ) .into(), // FIXME: all the big unifier or? - unifiers: Default::default(), + unifiers: Arc::new(RwLock::new(vec![(self.unifier.get_shared_unifier(), self.primitives_ty)])), } } @@ -118,14 +119,16 @@ impl TopLevelComposer { // parse class def body and register class methods into the def list. // module's symbol resolver would not know the name of the class methods, // thus cannot return their definition_id - let mut class_method_name_def_ids: Vec<( + type MethodInfo = ( // the simple method name without class name String, // in this top level def, method name is prefixed with the class name Arc>, DefinitionId, Type, - )> = Vec::new(); + ast::Stmt<()>, + ); + let mut class_method_name_def_ids: Vec = Vec::new(); // we do not push anything to the def list, so we keep track of the index // and then push in the correct order after the for loop let mut class_method_index_offset = 0; @@ -166,6 +169,7 @@ impl TopLevelComposer { .into(), DefinitionId(method_def_id), dummy_method_type.0, + b.clone(), )); } else { // do nothing @@ -179,7 +183,7 @@ impl TopLevelComposer { // move the ast to the entry of the class in the ast_list class_def_ast.1 = Some(ast); // get the methods into the top level class_def - for (name, _, id, ty) in &class_method_name_def_ids { + for (name, _, id, ty, ..) in &class_method_name_def_ids { let mut class_def = class_def_ast.0.write(); if let TopLevelDef::Class { methods, .. } = class_def.deref_mut() { methods.push((name.clone(), *ty, *id)) @@ -189,8 +193,8 @@ impl TopLevelComposer { } // now class_def_ast and class_method_def_ast_ids are ok, put them into actual def list in correct order self.definition_ast_list.push(class_def_ast); - for (_, def, ..) in class_method_name_def_ids { - self.definition_ast_list.push((def, None)); + for (_, def, _, _, ast) in class_method_name_def_ids { + self.definition_ast_list.push((def, Some(ast))); } // put the constructor into the def_list @@ -209,7 +213,7 @@ impl TopLevelComposer { } let fun_name = name.to_string(); if !defined_function_name.insert({ - let mut n = mod_path.clone(); + let mut n = mod_path; n.push_str(name.as_str()); n }) { @@ -555,16 +559,19 @@ impl TopLevelComposer { for (function_def, function_ast) in def_list.iter().skip(5) { let mut function_def = function_def.write(); let function_def = function_def.deref_mut(); - let function_ast = if let Some(function_ast) = function_ast { - function_ast + let function_ast = if let Some(x) = function_ast.as_ref() { + x } else { - // no ast, class method, continue continue; }; if let TopLevelDef::Function { signature: dummy_ty, resolver, var_id, .. } = function_def { + if matches!(unifier.get_ty(*dummy_ty).as_ref(), TypeEnum::TFunc(_)) { + // already have a function type, is class method, skip + continue; + } if let ast::StmtKind::FunctionDef { args, returns, .. } = &function_ast.node { let resolver = resolver.as_ref(); let resolver = resolver.unwrap();