<commit_before>from PythonUtil import *    
from types import *
import string
import FFIConstants
import FFISpecs

"""
Things that are not supported:
 - Overloading a function based on an enum being differentiated from an int
 - Type names from C++ cannot have __enum__ in their name
 - Overloading static and non-static methods with the same name
"""

AT_not_atomic = 0
AT_int = 1
AT_float = 2
AT_double = 3
AT_bool = 4
AT_char = 5
AT_void = 6
AT_string = 7

def cullOverloadedMethods(fullMethodDict):
    """
    Find all the entries that have multiple indexes for the same method name
    Get rid of all others.
    """
    tmpDict = {}
    # For each class
    for methodName in fullMethodDict.keys():
        methodList = fullMethodDict[methodName]
        # See if this method has more than one function index (overloaded)
        if (len(methodList) > 1):
            tmpDict[methodName] = methodList
            # Mark all the method specifications as overloaded
            for methodSpec in methodList:
                methodSpec.overloaded = 1

    return tmpDict


def getTypeName(classTypeDesc, typeDesc):
    """
    Map the interrogate primitive type names to python type names.
    We assume that the module using this has imported the types module.
    It is valid to pass in None for classTypeDesc if we are not in a class
    """

    typeName = typeDesc.getFullNestedName()

    # Atomic C++ types are type checked against the builtin
    # Python types. This code sorts out the mapping
    if typeDesc.isAtomic():
        
        # Ints, bools, and chars are treated as ints.
        # Enums are special and are not atomic, see below
        if ((typeDesc.atomicType == AT_int) or
            (typeDesc.atomicType == AT_bool) or
            (typeDesc.atomicType == AT_char)):
            return 'types.IntType'
        
        # Floats and doubles are both floats in Python
        elif ((typeDesc.atomicType == AT_float) or
            (typeDesc.atomicType == AT_double)):
            return 'types.FloatType'

        # Strings are treated as Python strings
        elif ((typeDesc.atomicType == AT_string)):
            return 'types.StringType'
        
        elif (typeDesc.atomicType == AT_void):
            # Convert the void type to None type... I guess...
            # So far we do not have any code that uses this
            return 'types.NoneType'

        else:
            FFIConstants.notify.error("Unknown atomicType: " + typeDesc.atomicType)
        
    # If the type is an enum, we really want to treat it like an int
    # To handle this, the type will have __enum__ in the name
    # Usually it will start the typeName, but some typeNames have the
    # surrounding class as part of their name
    # like BoundedObject.__enum__BoundingVolumeType
    elif (typeName.find('__enum__') >= 0):
        return 'types.IntType'

    # If it was not atomic or enum, it must be a class which is a
    # bit trickier because we output different things depending on the
    # scoping of the type. 
    else:

        #   classTypeDesc  typeDesc fullNestedName Resulting TypeName
        # 1   Outer         Other     Other          Other.Other
        # 2   Outer         Outer     Outer          Outer
        # 3   Outer         Inner     Outer.Inner    Outer.Inner
        # 4   Inner         Other     Other          Other.Other
        # 5   Inner         Outer     Outer          Outer
        # 6   Inner         Inner     Outer.Inner    Outer.Inner
        # 7   None          Other     Other          Other.Other

        # CASES 1,4, and 7 are the only ones that are different from the full
        # nested name, returning Other.Other

        returnNestedTypeNames = string.split(typeName, '.')
        returnModuleName = returnNestedTypeNames[0] 

        if classTypeDesc:
            classTypeName = classTypeDesc.getFullNestedName()
            classNestedTypeNames = string.split(classTypeName, '.')
            # If there is no nesting, return typeName.typeName
            if ((not (classTypeDesc.foreignTypeName in returnNestedTypeNames)) and
                (not (typeDesc.foreignTypeName in classNestedTypeNames))):
                return (returnModuleName + '.' + typeName)
            # All other cases, we just need typeName
            else:
                return typeName
        else:
            # If you had no class, you need to specify module plus typename
            return (returnModuleName + '.' + typeName)


