Merge pull request #35 from robotpy/mypy-madness

Check codebase using mypy
This commit is contained in:
Dustin Spicuzza 2022-01-02 21:55:40 -05:00 committed by GitHub
commit 944c9daf10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 353 additions and 253 deletions

View File

@ -16,6 +16,22 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: psf/black@stable - uses: psf/black@stable
check-mypy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# - uses: jpetrucciani/mypy-check@0.930
# .. can't use that because we need to install pytest
- uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install requirements
run: |
pip --disable-pip-version-check install mypy pytest
- name: Run mypy
run: |
mypy .
check-doc: check-doc:
runs-on: ubuntu-18.04 runs-on: ubuntu-18.04
@ -77,7 +93,7 @@ jobs:
publish: publish:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [check, check-doc, test] needs: [check, check-mypy, check-doc, test]
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
steps: steps:

View File

@ -1,4 +1,4 @@
try: try:
from .version import __version__ from .version import __version__ # type: ignore
except ImportError: except ImportError:
__version__ = "master" __version__ = "master"

View File

@ -9,7 +9,7 @@ from .options import ParserOptions
from .simple import parse_file from .simple import parse_file
def dumpmain(): def dumpmain() -> None:
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("header") parser.add_argument("header")

View File

@ -2,12 +2,13 @@ import argparse
import dataclasses import dataclasses
import inspect import inspect
import subprocess import subprocess
import typing
from .options import ParserOptions from .options import ParserOptions
from .simple import parse_string from .simple import parse_string, ParsedData
def nondefault_repr(data): def nondefault_repr(data: ParsedData) -> str:
""" """
Similar to the default dataclass repr, but exclude any Similar to the default dataclass repr, but exclude any
default parameters or parameters with compare=False default parameters or parameters with compare=False
@ -17,7 +18,7 @@ def nondefault_repr(data):
get_fields = dataclasses.fields get_fields = dataclasses.fields
MISSING = dataclasses.MISSING MISSING = dataclasses.MISSING
def _inner_repr(o) -> str: def _inner_repr(o: typing.Any) -> str:
if is_dataclass(o): if is_dataclass(o):
vals = [] vals = []
for f in get_fields(o): for f in get_fields(o):
@ -46,7 +47,7 @@ def nondefault_repr(data):
return _inner_repr(data) return _inner_repr(data)
def gentest(infile: str, name: str, outfile: str, verbose: bool): def gentest(infile: str, name: str, outfile: str, verbose: bool) -> None:
# Goal is to allow making a unit test as easy as running this dumper # Goal is to allow making a unit test as easy as running this dumper
# on a file and copy/pasting this into a test # on a file and copy/pasting this into a test
@ -64,7 +65,7 @@ def gentest(infile: str, name: str, outfile: str, verbose: bool):
stmt = inspect.cleandoc( stmt = inspect.cleandoc(
f''' f'''
def test_{name}(): def test_{name}() -> None:
content = """ content = """
{content} {content}
""" """

View File

@ -42,6 +42,9 @@ class LexToken(Protocol):
#: Location token was found at #: Location token was found at
location: Location location: Location
#: private
lexer: "Lexer"
PhonyEnding: LexToken = lex.LexToken() # type: ignore PhonyEnding: LexToken = lex.LexToken() # type: ignore
PhonyEnding.type = "PLACEHOLDER" PhonyEnding.type = "PLACEHOLDER"
@ -183,13 +186,13 @@ class Lexer:
t_NUMBER = r"[0-9][0-9XxA-Fa-f]*" t_NUMBER = r"[0-9][0-9XxA-Fa-f]*"
t_FLOAT_NUMBER = r"[-+]?[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?" t_FLOAT_NUMBER = r"[-+]?[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?"
def t_NAME(self, t): def t_NAME(self, t: LexToken) -> LexToken:
r"[A-Za-z_~][A-Za-z0-9_]*" r"[A-Za-z_~][A-Za-z0-9_]*"
if t.value in self.keywords: if t.value in self.keywords:
t.type = t.value t.type = t.value
return t return t
def t_PRECOMP_MACRO(self, t): def t_PRECOMP_MACRO(self, t: LexToken) -> typing.Optional[LexToken]:
r"\#.*" r"\#.*"
m = _line_re.match(t.value) m = _line_re.match(t.value)
if m: if m:
@ -200,11 +203,11 @@ class Lexer:
self.filename = filename self.filename = filename
self.line_offset = 1 + self.lex.lineno - int(m.group(1)) self.line_offset = 1 + self.lex.lineno - int(m.group(1))
return None
else: else:
return t return t
def t_COMMENT_SINGLELINE(self, t): def t_COMMENT_SINGLELINE(self, t: LexToken) -> LexToken:
r"\/\/.*\n?" r"\/\/.*\n?"
if t.value.startswith("///") or t.value.startswith("//!"): if t.value.startswith("///") or t.value.startswith("//!"):
self.comments.append(t.value.lstrip("\t ").rstrip("\n")) self.comments.append(t.value.lstrip("\t ").rstrip("\n"))
@ -227,7 +230,7 @@ class Lexer:
t_STRING_LITERAL = r'"([^"\\]|\\.)*"' t_STRING_LITERAL = r'"([^"\\]|\\.)*"'
# Found at http://ostermiller.org/findcomment.html # Found at http://ostermiller.org/findcomment.html
def t_COMMENT_MULTILINE(self, t): def t_COMMENT_MULTILINE(self, t: LexToken) -> LexToken:
r"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/\n?" r"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/\n?"
if t.value.startswith("/**") or t.value.startswith("/*!"): if t.value.startswith("/**") or t.value.startswith("/*!"):
# not sure why, but get double new lines # not sure why, but get double new lines
@ -238,19 +241,20 @@ class Lexer:
t.lexer.lineno += t.value.count("\n") t.lexer.lineno += t.value.count("\n")
return t return t
def t_NEWLINE(self, t): def t_NEWLINE(self, t: LexToken) -> LexToken:
r"\n+" r"\n+"
t.lexer.lineno += len(t.value) t.lexer.lineno += len(t.value)
del self.comments[:] del self.comments[:]
return t return t
def t_error(self, v): def t_error(self, t: LexToken) -> None:
print("Lex error: ", v) print("Lex error: ", t)
_lexer = None _lexer = None
lex: lex.Lexer lex: lex.Lexer
lineno: int
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs) -> "Lexer":
# only build the lexer once # only build the lexer once
inst = super().__new__(cls) inst = super().__new__(cls)
if cls._lexer is None: if cls._lexer is None:
@ -261,16 +265,16 @@ class Lexer:
return inst return inst
def __init__(self, filename: typing.Optional[str] = None): def __init__(self, filename: typing.Optional[str] = None):
self.input = self.lex.input self.input: typing.Callable[[str], None] = self.lex.input
# For tracking current file/line position # For tracking current file/line position
self.filename = filename self.filename = filename
self.line_offset = 0 self.line_offset = 0
self.filenames = [] self.filenames: typing.List[str] = []
self._filenames_set = set() self._filenames_set: typing.Set[str] = set()
if self.filename: if filename:
self.filenames.append(filename) self.filenames.append(filename)
self._filenames_set.add(filename) self._filenames_set.add(filename)
@ -330,22 +334,24 @@ class Lexer:
del self.comments[:] del self.comments[:]
comments = "\n".join(comments) comment_str = "\n".join(comments)
del self.comments[:] del self.comments[:]
if comments: if comment_str:
return comments return comment_str
return None return None
_discard_types = {"NEWLINE", "COMMENT_SINGLELINE", "COMMENT_MULTILINE"} _discard_types = {"NEWLINE", "COMMENT_SINGLELINE", "COMMENT_MULTILINE"}
def _token_limit_exceeded(self): def _token_limit_exceeded(self) -> typing.NoReturn:
from .errors import CxxParseError from .errors import CxxParseError
raise CxxParseError("no more tokens left in this group") raise CxxParseError("no more tokens left in this group")
@contextlib.contextmanager @contextlib.contextmanager
def set_group_of_tokens(self, toks: typing.List[LexToken]): def set_group_of_tokens(
self, toks: typing.List[LexToken]
) -> typing.Generator[typing.Deque[LexToken], None, None]:
# intended for use when you have a set of tokens that you know # intended for use when you have a set of tokens that you know
# must be consumed, such as a paren grouping or some type of # must be consumed, such as a paren grouping or some type of
# lookahead case # lookahead case

View File

@ -93,9 +93,9 @@ class CxxParser:
self.verbose = True if self.options.verbose else False self.verbose = True if self.options.verbose else False
if self.verbose: if self.verbose:
def debug_print(fmt: str, *args: typing.Any): def debug_print(fmt: str, *args: typing.Any) -> None:
fmt = f"[%4d] {fmt}" fmt = f"[%4d] {fmt}"
args = (inspect.currentframe().f_back.f_lineno,) + args args = (inspect.currentframe().f_back.f_lineno,) + args # type: ignore
print(fmt % args) print(fmt % args)
self.debug_print = debug_print self.debug_print = debug_print
@ -135,7 +135,7 @@ class CxxParser:
# #
def _parse_error( def _parse_error(
self, tok: typing.Optional[LexToken], expected="" self, tok: typing.Optional[LexToken], expected: str = ""
) -> CxxParseError: ) -> CxxParseError:
if not tok: if not tok:
# common case after a failed token_if # common case after a failed token_if
@ -220,6 +220,8 @@ class CxxParser:
match_stack = deque((token_map[tok.type] for tok in consumed)) match_stack = deque((token_map[tok.type] for tok in consumed))
get_token = self.lex.token get_token = self.lex.token
tok: typing.Optional[LexToken]
while True: while True:
tok = get_token() tok = get_token()
consumed.append(tok) consumed.append(tok)
@ -544,7 +546,7 @@ class CxxParser:
return TemplateDecl(params) return TemplateDecl(params)
def _parse_template(self, tok: LexToken, doxygen: typing.Optional[str]): def _parse_template(self, tok: LexToken, doxygen: typing.Optional[str]) -> None:
template = self._parse_template_decl() template = self._parse_template_decl()
@ -600,7 +602,7 @@ class CxxParser:
raise self._parse_error(None) raise self._parse_error(None)
mods.validate(var_ok=False, meth_ok=False, msg="") mods.validate(var_ok=False, meth_ok=False, msg="")
dtype = self._parse_cv_ptr(parsed_type, nonptr_fn=True) dtype = self._parse_cv_ptr_or_fn(parsed_type, nonptr_fn=True)
self._next_token_must_be(PhonyEnding.type) self._next_token_must_be(PhonyEnding.type)
except CxxParseError: except CxxParseError:
dtype = None dtype = None
@ -710,10 +712,12 @@ class CxxParser:
break break
# multiple attributes can be specified # multiple attributes can be specified
tok = self.lex.token_if(*self._attribute_specifier_seq_start_types) maybe_tok = self.lex.token_if(*self._attribute_specifier_seq_start_types)
if tok is None: if maybe_tok is None:
break break
tok = maybe_tok
# TODO return attrs # TODO return attrs
# #
@ -982,7 +986,7 @@ class CxxParser:
template: typing.Optional[TemplateDecl], template: typing.Optional[TemplateDecl],
typedef: bool, typedef: bool,
location: Location, location: Location,
props: typing.Dict[str, LexToken], mods: ParsedTypeModifiers,
) -> None: ) -> None:
""" """
class_specifier: class_head "{" [member_specification] "}" class_specifier: class_head "{" [member_specification] "}"
@ -1038,7 +1042,7 @@ class CxxParser:
typename, bases, template, explicit, final, doxygen, self._current_access typename, bases, template, explicit, final, doxygen, self._current_access
) )
state = self._push_state( state = self._push_state(
ClassBlockState, clsdecl, default_access, typedef, props ClassBlockState, clsdecl, default_access, typedef, mods
) )
state.location = location state.location = location
self.visitor.on_class_start(state) self.visitor.on_class_start(state)
@ -1133,7 +1137,11 @@ class CxxParser:
state = self.state state = self.state
state.location = location state.location = location
is_class_block = isinstance(state, ClassBlockState) if isinstance(state, ClassBlockState):
is_class_block = True
class_state = state
else:
is_class_block = False
name = None name = None
bits = None bits = None
default = None default = None
@ -1198,17 +1206,21 @@ class CxxParser:
props.update(dict.fromkeys(mods.vars.keys(), True)) props.update(dict.fromkeys(mods.vars.keys(), True))
if is_class_block: if is_class_block:
access = self._current_access
assert access is not None
f = Field( f = Field(
name=name, name=name,
type=dtype, type=dtype,
access=self._current_access, access=access,
value=default, value=default,
bits=bits, bits=bits,
doxygen=doxygen, doxygen=doxygen,
**props, **props,
) )
self.visitor.on_class_field(state, f) self.visitor.on_class_field(class_state, f)
else: else:
assert pqname is not None
v = Variable( v = Variable(
pqname, dtype, default, doxygen=doxygen, template=template, **props pqname, dtype, default, doxygen=doxygen, template=template, **props
) )
@ -1691,6 +1703,7 @@ class CxxParser:
if not isinstance(pqname.segments[-1], NameSpecifier): if not isinstance(pqname.segments[-1], NameSpecifier):
raise self._parse_error(None) raise self._parse_error(None)
props: typing.Dict
props = dict.fromkeys(mods.both.keys(), True) props = dict.fromkeys(mods.both.keys(), True)
if msvc_convention: if msvc_convention:
props["msvc_convention"] = msvc_convention.value props["msvc_convention"] = msvc_convention.value
@ -1702,10 +1715,15 @@ class CxxParser:
params, vararg = self._parse_parameters() params, vararg = self._parse_parameters()
if is_class_block and not is_typedef: if is_class_block and not is_typedef:
assert isinstance(state, ClassBlockState)
props.update(dict.fromkeys(mods.meths.keys(), True)) props.update(dict.fromkeys(mods.meths.keys(), True))
method: Method method: Method
current_access = self._current_access
assert current_access is not None
if op: if op:
method = Operator( method = Operator(
return_type, return_type,
@ -1715,8 +1733,8 @@ class CxxParser:
doxygen=doxygen, doxygen=doxygen,
operator=op, operator=op,
template=template, template=template,
access=self._current_access, access=current_access,
**props, **props, # type: ignore
) )
else: else:
method = Method( method = Method(
@ -1728,8 +1746,8 @@ class CxxParser:
constructor=constructor, constructor=constructor,
destructor=destructor, destructor=destructor,
template=template, template=template,
access=self._current_access, access=current_access,
**props, **props, # type: ignore
) )
self._parse_method_end(method) self._parse_method_end(method)
@ -1740,7 +1758,7 @@ class CxxParser:
else: else:
# method must not have multiple segments except for operator # method must not have multiple segments except for operator
if len(pqname.segments) > 1: if len(pqname.segments) > 1:
if not pqname.segments[0].name == "operator": if getattr(pqname.segments[0], "name", None) != "operator":
raise self._parse_error(None) raise self._parse_error(None)
self.visitor.on_class_method(state, method) self.visitor.on_class_method(state, method)
@ -1748,6 +1766,7 @@ class CxxParser:
return method.has_body or method.has_trailing_return return method.has_body or method.has_trailing_return
else: else:
assert return_type is not None
fn = Function( fn = Function(
return_type, return_type,
pqname, pqname,
@ -1764,6 +1783,10 @@ class CxxParser:
raise CxxParseError( raise CxxParseError(
"typedef name may not be a nested-name-specifier" "typedef name may not be a nested-name-specifier"
) )
name: typing.Optional[str] = getattr(pqname.segments[0], "name", None)
if not name:
raise CxxParseError("typedef function must have a name")
if fn.constexpr: if fn.constexpr:
raise CxxParseError("typedef function may not be constexpr") raise CxxParseError("typedef function may not be constexpr")
if fn.extern: if fn.extern:
@ -1777,8 +1800,12 @@ class CxxParser:
if fn.template: if fn.template:
raise CxxParseError("typedef function may not have a template") raise CxxParseError("typedef function may not have a template")
return_type = fn.return_type
if return_type is None:
raise CxxParseError("typedef function must have return type")
fntype = FunctionType( fntype = FunctionType(
fn.return_type, return_type,
fn.parameters, fn.parameters,
fn.vararg, fn.vararg,
fn.has_trailing_return, fn.has_trailing_return,
@ -1786,7 +1813,7 @@ class CxxParser:
msvc_convention=fn.msvc_convention, msvc_convention=fn.msvc_convention,
) )
typedef = Typedef(fntype, pqname.segments[0].name, self._current_access) typedef = Typedef(fntype, name, self._current_access)
self.visitor.on_typedef(state, typedef) self.visitor.on_typedef(state, typedef)
return False return False
else: else:
@ -1801,6 +1828,9 @@ class CxxParser:
assert tok.type == "[" assert tok.type == "["
if isinstance(dtype, (Reference, MoveReference)):
raise CxxParseError("arrays of references are illegal", tok)
toks = self._consume_balanced_tokens(tok) toks = self._consume_balanced_tokens(tok)
otok = self.lex.token_if("[") otok = self.lex.token_if("[")
if otok: if otok:
@ -1817,9 +1847,20 @@ class CxxParser:
def _parse_cv_ptr( def _parse_cv_ptr(
self, self,
dtype: typing.Union[Array, FunctionType, Pointer, Type], dtype: DecoratedType,
nonptr_fn: bool = False,
) -> DecoratedType: ) -> DecoratedType:
dtype_or_fn = self._parse_cv_ptr_or_fn(dtype)
if isinstance(dtype_or_fn, FunctionType):
raise CxxParseError("unexpected function type")
return dtype_or_fn
def _parse_cv_ptr_or_fn(
self,
dtype: typing.Union[
Array, Pointer, MoveReference, Reference, Type, FunctionType
],
nonptr_fn: bool = False,
) -> typing.Union[Array, Pointer, MoveReference, Reference, Type, FunctionType]:
# nonptr_fn is for parsing function types directly in template specialization # nonptr_fn is for parsing function types directly in template specialization
while True: while True:
@ -1828,10 +1869,16 @@ class CxxParser:
break break
if tok.type == "*": if tok.type == "*":
if isinstance(dtype, (Reference, MoveReference)):
raise self._parse_error(tok)
dtype = Pointer(dtype) dtype = Pointer(dtype)
elif tok.type == "const": elif tok.type == "const":
if not isinstance(dtype, (Pointer, Type)):
raise self._parse_error(tok)
dtype.const = True dtype.const = True
elif tok.type == "volatile": elif tok.type == "volatile":
if not isinstance(dtype, (Pointer, Type)):
raise self._parse_error(tok)
dtype.volatile = True dtype.volatile = True
elif nonptr_fn: elif nonptr_fn:
# remove any inner grouping parens # remove any inner grouping parens
@ -1844,14 +1891,17 @@ class CxxParser:
self.lex.return_tokens(toks[1:-1]) self.lex.return_tokens(toks[1:-1])
fn_params, vararg = self._parse_parameters() fn_params, vararg = self._parse_parameters()
dtype = FunctionType(dtype, fn_params, vararg)
assert not isinstance(dtype, FunctionType)
dtype = dtype_fn = FunctionType(dtype, fn_params, vararg)
if self.lex.token_if("ARROW"): if self.lex.token_if("ARROW"):
self._parse_trailing_return_type(dtype) self._parse_trailing_return_type(dtype_fn)
else: else:
msvc_convention = self.lex.token_if_val(*self._msvc_conventions) msvc_convention = None
if msvc_convention: msvc_convention_tok = self.lex.token_if_val(*self._msvc_conventions)
msvc_convention = msvc_convention.value if msvc_convention_tok:
msvc_convention = msvc_convention_tok.value
# Check to see if this is a grouping paren or something else # Check to see if this is a grouping paren or something else
if not self.lex.token_peek_if("*", "&"): if not self.lex.token_peek_if("*", "&"):
@ -1865,11 +1915,14 @@ class CxxParser:
aptok = self.lex.token_if("[", "(") aptok = self.lex.token_if("[", "(")
if aptok: if aptok:
if aptok.type == "[": if aptok.type == "[":
assert not isinstance(dtype, FunctionType)
dtype = self._parse_array_type(aptok, dtype) dtype = self._parse_array_type(aptok, dtype)
elif aptok.type == "(": elif aptok.type == "(":
fn_params, vararg = self._parse_parameters() fn_params, vararg = self._parse_parameters()
# the type we already have is the return type of the function pointer # the type we already have is the return type of the function pointer
assert not isinstance(dtype, FunctionType)
dtype = FunctionType( dtype = FunctionType(
dtype, fn_params, vararg, msvc_convention=msvc_convention dtype, fn_params, vararg, msvc_convention=msvc_convention
) )
@ -1882,11 +1935,13 @@ class CxxParser:
# -> this could return some weird results for invalid code, but # -> this could return some weird results for invalid code, but
# we don't support that anyways so it's fine? # we don't support that anyways so it's fine?
self.lex.return_tokens(toks[1:-1]) self.lex.return_tokens(toks[1:-1])
dtype = self._parse_cv_ptr(dtype) dtype = self._parse_cv_ptr_or_fn(dtype, nonptr_fn)
break break
tok = self.lex.token_if("&", "DBL_AMP") tok = self.lex.token_if("&", "DBL_AMP")
if tok: if tok:
assert not isinstance(dtype, (Reference, MoveReference))
if tok.type == "&": if tok.type == "&":
dtype = Reference(dtype) dtype = Reference(dtype)
else: else:
@ -1895,7 +1950,7 @@ class CxxParser:
# peek at the next token and see if it's a paren. If so, it might # peek at the next token and see if it's a paren. If so, it might
# be a nasty function pointer # be a nasty function pointer
if self.lex.token_peek_if("("): if self.lex.token_peek_if("("):
dtype = self._parse_cv_ptr(dtype, nonptr_fn) dtype = self._parse_cv_ptr_or_fn(dtype, nonptr_fn)
return dtype return dtype
@ -2011,6 +2066,7 @@ class CxxParser:
toks = [] toks = []
# On entry we only have the base type, decorate it # On entry we only have the base type, decorate it
dtype: typing.Optional[DecoratedType]
dtype = self._parse_cv_ptr(parsed_type) dtype = self._parse_cv_ptr(parsed_type)
state = self.state state = self.state
@ -2104,6 +2160,8 @@ class CxxParser:
if not self.lex.token_if(";"): if not self.lex.token_if(";"):
raise self._parse_error(None) raise self._parse_error(None)
assert isinstance(state, ClassBlockState)
fwd = ForwardDecl( fwd = ForwardDecl(
parsed_type.typename, parsed_type.typename,
template, template,
@ -2117,6 +2175,9 @@ class CxxParser:
if op: if op:
raise self._parse_error(None) raise self._parse_error(None)
if not dtype:
raise CxxParseError("appear to be parsing a field without a type")
self._parse_field(mods, dtype, pqname, template, doxygen, location, is_typedef) self._parse_field(mods, dtype, pqname, template, doxygen, location, is_typedef)
return False return False
@ -2128,7 +2189,7 @@ class CxxParser:
template: typing.Optional[TemplateDecl], template: typing.Optional[TemplateDecl],
is_typedef: bool, is_typedef: bool,
is_friend: bool, is_friend: bool,
): ) -> None:
tok = self._next_token_must_be("operator") tok = self._next_token_must_be("operator")
if is_typedef: if is_typedef:
@ -2145,7 +2206,7 @@ class CxxParser:
self._next_token_must_be("(") self._next_token_must_be("(")
# make our own pqname/op here # make our own pqname/op here
segments = [NameSpecifier("operator")] segments: typing.List[PQNameSegment] = [NameSpecifier("operator")]
pqname = PQName(segments) pqname = PQName(segments)
op = "conversion" op = "conversion"
@ -2276,12 +2337,14 @@ class CxxParser:
fdecl = ForwardDecl( fdecl = ForwardDecl(
parsed_type.typename, template, doxygen, access=self._current_access parsed_type.typename, template, doxygen, access=self._current_access
) )
self.state.location = location state = self.state
state.location = location
if is_friend: if is_friend:
assert isinstance(state, ClassBlockState)
friend = FriendDecl(cls=fdecl) friend = FriendDecl(cls=fdecl)
self.visitor.on_class_friend(self.state, friend) self.visitor.on_class_friend(state, friend)
else: else:
self.visitor.on_forward_decl(self.state, fdecl) self.visitor.on_forward_decl(state, fdecl)
return True return True
tok = self.lex.token_if_in_set(self._class_enum_stage2) tok = self.lex.token_if_in_set(self._class_enum_stage2)

View File

@ -57,7 +57,7 @@ class ExternBlockState(State):
super().__init__(parent) super().__init__(parent)
self.linkage = linkage self.linkage = linkage
def _finish(self, visitor: "CxxVisitor"): def _finish(self, visitor: "CxxVisitor") -> None:
visitor.on_extern_block_end(self) visitor.on_extern_block_end(self)

0
cxxheaderparser/py.typed Normal file
View File

View File

@ -93,7 +93,7 @@ class NamespaceScope:
classes: typing.List["ClassScope"] = field(default_factory=list) classes: typing.List["ClassScope"] = field(default_factory=list)
enums: typing.List[EnumDecl] = field(default_factory=list) enums: typing.List[EnumDecl] = field(default_factory=list)
functions: typing.List[Method] = field(default_factory=list) functions: typing.List[Function] = field(default_factory=list)
typedefs: typing.List[Typedef] = field(default_factory=list) typedefs: typing.List[Typedef] = field(default_factory=list)
variables: typing.List[Variable] = field(default_factory=list) variables: typing.List[Variable] = field(default_factory=list)
@ -185,7 +185,7 @@ class SimpleCxxVisitor:
namespace: NamespaceScope namespace: NamespaceScope
block: Block block: Block
def __init__(self): def __init__(self) -> None:
self.namespace = NamespaceScope("") self.namespace = NamespaceScope("")
self.block = self.namespace self.block = self.namespace
@ -236,6 +236,8 @@ class SimpleCxxVisitor:
parent_ns.namespaces[name] = ns parent_ns.namespaces[name] = ns
parent_ns = ns parent_ns = ns
assert ns is not None
self.block = ns self.block = ns
self.namespace = ns self.namespace = ns
@ -247,19 +249,22 @@ class SimpleCxxVisitor:
self.block.forward_decls.append(fdecl) self.block.forward_decls.append(fdecl)
def on_variable(self, state: State, v: Variable) -> None: def on_variable(self, state: State, v: Variable) -> None:
assert isinstance(self.block, NamespaceScope)
self.block.variables.append(v) self.block.variables.append(v)
def on_function(self, state: State, fn: Function) -> None: def on_function(self, state: State, fn: Function) -> None:
assert isinstance(self.block, NamespaceScope)
self.block.functions.append(fn) self.block.functions.append(fn)
def on_typedef(self, state: State, typedef: Typedef) -> None: def on_typedef(self, state: State, typedef: Typedef) -> None:
self.block.typedefs.append(typedef) self.block.typedefs.append(typedef)
def on_using_namespace(self, state: State, namespace: typing.List[str]) -> None: def on_using_namespace(self, state: State, namespace: typing.List[str]) -> None:
assert isinstance(self.block, NamespaceScope)
ns = UsingNamespace("::".join(namespace)) ns = UsingNamespace("::".join(namespace))
self.block.using_ns.append(ns) self.block.using_ns.append(ns)
def on_using_alias(self, state: State, using: UsingAlias): def on_using_alias(self, state: State, using: UsingAlias) -> None:
self.block.using_alias.append(using) self.block.using_alias.append(using)
def on_using_declaration(self, state: State, using: UsingDecl) -> None: def on_using_declaration(self, state: State, using: UsingDecl) -> None:
@ -283,12 +288,15 @@ class SimpleCxxVisitor:
self.block = block self.block = block
def on_class_field(self, state: State, f: Field) -> None: def on_class_field(self, state: State, f: Field) -> None:
assert isinstance(self.block, ClassScope)
self.block.fields.append(f) self.block.fields.append(f)
def on_class_method(self, state: ClassBlockState, method: Method) -> None: def on_class_method(self, state: ClassBlockState, method: Method) -> None:
assert isinstance(self.block, ClassScope)
self.block.methods.append(method) self.block.methods.append(method)
def on_class_friend(self, state: ClassBlockState, friend: FriendDecl): def on_class_friend(self, state: ClassBlockState, friend: FriendDecl) -> None:
assert isinstance(self.block, ClassScope)
self.block.friends.append(friend) self.block.friends.append(friend)
def on_class_end(self, state: ClassBlockState) -> None: def on_class_end(self, state: ClassBlockState) -> None:
@ -298,7 +306,7 @@ class SimpleCxxVisitor:
def parse_string( def parse_string(
content: str, content: str,
*, *,
filename="<str>", filename: str = "<str>",
options: typing.Optional[ParserOptions] = None, options: typing.Optional[ParserOptions] = None,
cleandoc: bool = False, cleandoc: bool = False,
) -> ParsedData: ) -> ParsedData:

View File

@ -56,7 +56,7 @@ if __name__ == "__main__":
lexer = Lexer(args.header) lexer = Lexer(args.header)
with open(lexer.filename) as fp: with open(lexer.filename) as fp:
lexer.input(fp.read()) lexer.input(fp.read()) # type: ignore
toks: typing.List[Token] = [] toks: typing.List[Token] = []
while True: while True:

View File

@ -193,7 +193,7 @@ class TemplateArgument:
#: If this argument is a type, it is stored here as a DecoratedType, #: If this argument is a type, it is stored here as a DecoratedType,
#: otherwise it's stored as an unparsed set of values #: otherwise it's stored as an unparsed set of values
arg: typing.Union["DecoratedType", Value] arg: typing.Union["DecoratedType", "FunctionType", Value]
param_pack: bool = False param_pack: bool = False
@ -297,7 +297,7 @@ class Reference:
A lvalue (``&``) reference A lvalue (``&``) reference
""" """
ref_to: typing.Union[Array, Pointer, Type] ref_to: typing.Union[Array, FunctionType, Pointer, Type]
@dataclass @dataclass
@ -306,7 +306,7 @@ class MoveReference:
An rvalue (``&&``) reference An rvalue (``&&``) reference
""" """
moveref_to: typing.Union[Array, Pointer, Type] moveref_to: typing.Union[Array, FunctionType, Pointer, Type]
#: A type or function type that is decorated with various things #: A type or function type that is decorated with various things
@ -468,7 +468,9 @@ class Function:
A function declaration, potentially with the function body A function declaration, potentially with the function body
""" """
return_type: DecoratedType #: Only constructors and destructors don't have a return type
return_type: typing.Optional[DecoratedType]
name: PQName name: PQName
parameters: typing.List[Parameter] parameters: typing.List[Parameter]
@ -510,9 +512,6 @@ class Method(Function):
A method declaration, potentially with the method body A method declaration, potentially with the method body
""" """
#: constructors and destructors don't have a return type
return_type: typing.Optional[DecoratedType]
access: str = "" access: str = ""
const: bool = False const: bool = False

View File

@ -119,7 +119,7 @@ class CxxVisitor(Protocol):
using namespace std; using namespace std;
""" """
def on_using_alias(self, state: State, using: UsingAlias): def on_using_alias(self, state: State, using: UsingAlias) -> None:
""" """
.. code-block:: c++ .. code-block:: c++
@ -171,7 +171,7 @@ class CxxVisitor(Protocol):
Called when a field of a class is encountered Called when a field of a class is encountered
""" """
def on_class_friend(self, state: ClassBlockState, friend: FriendDecl): def on_class_friend(self, state: ClassBlockState, friend: FriendDecl) -> None:
""" """
Called when a friend declaration is encountered Called when a friend declaration is encountered
""" """

5
mypy.ini Normal file
View File

@ -0,0 +1,5 @@
[mypy]
exclude = setup\.py|docs
[mypy-cxxheaderparser._ply.*]
ignore_errors = True

View File

@ -71,6 +71,7 @@ setup(
license="BSD", license="BSD",
platforms="Platform Independent", platforms="Platform Independent",
packages=find_packages(), packages=find_packages(),
package_data={"cxxheaderparser": ["py.typed"]},
keywords="c++ header parser ply", keywords="c++ header parser ply",
python_requires=">= 3.6", python_requires=">= 3.6",
classifiers=CLASSIFIERS, classifiers=CLASSIFIERS,

View File

@ -28,7 +28,7 @@ from cxxheaderparser.simple import (
) )
def test_attributes_everywhere(): def test_attributes_everywhere() -> None:
# TODO: someday we'll actually support storing attributes, # TODO: someday we'll actually support storing attributes,
# but for now just make sure they don't get in the way # but for now just make sure they don't get in the way
@ -124,7 +124,7 @@ def test_attributes_everywhere():
) )
def test_attributes_gcc_enum_packed(): def test_attributes_gcc_enum_packed() -> None:
content = """ content = """
enum Wheat { enum Wheat {
w1, w1,
@ -152,7 +152,7 @@ def test_attributes_gcc_enum_packed():
) )
def test_friendly_declspec(): def test_friendly_declspec() -> None:
content = """ content = """
struct D { struct D {
friend __declspec(dllexport) void my_friend(); friend __declspec(dllexport) void my_friend();
@ -205,7 +205,7 @@ def test_friendly_declspec():
) )
def test_declspec_template(): def test_declspec_template() -> None:
content = """ content = """
template <class T2> template <class T2>
__declspec(deprecated("message")) __declspec(deprecated("message"))

