Beispiel #1
0
 def has_hdf5_scheme(self, c):
     """True iif the class c has a static method std::string hdf5_scheme()"""
     keep = lambda m : CL.is_public(m)
     for m in CL.get_methods(c, True, keep):
         if m.spelling == "hdf5_scheme" and m.is_static_method() and ('string' in m.result_type.spelling) and len(list(CL.get_params(m))) == 0: 
            return True
     return False
Beispiel #2
0
 def has_hdf5_scheme(self, c):
     """True iif the class c has a static method std::string hdf5_scheme()"""
     keep = lambda m: CL.is_public(m)
     for m in CL.get_methods(c, True, keep):
         if m.spelling == "hdf5_scheme" and m.is_static_method() and (
                 'string' in m.result_type.spelling) and len(
                     list(CL.get_params(m))) == 0:
             return True
     return False
Beispiel #3
0
 def get_all_functions_and_methods(self):
     """ AST nodes for every function, class methods and constructors"""
     for f in self.all_functions_gen():
         yield f
     for c in self.all_classes_gen():
         for m in CL.get_methods(c):
             yield m
         for m in CL.get_constructors(c):
             yield m
Beispiel #4
0
 def get_all_functions_and_methods(self):
     """ AST nodes for every function, class methods and constructors"""
     for f in self.all_functions_gen(): 
         yield f
     for c in self.all_classes_gen(): 
         for m in CL.get_methods(c):
             yield m
         for m in CL.get_constructors(c):
             yield m
Beispiel #5
0
    def get_public_methods(self, c):
        """
        Parameters
        -----------

        c:  AST node
            a cursor to a class
        
        Returns
        --------
        A list of cursors to the methods
        return : a tuple (proplist, methodlist) where proplist : a list of property_  and methodlist : the others methods
        """
        keep = lambda m : CL.is_public(m) and not CL.is_template(m) and not ("ignore_in_python" in CL.get_annotations(m)) and not m.spelling.startswith('operator')
        return CL.get_methods(c, True, keep)
Beispiel #6
0
    def get_public_methods(self, c):
        """
        Parameters
        -----------

        c:  AST node
            a cursor to a class
        
        Returns
        --------
        A list of cursors to the methods
        return : a tuple (proplist, methodlist) where proplist : a list of property_  and methodlist : the others methods
        """
        keep = lambda m: CL.is_public(m) and not m.spelling.startswith(
            'operator')
        return CL.get_methods(c, True, keep)
Beispiel #7
0
    def get_all_params_ret_type(self, param_cls_list):
        """Yields every parameters and return type of every methods and functions"""

        for f in self.all_functions_gen():
            yield getattr(f, 'result_type', None)
            for p in CL.get_params(f):
                yield p.type

        for x in itertools.chain(param_cls_list, self.all_classes_gen()):
            for m in CL.get_members(x, False):  # False : no inherited
                yield m.type
            for m in itertools.chain(CL.get_constructors(x),
                                     CL.get_methods(x)):
                yield getattr(m, 'result_type', None)
                for p in CL.get_params(m):
                    yield p.type
Beispiel #8
0
    def get_all_params_ret_type(self, param_cls_list):
        """Yields every parameters and return type of every methods and functions"""
       
        for f in self.all_functions_gen():
            yield getattr(f, 'result_type', None)
            for p in CL.get_params(f) : 
                yield p.type

        for x in itertools.chain(param_cls_list, self.all_classes_gen()): 
            for m in CL.get_members(x, False): # False : no inherited
                yield m.type
            for m in itertools.chain(CL.get_constructors(x), CL.get_methods(x)):
                # A minimal filter, do not reuse self.keep_fnt here, because the namespace is N1::N2:...::ClassName
                if CL.is_template(m) or ("ignore_in_python" in CL.get_annotations(m)): continue
                yield getattr(m, 'result_type', None)
                for p in CL.get_params(m) : 
                    yield p.type
Beispiel #9
0
    def get_public_methods(self, c):
        """
        Parameters
        -----------

        c:  AST node
            a cursor to a class
        
        Returns
        --------
        A list of cursors to the methods
        return : a tuple (proplist, methodlist) where proplist : a list of property_  and methodlist : the others methods
        """
        keep = lambda m: CL.is_public(m) and not CL.is_template(
            m) and not ("ignore_in_python" in CL.get_annotations(m)
                        ) and not (m.spelling.startswith('operator') and not m.
                                   spelling == "operator()")
        return CL.get_methods(c, True, keep)
