Beispiel #1
0
 def _process_method(self, c: Cursor, class_, store_global: bool):
     func = Method(
         parent=class_,
         name=c.spelling,
         location=location_from_cursor(c),
         ret_type=c.result_type.spelling,
         access=c.access_specifier.name.lower(),
         is_virtual=c.is_virtual_method(),
         is_pure_virtual=c.is_pure_virtual_method(),
         is_static=c.is_static_method(),
         brief_comment=c.brief_comment,
     )
     for ac in c.get_arguments():
         arg = self._process_variable(ac,
                                      class_,
                                      warn_failed=False,
                                      store_global=store_global)
         func.args.append(arg)
     for ac in c.get_children():
         if ac.kind == CursorKind.CXX_FINAL_ATTR:
             func.is_final = True
         elif ac.kind in METHOD_UNSUPPORTED_CURSORS:
             pass
         else:
             logger.warning(
                 "unknown kind in cxx_method child: %s %s",
                 ac.kind,
                 ac.extent,
             )
     if store_global:
         self.objects[func.full_name] = func
     return func
Beispiel #2
0
 def _parse_literal_cursor(self, c: Cursor, warn_failed: bool = False) \
     -> Tuple[Optional[str], Optional[Union[str, float, int]]]:
     """
     used to parse variable
     :return: literal, value
     """
     tokens: List[Token] = list(c.get_tokens())
     has_assign = False
     for i, t in enumerate(tokens):
         if has_assign:
             if t.kind == TokenKind.IDENTIFIER:
                 if t.cursor.kind == CursorKind.MACRO_INSTANTIATION:
                     return self._parse_macro_literal_cursor(c)
             if t.kind == TokenKind.LITERAL:
                 spelling = t.spelling
                 val = self._try_parse_literal(t.cursor.kind, t.spelling)
                 last_t = tokens[i - 1]
                 if last_t.kind == TokenKind.PUNCTUATION and last_t.spelling == '-':
                     return spelling, -val
                 return spelling, val
         elif t.spelling == '=':
             has_assign = True
     if has_assign:
         if warn_failed:
             logger.warning("unknown literal, kind:%s, spelling:%s, %s",
                            c.kind, c.spelling, c.extent)
     return None, None
Beispiel #3
0
    def _process_namespace(
        self,
        c: Cursor,
        n: Namespace,
        store_global: bool,
        on_progress: on_progress_type = None,
    ):
        """All result will append in parameter n"""
        n.location = location_from_cursor(c)
        self.objects[n.full_name] = n
        if c.kind == CursorKind.NAMESPACE and c.spelling:
            n.name = c.spelling
        children = list(c.get_children())
        count = len(children)

        passed = False

        for i, ac in enumerate(children):
            # log cursor kind
            if ac.kind != CursorKind.MACRO_DEFINITION:
                logger.debug("%s", ac.kind)
            if passed or ac.spelling == 'A':
                passed = True
                print(ac.kind)

            # skip macros
            if ac.kind == CursorKind.MACRO_DEFINITION:
                continue

            self._process_namespace_child(ac, n, store_global=store_global)
            if on_progress:
                on_progress(i + 1, count)
        return n
Beispiel #4
0
 def _process_enum(self, c: Cursor, parent: AnyCxxSymbol, store_global: bool):
     e = Enum(name=c.spelling,
              parent=parent,
              location=location_from_cursor(c),
              type=c.enum_type.spelling,
              is_strong_typed=c.is_scoped_enum(),
              brief_comment=c.brief_comment,
              )
     for i in list(c.get_children()):
         e.variables[i.spelling] = Variable(
             parent=e,
             name=i.spelling,
             location=location_from_cursor(i),
             type=e.name,
             value=i.enum_value,
             brief_comment=c.brief_comment,
         )
     if store_global:
         self.objects[e.full_name] = e
     return e
Beispiel #5
0
 def _parse_macro_literal_cursor(self, c: Cursor):
     """
     parse macro instantiation cursor.
     :param c:
     :return:
     """
     for child in c.walk_preorder():
         if self._is_literal_cursor(child):
             tokens = [t for t in child.get_tokens()]
             for t in tokens:
                 if t.kind == TokenKind.LITERAL:
                     return t.spelling, self._try_parse_literal(child.kind, t.spelling)
Beispiel #6
0
 def _process_macro_definition(c: Cursor):
     name = c.spelling
     tokens = list(c.get_tokens())
     length = len(tokens)
     m = Macro(name=name,
               parent=None,  # macro has no parent
               location=location_from_cursor(c),
               definition="",
               brief_comment=c.brief_comment,
               )
     if length == 1:
         return m
     m.definition = " ".join([i.spelling for i in tokens[1:]])
     return m
