# Path: javadecompiler/Krakatau/ssa/objtypes.py
# def isSubtype(env, x, y):
# def commonSupertype(env, tts):
# def verifierToSynthetic_seq(vtypes):
# def verifierToSynthetic(vtype):
# def declTypeToActual(env, decltype):


from ..ssa.objtypes import IntTT, ShortTT, CharTT, ByteTT, BoolTT, BExpr
from . import ast
##############################################################
def visitStatementTree(scope, callback):
    for item in scope.statements:
        for sub in item.getScopes():
            visitStatementTree(sub, callback=callback)
        if item.expr is not None:
            callback(item, item.expr)

int_tags = frozenset(tt[0] for tt in [IntTT, ShortTT, CharTT, ByteTT, BoolTT])
array_tags = frozenset([ByteTT[0], BoolTT[0], BExpr])

def boolizeVars(root, arg_vars):
    varlist = []
    sets = UnionFind()

    def visitExpr(expr, forceExact=False):
        #see if we have to merge
        if isinstance(expr, ast.Assignment) or isinstance(expr, ast.BinaryInfix) and expr.opstr in ('==','!=','&','|','^'):
            subs = [visitExpr(param) for param in expr.params]
            sets.union(*subs) # these operators can work on either type but need the same type on each side
        elif isinstance(expr, ast.ArrayAccess):
            sets.union(False, visitExpr(expr.params[1])) # array index is int only
        elif isinstance(expr, ast.BinaryInfix) and expr.opstr in ('* / % + - << >> >>>'):
            sets.union(False, visitExpr(expr.params[0])) # these operators are int only
            sets.union(False, visitExpr(expr.params[1]))

        if isinstance(expr, ast.Local):
            tag, dim = expr.dtype
            if (dim == 0 and tag in int_tags) or (dim > 0 and tag in array_tags):
                # the only "unknown" vars are bexpr[] and ints. All else have fixed types

# Path: javadecompiler/Krakatau/ssa/objtypes.py
# def isSubtype(env, x, y):
# def commonSupertype(env, tts):
# def verifierToSynthetic_seq(vtypes):
# def verifierToSynthetic(vtype):
# def declTypeToActual(env, decltype):


# Path: javadecompiler/Krakatau/java/boolize.py
from ..ssa.objtypes import IntTT, ShortTT, CharTT, ByteTT, BoolTT, BExpr
from . import ast

##############################################################
def visitStatementTree(scope, callback):
    for item in scope.statements:
        for sub in item.getScopes():
            visitStatementTree(sub, callback=callback)
        if item.expr is not None:
            callback(item, item.expr)

int_tags = frozenset(tt[0] for tt in [IntTT, ShortTT, CharTT, ByteTT, BoolTT])
array_tags = frozenset([ByteTT[0], BoolTT[0], BExpr])

def boolizeVars(root, arg_vars):
    varlist = []
    sets = UnionFind()

    def visitExpr(expr, forceExact=False):
        #see if we have to merge
        if isinstance(expr, ast.Assignment) or isinstance(expr, ast.BinaryInfix) and expr.opstr in ('==','!=','&','|','^'):
            subs = [visitExpr(param) for param in expr.params]
            sets.union(*subs) # these operators can work on either type but need the same type on each side
        elif isinstance(expr, ast.ArrayAccess):
            sets.union(False, visitExpr(expr.params[1])) # array index is int only
        elif isinstance(expr, ast.BinaryInfix) and expr.opstr in ('* / % + - << >> >>>'):
            sets.union(False, visitExpr(expr.params[0])) # these operators are int only
            sets.union(False, visitExpr(expr.params[1]))

        if isinstance(expr, ast.Local):
            tag, dim = expr.dtype
            if (dim == 0 and tag in int_tags) or (dim > 0 and tag in array_tags):
                # the only "unknown" vars are bexpr[] and ints. All else have fixed types

                if forceExact or (tag != BExpr and tag != IntTT[0]):