def cullOverloadedMethods(self):
     """
     Find all the entries that have multiple indexes for the same method name
     Get rid of all others. Do this for class methods and instance methods
     """
     self.overloadedClassMethods = FFIOverload.cullOverloadedMethods(self.overloadedClassMethods)
     self.overloadedInstanceMethods = FFIOverload.cullOverloadedMethods(self.overloadedInstanceMethods)
Esempio n. 2
0
 def generateReturnValueWrapper(self, classTypeDesc, file,
                                userManagesMemory, needsDowncast, nesting):
     """
     Generate code that creates a shadow object of this type
     then sets the this pointer and returns the object. We call the
     class destructor with None as the only parameter to get an
     empty shadow object.
     """
     if classTypeDesc != self:
         indent(file, nesting, 'import ' + self.foreignTypeName + '\n')
     indent(file, nesting, 'returnObject = ')
     # Do not put Class.Class if this file is the file that defines Class
     # Also check for nested classes. They do not need the module name either
     typeName = FFIOverload.getTypeName(classTypeDesc, self)
     file.write(typeName)
     file.write('(None)\n')
     indent(file, nesting, 'returnObject.this = returnValue\n')
     # Zero this pointers get returned as the Python None object
     indent(file, nesting, 'if (returnObject.this == 0): return None\n')
     if userManagesMemory:
         indent(file, nesting, 'returnObject.userManagesMemory = 1\n')
     if needsDowncast:
         if (FFIOverload.inheritsFrom(self, TypedObjectDescriptor)
                 or self == TypedObjectDescriptor):
             indent(file, nesting, 'return returnObject.setPointer()\n')
         else:
             indent(file, nesting, 'return returnObject\n')
     else:
         indent(file, nesting, 'return returnObject\n')
Esempio n. 3
0
 def generateReturnValueWrapper(self, classTypeDesc, file, userManagesMemory,
                                needsDowncast, nesting):
     """
     Generate code that creates a shadow object of this type
     then sets the this pointer and returns the object. We call the
     class destructor with None as the only parameter to get an
     empty shadow object.
     """
     if classTypeDesc != self:
         indent(file, nesting, 'import ' + self.foreignTypeName + '\n')
     indent(file, nesting, 'returnObject = ')
     # Do not put Class.Class if this file is the file that defines Class
     # Also check for nested classes. They do not need the module name either
     typeName = FFIOverload.getTypeName(classTypeDesc, self)
     file.write(typeName)
     file.write('(None)\n')
     indent(file, nesting, 'returnObject.this = returnValue\n')
     # Zero this pointers get returned as the Python None object
     indent(file, nesting, 'if (returnObject.this == 0): return None\n')
     if userManagesMemory:
         indent(file, nesting, 'returnObject.userManagesMemory = 1\n')
     if needsDowncast:
         if (FFIOverload.inheritsFrom(self, TypedObjectDescriptor) or
             self == TypedObjectDescriptor):
             indent(file, nesting, 'return returnObject.setPointer()\n')
         else:
             indent(file, nesting, 'return returnObject\n')
     else:
         indent(file, nesting, 'return returnObject\n')
Esempio n. 4
0
 def cullOverloadedMethods(self):
     """
     Find all the entries that have multiple indexes for the same method name
     Get rid of all others. Do this for class methods and instance methods
     """
     self.overloadedClassMethods = FFIOverload.cullOverloadedMethods(
         self.overloadedClassMethods)
     self.overloadedInstanceMethods = FFIOverload.cullOverloadedMethods(
         self.overloadedInstanceMethods)
Esempio n. 5
0
    def outputTypeChecking(self, methodClass, args, file, nesting):
        """
        Output an assert statement to check the type of each arg in this method
        This can be turned off with a command line parameter in generatePythonCode
        It is valid to pass in None for methodClass if you are not in any methodClass
        """
        if FFIConstants.wantTypeChecking:
            for i in range(len(args)):
                methodArgSpec = args[i]
                typeDesc = methodArgSpec.typeDescriptor.recursiveTypeDescriptor()
                typeName = FFIOverload.getTypeName(methodClass, typeDesc)

                # We only do type checking on class types.  C++ can do
                # type checking on the primitive types, and will do a
                # better job anyway.
                if typeDesc.__class__ == FFITypes.ClassTypeDescriptor:
                    # Get the real return type (not derived)
                    if (
                        (not typeDesc.isNested)
                        and
                        # Do not put our own module in the import list
                        (methodClass != typeDesc)
                    ):
                        indent(file, nesting, "import " + typeDesc.foreignTypeName + "\n")
                    indent(file, nesting, "if not isinstance(" + methodArgSpec.name + ", " + typeName + "):\n")
                    indent(
                        file,
                        nesting + 1,
                        'raise TypeError, "Invalid argument %s, expected <%s>"\n' % (i, typeDesc.foreignTypeName),
                    )
