parent
07b63127f7
commit
3c51a30efe
@ -574,7 +574,6 @@ class CxxParser:
|
|||||||
# tokens. If it succeeds we're done, otherwise we use the value
|
# tokens. If it succeeds we're done, otherwise we use the value
|
||||||
|
|
||||||
param_pack = False
|
param_pack = False
|
||||||
has_typename = True if self.lex.token_if("typename") else False
|
|
||||||
|
|
||||||
raw_toks = self._consume_value_until([], ",", ">", "ELLIPSIS")
|
raw_toks = self._consume_value_until([], ",", ">", "ELLIPSIS")
|
||||||
val = self._create_value(raw_toks)
|
val = self._create_value(raw_toks)
|
||||||
@ -601,9 +600,9 @@ class CxxParser:
|
|||||||
param_pack = True
|
param_pack = True
|
||||||
|
|
||||||
if dtype:
|
if dtype:
|
||||||
args.append(TemplateArgument(dtype, has_typename, param_pack))
|
args.append(TemplateArgument(dtype, param_pack))
|
||||||
else:
|
else:
|
||||||
args.append(TemplateArgument(val, has_typename, param_pack))
|
args.append(TemplateArgument(val, param_pack))
|
||||||
|
|
||||||
tok = self._next_token_must_be(",", ">")
|
tok = self._next_token_must_be(",", ">")
|
||||||
if tok.type == ">":
|
if tok.type == ">":
|
||||||
@ -1251,7 +1250,7 @@ class CxxParser:
|
|||||||
return parts
|
return parts
|
||||||
|
|
||||||
_pqname_start_tokens = (
|
_pqname_start_tokens = (
|
||||||
{"auto", "decltype", "NAME", "operator", "template", "DBL_COLON"}
|
{"auto", "decltype", "NAME", "operator", "template", "typename", "DBL_COLON"}
|
||||||
| _name_compound_start
|
| _name_compound_start
|
||||||
| _fundamentals
|
| _fundamentals
|
||||||
)
|
)
|
||||||
@ -1329,6 +1328,7 @@ class CxxParser:
|
|||||||
classkey = None
|
classkey = None
|
||||||
segments: typing.List[PQNameSegment] = []
|
segments: typing.List[PQNameSegment] = []
|
||||||
op = None
|
op = None
|
||||||
|
has_typename = False
|
||||||
|
|
||||||
if tok is None:
|
if tok is None:
|
||||||
tok = self.lex.token()
|
tok = self.lex.token()
|
||||||
@ -1369,6 +1369,11 @@ class CxxParser:
|
|||||||
self.anon_id += 1
|
self.anon_id += 1
|
||||||
segments.append(AnonymousName(self.anon_id))
|
segments.append(AnonymousName(self.anon_id))
|
||||||
return PQName(segments, classkey), None
|
return PQName(segments, classkey), None
|
||||||
|
elif tok.type == "typename":
|
||||||
|
has_typename = True
|
||||||
|
tok = self.lex.token()
|
||||||
|
if tok.type not in self._pqname_start_tokens:
|
||||||
|
raise self._parse_error(tok)
|
||||||
|
|
||||||
# First section of the name: Add empty segment if starting out with a
|
# First section of the name: Add empty segment if starting out with a
|
||||||
# namespace specifier
|
# namespace specifier
|
||||||
@ -1415,7 +1420,7 @@ class CxxParser:
|
|||||||
|
|
||||||
tok = self._next_token_must_be("NAME", "operator", "template", "decltype")
|
tok = self._next_token_must_be("NAME", "operator", "template", "decltype")
|
||||||
|
|
||||||
pqname = PQName(segments, classkey)
|
pqname = PQName(segments, classkey, has_typename)
|
||||||
|
|
||||||
self.debug_print(
|
self.debug_print(
|
||||||
"parse_pqname: %s op=%s",
|
"parse_pqname: %s op=%s",
|
||||||
|
@ -140,6 +140,9 @@ class PQName:
|
|||||||
#: Set if the name starts with class/enum/struct
|
#: Set if the name starts with class/enum/struct
|
||||||
classkey: typing.Optional[str] = None
|
classkey: typing.Optional[str] = None
|
||||||
|
|
||||||
|
#: Set to true if the type was preceded with 'typename'
|
||||||
|
has_typename: bool = False
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Enumerator:
|
class Enumerator:
|
||||||
@ -192,8 +195,6 @@ class TemplateArgument:
|
|||||||
#: 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", Value]
|
||||||
|
|
||||||
#: Set if starts with "typename"
|
|
||||||
has_typename: bool = False
|
|
||||||
param_pack: bool = False
|
param_pack: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
108
tests/test_fn.py
108
tests/test_fn.py
@ -17,6 +17,7 @@ from cxxheaderparser.types import (
|
|||||||
TemplateTypeParam,
|
TemplateTypeParam,
|
||||||
Token,
|
Token,
|
||||||
Type,
|
Type,
|
||||||
|
Value,
|
||||||
)
|
)
|
||||||
from cxxheaderparser.simple import (
|
from cxxheaderparser.simple import (
|
||||||
NamespaceScope,
|
NamespaceScope,
|
||||||
@ -71,6 +72,61 @@ def test_fn_returns_class():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_fn_returns_typename():
|
||||||
|
content = """
|
||||||
|
typename ns::X fn();
|
||||||
|
"""
|
||||||
|
data = parse_string(content, cleandoc=True)
|
||||||
|
|
||||||
|
assert data == ParsedData(
|
||||||
|
namespace=NamespaceScope(
|
||||||
|
functions=[
|
||||||
|
Function(
|
||||||
|
return_type=Type(
|
||||||
|
typename=PQName(
|
||||||
|
segments=[
|
||||||
|
NameSpecifier(name="ns"),
|
||||||
|
NameSpecifier(name="X"),
|
||||||
|
],
|
||||||
|
has_typename=True,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
name=PQName(segments=[NameSpecifier(name="fn")]),
|
||||||
|
parameters=[],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_fn_returns_typename_const():
|
||||||
|
content = """
|
||||||
|
const typename ns::X fn();
|
||||||
|
"""
|
||||||
|
data = parse_string(content, cleandoc=True)
|
||||||
|
|
||||||
|
assert data == ParsedData(
|
||||||
|
namespace=NamespaceScope(
|
||||||
|
functions=[
|
||||||
|
Function(
|
||||||
|
return_type=Type(
|
||||||
|
typename=PQName(
|
||||||
|
segments=[
|
||||||
|
NameSpecifier(name="ns"),
|
||||||
|
NameSpecifier(name="X"),
|
||||||
|
],
|
||||||
|
has_typename=True,
|
||||||
|
),
|
||||||
|
const=True,
|
||||||
|
),
|
||||||
|
name=PQName(segments=[NameSpecifier(name="fn")]),
|
||||||
|
parameters=[],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_fn_pointer_params():
|
def test_fn_pointer_params():
|
||||||
content = """
|
content = """
|
||||||
int fn1(int *);
|
int fn1(int *);
|
||||||
@ -194,6 +250,58 @@ def test_fn_array_param():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_fn_typename_param():
|
||||||
|
content = """
|
||||||
|
void MethodA(const mynamespace::SomeObject &x,
|
||||||
|
typename mynamespace::SomeObject * = 0);
|
||||||
|
|
||||||
|
"""
|
||||||
|
data = parse_string(content, cleandoc=True)
|
||||||
|
|
||||||
|
assert data == ParsedData(
|
||||||
|
namespace=NamespaceScope(
|
||||||
|
functions=[
|
||||||
|
Function(
|
||||||
|
return_type=Type(
|
||||||
|
typename=PQName(segments=[FundamentalSpecifier(name="void")])
|
||||||
|
),
|
||||||
|
name=PQName(segments=[NameSpecifier(name="MethodA")]),
|
||||||
|
parameters=[
|
||||||
|
Parameter(
|
||||||
|
type=Reference(
|
||||||
|
ref_to=Type(
|
||||||
|
typename=PQName(
|
||||||
|
segments=[
|
||||||
|
NameSpecifier(name="mynamespace"),
|
||||||
|
NameSpecifier(name="SomeObject"),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
const=True,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
name="x",
|
||||||
|
),
|
||||||
|
Parameter(
|
||||||
|
type=Pointer(
|
||||||
|
ptr_to=Type(
|
||||||
|
typename=PQName(
|
||||||
|
segments=[
|
||||||
|
NameSpecifier(name="mynamespace"),
|
||||||
|
NameSpecifier(name="SomeObject"),
|
||||||
|
],
|
||||||
|
has_typename=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
default=Value(tokens=[Token(value="0")]),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_fn_weird_refs():
|
def test_fn_weird_refs():
|
||||||
content = """
|
content = """
|
||||||
int aref(int(&x));
|
int aref(int(&x));
|
||||||
|
@ -1702,10 +1702,10 @@ def test_template_specialized_fn_typename():
|
|||||||
segments=[
|
segments=[
|
||||||
NameSpecifier(name=""),
|
NameSpecifier(name=""),
|
||||||
NameSpecifier(name="T"),
|
NameSpecifier(name="T"),
|
||||||
]
|
],
|
||||||
|
has_typename=True,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
has_typename=True,
|
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
@ -1795,10 +1795,10 @@ def test_template_specialized_fn_typename_template():
|
|||||||
]
|
]
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]
|
],
|
||||||
|
has_typename=True,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
has_typename=True,
|
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user