Beispiel #10
0
    def get_all_params_ret_type(self, param_cls_list):
        """Yields every parameters and return type of every methods and functions"""

        for f in self.all_functions_gen():
            yield getattr(f, 'result_type', None)
            for p in CL.get_params(f):
                yield p.type

        for x in itertools.chain(param_cls_list, self.all_classes_gen()):
            for m in CL.get_members(x, False):  # False : no inherited
                yield m.type
            for m in itertools.chain(CL.get_constructors(x),
                                     CL.get_methods(x)):
                # A minimal filter, do not reuse self.keep_fnt here, because the namespace is N1::N2:...::ClassName
                if CL.is_template(m) or ("ignore_in_python"
                                         in CL.get_annotations(m)):
                    continue
                yield getattr(m, 'result_type', None)
                for p in CL.get_params(m):
                    yield p.type
Beispiel #11
0
    def analyse_one_ns(self, namespace):

        print "*** Namespace %s ***" % namespace

        # ----------------------
        #      Filters
        # ----------------------
        def keep_ns(n):
            """Given a namespace node n, shall we keep it ?"""
            ns = CL.fully_qualified(n)
            return ns in namespace

        def keep_cls(c):
            """ Given a class node, shall we keep it ? 

               Reject if no raw_comment.
               Keeps if its namespace is EXACTLY in self.namespaces
               e.g. A::B::cls will be kept iif A::B is in self.namespaces, not it A is.

               The filter to keep a class/struct or an enum :
                 it must have a raw comment
                 if we a namespace list, it must be in it.
                 if target_file_only it has to be in the file given to c++2py
            """
            if c.spelling.startswith('_'): return False
            # FIXME : Commented for debug
            if not c.raw_comment: return False
            if namespace:
                qualified_ns = CL.get_namespace(c)
                if qualified_ns != namespace: return False
            return (c.location.file.name
                    == self.filename) if self.target_file_only else True

        def keep_fnt(f):
            #print "RAW", f.spelling, f.raw_comment
            if not f.raw_comment: return False
            if f.spelling.startswith('operator') or f.spelling in [
                    'begin', 'end'
            ]:
                return False
            return keep_cls(f)

        def keep_using(c):
            #if not c.raw_comment : return False
            if namespace:
                qualified_ns = CL.get_namespace(c)
                if qualified_ns != namespace: return False
            return (c.location.file.name
                    == self.filename) if self.target_file_only else True

        # ----------------------

        # A list of AST nodes for classes
        classes = CL.get_classes(self.root,
                                 keep_cls,
                                 traverse_namespaces=True,
                                 keep_ns=keep_ns)
        classes = list(
            classes)  # make a list to avoid exhaustion of the generator

        D = OrderedDict()
        for cls in classes:
            cls.namespace = CL.get_namespace(cls)
            cls.name = CL.get_name_with_template_specialization(
                cls) or cls.spelling
            cls.fully_qualified_name = '::'.join([cls.namespace, cls.name])
            cls.name_for_label = synopsis.make_label(cls.fully_qualified_name)
            D[cls.fully_qualified_name] = cls
            # print "CLASS", cls.name
            # print "CLASS", cls.fully_qualified_name
            # print "CLASS", cls.name_for_label
            # print "CLASS", "----------------------"

            print " ... class :  %s" % cls.fully_qualified_name, cls.location
            #assert ',' not in cls.fully_qualified_name, "Not implemented"

            # process the doc of the class and add it to the node
            cls.processed_doc = ProcessedDoc(cls)

            # all methods and constructors
            # we build a OrderedDict of the constructors (first) and the methods, in order of declaration
            constructors = list(CL.get_constructors(cls))
            for f in constructors:
                f.is_constructor = True  # tag them for later use
            methods = OrderedDict()
            if constructors: methods['constructor'] = constructors
            methods.update(
                self.regroup_func_by_names(CL.get_methods(
                    cls, True)))  # True : with inherited
            #methods.update(self.regroup_func_by_names(CL.get_methods(cls, True, keep = keep_fnt))) # True : with inherited

            # all non member functions
            friend_functions = self.regroup_func_by_names(
                CL.get_friend_functions(cls))
            #friend_functions = self.regroup_func_by_names(CL.get_friend_functions(cls, keep = keep_fnt))

            # Analyse the doc string for all methods and functions, and store the result in the node itself
            for (n, f_list) in (methods.items() + friend_functions.items()):
                for f in f_list:
                    f.processed_doc = ProcessedDoc(f)

            # attach to the node
            cls.methods, cls.friend_functions = methods, friend_functions

            # members
            cls.members = list(CL.get_members(cls, True))

            # using
            cls.usings = list(CL.get_usings(cls))  # , keep_using))

        # Eliminate doublons, like forward declarations
        classes = D.values()

        # A list of AST nodes for the methods and functions
        functions = CL.get_functions(self.root,
                                     keep_fnt,
                                     traverse_namespaces=True,
                                     keep_ns=keep_ns)
        functions = list(
            functions)  # make a to avoid exhaustion of the generator

        # Analyse the doc strings
        for f in functions:
            f.processed_doc = ProcessedDoc(f)

        # Find the using of this namespace, and make the list unique based on the fully_qualified_name
        usings = list(
            CL.get_usings(self.root,
                          keep_using,
                          traverse_namespaces=True,
                          keep_ns=keep_ns))
        D = OrderedDict()
        for c in usings:
            c.namespace = CL.get_namespace(c)
            c.fully_qualified_name = '::'.join([c.namespace, c.spelling])
            D[c.fully_qualified_name] = c
        usings = D.values()

        return classes, functions, usings