View File

@ -38,7 +38,7 @@ from cxxheaderparser.simple import (
) )
def test_class_member_spec_1(): def test_class_member_spec_1() -> None:
content = """ content = """
class S { class S {
int d1; // non-static data member int d1; // non-static data member
@ -266,7 +266,7 @@ def test_class_member_spec_1():
) )
def test_class_member_spec_2(): def test_class_member_spec_2() -> None:
content = """ content = """
class M { class M {
std::size_t C; std::size_t C;
@ -437,7 +437,7 @@ def test_class_member_spec_2():
) )
def test_class_member_spec_3(): def test_class_member_spec_3() -> None:
content = """ content = """
class S { class S {
public: public:
@ -513,7 +513,7 @@ def test_class_member_spec_3():
) )
def test_class_using(): def test_class_using() -> None:
content = """ content = """
class Base { class Base {
protected: protected:
@ -586,7 +586,7 @@ def test_class_using():
) )
def test_class_member_spec_6(): def test_class_member_spec_6() -> None:
content = """ content = """
struct S { struct S {
template<typename T> template<typename T>
@ -688,7 +688,7 @@ def test_class_member_spec_6():
) )
def test_class_fn_default_params(): def test_class_fn_default_params() -> None:
content = """ content = """
// clang-format off // clang-format off
class Hen class Hen
@ -796,7 +796,7 @@ def test_class_fn_default_params():
) )
def test_class_fn_inline_virtual(): def test_class_fn_inline_virtual() -> None:
content = """ content = """
class B { class B {
public: public:
@ -834,7 +834,7 @@ def test_class_fn_inline_virtual():
) )
def test_class_fn_pure_virtual_const(): def test_class_fn_pure_virtual_const() -> None:
content = """ content = """
class StoneClass { class StoneClass {
virtual int getNum2() const = 0; virtual int getNum2() const = 0;
@ -884,7 +884,7 @@ def test_class_fn_pure_virtual_const():
) )
def test_class_fn_return_global_ns(): def test_class_fn_return_global_ns() -> None:
content = """ content = """
struct Avacado { struct Avacado {
uint8_t foo() { return 4; } uint8_t foo() { return 4; }
@ -935,7 +935,7 @@ def test_class_fn_return_global_ns():
) )
def test_class_ns_class(): def test_class_ns_class() -> None:
content = """ content = """
namespace ns { namespace ns {
class N; class N;
@ -976,7 +976,7 @@ def test_class_ns_class():
) )
def test_class_ns_w_base(): def test_class_ns_w_base() -> None:
content = """ content = """
class Herb::Cilantro : public Plant {}; class Herb::Cilantro : public Plant {};
""" """
@ -1007,7 +1007,7 @@ def test_class_ns_w_base():
) )
def test_class_inner_class(): def test_class_inner_class() -> None:
content = """ content = """
class C { class C {
class Inner {}; class Inner {};
@ -1042,7 +1042,7 @@ def test_class_inner_class():
) )
def test_class_inner_fwd_class(): def test_class_inner_fwd_class() -> None:
content = """ content = """
class C { class C {
class N; class N;
@ -1083,7 +1083,7 @@ def test_class_inner_fwd_class():
) )
def test_class_inner_var_access(): def test_class_inner_var_access() -> None:
content = """ content = """
class Bug_3488053 { class Bug_3488053 {
public: public:
@ -1133,7 +1133,7 @@ def test_class_inner_var_access():
) )
def test_class_ns_and_inner(): def test_class_ns_and_inner() -> None:
content = """ content = """
namespace RoosterNamespace { namespace RoosterNamespace {
class RoosterOuterClass { class RoosterOuterClass {
@ -1275,7 +1275,7 @@ def test_class_ns_and_inner():
) )
def test_class_struct_access(): def test_class_struct_access() -> None:
content = """ content = """
struct SampleStruct { struct SampleStruct {
unsigned int meth(); unsigned int meth();
@ -1325,7 +1325,7 @@ def test_class_struct_access():
) )
def test_class_volatile_move_deleted_fn(): def test_class_volatile_move_deleted_fn() -> None:
content = """ content = """
struct C { struct C {
void foo() volatile && = delete; void foo() volatile && = delete;
@ -1363,7 +1363,7 @@ def test_class_volatile_move_deleted_fn():
) )
def test_class_bitfield_1(): def test_class_bitfield_1() -> None:
content = """ content = """
struct S { struct S {
// will usually occupy 2 bytes: // will usually occupy 2 bytes:
@ -1441,7 +1441,7 @@ def test_class_bitfield_1():
) )
def test_class_bitfield_2(): def test_class_bitfield_2() -> None:
content = """ content = """
struct HAL_ControlWord { struct HAL_ControlWord {
int x : 1; int x : 1;
@ -1521,7 +1521,7 @@ def test_class_bitfield_2():
) )
def test_class_anon_struct_as_globalvar(): def test_class_anon_struct_as_globalvar() -> None:
content = """ content = """
struct { struct {
int m; int m;
@ -1575,7 +1575,7 @@ def test_class_anon_struct_as_globalvar():
) )
def test_class_anon_struct_as_classvar(): def test_class_anon_struct_as_classvar() -> None:
content = """ content = """
struct AnonHolderClass { struct AnonHolderClass {
struct { struct {
@ -1633,7 +1633,7 @@ def test_class_anon_struct_as_classvar():
) )
def test_initializer_with_initializer_list_1(): def test_initializer_with_initializer_list_1() -> None:
content = """ content = """
struct ComplexInit : SomeBase { struct ComplexInit : SomeBase {
ComplexInit(int i) : m_stuff{i, 2} { auto i = something(); } ComplexInit(int i) : m_stuff{i, 2} { auto i = something(); }
@ -1730,7 +1730,7 @@ def test_initializer_with_initializer_list_1():
) )
def test_initializer_with_initializer_list_2(): def test_initializer_with_initializer_list_2() -> None:
content = """ content = """
template <typename T> class future final { template <typename T> class future final {
public: public:
@ -1804,7 +1804,7 @@ def test_initializer_with_initializer_list_2():
) )
def test_class_with_arrays(): def test_class_with_arrays() -> None:
content = """ content = """
const int MAX_ITEM = 7; const int MAX_ITEM = 7;
class Bird { class Bird {
@ -1875,7 +1875,7 @@ def test_class_with_arrays():
) )
def test_class_fn_inline_impl(): def test_class_fn_inline_impl() -> None:
content = """ content = """
class Monkey { class Monkey {
private: private:
@ -1929,7 +1929,7 @@ def test_class_fn_inline_impl():
) )
def test_class_fn_virtual_final_override(): def test_class_fn_virtual_final_override() -> None:
content = """ content = """
struct Lemon { struct Lemon {
virtual void foo() final; virtual void foo() final;
@ -2020,7 +2020,7 @@ def test_class_fn_virtual_final_override():
) )
def test_class_fn_return_class(): def test_class_fn_return_class() -> None:
content = """ content = """
class Peach { class Peach {
int abc; int abc;
@ -2144,7 +2144,7 @@ def test_class_fn_return_class():
) )
def test_class_fn_template_impl(): def test_class_fn_template_impl() -> None:
content = """ content = """
class Owl { class Owl {
private: private:
@ -2231,7 +2231,7 @@ def test_class_fn_template_impl():
) )
def test_class_fn_inline_template_impl(): def test_class_fn_inline_template_impl() -> None:
content = """ content = """
class Chicken { class Chicken {
template <typename T> static T Get(); template <typename T> static T Get();
@ -2287,7 +2287,7 @@ def test_class_fn_inline_template_impl():
) )
def test_class_fn_explicit_constructors(): def test_class_fn_explicit_constructors() -> None:
content = """ content = """
class Lizzard { class Lizzard {
Lizzard(); Lizzard();
@ -2337,7 +2337,7 @@ def test_class_fn_explicit_constructors():
) )
def test_class_fn_default_constructor(): def test_class_fn_default_constructor() -> None:
content = """ content = """
class DefaultConstDest { class DefaultConstDest {
public: public:
@ -2374,7 +2374,7 @@ def test_class_fn_default_constructor():
) )
def test_class_fn_delete_constructor(): def test_class_fn_delete_constructor() -> None:
content = """ content = """
class A { class A {
public: public:
@ -2408,7 +2408,7 @@ def test_class_fn_delete_constructor():
) )
def test_class_multi_vars(): def test_class_multi_vars() -> None:
content = """ content = """
class Grape { class Grape {
public: public:
@ -2580,7 +2580,7 @@ def test_class_multi_vars():
) )
def test_class_static_const_var_expr(): def test_class_static_const_var_expr() -> None:
content = """ content = """
class PandaClass { class PandaClass {
static const int CONST_A = (1 << 7) - 1; static const int CONST_A = (1 << 7) - 1;
@ -2648,7 +2648,7 @@ def test_class_static_const_var_expr():
) )
def test_class_fwd_struct(): def test_class_fwd_struct() -> None:
content = """ content = """
class PotatoClass { class PotatoClass {
struct FwdStruct; struct FwdStruct;
@ -2720,7 +2720,7 @@ def test_class_fwd_struct():
) )
def test_class_multi_array(): def test_class_multi_array() -> None:
content = """ content = """
struct Picture { struct Picture {
char name[25]; char name[25];
@ -2777,7 +2777,7 @@ def test_class_multi_array():
) )
def test_class_noexcept(): def test_class_noexcept() -> None:
content = """ content = """
struct Grackle { struct Grackle {
void no_noexcept(); void no_noexcept();
@ -2919,7 +2919,7 @@ def test_class_noexcept():
) )
def test_class_volatile(): def test_class_volatile() -> None:
content = """ content = """
class Foo class Foo
{ {
@ -2960,7 +2960,7 @@ def test_class_volatile():
) )
def test_class_mutable(): def test_class_mutable() -> None:
content = """ content = """
class Foo class Foo
{ {

View File

@ -21,7 +21,7 @@ from cxxheaderparser.simple import (
) )
def test_class_private_base(): def test_class_private_base() -> None:
content = """ content = """
namespace Citrus namespace Citrus
{ {
@ -108,7 +108,7 @@ def test_class_private_base():
) )
def test_class_virtual_base(): def test_class_virtual_base() -> None:
content = """ content = """
class BaseMangoClass {}; class BaseMangoClass {};
class MangoClass : virtual public BaseMangoClass {}; class MangoClass : virtual public BaseMangoClass {};
@ -148,7 +148,7 @@ def test_class_virtual_base():
) )
def test_class_multiple_base_with_virtual(): def test_class_multiple_base_with_virtual() -> None:
content = """ content = """
class BlueJay : public Bird, public virtual Food { class BlueJay : public Bird, public virtual Food {
public: public:
@ -193,7 +193,7 @@ def test_class_multiple_base_with_virtual():
) )
def test_class_base_specialized(): def test_class_base_specialized() -> None:
content = """ content = """
class Pea : public Vegetable<Green> { class Pea : public Vegetable<Green> {
int i; int i;

View File

@ -38,7 +38,7 @@ from cxxheaderparser.simple import (
) )
def test_doxygen_class(): def test_doxygen_class() -> None:
content = """ content = """
// clang-format off // clang-format off
@ -107,7 +107,7 @@ def test_doxygen_class():
) )
def test_doxygen_class_template(): def test_doxygen_class_template() -> None:
content = """ content = """
// clang-format off // clang-format off
@ -136,7 +136,7 @@ def test_doxygen_class_template():
) )
def test_doxygen_enum(): def test_doxygen_enum() -> None:
content = """ content = """
// clang-format off // clang-format off
@ -182,7 +182,7 @@ def test_doxygen_enum():
) )
def test_doxygen_fn_3slash(): def test_doxygen_fn_3slash() -> None:
content = """ content = """
// clang-format off // clang-format off
@ -209,7 +209,7 @@ def test_doxygen_fn_3slash():
) )
def test_doxygen_fn_cstyle(): def test_doxygen_fn_cstyle() -> None:
content = """ content = """
// clang-format off // clang-format off
@ -238,7 +238,7 @@ def test_doxygen_fn_cstyle():
) )
def test_doxygen_var_above(): def test_doxygen_var_above() -> None:
content = """ content = """
// clang-format off // clang-format off
@ -267,7 +267,7 @@ def test_doxygen_var_above():
) )
def test_doxygen_var_after(): def test_doxygen_var_after() -> None:
content = """ content = """
// clang-format off // clang-format off

