예제 #1
0
 def Export(self, codeunit, exported_names):
     if not self.info.exclude:
         decls = self.GetDeclarations(self.info.name)
         for decl in decls:
             self.info.policy = exporterutils.HandlePolicy(decl, self.info.policy)
             self.ExportDeclaration(decl, len(decls) == 1, codeunit)
             self.ExportOpaquePointer(decl, codeunit)
         self.GenerateOverloads(decls, codeunit)  
         exported_names[self.Name()] = 1
    def MethodDefinition(self, method):
        '''Returns a list of lines, which should be put inside the class_
        statement to export this method.'''
        # dont define abstract methods
        pyste = namespaces.pyste
        rename = self.info[method.name].rename or method.name
        default_names = self.DefaultImplementationNames(method)
        class_name = self.class_.FullName()
        wrapper_name = pyste + self.wrapper_name
        result = method.result.FullName()
        is_method_unique = method.is_unique
        constantness = ''
        if method.const:
            constantness = ' const'

        # create a list of default-impl pointers
        minArgs = method.minArgs
        maxArgs = method.maxArgs
        if method.abstract:
            default_pointers = []
        elif is_method_unique:
            default_pointers = ['&%s::%s' % (wrapper_name, x) for x in default_names]
        else:
            default_pointers = []
            for impl_name, argNum in zip(default_names, range(minArgs, maxArgs + 1)):
                param_list = [x.FullName() for x in method.parameters[:argNum]]
                params = ', '.join(param_list)
                signature = '%s (%s::*)(%s)%s' % (result, wrapper_name, params, constantness)
                default_pointer = '(%s)&%s::%s' % (signature, wrapper_name, impl_name)
                default_pointers.append(default_pointer)

        # get the pointer of the method
        pointer = method.PointerDeclaration()
        if method.abstract:
            pointer = namespaces.python + ('pure_virtual(%s)' % pointer)

        # warn the user if this method needs a policy and doesn't have one
        method_info = self.info[method.name]
        method_info.policy = exporterutils.HandlePolicy(method, method_info.policy)

        # Add policy to overloaded methods also
        policy = method_info.policy or ''
        if policy:
            policy = ', %s%s()' % (namespaces.python, policy.Code())

        # generate the defs
        definitions = []
        # basic def
        if default_pointers:
            definitions.append(
                '.def("%s", %s, %s%s)' % (rename, pointer, default_pointers[-1], policy))
            for default_pointer in default_pointers[:-1]:
                definitions.append('.def("%s", %s%s)' % (rename, default_pointer, policy))
        else:
            definitions.append('.def("%s", %s%s)' % (rename, pointer, policy))
        return definitions
예제 #3
0
    def ExportMethods(self):
        '''Export all the non-virtual methods of this class, plus any function
        that is to be exported as a method'''

        declared = {}

        def DeclareOverloads(m):
            'Declares the macro for the generation of the overloads'
            if (isinstance(m, Method) and m.static) or type(m) == Function:
                func = m.FullName()
                macro = 'BOOST_PYTHON_FUNCTION_OVERLOADS'
            else:
                func = m.name
                macro = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS'
            code = '%s(%s, %s, %i, %i)\n' % (macro, self.OverloadName(m), func,
                                             m.minArgs, m.maxArgs)
            if code not in declared:
                declared[code] = True
                self.Add('declaration', code)

        def Pointer(m):
            'returns the correct pointer declaration for the method m'
            # check if this method has a wrapper set for him
            wrapper = self.info[m.name].wrapper
            if wrapper:
                return '&' + wrapper.FullName()
            else:
                return m.PointerDeclaration()

        def IsExportable(m):
            'Returns true if the given method is exportable by this routine'
            ignore = (Constructor, ClassOperator, Destructor)
            return isinstance(
                m, Function) and not isinstance(m, ignore) and not m.virtual

        methods = [x for x in self.public_members if IsExportable(x)]
        methods.extend(self.GetAddedMethods())

        staticmethods = {}

        for method in methods:
            method_info = self.info[method.name]

            # skip this method if it was excluded by the user
            if method_info.exclude:
                continue

            # rename the method if the user requested
            name = method_info.rename or method.name

            # warn the user if this method needs a policy and doesn't have one
            method_info.policy = exporterutils.HandlePolicy(
                method, method_info.policy)

            # check for policies
            policy = method_info.policy or ''
            if policy:
                policy = ', %s%s()' % (namespaces.python, policy.Code())
            # check for overloads
            overload = ''
            if method.minArgs != method.maxArgs and not method_info.wrapper:
                # add the overloads for this method
                DeclareOverloads(method)
                overload_name = self.OverloadName(method)
                overload = ', %s%s()' % (namespaces.pyste, overload_name)

            # build the .def string to export the method
            pointer = Pointer(method)
            code = '.def("%s", %s' % (name, pointer)
            code += policy
            code += overload
            code += ')'
            self.Add('inside', code)
            # static method
            if isinstance(method, Method) and method.static:
                staticmethods[name] = 1
            # add wrapper code if this method has one
            wrapper = method_info.wrapper
            if wrapper and wrapper.code:
                self.Add('declaration', wrapper.code)

        # export staticmethod statements
        for name in staticmethods:
            code = '.staticmethod("%s")' % name
            self.Add('inside', code)