Beispiel #12
0
    def run(self, output_directory):

        print "Generating the documentation ..."
        mkchdir(output_directory)
        classes = list(self.all_classes_gen())

        # FIXME
        synopsis.class_list = classes
        synopsis.class_list_name = [n.spelling for n in classes]

        for c in classes:
            if not c.spelling.strip():
                print "Skipping a class with an empty name !"
                continue

            print " ... class :  " + c.spelling, CL.fully_qualified(
                c.referenced)

            # process the doc of the class
            cls_doc = self.process_doc_class(c)

            # all methods and constructors
            all_m = self.regroup_func_by_names(CL.get_methods(
                c, True))  # True : with inherited ?
            constructors = list(CL.get_constructors(c))
            if constructors: all_m['constructor'] = constructors

            # all non member functions
            all_friend_functions = self.regroup_func_by_names(
                CL.get_friend_functions(c))

            # process the doc
            doc_methods = dict(
                (n, [self.process_doc_function(f) for f in fs])
                for (n, fs) in (all_m.items() + all_friend_functions.items()))

            # One directory for the class
            cur_dir = os.getcwd()
            mkchdir_for_one_class(c)

            # the file for the class
            r = render_cls(doc_class=self.process_doc_class(c),
                           doc_methods=doc_methods,
                           cls=c,
                           all_m=all_m,
                           all_friend_functions=all_friend_functions)
            safe_write(c.spelling, r)

            mkchdir(c.spelling)

            def render(mess, d):
                for f_name, f_overloads in all_m.items():
                    print " ...... %s %s" % (mess, f_name)
                    r = render_fnt(doc_methods=doc_methods[f_name],
                                   parent_class=c,
                                   f_name=f_name,
                                   f_overloads=f_overloads)
                    safe_write(f_name, r)

            render('method', all_m)
            render('non member function', all_friend_functions)

            os.chdir(cur_dir)

        all_functions = self.regroup_func_by_names(self.all_functions_gen())

        docs = dict((n, [self.process_doc_function(f) for f in fs])
                    for (n, fs) in all_functions.items())

        for f_name, f_overloads in all_functions.items():
            print " ... function " + f_name
            cur_dir = os.getcwd()
            mkchdir_for_one_class(f_overloads[0])
            print " ..... located: ", f_overloads[0].location.file.name
            r = render_fnt(doc_methods=docs[f_name],
                           parent_class=None,
                           f_name=f_name,
                           f_overloads=f_overloads)
            safe_write(f_name, r)
            os.chdir(cur_dir)

        print "... done"
