Ejemplo n.º 1
0
def _result(comment,
            cursor=None,
            fmt=docstr.Type.TEXT,
            nest=0,
            name=None,
            ttype=None,
            args=None,
            compat=None):

    # FIXME: docstr.generate changes the number of lines in output. This impacts
    # the error reporting via meta['line']. Adjust meta to take this into
    # account.

    doc = docstr.generate(text=comment.spelling,
                          fmt=fmt,
                          name=name,
                          ttype=ttype,
                          args=args,
                          transform=compat)

    doc = docstr.nest(doc, nest)

    meta = {'line': comment.extent.start.line}
    if cursor:
        meta['cursor.kind'] = cursor.kind,
        meta['cursor.displayname'] = cursor.displayname,
        meta['cursor.spelling'] = cursor.spelling

    return [(doc, meta)]
Ejemplo n.º 2
0
def _recursive_parse(comments, cursor, nest, compat):
    comment = comments[cursor.hash]
    name = cursor.spelling
    ttype = cursor.type.spelling

    if cursor.kind == CursorKind.MACRO_DEFINITION:
        # FIXME: check args against comment
        args = _get_macro_args(cursor)
        fmt = docstr.Type.MACRO if args is None else docstr.Type.MACRO_FUNC

        return _result(comment,
                       cursor=cursor,
                       fmt=fmt,
                       nest=nest,
                       name=name,
                       args=args,
                       compat=compat)

    elif cursor.kind == CursorKind.VAR_DECL:
        fmt = docstr.Type.VAR

        return _result(comment,
                       cursor=cursor,
                       fmt=fmt,
                       nest=nest,
                       name=name,
                       ttype=ttype,
                       compat=compat)

    elif cursor.kind == CursorKind.TYPEDEF_DECL:
        # FIXME: function pointers typedefs.
        fmt = docstr.Type.TYPE

        return _result(comment,
                       cursor=cursor,
                       fmt=fmt,
                       nest=nest,
                       name=ttype,
                       compat=compat)

    elif cursor.kind in [
            CursorKind.STRUCT_DECL, CursorKind.UNION_DECL, CursorKind.ENUM_DECL
    ]:

        # FIXME:
        # Handle cases where variables are instantiated on type declaration,
        # including anonymous cases. Idea is that if there is a variable
        # instantiation, the documentation should be applied to the variable if
        # the structure is anonymous or to the type otherwise.
        #
        # Due to the new recursiveness of the parser, fixing this here, _should_
        # handle all cases (struct, union, enum).

        # FIXME: Handle anonymous enumerators.

        fmt = docstr.Type.TYPE
        result = _result(comment,
                         cursor=cursor,
                         fmt=fmt,
                         nest=nest,
                         name=ttype,
                         compat=compat)

        nest += 1
        for c in cursor.get_children():
            if c.hash in comments:
                result.extend(_recursive_parse(comments, c, nest, compat))

        return result

    elif cursor.kind == CursorKind.ENUM_CONSTANT_DECL:
        fmt = docstr.Type.ENUM_VAL

        return _result(comment,
                       cursor=cursor,
                       fmt=fmt,
                       nest=nest,
                       name=name,
                       compat=compat)

    elif cursor.kind == CursorKind.FIELD_DECL:
        fmt = docstr.Type.MEMBER

        return _result(comment,
                       cursor=cursor,
                       fmt=fmt,
                       nest=nest,
                       name=name,
                       ttype=ttype,
                       compat=compat)

    elif cursor.kind == CursorKind.FUNCTION_DECL:
        # FIXME: check args against comment
        # FIXME: children may contain extra stuff if the return type is a
        # typedef, for example
        args = []
        for c in cursor.get_children():
            if c.kind == CursorKind.PARM_DECL:
                args.append('{ttype} {arg}'.format(ttype=c.type.spelling,
                                                   arg=c.spelling))

        if cursor.type.is_function_variadic():
            args.append('...')

        fmt = docstr.Type.FUNC
        ttype = cursor.result_type.spelling

        return _result(comment,
                       cursor=cursor,
                       fmt=fmt,
                       nest=nest,
                       name=name,
                       ttype=ttype,
                       args=args,
                       compat=compat)

    # FIXME: If we reach here, nothing matched. This is a warning or even error
    # and it should be logged, but it should also return an empty list so that
    # it doesn't break. I.e. the parser needs to pass warnings and errors to the
    # Sphinx extension instead of polluting the generated output.
    fmt = docstr.Type.TEXT
    text = 'warning: unhandled cursor {kind} {name}\n'.format(
        kind=str(cursor.kind), name=cursor.spelling)

    doc = docstr.generate(text=text, fmt=fmt)

    meta = {
        'line': comment.extent.start.line,
        'cursor.kind': cursor.kind,
        'cursor.displayname': cursor.displayname,
        'cursor.spelling': cursor.spelling
    }

    return [(doc, meta)]