View File

@ -25,7 +25,7 @@ from cxxheaderparser.simple import (
) )
def test_basic_enum(): def test_basic_enum() -> None:
content = """ content = """
enum Foo { enum Foo {
A, A,
@ -48,7 +48,7 @@ def test_basic_enum():
) )
def test_enum_w_expr(): def test_enum_w_expr() -> None:
content = """ content = """
enum Foo { enum Foo {
A = (1 / 2), A = (1 / 2),
@ -85,7 +85,7 @@ def test_enum_w_expr():
) )
def test_enum_w_multiline_expr(): def test_enum_w_multiline_expr() -> None:
content = r""" content = r"""
// clang-format off // clang-format off
enum Author enum Author
@ -139,7 +139,7 @@ def test_enum_w_multiline_expr():
) )
def test_basic_enum_class(): def test_basic_enum_class() -> None:
content = """ content = """
enum class BE { BEX }; enum class BE { BEX };
""" """
@ -159,7 +159,7 @@ def test_basic_enum_class():
) )
def test_basic_enum_struct(): def test_basic_enum_struct() -> None:
content = """ content = """
enum struct BE { BEX }; enum struct BE { BEX };
""" """
@ -179,7 +179,7 @@ def test_basic_enum_struct():
) )
def test_enum_base(): def test_enum_base() -> None:
content = """ content = """
enum class E : int {}; enum class E : int {};
""" """
@ -203,7 +203,7 @@ def test_enum_base():
# instances # instances
def test_enum_instance_1(): def test_enum_instance_1() -> None:
content = """ content = """
enum class BE { BEX } be1; enum class BE { BEX } be1;
""" """
@ -233,7 +233,7 @@ def test_enum_instance_1():
) )
def test_enum_instance_2(): def test_enum_instance_2() -> None:
content = """ content = """
enum class BE { BEX } be1, *be2; enum class BE { BEX } be1, *be2;
""" """
@ -277,7 +277,7 @@ def test_enum_instance_2():
# bases in namespaces # bases in namespaces
def test_enum_base_in_ns(): def test_enum_base_in_ns() -> None:
content = """ content = """
namespace EN { namespace EN {
typedef int EINT; typedef int EINT;
@ -322,7 +322,7 @@ def test_enum_base_in_ns():
# forward declarations # forward declarations
def test_enum_fwd(): def test_enum_fwd() -> None:
content = """ content = """
enum class BE1; enum class BE1;
enum class BE2 : EN::EINT; enum class BE2 : EN::EINT;
@ -350,7 +350,7 @@ def test_enum_fwd():
) )
def test_enum_private_in_class(): def test_enum_private_in_class() -> None:
content = """ content = """
class C { class C {
@ -383,7 +383,7 @@ def test_enum_private_in_class():
) )
def test_enum_public_in_class(): def test_enum_public_in_class() -> None:
content = """ content = """
class C { class C {
@ -417,7 +417,7 @@ def test_enum_public_in_class():
) )
def test_default_enum(): def test_default_enum() -> None:
content = """ content = """
class A { class A {
enum { enum {
@ -497,7 +497,7 @@ def test_default_enum():
) )
def test_enum_template_vals(): def test_enum_template_vals() -> None:
content = """ content = """
enum { enum {
IsRandomAccess = std::is_base_of<std::random_access_iterator_tag, IsRandomAccess = std::is_base_of<std::random_access_iterator_tag,
@ -559,7 +559,7 @@ def test_enum_template_vals():
) )
def test_enum_fn(): def test_enum_fn() -> None:
content = """ content = """
enum E { enum E {
VALUE, VALUE,

View File

@ -31,7 +31,7 @@ from cxxheaderparser.simple import (
) )
def test_fn_returns_class(): def test_fn_returns_class() -> None:
content = """ content = """
class X *fn1(); class X *fn1();
struct Y fn2(); struct Y fn2();
@ -77,7 +77,7 @@ def test_fn_returns_class():
) )
def test_fn_returns_typename(): def test_fn_returns_typename() -> None:
content = """ content = """
typename ns::X fn(); typename ns::X fn();
""" """
@ -104,7 +104,7 @@ def test_fn_returns_typename():
) )
def test_fn_returns_typename_const(): def test_fn_returns_typename_const() -> None:
content = """ content = """
const typename ns::X fn(); const typename ns::X fn();
""" """
@ -132,7 +132,7 @@ def test_fn_returns_typename_const():
) )
def test_fn_pointer_params(): def test_fn_pointer_params() -> None:
content = """ content = """
int fn1(int *); int fn1(int *);
int fn2(int *p); int fn2(int *p);
@ -201,7 +201,7 @@ def test_fn_pointer_params():
) )
def test_fn_void_is_no_params(): def test_fn_void_is_no_params() -> None:
content = """ content = """
int fn(void); int fn(void);
""" """
@ -222,7 +222,7 @@ def test_fn_void_is_no_params():
) )
def test_fn_array_param(): def test_fn_array_param() -> None:
content = """ content = """
void fn(int array[]); void fn(int array[]);
""" """
@ -255,7 +255,7 @@ def test_fn_array_param():
) )
def test_fn_typename_param(): def test_fn_typename_param() -> None:
content = """ content = """
void MethodA(const mynamespace::SomeObject &x, void MethodA(const mynamespace::SomeObject &x,
typename mynamespace::SomeObject * = 0); typename mynamespace::SomeObject * = 0);
@ -307,7 +307,7 @@ def test_fn_typename_param():
) )
def test_fn_weird_refs(): def test_fn_weird_refs() -> None:
content = """ content = """
int aref(int(&x)); int aref(int(&x));
void ptr_ref(int(*&name)); void ptr_ref(int(*&name));
@ -382,7 +382,7 @@ def test_fn_weird_refs():
) )
def test_fn_too_many_parens(): def test_fn_too_many_parens() -> None:
content = """ content = """
int fn1(int (x)); int fn1(int (x));
void (fn2 (int (*const (name)))); void (fn2 (int (*const (name))));
@ -439,7 +439,7 @@ void (__stdcall * fn)
""" """
def test_fn_same_line(): def test_fn_same_line() -> None:
# multiple functions on the same line # multiple functions on the same line
content = """ content = """
void fn1(), fn2(); void fn1(), fn2();
@ -487,7 +487,7 @@ def test_fn_same_line():
) )
def test_fn_auto_template(): def test_fn_auto_template() -> None:
content = """ content = """
template<class T, class U> template<class T, class U>
auto add(T t, U u) { return t + u; } auto add(T t, U u) { return t + u; }
@ -527,7 +527,7 @@ def test_fn_auto_template():
) )
def test_fn_template_ptr(): def test_fn_template_ptr() -> None:
content = """ content = """
std::vector<Pointer *> *fn(std::vector<Pointer *> *ps); std::vector<Pointer *> *fn(std::vector<Pointer *> *ps);
""" """
@ -607,7 +607,7 @@ def test_fn_template_ptr():
) )
def test_fn_with_impl(): def test_fn_with_impl() -> None:
content = """ content = """
// clang-format off // clang-format off
void termite(void) void termite(void)
@ -634,7 +634,7 @@ def test_fn_with_impl():
) )
def test_fn_return_std_function(): def test_fn_return_std_function() -> None:
content = """ content = """
std::function<void(int)> fn(); std::function<void(int)> fn();
""" """
@ -700,7 +700,7 @@ def test_fn_return_std_function():
assert data2 == expected assert data2 == expected
def test_fn_return_std_function_trailing(): def test_fn_return_std_function_trailing() -> None:
content = """ content = """
std::function<auto(int)->int> fn(); std::function<auto(int)->int> fn();
""" """
@ -759,7 +759,7 @@ def test_fn_return_std_function_trailing():
) )
def test_fn_trailing_return_simple(): def test_fn_trailing_return_simple() -> None:
content = """ content = """
auto fn() -> int; auto fn() -> int;
""" """
@ -781,7 +781,7 @@ def test_fn_trailing_return_simple():
) )
def test_fn_trailing_return_std_function(): def test_fn_trailing_return_std_function() -> None:
content = """ content = """
auto fn() -> std::function<int()>; auto fn() -> std::function<int()>;
""" """
@ -828,7 +828,7 @@ def test_fn_trailing_return_std_function():
) )
def test_inline_volatile_fn(): def test_inline_volatile_fn() -> None:
content = """ content = """
inline int Standard_Atomic_Increment (volatile int* theValue); inline int Standard_Atomic_Increment (volatile int* theValue);
""" """
@ -864,7 +864,7 @@ def test_inline_volatile_fn():
) )
def test_method_w_reference(): def test_method_w_reference() -> None:
content = """ content = """
struct StreamBuffer struct StreamBuffer
{ {
@ -947,7 +947,7 @@ def test_method_w_reference():
) )
def test_fn_w_mvreference(): def test_fn_w_mvreference() -> None:
content = """ content = """
void fn1(int && (*)(int)); void fn1(int && (*)(int));
@ -996,7 +996,7 @@ def test_fn_w_mvreference():
) )
def test_msvc_conventions(): def test_msvc_conventions() -> None:
content = """ content = """
void __cdecl fn(); void __cdecl fn();
typedef const char* (__stdcall *wglGetExtensionsStringARB_t)(HDC theDeviceContext); typedef const char* (__stdcall *wglGetExtensionsStringARB_t)(HDC theDeviceContext);