def inheritsFrom(type1, type2):
    """
    Return true if type1 inherits from type2
    This works by recursively checking parentTypes for type1
    """
    if type1.parentTypes:
        if type2 in type1.parentTypes:
            return 1
        else:
            result = 0
            for type in type1.parentTypes:
                result = (result or inheritsFrom(type, type2))
            return result
    else:
        return 0

def getInheritanceLevel(type, checkNested = 1):
    #    if (len(type.parentTypes) == 0):
    #        return 0
    ##if type.isNested:
    ##    level = 1+getInheritanceLevel(type.outerType, 0)
    ##else:
    ##    level = 0
    level = 0
    if type.isNested:
        offset = getInheritanceLevel(type.outerType, 0)
    else:
        offset = 0
    for parentType in type.parentTypes:
        level = max(level, 1+getInheritanceLevel(parentType))
    if checkNested:
        for nestedType in type.nestedTypes:
            level = max(level, 1+getInheritanceLevel(nestedType))
    return level + offset

def inheritanceLevelSort(type1, type2):
    level1 = getInheritanceLevel(type1)
    level2 = getInheritanceLevel(type2)
    if (level1 == level2):
        return 0
    elif (level1 < level2):
        return -1
    elif (level1 > level2):
        return 1


def subclass(type1, type2):
    """
    Helper funcion used in sorting classes by inheritance
    """
    # If the types are the same, return 0
    if type1 == type2:
	return 0
    # If you have no args, sort you first
    elif (type1 == 0):
        return 1
    elif (type2 == 0):
        return -1
    # If class1 inherits from class2 return 1
    elif inheritsFrom(type1, type2):
	return 1
    # If class2 inherits from class1 return -1
    elif inheritsFrom(type2, type1):
        return -1
    else:
        # This is the dont care case. We must specify a sorting
        # rule just so it is not arbitrary<commit_msg>*** empty log message ***<commit_after>from PythonUtil import *    
from types import *
import string
import FFIConstants
import FFISpecs

"""
Things that are not supported:
 - Overloading a function based on an enum being differentiated from an int
 - Type names from C++ cannot have __enum__ in their name
 - Overloading static and non-static methods with the same name
"""

AT_not_atomic = 0
AT_int = 1
AT_float = 2
AT_double = 3
AT_bool = 4
AT_char = 5
AT_void = 6
AT_string = 7

def cullOverloadedMethods(fullMethodDict):
    """
    Find all the entries that have multiple indexes for the same method name
    Get rid of all others.
    """
    tmpDict = {}
    # For each class
    for methodName in fullMethodDict.keys():
        methodList = fullMethodDict[methodName]
        # See if this method has more than one function index (overloaded)
        if (len(methodList) > 1):
            tmpDict[methodName] = methodList
            # Mark all the method specifications as overloaded
            for methodSpec in methodList:
                methodSpec.overloaded = 1

    return tmpDict


