示例#1
0
 def _process_method(self, c: Cursor, class_):
     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(),
     )
     for ac in c.get_arguments():
         arg = self._process_variable(ac, class_, warn_failed=False)
         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,
             )
     self.objects[func.full_name] = func
     return func
示例#2
0
 def _process_enum(self, c: Cursor, parent: AnyCxxSymbol):
     e = Enum(name=c.spelling,
              parent=parent,
              location=location_from_cursor(c),
              type=c.enum_type.spelling,
              is_strong_typed=c.is_scoped_enum())
     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)
     self.objects[e.full_name] = e
     return e
示例#3
0
    def _process_namespace(self,
                           c: Cursor,
                           n: Namespace,
                           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)
            if on_progress:
                on_progress(i + 1, count)
        return n
示例#4
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
示例#5
0
 def _parse_macro_literal_cursor(self, c: Cursor):
     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)
示例#6
0
 def _process_class_child(self, ac: Cursor, class_: Class):
     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_)
         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.UNION_DECL
           or ac.kind == CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION
     ):
         if not ac.is_anonymous():
             child = self._process_class(ac, class_)
             class_.classes[child.name] = child
         else:
             child = self._process_class(ac, class_, store_global=False)
             class_.extend(child)
     elif ac.kind == CursorKind.DESTRUCTOR:
         func = self._process_method(ac, class_)
         if func.is_virtual:
             class_.is_polymorphic = True
         class_.destructor = func
     elif ac.kind == CursorKind.ENUM_DECL:
         e = self._process_enum(ac, class_)
         class_.enums[e.name] = e
     elif ac.kind == CursorKind.FIELD_DECL:
         v = self._process_variable(ac, class_)
         class_.variables[v.name] = v
     elif ac.kind == CursorKind.CXX_METHOD:
         func = self._process_method(ac, class_)
         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_)
         class_.typedefs[tp.name] = tp
     elif ac.kind == CursorKind.TYPE_ALIAS_TEMPLATE_DECL:
         tp = self._process_template_alias(ac, class_)
         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,
         )
示例#7
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="")
     if length == 1:
         return m
     m.definition = " ".join([i.spelling for i in tokens[1:]])
     return m
示例#8
0
 def _process_function(self, c: Cursor, parent: Namespace):
     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()
         ],
     )
     self.objects[func.full_name] = func
     return func
示例#9
0
    def _process_class(self, c: Cursor, parent: AnyCxxSymbol, store_global=True):
        # 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_)

        if store_global:
            self.objects[class_.full_name] = class_
        return class_
示例#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