View File

@ -23,7 +23,7 @@ from cxxheaderparser.simple import (
) )
# friends # friends
def test_various_friends(): def test_various_friends() -> None:
content = """ content = """
class FX { class FX {
public: public:
@ -170,7 +170,7 @@ def test_various_friends():
) )
def test_more_friends(): def test_more_friends() -> None:
content = """ content = """
template <typename T> struct X { static int x; }; template <typename T> struct X { static int x; };
@ -285,7 +285,7 @@ def test_more_friends():
) )
def test_friend_type_no_class(): def test_friend_type_no_class() -> None:
content = """ content = """
class DogClass; class DogClass;
class CatClass { class CatClass {
@ -327,7 +327,7 @@ def test_friend_type_no_class():
) )
def test_friend_with_impl(): def test_friend_with_impl() -> None:
content = """ content = """
// clang-format off // clang-format off
class Garlic { class Garlic {

View File

@ -28,7 +28,7 @@ from cxxheaderparser.simple import (
# #
def test_define(): def test_define() -> None:
content = """ content = """
#define simple #define simple
#define complex(thing) stuff(thing) #define complex(thing) stuff(thing)
@ -45,7 +45,7 @@ def test_define():
) )
def test_includes(): def test_includes() -> None:
content = """ content = """
#include <global.h> #include <global.h>
#include "local.h" #include "local.h"
@ -55,7 +55,7 @@ def test_includes():
assert data == ParsedData(includes=[Include("<global.h>"), Include('"local.h"')]) assert data == ParsedData(includes=[Include("<global.h>"), Include('"local.h"')])
def test_pragma(): def test_pragma() -> None:
content = """ content = """
#pragma once #pragma once
@ -71,7 +71,7 @@ def test_pragma():
# #
def test_extern_c(): def test_extern_c() -> None:
content = """ content = """
extern "C" { extern "C" {
int x; int x;
@ -101,7 +101,7 @@ def test_extern_c():
) )
def test_misc_extern_inline(): def test_misc_extern_inline() -> None:
content = """ content = """
extern "C++" { extern "C++" {
inline HAL_Value HAL_GetSimValue(HAL_SimValueHandle handle) { inline HAL_Value HAL_GetSimValue(HAL_SimValueHandle handle) {
@ -143,7 +143,7 @@ def test_misc_extern_inline():
# #
def test_static_assert_1(): def test_static_assert_1() -> None:
# static_assert should be ignored # static_assert should be ignored
content = """ content = """
static_assert(x == 1); static_assert(x == 1);
@ -153,7 +153,7 @@ def test_static_assert_1():
assert data == ParsedData() assert data == ParsedData()
def test_static_assert_2(): def test_static_assert_2() -> None:
# static_assert should be ignored # static_assert should be ignored
content = """ content = """
static_assert(sizeof(int) == 4, static_assert(sizeof(int) == 4,
@ -165,7 +165,7 @@ def test_static_assert_2():
assert data == ParsedData() assert data == ParsedData()
def test_comment_eof(): def test_comment_eof() -> None:
content = """ content = """
namespace a {} // namespace a""" namespace a {} // namespace a"""
data = parse_string(content, cleandoc=True) data = parse_string(content, cleandoc=True)
@ -175,7 +175,7 @@ def test_comment_eof():
) )
def test_final(): def test_final() -> None:
content = """ content = """
// ok here // ok here
int fn(const int final); int fn(const int final);

View File

@ -16,7 +16,7 @@ from cxxheaderparser.simple import (
) )
def test_dups_in_different_ns(): def test_dups_in_different_ns() -> None:
content = """ content = """
namespace { namespace {
@ -58,7 +58,7 @@ def test_dups_in_different_ns():
) )
def test_correct_ns(): def test_correct_ns() -> None:
content = """ content = """
namespace a::b::c { namespace a::b::c {
int i1; int i1;

View File

@ -18,7 +18,7 @@ from cxxheaderparser.simple import (
) )
def test_class_operators(): def test_class_operators() -> None:
content = r""" content = r"""
class OperatorClass { class OperatorClass {
public: public:
@ -554,7 +554,7 @@ def test_class_operators():
) )
def test_conversion_operators(): def test_conversion_operators() -> None:
content = """ content = """
class Foo class Foo

View File

@ -29,7 +29,7 @@ from cxxheaderparser.types import (
from cxxheaderparser.simple import ClassScope, NamespaceScope, ParsedData, parse_string from cxxheaderparser.simple import ClassScope, NamespaceScope, ParsedData, parse_string
def test_template_base_template_ns(): def test_template_base_template_ns() -> None:
content = """ content = """
class A : public B<int, int>::C {}; class A : public B<int, int>::C {};
""" """
@ -89,7 +89,7 @@ def test_template_base_template_ns():
) )
def test_template_non_type_various(): def test_template_non_type_various() -> None:
content = """ content = """
// simple non-type template parameter // simple non-type template parameter
template <int N> struct S { int a[N]; }; template <int N> struct S { int a[N]; };
@ -257,7 +257,7 @@ def test_template_non_type_various():
) )
def test_template_dependent_nontype_default(): def test_template_dependent_nontype_default() -> None:
content = """ content = """
template <class T, typename T::type n = 0> class X; template <class T, typename T::type n = 0> class X;
""" """
@ -293,7 +293,7 @@ def test_template_dependent_nontype_default():
) )
def test_template_optional_names(): def test_template_optional_names() -> None:
content = """ content = """
template <class> class My_vector; template <class> class My_vector;
template <class = void> struct My_op_functor; template <class = void> struct My_op_functor;
@ -337,7 +337,7 @@ def test_template_optional_names():
) )
def test_template_template_template(): def test_template_template_template() -> None:
content = """ content = """
template<typename T> struct eval; // primary template template<typename T> struct eval; // primary template
@ -438,7 +438,7 @@ def test_template_template_template():
) )
def test_template_static_var(): def test_template_static_var() -> None:
content = """ content = """
template <typename T> template <typename T>
struct X { struct X {
@ -510,7 +510,7 @@ def test_template_static_var():
) )
def test_template_fn_template(): def test_template_fn_template() -> None:
content = """ content = """
class S { class S {
template <typename Allocator> StringRef copy(Allocator &A) const { template <typename Allocator> StringRef copy(Allocator &A) const {
@ -574,7 +574,7 @@ def test_template_fn_template():
) )
def test_template_fn_param_initializer(): def test_template_fn_param_initializer() -> None:
content = """ content = """
template <typename T, typename U> template <typename T, typename U>
void fn(something<T, U> s = something<T, U>{1, 2, 3}); void fn(something<T, U> s = something<T, U>{1, 2, 3});
@ -658,7 +658,7 @@ def test_template_fn_param_initializer():
) )
def test_template_huge(): def test_template_huge() -> None:
content = """ content = """
// clang-format off // clang-format off
class AlmondClass class AlmondClass
@ -872,7 +872,7 @@ def test_template_huge():
) )
def test_template_specialized(): def test_template_specialized() -> None:
content = """ content = """
template <> class FruitFly<int> : public Fly {}; template <> class FruitFly<int> : public Fly {};
""" """
@ -920,7 +920,7 @@ def test_template_specialized():
) )
def test_template_class_defaults(): def test_template_class_defaults() -> None:
content = """ content = """
template <typename VALUE, typename VALUE_SET_ITERATOR, template <typename VALUE, typename VALUE_SET_ITERATOR,
typename ACCESSOR = Raddish::SimpleAccessor<VALUE, VALUE_SET_ITERATOR>> typename ACCESSOR = Raddish::SimpleAccessor<VALUE, VALUE_SET_ITERATOR>>
@ -1068,7 +1068,7 @@ def test_template_class_defaults():
) )
def test_template_many_packs(): def test_template_many_packs() -> None:
content = """ content = """
// clang-format off // clang-format off
@ -1651,7 +1651,7 @@ def test_template_many_packs():
) )
def test_template_specialized_fn_typename(): def test_template_specialized_fn_typename() -> None:
content = """ content = """
// clang-format off // clang-format off
struct T{}; struct T{};
@ -1723,7 +1723,7 @@ def test_template_specialized_fn_typename():
) )
def test_template_specialized_fn_typename_template(): def test_template_specialized_fn_typename_template() -> None:
content = """ content = """
// clang-format off // clang-format off
template <typename X> template <typename X>

