# Path: krakatau-lib/src/main/resources/Lib/Krakatau/verifier/verifier_types.py
# def _makeinfo(tag, dim=0, extra=None):
# def T_ADDRESS(entry):
# def T_OBJECT(name):
# def T_ARRAY(baset, newDimensions=1):
# def T_UNINIT_OBJECT(origin):
# def objOrArray(fi): #False on uninitialized
# def unSynthesizeType(t):
# def decrementDim(fi):
# def withNoDimension(fi):
# def _decToObjArray(fi):
# def _arrbase(fi):
# def mergeTypes(env, t1, t2, forAssignment=False):
# def isAssignable(env, t1, t2):
# def vt_toStr(self):
# T_INVALID = _makeinfo(None)
# T_INT = _makeinfo('.int')
# T_FLOAT = _makeinfo('.float')
# T_DOUBLE = _makeinfo('.double')
# T_DOUBLE2 = _makeinfo('.double2') #Hotspot only uses these in locals, but we use them on the stack too to simplify things
# T_LONG = _makeinfo('.long')
# T_LONG2 = _makeinfo('.long2')
# T_NULL = _makeinfo('.obj')
# T_UNINIT_THIS = _makeinfo('.init')
# T_BYTE = _makeinfo('.byte')
# T_SHORT = _makeinfo('.short')
# T_CHAR = _makeinfo('.char')
# T_BOOL = _makeinfo('.boolean') #Hotspot doesn't have a bool type, but we can use this elsewhere
# OBJECT_INFO = T_OBJECT('java/lang/Object')
# CLONE_INFO = T_OBJECT('java/lang/Cloneable')
# SERIAL_INFO = T_OBJECT('java/io/Serializable')
# THROWABLE_INFO = T_OBJECT('java/lang/Throwable')
# 
# Path: krakatau-lib/src/main/resources/Lib/Krakatau/error.py
# class ClassLoaderError(Exception):
#     def __init__(self, typen=None, data=""):
#         self.type = typen
#         self.data = data
# 
#         message = u"\n{}: {}".format(typen, data) if typen else unicode(data)
#         super(ClassLoaderError, self).__init__(message)


from ..verifier import verifier_types as vtypes
from ..error import ClassLoaderError
        return yname in ('java/lang/Object','java/lang/Cloneable','java/io/Serializable')
    else:
        return isBaseTClass(x) and isBaseTClass(y) and env.isSubclass(xname, yname)

#Will not return interface unless all inputs are same interface or null
def commonSupertype(env, tts):
    assert(hasattr(env, 'getClass')) #catch common errors where we forget the env argument

    tts = set(tts)
    tts.discard(NullTT)

    if len(tts) == 1:
        return tts.pop()
    elif not tts:
        return NullTT

    dims = map(dim, tts)
    newdim = min(dims)
    if max(dims) > newdim or any(baset(tt) == 'java/lang/Object' for tt in tts):
        return TypeTT('java/lang/Object', newdim)
    # if any are primative arrays, result is object array of dim-1
    if not all(isBaseTClass(tt) for tt in tts):
        return TypeTT('java/lang/Object', newdim-1)

    # find common superclass of base types
    baselists = [env.getSupers(baset(tt)) for tt in tts]
    common = [x for x in zip(*baselists) if len(set(x)) == 1]
    return TypeTT(common[-1][0], newdim)

######################################################################################################

# Path: krakatau-lib/src/main/resources/Lib/Krakatau/verifier/verifier_types.py
# def _makeinfo(tag, dim=0, extra=None):
# def T_ADDRESS(entry):
# def T_OBJECT(name):
# def T_ARRAY(baset, newDimensions=1):
# def T_UNINIT_OBJECT(origin):
# def objOrArray(fi): #False on uninitialized
# def unSynthesizeType(t):
# def decrementDim(fi):
# def withNoDimension(fi):
# def _decToObjArray(fi):
# def _arrbase(fi):
# def mergeTypes(env, t1, t2, forAssignment=False):
# def isAssignable(env, t1, t2):
# def vt_toStr(self):
# T_INVALID = _makeinfo(None)
# T_INT = _makeinfo('.int')
# T_FLOAT = _makeinfo('.float')
# T_DOUBLE = _makeinfo('.double')
# T_DOUBLE2 = _makeinfo('.double2') #Hotspot only uses these in locals, but we use them on the stack too to simplify things
# T_LONG = _makeinfo('.long')
# T_LONG2 = _makeinfo('.long2')
# T_NULL = _makeinfo('.obj')
# T_UNINIT_THIS = _makeinfo('.init')
# T_BYTE = _makeinfo('.byte')
# T_SHORT = _makeinfo('.short')
# T_CHAR = _makeinfo('.char')
# T_BOOL = _makeinfo('.boolean') #Hotspot doesn't have a bool type, but we can use this elsewhere
# OBJECT_INFO = T_OBJECT('java/lang/Object')
# CLONE_INFO = T_OBJECT('java/lang/Cloneable')
# SERIAL_INFO = T_OBJECT('java/io/Serializable')
# THROWABLE_INFO = T_OBJECT('java/lang/Throwable')
# 
# Path: krakatau-lib/src/main/resources/Lib/Krakatau/error.py
# class ClassLoaderError(Exception):
#     def __init__(self, typen=None, data=""):
#         self.type = typen
#         self.data = data
# 
#         message = u"\n{}: {}".format(typen, data) if typen else unicode(data)
#         super(ClassLoaderError, self).__init__(message)


# Path: krakatau-lib/src/main/resources/Lib/Krakatau/ssa/objtypes.py
from ..verifier import verifier_types as vtypes
from ..error import ClassLoaderError

        return yname in ('java/lang/Object','java/lang/Cloneable','java/io/Serializable')
    else:
        return isBaseTClass(x) and isBaseTClass(y) and env.isSubclass(xname, yname)

#Will not return interface unless all inputs are same interface or null
def commonSupertype(env, tts):
    assert(hasattr(env, 'getClass')) #catch common errors where we forget the env argument

    tts = set(tts)
    tts.discard(NullTT)

    if len(tts) == 1:
        return tts.pop()
    elif not tts:
        return NullTT

    dims = map(dim, tts)
    newdim = min(dims)
    if max(dims) > newdim or any(baset(tt) == 'java/lang/Object' for tt in tts):
        return TypeTT('java/lang/Object', newdim)
    # if any are primative arrays, result is object array of dim-1
    if not all(isBaseTClass(tt) for tt in tts):
        return TypeTT('java/lang/Object', newdim-1)

    # find common superclass of base types
    baselists = [env.getSupers(baset(tt)) for tt in tts]
    common = [x for x in zip(*baselists) if len(set(x)) == 1]
    return TypeTT(common[-1][0], newdim)

######################################################################################################

_verifierConvert = {vtypes.T_INT:IntTT, vtypes.T_FLOAT:FloatTT, vtypes.T_LONG:LongTT,