cxxheaderparser 1.7.4__tar.gz → 1.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/PKG-INFO +1 -1
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/lexer.py +4 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/parser.py +88 -14
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/types.py +11 -5
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/version.py +2 -2
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/.gitignore +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/LICENSE.txt +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/README.md +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/__init__.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/__main__.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/_ply/__init__.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/_ply/lex.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/dump.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/errors.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/gentest.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/options.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/parserstate.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/preprocessor.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/py.typed +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/simple.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/tokfmt.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/cxxheaderparser/visitor.py +0 -0
- {cxxheaderparser-1.7.4 → cxxheaderparser-1.8.0}/pyproject.toml +0 -0
|
@@ -273,6 +273,40 @@ class CxxParser:
|
|
|
273
273
|
if next_end:
|
|
274
274
|
match_stack.append(next_end)
|
|
275
275
|
|
|
276
|
+
def _consume_balanced_tokens_with_inner(
|
|
277
|
+
self,
|
|
278
|
+
*init_tokens: LexToken,
|
|
279
|
+
token_map: typing.Optional[typing.Dict[str, str]] = None,
|
|
280
|
+
) -> typing.Tuple[LexTokenList, LexTokenList]:
|
|
281
|
+
toks = self._consume_balanced_tokens(*init_tokens, token_map=token_map)
|
|
282
|
+
inner_toks = toks[1:-1]
|
|
283
|
+
|
|
284
|
+
# Redundant declarator grouping is valid: int ((*p))(int),
|
|
285
|
+
# int ((*p))[3], and void ((f))(int). Strip only parens that
|
|
286
|
+
# enclose the whole inner token list.
|
|
287
|
+
while (
|
|
288
|
+
len(inner_toks) >= 2
|
|
289
|
+
and inner_toks[0].type == "("
|
|
290
|
+
and inner_toks[-1].type == ")"
|
|
291
|
+
):
|
|
292
|
+
depth = 0
|
|
293
|
+
encloses_all = True
|
|
294
|
+
for i, itok in enumerate(inner_toks):
|
|
295
|
+
if itok.type == "(":
|
|
296
|
+
depth += 1
|
|
297
|
+
elif itok.type == ")":
|
|
298
|
+
depth -= 1
|
|
299
|
+
if depth == 0 and i != len(inner_toks) - 1:
|
|
300
|
+
encloses_all = False
|
|
301
|
+
break
|
|
302
|
+
|
|
303
|
+
if not encloses_all or depth != 0:
|
|
304
|
+
break
|
|
305
|
+
|
|
306
|
+
inner_toks = inner_toks[1:-1]
|
|
307
|
+
|
|
308
|
+
return toks, inner_toks
|
|
309
|
+
|
|
276
310
|
def _discard_contents(self, start_type: str, end_type: str) -> None:
|
|
277
311
|
# use this instead of consume_balanced_tokens because
|
|
278
312
|
# we don't care at all about the internals
|
|
@@ -1677,6 +1711,10 @@ class CxxParser:
|
|
|
1677
1711
|
"float",
|
|
1678
1712
|
"double",
|
|
1679
1713
|
"char",
|
|
1714
|
+
"__int8",
|
|
1715
|
+
"__int16",
|
|
1716
|
+
"__int32",
|
|
1717
|
+
"__int64",
|
|
1680
1718
|
}
|
|
1681
1719
|
|
|
1682
1720
|
_fundamentals = _compound_fundamentals | {
|
|
@@ -1967,6 +2005,14 @@ class CxxParser:
|
|
|
1967
2005
|
if tok:
|
|
1968
2006
|
param_name = tok.value
|
|
1969
2007
|
|
|
2008
|
+
# Function parameter declarations can use function declarator syntax,
|
|
2009
|
+
# e.g. ``bool predicate(const T&)``. In parameter lists, function types
|
|
2010
|
+
# are adjusted to pointers to functions, matching the explicit
|
|
2011
|
+
# ``bool (*predicate)(const T&)`` spelling.
|
|
2012
|
+
if param_name and self.lex.token_if("("):
|
|
2013
|
+
fn_params, vararg, _ = self._parse_parameters(False, False)
|
|
2014
|
+
dtype = Pointer(FunctionType(dtype, fn_params, vararg))
|
|
2015
|
+
|
|
1970
2016
|
# optional array parameter
|
|
1971
2017
|
tok = self.lex.token_if("[")
|
|
1972
2018
|
if tok:
|
|
@@ -2460,8 +2506,8 @@ class CxxParser:
|
|
|
2460
2506
|
if not gtok:
|
|
2461
2507
|
break
|
|
2462
2508
|
|
|
2463
|
-
|
|
2464
|
-
self.lex.return_tokens(
|
|
2509
|
+
_, inner_toks = self._consume_balanced_tokens_with_inner(gtok)
|
|
2510
|
+
self.lex.return_tokens(inner_toks)
|
|
2465
2511
|
|
|
2466
2512
|
fn_params, vararg, _ = self._parse_parameters(False, False)
|
|
2467
2513
|
|
|
@@ -2478,14 +2524,26 @@ class CxxParser:
|
|
|
2478
2524
|
if msvc_convention_tok:
|
|
2479
2525
|
msvc_convention = msvc_convention_tok.value
|
|
2480
2526
|
|
|
2527
|
+
# this might be a grouping paren, so consume it and inspect it
|
|
2528
|
+
toks, inner_toks = self._consume_balanced_tokens_with_inner(tok)
|
|
2529
|
+
member_ptr_idx = next(
|
|
2530
|
+
(
|
|
2531
|
+
i
|
|
2532
|
+
for i, itok in enumerate(inner_toks)
|
|
2533
|
+
if itok.type == "*"
|
|
2534
|
+
and i > 0
|
|
2535
|
+
and inner_toks[i - 1].type == "DBL_COLON"
|
|
2536
|
+
),
|
|
2537
|
+
None,
|
|
2538
|
+
)
|
|
2539
|
+
|
|
2481
2540
|
# Check to see if this is a grouping paren or something else
|
|
2482
|
-
if not
|
|
2483
|
-
|
|
2541
|
+
if not inner_toks or (
|
|
2542
|
+
inner_toks[0].type not in ("*", "&") and member_ptr_idx is None
|
|
2543
|
+
):
|
|
2544
|
+
self.lex.return_tokens(toks)
|
|
2484
2545
|
break
|
|
2485
2546
|
|
|
2486
|
-
# this is a grouping paren, so consume it
|
|
2487
|
-
toks = self._consume_balanced_tokens(tok)
|
|
2488
|
-
|
|
2489
2547
|
# Now check to see if we have either an array or a function pointer
|
|
2490
2548
|
aptok = self.lex.token_if("[", "(")
|
|
2491
2549
|
if aptok:
|
|
@@ -2502,14 +2560,30 @@ class CxxParser:
|
|
|
2502
2560
|
dtype, fn_params, vararg, msvc_convention=msvc_convention
|
|
2503
2561
|
)
|
|
2504
2562
|
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2563
|
+
if isinstance(dtype, FunctionType) and member_ptr_idx is not None:
|
|
2564
|
+
# Keep the * and declarator name for the normal pointer/name
|
|
2565
|
+
# parsing below, and store the qualified class name on the
|
|
2566
|
+
# function type.
|
|
2567
|
+
class_toks = inner_toks[: member_ptr_idx - 1] + [PhonyEnding]
|
|
2568
|
+
old_lex = self.lex
|
|
2569
|
+
try:
|
|
2570
|
+
self.lex = lexer.BoundedTokenStream(class_toks)
|
|
2571
|
+
classname, _ = self._parse_pqname(
|
|
2572
|
+
None, compound_ok=False, fn_ok=False, fund_ok=False
|
|
2573
|
+
)
|
|
2574
|
+
self._next_token_must_be(PhonyEnding.type)
|
|
2575
|
+
finally:
|
|
2576
|
+
self.lex = old_lex
|
|
2577
|
+
|
|
2578
|
+
dtype.classname = classname
|
|
2579
|
+
inner_toks = [inner_toks[member_ptr_idx]] + inner_toks[
|
|
2580
|
+
member_ptr_idx + 1 :
|
|
2581
|
+
]
|
|
2508
2582
|
|
|
2509
2583
|
# return the inner toks and recurse
|
|
2510
2584
|
# -> this could return some weird results for invalid code, but
|
|
2511
2585
|
# we don't support that anyways so it's fine?
|
|
2512
|
-
self.lex.return_tokens(
|
|
2586
|
+
self.lex.return_tokens(inner_toks)
|
|
2513
2587
|
dtype = self._parse_cv_ptr_or_fn(dtype, nonptr_fn)
|
|
2514
2588
|
break
|
|
2515
2589
|
|
|
@@ -2668,7 +2742,7 @@ class CxxParser:
|
|
|
2668
2742
|
is_friend: bool,
|
|
2669
2743
|
attributes: typing.List[Attribute],
|
|
2670
2744
|
) -> bool:
|
|
2671
|
-
toks = []
|
|
2745
|
+
toks: LexTokenList = []
|
|
2672
2746
|
|
|
2673
2747
|
# On entry we only have the base type, decorate it
|
|
2674
2748
|
dtype: typing.Optional[DecoratedType]
|
|
@@ -2730,7 +2804,7 @@ class CxxParser:
|
|
|
2730
2804
|
if dtype:
|
|
2731
2805
|
# if it's not a constructor/destructor, it could be a
|
|
2732
2806
|
# grouping paren like "void (name(int x));"
|
|
2733
|
-
toks = self.
|
|
2807
|
+
toks, inner_toks = self._consume_balanced_tokens_with_inner(tok)
|
|
2734
2808
|
|
|
2735
2809
|
# check to see if the next token is an arrow, and thus a trailing return
|
|
2736
2810
|
if self.lex.token_peek_if("ARROW"):
|
|
@@ -2740,7 +2814,7 @@ class CxxParser:
|
|
|
2740
2814
|
is_guide = True
|
|
2741
2815
|
else:
|
|
2742
2816
|
# .. not sure what it's grouping, so put it back?
|
|
2743
|
-
self.lex.return_tokens(
|
|
2817
|
+
self.lex.return_tokens(inner_toks)
|
|
2744
2818
|
|
|
2745
2819
|
if dtype:
|
|
2746
2820
|
msvc_convention = self.lex.token_if_val(*self._msvc_conventions)
|
|
@@ -272,9 +272,6 @@ class FunctionType:
|
|
|
272
272
|
return_type: "DecoratedType"
|
|
273
273
|
parameters: typing.List["Parameter"]
|
|
274
274
|
|
|
275
|
-
#: If a member function pointer
|
|
276
|
-
# TODO classname: typing.Optional[PQName]
|
|
277
|
-
|
|
278
275
|
#: Set to True if ends with ``...``
|
|
279
276
|
vararg: bool = False
|
|
280
277
|
|
|
@@ -293,6 +290,9 @@ class FunctionType:
|
|
|
293
290
|
#: calling convention
|
|
294
291
|
msvc_convention: typing.Optional[str] = None
|
|
295
292
|
|
|
293
|
+
#: If a member function pointer, the class that owns the member function.
|
|
294
|
+
classname: typing.Optional[PQName] = None
|
|
295
|
+
|
|
296
296
|
def format(self) -> str:
|
|
297
297
|
vararg = "..." if self.vararg else ""
|
|
298
298
|
params = ", ".join(p.format() for p in self.parameters)
|
|
@@ -379,7 +379,9 @@ class Pointer:
|
|
|
379
379
|
v = " volatile" if self.volatile else ""
|
|
380
380
|
r = " __restrict__" if self.restrict else ""
|
|
381
381
|
ptr_to = self.ptr_to
|
|
382
|
-
if isinstance(ptr_to,
|
|
382
|
+
if isinstance(ptr_to, FunctionType) and ptr_to.classname:
|
|
383
|
+
return ptr_to.format_decl(f"({ptr_to.classname.format()}::*{r}{c}{v})")
|
|
384
|
+
elif isinstance(ptr_to, (Array, FunctionType)):
|
|
383
385
|
return ptr_to.format_decl(f"(*{r}{c}{v})")
|
|
384
386
|
else:
|
|
385
387
|
return f"{ptr_to.format()}*{r}{c}{v}"
|
|
@@ -390,7 +392,11 @@ class Pointer:
|
|
|
390
392
|
v = " volatile" if self.volatile else ""
|
|
391
393
|
r = " __restrict__" if self.restrict else ""
|
|
392
394
|
ptr_to = self.ptr_to
|
|
393
|
-
if isinstance(ptr_to,
|
|
395
|
+
if isinstance(ptr_to, FunctionType) and ptr_to.classname:
|
|
396
|
+
return ptr_to.format_decl(
|
|
397
|
+
f"({ptr_to.classname.format()}::*{r}{c}{v} {name})"
|
|
398
|
+
)
|
|
399
|
+
elif isinstance(ptr_to, (Array, FunctionType)):
|
|
394
400
|
return ptr_to.format_decl(f"(*{r}{c}{v} {name})")
|
|
395
401
|
else:
|
|
396
402
|
return f"{ptr_to.format()}*{r}{c}{v} {name}"
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.
|
|
22
|
-
__version_tuple__ = version_tuple = (1,
|
|
21
|
+
__version__ = version = '1.8.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 8, 0)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|