def getTypeName(classTypeDesc, typeDesc):
    """
    Map the interrogate primitive type names to python type names.
    We assume that the module using this has imported the types module.
    It is valid to pass in None for classTypeDesc if we are not in a class
    """

    typeName = typeDesc.getFullNestedName()

    # Atomic C++ types are type checked against the builtin
    # Python types. This code sorts out the mapping
    if typeDesc.isAtomic():
        
        # Ints, bools, and chars are treated as ints.
        # Enums are special and are not atomic, see below
        if ((typeDesc.atomicType == AT_int) or
            (typeDesc.atomicType == AT_bool) or
            (typeDesc.atomicType == AT_char)):
            return 'types.IntType'
        
        # Floats and doubles are both floats in Python
        elif ((typeDesc.atomicType == AT_float) or
            (typeDesc.atomicType == AT_double)):
            return 'types.FloatType'

        # Strings are treated as Python strings
        elif ((typeDesc.atomicType == AT_string)):
            return 'types.StringType'
        
        elif (typeDesc.atomicType == AT_void):
            # Convert the void type to None type... I guess...
            # So far we do not have any code that uses this
            return 'types.NoneType'

        else:
            FFIConstants.notify.error("Unknown atomicType: " + typeDesc.atomicType)
        
    # If the type is an enum, we really want to treat it like an int
    # To handle this, the type will have __enum__ in the name
    # Usually it will start the typeName, but some typeNames have the
    # surrounding class as part of their name
    # like BoundedObject.__enum__BoundingVolumeType
    elif (typeName.find('__enum__') >= 0):
        return 'types.IntType'

    # If it was not atomic or enum, it must be a class which is a
    # bit trickier because we output different things depending on the
    # scoping of the type. 
    else:

        #   classTypeDesc  typeDesc fullNestedName Resulting TypeName
        # 1   Outer         Other     Other          Other.Other
        # 2   Outer         Outer     Outer          Outer
        # 3   Outer         Inner     Outer.Inner    Outer.Inner
        # 4   Inner         Other     Other          Other.Other
        # 5   Inner         Outer     Outer          Outer
        # 6   Inner         Inner     Outer.Inner    Outer.Inner
        # 7   None          Other     Other          Other.Other

        # CASES 1,4, and 7 are the only ones that are different from the full
        # nested name, returning Other.Other

        returnNestedTypeNames = string.split(typeName, '.')
        returnModuleName = returnNestedTypeNames[0] 

        if classTypeDesc:
            classTypeName = classTypeDesc.getFullNestedName()
            classNestedTypeNames = string.split(classTypeName, '.')
            # If there is no nesting, return typeName.typeName
            if ((not (classTypeDesc.foreignTypeName in returnNestedTypeNames)) and
                (not (typeDesc.foreignTypeName in classNestedTypeNames))):
                return (returnModuleName + '.' + typeName)
            # All other cases, we just need typeName
            else:
                return typeName
        else:
            # If you had no class, you need to specify module plus typename
            return (returnModuleName + '.' + typeName)


def inheritsFrom(type1, type2):
    """
    Return true if type1 inherits from type2
    This works by recursively checking parentTypes for type1
    """
    if type1.parentTypes:
        if type2 in type1.parentTypes:
            return 1
        else:
            result = 0
            for type in type1.parentTypes:
                result = (result or inheritsFrom(type, type2))
            return result
    else:
        return 0

def getInheritanceLevel(type, checkNested = 1):
    # If this is a nested type, return the inheritance level of the outer type.
    if type.isNested:
        # Check the level of your outer class
        # pass the checkNested flag as 0 to prevent an infinite loop
        # between the parent and child
        level = getInheritanceLevel(type.outerType, 0)
    else:
        level = 0

    for parentType in type.parentTypes:
        # Add 1 because you are one level higher than your parent
        level = max(level, 1+getInheritanceLevel(parentType))

    if checkNested:
        for nestedType in type.nestedTypes:
            # Do not add 1 to your nested types
            level = max(level, getInheritanceLevel(nestedType))

    return level

def inheritanceLevelSort(type1, type2):
    level1 = getInheritanceLevel(type1)
    level2 = getInheritanceLevel(type2)
    if (level1 == level2):
        # If they are equal in the inheritance,
        # sort them alphabetically by their type name
        return cmp(type1.foreignTypeName, type2.foreignTypeName)
    elif (level1 < level2):
        return -1
    elif (level1 > level2):
        return 1


def subclass(type1, type2):
    """
    Helper funcion used in sorting classes by inheritance
    """
    # If the types are the same, return 0
    if type1 == type2:
	return 0
    # If you have no args, sort you first
    elif (type1 == 0):
        return 1
    elif (type2 == 0):
        return -1
    # If class1 inherits from class2 return 1
    elif inheritsFrom(type1, type2):
	return 1
    # If class2 inherits from class1 return -1
    elif inheritsFrom(type2, type1):
        return -1
    else:
        # This is the dont care case. We must specify a sorting
        # rule just so it is not arbitrary
{'fraction_non_alphanumeric': 0.06577242588217362, 'fraction_numerical': 0.012727688438381221, 'mean_word_length': 2.1198288159771757, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, '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': '4306210', 'n_tokens_mistral': 3729, 'n_tokens_neox': 3535, 'n_words': 1384}