311 lines
8.0 KiB
Python
311 lines
8.0 KiB
Python
import sys
|
|
import typing
|
|
|
|
if sys.version_info >= (3, 8):
|
|
from typing import Protocol
|
|
else:
|
|
Protocol = object # pragma: no cover
|
|
|
|
|
|
from .types import (
|
|
EnumDecl,
|
|
Field,
|
|
ForwardDecl,
|
|
FriendDecl,
|
|
Function,
|
|
Method,
|
|
NamespaceAlias,
|
|
TemplateInst,
|
|
Typedef,
|
|
UsingAlias,
|
|
UsingDecl,
|
|
Variable,
|
|
Value,
|
|
)
|
|
|
|
from .parserstate import (
|
|
State,
|
|
ClassBlockState,
|
|
ExternBlockState,
|
|
NamespaceBlockState,
|
|
NonClassBlockState,
|
|
)
|
|
|
|
|
|
class CxxVisitor(Protocol):
|
|
"""
|
|
Defines the interface used by the parser to emit events
|
|
"""
|
|
|
|
def on_parse_start(self, state: NamespaceBlockState) -> None:
|
|
"""
|
|
Called when parsing begins
|
|
"""
|
|
|
|
def on_pragma(self, state: State, content: Value) -> None:
|
|
"""
|
|
Called once for each ``#pragma`` directive encountered
|
|
"""
|
|
|
|
def on_include(self, state: State, filename: str) -> None:
|
|
"""
|
|
Called once for each ``#include`` directive encountered
|
|
"""
|
|
|
|
def on_extern_block_start(self, state: ExternBlockState) -> typing.Optional[bool]:
|
|
"""
|
|
.. code-block:: c++
|
|
|
|
extern "C" {
|
|
|
|
}
|
|
|
|
If this function returns False, the visitor will not be called for any
|
|
items inside this block (including on_extern_block_end)
|
|
"""
|
|
|
|
def on_extern_block_end(self, state: ExternBlockState) -> None:
|
|
"""
|
|
Called when an extern block ends
|
|
"""
|
|
|
|
def on_namespace_start(self, state: NamespaceBlockState) -> typing.Optional[bool]:
|
|
"""
|
|
Called when a ``namespace`` directive is encountered
|
|
|
|
If this function returns False, the visitor will not be called for any
|
|
items inside this namespace (including on_namespace_end)
|
|
"""
|
|
|
|
def on_namespace_end(self, state: NamespaceBlockState) -> None:
|
|
"""
|
|
Called at the end of a ``namespace`` block
|
|
"""
|
|
|
|
def on_namespace_alias(
|
|
self, state: NonClassBlockState, alias: NamespaceAlias
|
|
) -> None:
|
|
"""
|
|
Called when a ``namespace`` alias is encountered
|
|
"""
|
|
|
|
def on_forward_decl(self, state: State, fdecl: ForwardDecl) -> None:
|
|
"""
|
|
Called when a forward declaration is encountered
|
|
"""
|
|
|
|
def on_template_inst(self, state: State, inst: TemplateInst) -> None:
|
|
"""
|
|
Called when an explicit template instantiation is encountered
|
|
"""
|
|
|
|
def on_variable(self, state: State, v: Variable) -> None:
|
|
"""
|
|
Called when a global variable is encountered
|
|
"""
|
|
|
|
def on_function(self, state: NonClassBlockState, fn: Function) -> None:
|
|
"""
|
|
Called when a function is encountered that isn't part of a class
|
|
"""
|
|
|
|
def on_method_impl(self, state: NonClassBlockState, method: Method) -> None:
|
|
"""
|
|
Called when a method implementation is encountered outside of a class
|
|
declaration. For example:
|
|
|
|
.. code-block:: c++
|
|
|
|
void MyClass::fn() {
|
|
// does something
|
|
}
|
|
|
|
.. note:: The above implementation is ambiguous, as it technically could
|
|
be a function in a namespace. We emit this instead as it's
|
|
more likely to be the case in common code.
|
|
"""
|
|
|
|
def on_typedef(self, state: State, typedef: Typedef) -> None:
|
|
"""
|
|
Called for each typedef instance encountered. For example:
|
|
|
|
.. code-block:: c++
|
|
|
|
typedef int T, *PT;
|
|
|
|
Will result in ``on_typedef`` being called twice, once for ``T`` and
|
|
once for ``*PT``
|
|
"""
|
|
|
|
def on_using_namespace(
|
|
self, state: NonClassBlockState, namespace: typing.List[str]
|
|
) -> None:
|
|
"""
|
|
.. code-block:: c++
|
|
|
|
using namespace std;
|
|
"""
|
|
|
|
def on_using_alias(self, state: State, using: UsingAlias) -> None:
|
|
"""
|
|
.. code-block:: c++
|
|
|
|
using foo = int;
|
|
|
|
template <typename T>
|
|
using VectorT = std::vector<T>;
|
|
|
|
"""
|
|
|
|
def on_using_declaration(self, state: State, using: UsingDecl) -> None:
|
|
"""
|
|
.. code-block:: c++
|
|
|
|
using NS::ClassName;
|
|
|
|
"""
|
|
|
|
#
|
|
# Enums
|
|
#
|
|
|
|
def on_enum(self, state: State, enum: EnumDecl) -> None:
|
|
"""
|
|
Called after an enum is encountered
|
|
"""
|
|
|
|
#
|
|
# Class/union/struct
|
|
#
|
|
|
|
def on_class_start(self, state: ClassBlockState) -> typing.Optional[bool]:
|
|
"""
|
|
Called when a class/struct/union is encountered
|
|
|
|
When part of a typedef:
|
|
|
|
.. code-block:: c++
|
|
|
|
typedef struct { } X;
|
|
|
|
This is called first, followed by on_typedef for each typedef instance
|
|
encountered. The compound type object is passed as the type to the
|
|
typedef.
|
|
|
|
If this function returns False, the visitor will not be called for any
|
|
items inside this class (including on_class_end)
|
|
"""
|
|
|
|
def on_class_field(self, state: ClassBlockState, f: Field) -> None:
|
|
"""
|
|
Called when a field of a class is encountered
|
|
"""
|
|
|
|
def on_class_friend(self, state: ClassBlockState, friend: FriendDecl) -> None:
|
|
"""
|
|
Called when a friend declaration is encountered
|
|
"""
|
|
|
|
def on_class_method(self, state: ClassBlockState, method: Method) -> None:
|
|
"""
|
|
Called when a method of a class is encountered inside of a class
|
|
"""
|
|
|
|
def on_class_end(self, state: ClassBlockState) -> None:
|
|
"""
|
|
Called when the end of a class/struct/union is encountered.
|
|
|
|
When a variable like this is declared:
|
|
|
|
.. code-block:: c++
|
|
|
|
struct X {
|
|
|
|
} x;
|
|
|
|
Then ``on_class_start``, .. ``on_class_end`` are emitted, along with
|
|
``on_variable`` for each instance declared.
|
|
"""
|
|
|
|
|
|
class NullVisitor:
|
|
"""
|
|
This visitor does nothing
|
|
"""
|
|
|
|
def on_parse_start(self, state: NamespaceBlockState) -> None:
|
|
return None
|
|
|
|
def on_pragma(self, state: State, content: Value) -> None:
|
|
return None
|
|
|
|
def on_include(self, state: State, filename: str) -> None:
|
|
return None
|
|
|
|
def on_extern_block_start(self, state: ExternBlockState) -> typing.Optional[bool]:
|
|
return None
|
|
|
|
def on_extern_block_end(self, state: ExternBlockState) -> None:
|
|
return None
|
|
|
|
def on_namespace_start(self, state: NamespaceBlockState) -> typing.Optional[bool]:
|
|
return None
|
|
|
|
def on_namespace_end(self, state: NamespaceBlockState) -> None:
|
|
return None
|
|
|
|
def on_namespace_alias(
|
|
self, state: NonClassBlockState, alias: NamespaceAlias
|
|
) -> None:
|
|
return None
|
|
|
|
def on_forward_decl(self, state: State, fdecl: ForwardDecl) -> None:
|
|
return None
|
|
|
|
def on_template_inst(self, state: State, inst: TemplateInst) -> None:
|
|
return None
|
|
|
|
def on_variable(self, state: State, v: Variable) -> None:
|
|
return None
|
|
|
|
def on_function(self, state: NonClassBlockState, fn: Function) -> None:
|
|
return None
|
|
|
|
def on_method_impl(self, state: NonClassBlockState, method: Method) -> None:
|
|
return None
|
|
|
|
def on_typedef(self, state: State, typedef: Typedef) -> None:
|
|
return None
|
|
|
|
def on_using_namespace(
|
|
self, state: NonClassBlockState, namespace: typing.List[str]
|
|
) -> None:
|
|
return None
|
|
|
|
def on_using_alias(self, state: State, using: UsingAlias) -> None:
|
|
return None
|
|
|
|
def on_using_declaration(self, state: State, using: UsingDecl) -> None:
|
|
return None
|
|
|
|
def on_enum(self, state: State, enum: EnumDecl) -> None:
|
|
return None
|
|
|
|
def on_class_start(self, state: ClassBlockState) -> typing.Optional[bool]:
|
|
return None
|
|
|
|
def on_class_field(self, state: ClassBlockState, f: Field) -> None:
|
|
return None
|
|
|
|
def on_class_friend(self, state: ClassBlockState, friend: FriendDecl) -> None:
|
|
return None
|
|
|
|
def on_class_method(self, state: ClassBlockState, method: Method) -> None:
|
|
return None
|
|
|
|
def on_class_end(self, state: ClassBlockState) -> None:
|
|
return None
|
|
|
|
|
|
null_visitor = NullVisitor()
|