Beispiel #13
0
    def analyse_one_ns(self, namespace):

        print "*** Namespace %s ***"%namespace

        # ----------------------
        #      Filters
        # ----------------------
        def keep_ns(n):
            """Given a namespace node n, shall we keep it ?"""
            ns = CL.fully_qualified(n) 
            return ns in namespace
        
        def keep_cls(c):
            """ Given a class node, shall we keep it ? 

               Reject if no raw_comment.
               Keeps if its namespace is EXACTLY in self.namespaces
               e.g. A::B::cls will be kept iif A::B is in self.namespaces, not it A is.

               The filter to keep a class/struct or an enum :
                 it must have a raw comment
                 if we a namespace list, it must be in it.
                 if target_file_only it has to be in the file given to c++2py
            """
            if c.spelling.startswith('_') : return False
            # FIXME : Commented for debug
            if not c.raw_comment : return False
            if namespace:
                qualified_ns = CL.get_namespace(c) 
                if qualified_ns != namespace : return False
            return (c.location.file.name == self.filename) if self.target_file_only else True
        
        def keep_fnt(f):
            #print "RAW", f.spelling, f.raw_comment
            if not f.raw_comment : return False
            if  f.spelling.startswith('operator') or f.spelling in ['begin','end'] : return False
            return keep_cls(f) 

        def keep_using(c):
            #if not c.raw_comment : return False
            if namespace:
                qualified_ns = CL.get_namespace(c) 
                if qualified_ns != namespace : return False
            return (c.location.file.name == self.filename) if self.target_file_only else True

        # ----------------------

        # A list of AST nodes for classes
        classes = CL.get_classes(self.root, keep_cls, traverse_namespaces = True, keep_ns = keep_ns)
        classes = list(classes) # make a list to avoid exhaustion of the generator
  
        D = OrderedDict()
        for cls in classes: 
            cls.namespace = CL.get_namespace(cls)
            cls.name = CL.get_name_with_template_specialization(cls) or cls.spelling 
            cls.fully_qualified_name = '::'.join([cls.namespace, cls.name])
            cls.name_for_label = synopsis.make_label(cls.fully_qualified_name)
            D[cls.fully_qualified_name] = cls
            # print "CLASS", cls.name
            # print "CLASS", cls.fully_qualified_name 
            # print "CLASS", cls.name_for_label
            # print "CLASS", "----------------------"
       
            print " ... class :  %s"%cls.fully_qualified_name, cls.location
            #assert ',' not in cls.fully_qualified_name, "Not implemented"

            # process the doc of the class and add it to the node
            cls.processed_doc = ProcessedDoc(cls)

            # all methods and constructors
            # we build a OrderedDict of the constructors (first) and the methods, in order of declaration 
            constructors = list(CL.get_constructors(cls))
            for f in constructors : f.is_constructor = True # tag them for later use
            methods = OrderedDict()
            if constructors: methods['constructor'] = constructors
            methods.update(self.regroup_func_by_names(CL.get_methods(cls, True))) # True : with inherited 
            #methods.update(self.regroup_func_by_names(CL.get_methods(cls, True, keep = keep_fnt))) # True : with inherited 

            # all non member functions
            friend_functions = self.regroup_func_by_names(CL.get_friend_functions(cls))
            #friend_functions = self.regroup_func_by_names(CL.get_friend_functions(cls, keep = keep_fnt))

            # Analyse the doc string for all methods and functions, and store the result in the node itself
            for (n,f_list) in (methods.items() + friend_functions.items()):
                for f in f_list:
                    f.processed_doc = ProcessedDoc(f)

            # attach to the node
            cls.methods, cls.friend_functions = methods, friend_functions

            # members 
            cls.members = list(CL.get_members(cls, True)) 
            
            # using 
            cls.usings = list(CL.get_usings(cls)) # , keep_using)) 
             
        # Eliminate doublons, like forward declarations
        classes = D.values()

        # A list of AST nodes for the methods and functions
        functions = CL.get_functions(self.root, keep_fnt, traverse_namespaces = True, keep_ns = keep_ns)
        functions = list(functions) # make a to avoid exhaustion of the generator

        # Analyse the doc strings 
        for f in functions:
            f.processed_doc = ProcessedDoc(f)
        
        # Find the using of this namespace, and make the list unique based on the fully_qualified_name 
        usings = list(CL.get_usings(self.root, keep_using, traverse_namespaces = True, keep_ns = keep_ns)) 
        D = OrderedDict()
        for c in usings:
            c.namespace = CL.get_namespace(c)
            c.fully_qualified_name = '::'.join([c.namespace, c.spelling])
            D[c.fully_qualified_name] = c
        usings = D.values()

        return classes, functions, usings
