def analyse_expressions(self, env): """ Analyse the expressions. Take care to only evaluate default arguments once and clone the result for all specializations """ for fused_compound_type in self.fused_compound_types: for fused_type in fused_compound_type.get_fused_types(): for specialization_type in fused_type.types: if specialization_type.is_complex: specialization_type.create_declaration_utility_code( env) if self.py_func: self.__signatures__ = self.__signatures__.analyse_expressions(env) self.py_func = self.py_func.analyse_expressions(env) self.resulting_fused_function = self.resulting_fused_function.analyse_expressions( env) self.fused_func_assignment = self.fused_func_assignment.analyse_expressions( env) self.defaults = defaults = [] for arg in self.node.args: if arg.default: arg.default = arg.default.analyse_expressions(env) defaults.append(ProxyNode(arg.default)) else: defaults.append(None) for i, stat in enumerate(self.stats): stat = self.stats[i] = stat.analyse_expressions(env) if isinstance(stat, FuncDefNode): for arg, default in zip(stat.args, defaults): if default is not None: arg.default = CloneNode(default).coerce_to( arg.type, env) if self.py_func: args = [CloneNode(default) for default in defaults if default] self.defaults_tuple = TupleNode(self.pos, args=args) self.defaults_tuple = self.defaults_tuple.analyse_types( env, skip_children=True) self.defaults_tuple = ProxyNode(self.defaults_tuple) self.code_object = ProxyNode( self.specialized_pycfuncs[0].code_object) fused_func = self.resulting_fused_function.arg fused_func.defaults_tuple = CloneNode(self.defaults_tuple) fused_func.code_object = CloneNode(self.code_object) for i, pycfunc in enumerate(self.specialized_pycfuncs): pycfunc.code_object = CloneNode(self.code_object) pycfunc = self.specialized_pycfuncs[i] = pycfunc.analyse_types( env) pycfunc.defaults_tuple = CloneNode(self.defaults_tuple) return self