View File

@ -2,6 +2,7 @@ import pytest
from cxxheaderparser.lexer import Lexer from cxxheaderparser.lexer import Lexer
from cxxheaderparser.tokfmt import tokfmt from cxxheaderparser.tokfmt import tokfmt
from cxxheaderparser.types import Token
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -34,7 +35,7 @@ from cxxheaderparser.tokfmt import tokfmt
"operator>=", "operator>=",
], ],
) )
def test_tokfmt(instr): def test_tokfmt(instr: str) -> None:
""" """
Each input string is exactly what the output of tokfmt should be Each input string is exactly what the output of tokfmt should be
""" """
@ -47,6 +48,6 @@ def test_tokfmt(instr):
if not tok: if not tok:
break break
toks.append(tok) toks.append(Token(tok.value, tok.type))
assert tokfmt(toks) == instr assert tokfmt(toks) == instr

View File

@ -26,7 +26,7 @@ from cxxheaderparser.types import (
from cxxheaderparser.simple import ClassScope, NamespaceScope, ParsedData, parse_string from cxxheaderparser.simple import ClassScope, NamespaceScope, ParsedData, parse_string
def test_simple_typedef(): def test_simple_typedef() -> None:
content = """ content = """
typedef std::vector<int> IntVector; typedef std::vector<int> IntVector;
""" """
@ -68,7 +68,7 @@ def test_simple_typedef():
) )
def test_struct_typedef_1(): def test_struct_typedef_1() -> None:
content = """ content = """
typedef struct { typedef struct {
int m; int m;
@ -122,7 +122,7 @@ def test_struct_typedef_1():
) )
def test_struct_typedef_2(): def test_struct_typedef_2() -> None:
content = """ content = """
typedef struct { typedef struct {
int m; int m;
@ -176,7 +176,7 @@ def test_struct_typedef_2():
) )
def test_typedef_array(): def test_typedef_array() -> None:
content = """ content = """
typedef char TenCharArray[10]; typedef char TenCharArray[10];
""" """
@ -201,7 +201,7 @@ def test_typedef_array():
) )
def test_typedef_array_of_struct(): def test_typedef_array_of_struct() -> None:
content = """ content = """
typedef struct{} tx[3], ty; typedef struct{} tx[3], ty;
""" """
@ -243,7 +243,7 @@ def test_typedef_array_of_struct():
) )
def test_typedef_class_w_base(): def test_typedef_class_w_base() -> None:
content = """ content = """
typedef class XX : public F {} G; typedef class XX : public F {} G;
""" """
@ -280,7 +280,7 @@ def test_typedef_class_w_base():
) )
def test_complicated_typedef(): def test_complicated_typedef() -> None:
content = """ content = """
typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10]; typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10];
""" """
@ -345,7 +345,7 @@ def test_complicated_typedef():
) )
def test_typedef_c_struct_idiom(): def test_typedef_c_struct_idiom() -> None:
content = """ content = """
// common C idiom to avoid having to write "struct S" // common C idiom to avoid having to write "struct S"
typedef struct {int a; int b;} S, *pS; typedef struct {int a; int b;} S, *pS;
@ -407,7 +407,7 @@ def test_typedef_c_struct_idiom():
) )
def test_typedef_struct_same_name(): def test_typedef_struct_same_name() -> None:
content = """ content = """
typedef struct Fig { typedef struct Fig {
int a; int a;
@ -451,7 +451,7 @@ def test_typedef_struct_same_name():
) )
def test_typedef_struct_w_enum(): def test_typedef_struct_w_enum() -> None:
content = """ content = """
typedef struct { typedef struct {
enum BeetEnum : int { FAIL = 0, PASS = 1 }; enum BeetEnum : int { FAIL = 0, PASS = 1 };
@ -502,7 +502,7 @@ def test_typedef_struct_w_enum():
) )
def test_typedef_union(): def test_typedef_union() -> None:
content = """ content = """
typedef union apricot_t { typedef union apricot_t {
int i; int i;
@ -569,7 +569,7 @@ def test_typedef_union():
) )
def test_typedef_fnptr(): def test_typedef_fnptr() -> None:
content = """ content = """
typedef void *(*fndef)(int); typedef void *(*fndef)(int);
""" """
@ -606,7 +606,7 @@ def test_typedef_fnptr():
) )
def test_typedef_const(): def test_typedef_const() -> None:
content = """ content = """
typedef int theint, *const ptheint; typedef int theint, *const ptheint;
""" """
@ -635,7 +635,7 @@ def test_typedef_const():
) )
def test_enum_typedef_1(): def test_enum_typedef_1() -> None:
content = """ content = """
typedef enum {} E; typedef enum {} E;
""" """
@ -661,7 +661,7 @@ def test_enum_typedef_1():
) )
def test_enum_typedef_2(): def test_enum_typedef_2() -> None:
content = """ content = """
typedef enum { E1 } BE; typedef enum { E1 } BE;
""" """
@ -687,7 +687,7 @@ def test_enum_typedef_2():
) )
def test_enum_typedef_3(): def test_enum_typedef_3() -> None:
content = """ content = """
typedef enum { E1, E2, } E; typedef enum { E1, E2, } E;
""" """
@ -713,7 +713,7 @@ def test_enum_typedef_3():
) )
def test_enum_typedef_3_1(): def test_enum_typedef_3_1() -> None:
content = """ content = """
typedef enum { E1 } * PBE; typedef enum { E1 } * PBE;
""" """
@ -743,7 +743,7 @@ def test_enum_typedef_3_1():
) )
def test_enum_typedef_4(): def test_enum_typedef_4() -> None:
content = """ content = """
typedef enum { E1 } * PBE, BE; typedef enum { E1 } * PBE, BE;
""" """
@ -779,7 +779,7 @@ def test_enum_typedef_4():
) )
def test_enum_typedef_5(): def test_enum_typedef_5() -> None:
content = """ content = """
typedef enum { E1 } BE, *PBE; typedef enum { E1 } BE, *PBE;
""" """
@ -815,7 +815,7 @@ def test_enum_typedef_5():
) )
def test_enum_typedef_fwd(): def test_enum_typedef_fwd() -> None:
content = """ content = """
typedef enum BE BET; typedef enum BE BET;
""" """
@ -837,7 +837,7 @@ def test_enum_typedef_fwd():
) )
def test_typedef_enum_expr(): def test_typedef_enum_expr() -> None:
content = """ content = """
typedef enum { StarFruit = (2 + 2) / 2 } Carambola; typedef enum { StarFruit = (2 + 2) / 2 } Carambola;
""" """
@ -878,7 +878,7 @@ def test_typedef_enum_expr():
) )
def test_volatile_typedef(): def test_volatile_typedef() -> None:
content = """ content = """
typedef volatile signed short vint16; typedef volatile signed short vint16;
""" """
@ -901,7 +901,7 @@ def test_volatile_typedef():
) )
def test_function_typedef(): def test_function_typedef() -> None:
content = """ content = """
typedef void fn(int); typedef void fn(int);
typedef auto fntype(int) -> int; typedef auto fntype(int) -> int;