Esempio n. 6
0
    def outputTypeChecking(self, methodClass, args, file, nesting):
        """
        Output an assert statement to check the type of each arg in this method
        This can be turned off with a command line parameter in generatePythonCode
        It is valid to pass in None for methodClass if you are not in any methodClass
        """
        if FFIConstants.wantTypeChecking:
            for i in range(len(args)):
                methodArgSpec = args[i]
                typeDesc = methodArgSpec.typeDescriptor.recursiveTypeDescriptor(
                )
                typeName = FFIOverload.getTypeName(methodClass, typeDesc)

                # We only do type checking on class types.  C++ can do
                # type checking on the primitive types, and will do a
                # better job anyway.
                if typeDesc.__class__ == FFITypes.ClassTypeDescriptor:
                    # Get the real return type (not derived)
                    if ((not typeDesc.isNested) and
                            # Do not put our own module in the import list
                        (methodClass != typeDesc)):
                        indent(file, nesting,
                               'import ' + typeDesc.foreignTypeName + '\n')
                    indent(
                        file, nesting, 'if not isinstance(' +
                        methodArgSpec.name + ', ' + typeName + '):\n')
                    indent(
                        file, nesting + 1,
                        'raise TypeError, "Invalid argument %s, expected <%s>"\n'
                        % (i, typeDesc.foreignTypeName))
Esempio n. 7
0
    def copyParentMethodsRecursively(self, parentList, file, nesting):
        """
        Copy all the parents instance methods
        Do not copy functions if this class already has a function with that name
        We need to recurse up the hierarchy copying all our parents nodes all
        the way up the tree stopping either at the top, or at another MI node
        that has already copied his parent's methods in
        Note: Do not copy the downcast methods
        """
        parent = parentList[-1]
        if (len(parent.parentTypes) > 0):
            recurse = 1
        else:
            recurse = 0

        for method in parent.instanceMethods:
            if not self.inheritsMethodNamed(parentList, method.name):
                # with downcast for all instance methods that are not themselves upcasts
                method.generateInheritedMethodCode(self, parentList, file,
                                                   nesting, 1)

        # Also duplicate the overloaded method dispatch functions, if
        # we don't already have any matching methods by this name.
        for methodSpecList in parent.overloadedInstanceMethods.values():
            if not self.inheritsMethodNamed(parentList,
                                            methodSpecList[0].name):
                treeColl = FFIOverload.FFIMethodArgumentTreeCollection(
                    self, methodSpecList)
                treeColl.generateCode(file, nesting)

        # Copy all the parents upcast methods so we transitively pick them up
        for method in parent.upcastMethods:
            if not self.inheritsMethodNamed(parentList, method.name):
                # no downcast for all instance methods that are themselves upcasts
                # that would cause an infinite loop
                method.generateInheritedMethodCode(self, parentList, file,
                                                   nesting, 0)

        # Now recurse up the hierarchy until we get to a node that is itself
        # a multiple inheritance node and stop there because he will have already
        # copied all his parent functions in
        if recurse:
            for parentType in parent.parentTypes:
                newParentList = parentList[:]
                newParentList.append(parentType)
                self.copyParentMethodsRecursively(newParentList, file, nesting)
Esempio n. 8
0
 def generateOverloadedMethods(self, file, nesting):
     """
     Generate code for all the overloaded methods of this class
     """
     if (len(self.overloadedClassMethods.values())
             or len(self.overloadedInstanceMethods.values())):
         indent(file, nesting + 1, '\n')
         indent(file, nesting + 1,
                '##################################################\n')
         indent(file, nesting + 1,
                '#  Overloaded methods                            #\n')
         indent(file, nesting + 1,
                '##################################################\n')
         indent(file, nesting + 1, '\n')
     # Overload all the class and instance methods
     for methodSpecList in (self.overloadedClassMethods.values() +
                            self.overloadedInstanceMethods.values()):
         treeColl = FFIOverload.FFIMethodArgumentTreeCollection(
             self, methodSpecList)
         treeColl.generateCode(file, nesting)
