Пример #1
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)
Пример #2
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)
Пример #3
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)