View File

@ -17,7 +17,7 @@ from cxxheaderparser.simple import (
) )
def test_union_basic(): def test_union_basic() -> None:
content = """ content = """
struct HAL_Value { struct HAL_Value {
@ -86,7 +86,7 @@ def test_union_basic():
) )
def test_union_anon_in_struct(): def test_union_anon_in_struct() -> None:
content = """ content = """
struct Outer { struct Outer {
union { union {

View File

@ -30,7 +30,7 @@ from cxxheaderparser.simple import (
) )
def test_using_namespace(): def test_using_namespace() -> None:
content = """ content = """
using namespace foo; using namespace foo;
using namespace foo::bar; using namespace foo::bar;
@ -52,7 +52,7 @@ def test_using_namespace():
) )
def test_using_declaration(): def test_using_declaration() -> None:
content = """ content = """
using ::foo; using ::foo;
using foo::bar; using foo::bar;
@ -104,7 +104,7 @@ def test_using_declaration():
# alias-declaration # alias-declaration
def test_alias_declaration_1(): def test_alias_declaration_1() -> None:
content = """ content = """
using alias = foo; using alias = foo;
""" """
@ -122,7 +122,7 @@ def test_alias_declaration_1():
) )
def test_alias_declaration_2(): def test_alias_declaration_2() -> None:
content = """ content = """
template <typename T> using alias = foo<T>; template <typename T> using alias = foo<T>;
""" """
@ -164,7 +164,7 @@ def test_alias_declaration_2():
) )
def test_alias_declaration_3(): def test_alias_declaration_3() -> None:
content = """ content = """
using alias = ::foo::bar; using alias = ::foo::bar;
""" """
@ -190,7 +190,7 @@ def test_alias_declaration_3():
) )
def test_alias_declaration_4(): def test_alias_declaration_4() -> None:
content = """ content = """
template <typename T> using alias = ::foo::bar<T>; template <typename T> using alias = ::foo::bar<T>;
""" """
@ -234,7 +234,7 @@ def test_alias_declaration_4():
) )
def test_alias_declaration_5(): def test_alias_declaration_5() -> None:
content = """ content = """
using alias = foo::bar; using alias = foo::bar;
""" """
@ -259,7 +259,7 @@ def test_alias_declaration_5():
) )
def test_alias_declaration_6(): def test_alias_declaration_6() -> None:
content = """ content = """
template <typename T> using alias = foo<T>::bar; template <typename T> using alias = foo<T>::bar;
""" """
@ -302,7 +302,7 @@ def test_alias_declaration_6():
) )
def test_using_many_things(): def test_using_many_things() -> None:
content = """ content = """
// clang-format off // clang-format off