Beispiel #14
0
    def run(self, output_directory):

        print "Generating the documentation ..."
        mkchdir(output_directory)

        # Filters
        def keep_ns(n):
            ns = CL.fully_qualified(n)
            if 'std' in ns or 'boost' in ns or 'detail' in ns or 'impl' in ns:
                return False
            if len(self.namespaces) == 0: return True
            return any((ns in x) for x in self.namespaces)

        def keep_cls(c):
            """
               The filter to keep a class/struct or an enum :
                 it must have a raw comment
                 if we a namespace list, it must be in it.
                 if target_file_only it has to be in the file given to c++2py
            """
            if not c.raw_comment: return False
            if self.namespaces:
                qualified_ns = CL.get_namespace(c)
                if not any((x in qualified_ns) for x in self.namespaces):
                    return False
            return (c.location.file.name
                    == self.filename) if self.target_file_only else True

        def keep_fnt(f):
            if not f.raw_comment: return False
            if f.spelling.startswith('operator') or f.spelling in [
                    'begin', 'end'
            ]:
                return False
            return keep_cls(f)

        # A list of AST nodes for classes
        classes = CL.get_classes(self.root,
                                 keep_cls,
                                 traverse_namespaces=True,
                                 keep_ns=keep_ns)
        classes = list(classes)  # to avoid exhaustion of the generator

        # A list of AST nodes for the methods and functions
        all_functions = CL.get_functions(self.root,
                                         keep_fnt,
                                         traverse_namespaces=True,
                                         keep_ns=keep_ns)
        all_functions = list(
            all_functions)  # to avoid exhaustion of the generator

        # Build the doc for all functions
        for f in all_functions:
            f.processed_doc = ProcessedDoc(f)

        # c : AST node of name A::B::C::clsname makes and cd into A/B/C
        def mkchdir_for_one_node(node):
            mkchdir(*(CL.fully_qualified_name(node).split('::')[:-1]))

        # regroup the functions into a list of overloads
        def regroup_func_by_names(fs):
            """ Given a list of functions, regroup them by names"""
            d = OrderedDict()

            def decay(name):
                if 'operator' not in name: return name
                a, ca, c, co = '+ - * /', '+= -= \*= /=', "== !=", r" comparison"
                d = {
                    '*=': ca,
                    '+=': ca,
                    '/=': ca,
                    '-=': ca,
                    '*': a,
                    '+': a,
                    '/': a,
                    '-': a,
                    '==': c,
                    '!=': c,
                    '<': co,
                    '>': co,
                    '<=': co,
                    '>=': co
                }
                n = name.replace('operator', '').strip()
                return 'operator' + d[n] if n in d else name

            for f in fs:
                d.setdefault(decay(f.spelling), []).append(f)
            return d

        synopsis.class_list = classes
        synopsis.class_list_name = [n.spelling for n in classes]

        for c in classes:
            if not c.spelling.strip():
                print "Skipping a class with an empty name !"
                continue

            print " ... class :  " + c.spelling, CL.fully_qualified_name(
                c), c.kind, CL.get_name_with_template_specialization(c)

            # process the doc of the class and add it to the node
            c.processed_doc = ProcessedDoc(c)

            # all methods and constructors
            constructors = list(CL.get_constructors(c))
            for f in constructors:
                f.is_constructor = True  # tag them for later use
            all_methods = OrderedDict()
            if constructors: all_methods['constructor'] = constructors
            all_methods.update(regroup_func_by_names(CL.get_methods(
                c, True)))  # True : with inherited ?

            # all non member functions
            all_friend_functions = regroup_func_by_names(
                CL.get_friend_functions(c))

            # process the doc for all methods and functions, and store it in the node.
            for (n, f_list) in (all_methods.items() +
                                all_friend_functions.items()):
                for f in f_list:
                    f.processed_doc = ProcessedDoc(f)

            # One directory for the class
            cur_dir = os.getcwd()
            mkchdir_for_one_node(c)

            # the file for the class
            r = render_cls(c, all_methods, all_friend_functions)
            safe_write(c.spelling, r)

            # create a directory with the class name
            mkchdir(c.spelling)

            # write a file for each function
            def render(mess, d):
                for f_name, f_overloads in d.items():
                    print " ...... %s %s" % (mess, f_name)
                    r = render_fnt(parent_class=c,
                                   f_name=f_name,
                                   f_overloads=f_overloads)
                    safe_write(f_name, r)

            render('methods', all_methods)
            render('non member functions', all_friend_functions)

            # Change back to up directory
            os.chdir(cur_dir)

        all_functions = regroup_func_by_names(all_functions)

        docs = dict((n, [ProcessedDoc(f) for f in fs])
                    for (n, fs) in all_functions.items())

        for f_name, f_overloads in all_functions.items():
            print " ... function " + f_name, "      [", f_overloads[
                0].location.file.name, ']'
            cur_dir = os.getcwd()
            mkchdir_for_one_node(f_overloads[0])
            r = render_fnt(parent_class=None,
                           f_name=f_name,
                           f_overloads=f_overloads)
            safe_write(f_name, r)
            os.chdir(cur_dir)

        print "... done"