<commit_before>'''This module performs the return type inference, according to symbolic types, and reorder function declarations according to the return type dependencies.
    * type_all generates a node -> type binding
'''

import ast
import networkx as nx
import operator
from tables import type_to_str, operator_to_lambda, modules, builtin_constants, builtin_constructors
from analysis import global_declarations, constant_value, ordered_global_declarations, type_aliasing, yields
from syntax import PythranSyntaxError
from cxxtypes import *
from intrinsic import MethodIntr

import types
def copy_func(f, name=None):
    return types.FunctionType(f.func_code, f.func_globals, name or f.func_name,
        f.func_defaults, f.func_closure)

# networkx backward compatibility
if not "has_path" in nx.__dict__:
	def has_path(G,source,target):
		try:
			nx.shortest_path(G, source, target)
		except nx.NetworkXNoPath:
			return False
		return True
	nx.has_path=has_path

class Reorder(ast.NodeVisitor):
    def __init__(self, typedeps):
        self.typedeps=typedeps
        none_successors = self.typedeps.successors(TypeDependencies.NoDeps)
        for n in sorted(none_successors): # remove edges that implies a circular dependency
            for p in sorted(self.typedeps.predecessors(n)):
                if nx.has_path(self.typedeps,n,p):
                    self.typedeps.remove_edge(p,n)
        #nx.write_dot(self.typedeps,"b.dot")

    def visit_Module(self, node):
        newbody=list()
        olddef=list()
        for stmt in node.body:
            if isinstance(stmt, ast.FunctionDef):
                olddef.append(stmt)
            else: newbody.append(stmt)
        newdef = [ f for f in nx.topological_sort(self.typedeps, ordered_global_declarations(node)) if isinstance(f, ast.FunctionDef) ]
        assert set(newdef) == set(olddef)
        node.body=newbody + newdef


class TypeDependencies(ast.NodeVisitor):

    NoDeps="None"

    def __init__(self, name_to_node):
        self.types=nx.DiGraph()
        for k,v in name_to_node.iteritems():<commit_msg>Improve error reporting for infinite function recursion.<commit_after>'''This module performs the return type inference, according to symbolic types, and reorder function declarations according to the return type dependencies.
    * type_all generates a node -> type binding
'''

import ast
import networkx as nx
import operator
from tables import type_to_str, operator_to_lambda, modules, builtin_constants, builtin_constructors
from analysis import global_declarations, constant_value, ordered_global_declarations, type_aliasing, yields
from syntax import PythranSyntaxError
from cxxtypes import *
from intrinsic import MethodIntr

import types
def copy_func(f, name=None):
    return types.FunctionType(f.func_code, f.func_globals, name or f.func_name,
        f.func_defaults, f.func_closure)

# networkx backward compatibility
if not "has_path" in nx.__dict__:
	def has_path(G,source,target):
		try:
			nx.shortest_path(G, source, target)
		except nx.NetworkXNoPath:
			return False
		return True
	nx.has_path=has_path

class Reorder(ast.NodeVisitor):
    def __init__(self, typedeps):
        self.typedeps=typedeps
        none_successors = self.typedeps.successors(TypeDependencies.NoDeps)
        for n in sorted(none_successors): # remove edges that implies a circular dependency
            for p in sorted(self.typedeps.predecessors(n)):
                if nx.has_path(self.typedeps,n,p):
                    self.typedeps.remove_edge(p,n)
        #nx.write_dot(self.typedeps,"b.dot")

    def visit_Module(self, node):
        newbody=list()
        olddef=list()
        for stmt in node.body:
            if isinstance(stmt, ast.FunctionDef):
                olddef.append(stmt)
            else: newbody.append(stmt)
            try: newdef = [ f for f in nx.topological_sort(self.typedeps, ordered_global_declarations(node)) if isinstance(f, ast.FunctionDef) ]
            except nx.exception.NetworkXUnfeasible: raise PythranSyntaxError("Infinite function recursion",stmt)
        assert set(newdef) == set(olddef)
        node.body=newbody + newdef


class TypeDependencies(ast.NodeVisitor):

    NoDeps="None"

    def __init__(self, name_to_node):
        self.types=nx.DiGraph()
        for k,v in name_to_node.iteritems():
{'fraction_non_alphanumeric': 0.08416184971098266, 'fraction_numerical': 0.0, 'mean_word_length': 3.616862326574173, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4778227', 'n_tokens_mistral': 1344, 'n_tokens_neox': 1299, 'n_words': 340}