View File

@ -22,7 +22,7 @@ from cxxheaderparser.types import (
from cxxheaderparser.simple import ClassScope, NamespaceScope, ParsedData, parse_string from cxxheaderparser.simple import ClassScope, NamespaceScope, ParsedData, parse_string
def test_var_unixwiz_ridiculous(): def test_var_unixwiz_ridiculous() -> None:
# http://unixwiz.net/techtips/reading-cdecl.html # http://unixwiz.net/techtips/reading-cdecl.html
# #
# .. "we have no idea how this variable is useful, but at least we can # .. "we have no idea how this variable is useful, but at least we can
@ -73,7 +73,7 @@ def test_var_unixwiz_ridiculous():
) )
def test_var_ptr_to_array15_of_ptr_to_int(): def test_var_ptr_to_array15_of_ptr_to_int() -> None:
content = """ content = """
int *(*crocodile)[15]; int *(*crocodile)[15];
""" """
@ -102,7 +102,7 @@ def test_var_ptr_to_array15_of_ptr_to_int():
) )
def test_var_ref_to_array(): def test_var_ref_to_array() -> None:
content = """ content = """
int abase[3]; int abase[3];
int (&aname)[3] = abase; int (&aname)[3] = abase;
@ -140,7 +140,7 @@ def test_var_ref_to_array():
) )
def test_var_ptr_to_array(): def test_var_ptr_to_array() -> None:
content = """ content = """
int zz, (*aname)[3] = &abase; int zz, (*aname)[3] = &abase;
""" """
@ -174,7 +174,7 @@ def test_var_ptr_to_array():
) )
def test_var_multi_1(): def test_var_multi_1() -> None:
content = """ content = """
int zz, (&aname)[3] = abase; int zz, (&aname)[3] = abase;
""" """
@ -208,7 +208,7 @@ def test_var_multi_1():
) )
def test_var_array_of_fnptr_varargs(): def test_var_array_of_fnptr_varargs() -> None:
content = """ content = """
void (*a3[3])(int, ...); void (*a3[3])(int, ...);
""" """
@ -249,7 +249,7 @@ def test_var_array_of_fnptr_varargs():
) )
def test_var_double_fnptr_varargs(): def test_var_double_fnptr_varargs() -> None:
content = """ content = """
void (*(*a4))(int, ...); void (*(*a4))(int, ...);
""" """
@ -289,7 +289,7 @@ def test_var_double_fnptr_varargs():
) )
def test_var_fnptr_voidstar(): def test_var_fnptr_voidstar() -> None:
content = """ content = """
void(*(*a5)(int)); void(*(*a5)(int));
""" """
@ -326,7 +326,7 @@ def test_var_fnptr_voidstar():
) )
def test_var_fnptr_moreparens(): def test_var_fnptr_moreparens() -> None:
content = """ content = """
void (*x)(int(p1), int); void (*x)(int(p1), int);
""" """
@ -384,7 +384,7 @@ def test_var_fnptr_moreparens():
# Means "const pointer to pointer to char" # Means "const pointer to pointer to char"
def test_var_ptr_to_const_ptr_to_char(): def test_var_ptr_to_const_ptr_to_char() -> None:
content = """ content = """
char *const *p; char *const *p;
""" """
@ -411,7 +411,7 @@ def test_var_ptr_to_const_ptr_to_char():
) )
def test_var_const_ptr_to_ptr_to_char(): def test_var_const_ptr_to_ptr_to_char() -> None:
content = """ content = """
char **const p; char **const p;
""" """
@ -438,7 +438,7 @@ def test_var_const_ptr_to_ptr_to_char():
) )
def test_var_array_initializer1(): def test_var_array_initializer1() -> None:
content = """ content = """
int x[3]{1, 2, 3}; int x[3]{1, 2, 3};
""" """
@ -472,7 +472,7 @@ def test_var_array_initializer1():
) )
def test_var_array_initializer2(): def test_var_array_initializer2() -> None:
content = """ content = """
int x[3] = {1, 2, 3}; int x[3] = {1, 2, 3};
""" """
@ -506,7 +506,7 @@ def test_var_array_initializer2():
) )
def test_var_extern_c(): def test_var_extern_c() -> None:
content = """ content = """
extern "C" int x; extern "C" int x;
""" """
@ -528,7 +528,7 @@ def test_var_extern_c():
) )
def test_var_ns_1(): def test_var_ns_1() -> None:
content = """ content = """
int N::x; int N::x;
""" """
@ -550,7 +550,7 @@ def test_var_ns_1():
) )
def test_var_ns_2(): def test_var_ns_2() -> None:
content = """ content = """
int N::x = 4; int N::x = 4;
""" """
@ -573,7 +573,7 @@ def test_var_ns_2():
) )
def test_var_ns_3(): def test_var_ns_3() -> None:
content = """ content = """
int N::x{4}; int N::x{4};
""" """
@ -598,7 +598,7 @@ def test_var_ns_3():
) )
def test_var_static_struct(): def test_var_static_struct() -> None:
content = """ content = """
constexpr static struct SS {} s; constexpr static struct SS {} s;
""" """
@ -631,7 +631,7 @@ def test_var_static_struct():
) )
def test_var_constexpr_enum(): def test_var_constexpr_enum() -> None:
content = """ content = """
constexpr enum E { EE } e = EE; constexpr enum E { EE } e = EE;
""" """
@ -663,7 +663,7 @@ def test_var_constexpr_enum():
) )
def test_var_fnptr_in_class(): def test_var_fnptr_in_class() -> None:
content = """ content = """
struct DriverFuncs { struct DriverFuncs {
void *(*init)(); void *(*init)();
@ -747,7 +747,7 @@ def test_var_fnptr_in_class():
) )
def test_var_extern(): def test_var_extern() -> None:
content = """ content = """
extern int externVar; extern int externVar;
""" """