Esempio n. 9
0
    def generateCodeLib(self, codeDir, extensionsDir, CModuleName):
        # Reset the environment so we are clean from any old modules
        self.environment.reset()

        FFIConstants.notify.info('=' * 50)
        FFIConstants.notify.warning('Importing code library: ' + CModuleName)
        exec('import ' + CModuleName)

        if interrogate_error_flag():
            FFIConstants.notify.error(
                "Error reading interrogate database; can't continue.")

        self.updateBindings(CModuleName)

        FFIConstants.notify.info('Generating type code...')
        for type in self.environment.types.values():
            # Do not generate code for nested types at the top level
            if (not type.isNested):
                type.generateGlobalCode(codeDir, extensionsDir)

        FFIConstants.notify.info('Generating global downcast code...')
        downcastFile = constructDowncastFile(codeDir, CModuleName)
        # Output all the imports based on this list of functions
        outputGlobalFileImports(downcastFile,
                                self.environment.downcastFunctions,
                                CModuleName)
        for type in self.environment.downcastFunctions:
            type.generateGlobalDowncastCode(downcastFile)

        FFIConstants.notify.info('Generating global code...')
        globalFile = constructGlobalFile(codeDir, CModuleName)

        # Make a list of all the global functions. This includes the normal
        # global functions as well as the getters and setters on all the
        # global values. This list is used to figure out what files to import
        # Only include the global functions from the current C module
        globalFunctions = self.environment.globalFunctions
        for globalValue in self.environment.globalValues:
            if globalValue.getter:
                globalFunctions.append(globalValue.getter)
            if globalValue.setter:
                globalFunctions.append(globalValue.setter)
        # Output all the imports based on this list of functions
        outputGlobalFileImports(globalFile, globalFunctions, CModuleName)

        # Generate overloading
        overloadedGlobalFunctions = {}
        for methodSpec in globalFunctions:
            methodList = overloadedGlobalFunctions.setdefault(
                methodSpec.name, [])
            methodList.append(methodSpec)

        overloadedGlobalFunctions = FFIOverload.cullOverloadedMethods(
            overloadedGlobalFunctions)

        for methodSpecList in overloadedGlobalFunctions.values():
            treeColl = FFIOverload.FFIMethodArgumentTreeCollection(
                None, methodSpecList)
            treeColl.generateCode(globalFile, -1)

        FFIConstants.notify.info('Generating global values...')
        for type in self.environment.globalValues:
            type.generateGlobalCode(globalFile)

        FFIConstants.notify.info('Generating global functions...')
        for type in self.environment.globalFunctions:
            type.generateGlobalCode(globalFile)

        FFIConstants.notify.info('Generating manifests...')
        for type in self.environment.manifests:
            type.generateGlobalCode(globalFile)

        globalFile.close()

        FFIConstants.notify.info('Generating import code...')
        importFile = constructImportFile(codeDir, CModuleName)
        outputImportFileImports(importFile, self.environment.types.values(),
                                CModuleName)
Esempio n. 10
0
    def generateCodeLib(self, codeDir, extensionsDir, CModuleName):
        # Reset the environment so we are clean from any old modules
        self.environment.reset()

        FFIConstants.notify.info('='*50)
        FFIConstants.notify.warning('Importing code library: ' + CModuleName)
        exec('import ' + CModuleName)

        if interrogate_error_flag():
            FFIConstants.notify.error("Error reading interrogate database; can't continue.")

        self.updateBindings(CModuleName)
        
        FFIConstants.notify.info('Generating type code...')
        for type in self.environment.types.values():
            # Do not generate code for nested types at the top level
            if (not type.isNested):
                type.generateGlobalCode(codeDir, extensionsDir)


        FFIConstants.notify.info('Generating global downcast code...')
        downcastFile = constructDowncastFile(codeDir, CModuleName)
        # Output all the imports based on this list of functions
        outputGlobalFileImports(downcastFile,
                                self.environment.downcastFunctions,
                                CModuleName)
        for type in self.environment.downcastFunctions:
            type.generateGlobalDowncastCode(downcastFile)
            
        FFIConstants.notify.info('Generating global code...')
        globalFile = constructGlobalFile(codeDir, CModuleName)

        # Make a list of all the global functions. This includes the normal
        # global functions as well as the getters and setters on all the
        # global values. This list is used to figure out what files to import
        # Only include the global functions from the current C module
        globalFunctions = self.environment.globalFunctions
        for globalValue in self.environment.globalValues:
            if globalValue.getter:
                globalFunctions.append(globalValue.getter)
            if globalValue.setter:
                globalFunctions.append(globalValue.setter)
        # Output all the imports based on this list of functions
        outputGlobalFileImports(globalFile, globalFunctions, CModuleName)

        # Generate overloading
        overloadedGlobalFunctions = {}
        for methodSpec in globalFunctions:
            methodList = overloadedGlobalFunctions.setdefault(methodSpec.name, [])
            methodList.append(methodSpec)

        overloadedGlobalFunctions = FFIOverload.cullOverloadedMethods(overloadedGlobalFunctions)

        for methodSpecList in overloadedGlobalFunctions.values():
            treeColl = FFIOverload.FFIMethodArgumentTreeCollection(None, methodSpecList)
            treeColl.generateCode(globalFile, -1)

        FFIConstants.notify.info('Generating global values...')
        for type in self.environment.globalValues:
            type.generateGlobalCode(globalFile)
            
        FFIConstants.notify.info('Generating global functions...')
        for type in self.environment.globalFunctions:
            type.generateGlobalCode(globalFile)

        FFIConstants.notify.info('Generating manifests...')
        for type in self.environment.manifests:
            type.generateGlobalCode(globalFile)

        globalFile.close()

        FFIConstants.notify.info('Generating import code...')
        importFile = constructImportFile(codeDir, CModuleName)
        outputImportFileImports(importFile, self.environment.types.values(), CModuleName)