Beispiel #7
0
    def _process_class(self, c: Cursor, parent: AnyCxxSymbol, store_global: bool):
        # noinspection PyArgumentList
        name = c.spelling
        class_ = Class(name=name,
                       parent=parent,
                       location=location_from_cursor(c),
                       brief_comment=c.brief_comment,
                       )
        for ac in c.get_children():
            self._process_class_child(ac, class_, store_global=store_global)

        if store_global:
            self.objects[class_.full_name] = class_
        return class_
Beispiel #8
0
 def _process_function(self, c: Cursor, parent: Namespace, store_global: bool):
     func = Function(
         name=c.spelling,
         parent=parent,
         location=location_from_cursor(c),
         ret_type=c.result_type.spelling,
         args=[
             Variable(name=ac.spelling, type=ac.type.spelling)
             for ac in c.get_arguments()
         ],
         brief_comment=c.brief_comment,
     )
     if store_global:
         self.objects[func.full_name] = func
     return func
Beispiel #9
0
    def _process_typedef(self, c: Cursor, ns: Namespace, store_global: bool):
        name = c.spelling
        target_cursor = c.underlying_typedef_type
        target_name: str = self._qualified_name(target_cursor)

        for ac in c.get_children():
            kind = ac.kind
            if kind == CursorKind.STRUCT_DECL:
                class_ = self._process_class(ac, ns, store_global, name=name)
                return class_
                # ns.classes[class_.name] = class_
            elif kind in TYPEDEF_UNSUPPORTED_CURSORS:
                pass
            else:
                logger.warning("unknown cursor kind in typedef:%s", kind)
        if target_name != '::':
            return self.save_typedef(c,
                                     ns,
                                     name,
                                     target_name,
                                     store_global=store_global)
Beispiel #10
0
 def _get_template_alias_target(self, c: Cursor):
     children = list(c.get_children())
     for child in children:
         if child.kind == CursorKind.TYPE_ALIAS_DECL:
             return child.underlying_typedef_type
     return None
Beispiel #11
0
    def _process_class_child(self, ac: Cursor, class_: Class,
                             store_global: bool):
        if ac.kind == CursorKind.CXX_BASE_SPECIFIER:
            super_name = self._qualified_name(ac)
            if super_name in self.objects:
                # if parent class is a template class, it will not be parsed
                s = self.objects[super_name]
                class_.super.append(s)
            else:
                pass
        elif ac.kind == CursorKind.CONSTRUCTOR:
            func = self._process_method(ac, class_, store_global=store_global)
            if func.is_virtual:
                class_.is_polymorphic = True
            class_.constructors.append(func)
        elif (ac.kind == CursorKind.CLASS_DECL
              or ac.kind == CursorKind.STRUCT_DECL
              or ac.kind == CursorKind.CLASS_TEMPLATE
              or ac.kind == CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION):
            child = self._process_class(c=ac,
                                        parent=class_,
                                        store_global=store_global)
            class_.classes[child.name] = child
        elif ac.kind == CursorKind.UNION_DECL:
            # for type first
            scope_name = self._union_scope_name(ac)
            child = self._process_union(ac,
                                        scope_name,
                                        class_,
                                        store_global=True)
            anonymous = ac.is_anonymous()
            if scope_name and not anonymous:
                class_.classes[child.name] = child
                return
            if scope_name and anonymous:
                class_.classes[child.name] = child
                return
            if not scope_name and anonymous:
                class_.extend(child)
                return
            if not scope_name and not anonymous:
                class_.classes[child.name] = child
                class_.extend(child)
                return

        elif ac.kind == CursorKind.DESTRUCTOR:
            func = self._process_method(ac, class_, store_global=store_global)
            if func.is_virtual:
                class_.is_polymorphic = True
            class_.destructor = func
        elif ac.kind == CursorKind.ENUM_DECL:
            e = self._process_enum(ac, class_, store_global=store_global)
            class_.enums[e.name] = e
        elif ac.kind == CursorKind.FIELD_DECL:
            v = self._process_variable(ac, class_, store_global=store_global)
            class_.variables[v.name] = v
        elif ac.kind == CursorKind.CXX_METHOD:
            func = self._process_method(ac, class_, store_global=store_global)
            if func.is_virtual:
                class_.is_polymorphic = True
            class_.functions[func.name].append(func)
        elif (ac.kind == CursorKind.TYPEDEF_DECL
              or ac.kind == CursorKind.TYPE_ALIAS_DECL):
            tp = self._process_typedef(ac, class_, store_global=store_global)
            class_.typedefs[tp.name] = tp
        elif ac.kind == CursorKind.TYPE_ALIAS_TEMPLATE_DECL:
            tp = self._process_template_alias(ac,
                                              class_,
                                              store_global=store_global)
            class_.typedefs[tp.name] = tp
        elif ac.kind in CLASS_UNSUPPORTED_CURSORS:
            pass
        else:
            logger.warning(
                "unknown kind in class child, and not handled: %s %s",
                ac.kind,
                ac.extent,
            )