cxxheaderparser/tests/test_operators.py
Dustin Spicuzza c3fbe4c16c breaking change: Remove operator type and make part of Function
- Unifies free function operators and method operators -- otherwise users
  would need to parse the operator themselves to deal with free function operators
- We don't have any releases yet, so there are no stability guarantees
2023-09-23 21:45:30 -04:00

749 lines
31 KiB
Python

# Note: testcases generated via `python -m cxxheaderparser.gentest`
from cxxheaderparser.types import (
ClassDecl,
Function,
FundamentalSpecifier,
Method,
MoveReference,
NameSpecifier,
Pointer,
PQName,
Parameter,
Reference,
Type,
)
from cxxheaderparser.simple import (
ClassScope,
NamespaceScope,
parse_string,
ParsedData,
)
def test_class_operators() -> None:
content = r"""
class OperatorClass {
public:
void operator=(const Sample25Class &);
void operator-=(const Sample25Class &);
void operator+=();
void operator[]();
bool operator==(const int &b);
OperatorClass &operator+();
void operator-();
void operator*();
void operator\();
void operator%();
void operator^();
void operator|();
void operator&();
void operator~();
void operator<<();
void operator>>();
void operator!=();
void operator<();
void operator>();
void operator>=();
void operator<=();
void operator!();
void operator&&();
void operator||();
void operator+=();
void operator-=();
void operator*=();
void operator\=();
void operator%=();
void operator&=();
void operator|=();
void operator^=();
void operator<<=();
void operator>>=();
void operator++();
void operator--();
void operator()();
void operator->();
void operator,();
};
"""
data = parse_string(content, cleandoc=True)
assert data == ParsedData(
namespace=NamespaceScope(
classes=[
ClassScope(
class_decl=ClassDecl(
typename=PQName(
segments=[NameSpecifier(name="OperatorClass")],
classkey="class",
)
),
methods=[
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator=")]),
parameters=[
Parameter(
type=Reference(
ref_to=Type(
typename=PQName(
segments=[
NameSpecifier(name="Sample25Class")
]
),
const=True,
)
)
)
],
access="public",
operator="=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator-=")]),
parameters=[
Parameter(
type=Reference(
ref_to=Type(
typename=PQName(
segments=[
NameSpecifier(name="Sample25Class")
]
),
const=True,
)
)
)
],
access="public",
operator="-=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator+=")]),
parameters=[],
access="public",
operator="+=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator[]")]),
parameters=[],
access="public",
operator="[]",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="bool")]
)
),
name=PQName(segments=[NameSpecifier(name="operator==")]),
parameters=[
Parameter(
type=Reference(
ref_to=Type(
typename=PQName(
segments=[
FundamentalSpecifier(name="int")
]
),
const=True,
)
),
name="b",
)
],
access="public",
operator="==",
),
Method(
return_type=Reference(
ref_to=Type(
typename=PQName(
segments=[NameSpecifier(name="OperatorClass")]
)
)
),
name=PQName(segments=[NameSpecifier(name="operator+")]),
parameters=[],
access="public",
operator="+",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator-")]),
parameters=[],
access="public",
operator="-",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator*")]),
parameters=[],
access="public",
operator="*",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator\\")]),
parameters=[],
access="public",
operator="\\",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator%")]),
parameters=[],
access="public",
operator="%",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator^")]),
parameters=[],
access="public",
operator="^",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator|")]),
parameters=[],
access="public",
operator="|",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator&")]),
parameters=[],
access="public",
operator="&",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator~")]),
parameters=[],
access="public",
operator="~",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator<<")]),
parameters=[],
access="public",
operator="<<",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator>>")]),
parameters=[],
access="public",
operator=">>",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator!=")]),
parameters=[],
access="public",
operator="!=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator<")]),
parameters=[],
access="public",
operator="<",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator>")]),
parameters=[],
access="public",
operator=">",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator>=")]),
parameters=[],
access="public",
operator=">=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator<=")]),
parameters=[],
access="public",
operator="<=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator!")]),
parameters=[],
access="public",
operator="!",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator&&")]),
parameters=[],
access="public",
operator="&&",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator||")]),
parameters=[],
access="public",
operator="||",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator+=")]),
parameters=[],
access="public",
operator="+=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator-=")]),
parameters=[],
access="public",
operator="-=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator*=")]),
parameters=[],
access="public",
operator="*=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator\\=")]),
parameters=[],
access="public",
operator="\\=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator%=")]),
parameters=[],
access="public",
operator="%=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator&=")]),
parameters=[],
access="public",
operator="&=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator|=")]),
parameters=[],
access="public",
operator="|=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator^=")]),
parameters=[],
access="public",
operator="^=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator<<=")]),
parameters=[],
access="public",
operator="<<=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator>>=")]),
parameters=[],
access="public",
operator=">>=",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator++")]),
parameters=[],
access="public",
operator="++",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator--")]),
parameters=[],
access="public",
operator="--",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator()")]),
parameters=[],
access="public",
operator="()",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator->")]),
parameters=[],
access="public",
operator="->",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="void")]
)
),
name=PQName(segments=[NameSpecifier(name="operator,")]),
parameters=[],
access="public",
operator=",",
),
],
)
]
)
)
def test_conversion_operators() -> None:
content = """
class Foo
{
public:
operator Type1() const { return SomeMethod(); }
explicit operator Type2() const;
virtual operator bool() const;
};
"""
data = parse_string(content, cleandoc=True)
assert data == ParsedData(
namespace=NamespaceScope(
classes=[
ClassScope(
class_decl=ClassDecl(
typename=PQName(
segments=[NameSpecifier(name="Foo")], classkey="class"
)
),
methods=[
Method(
return_type=Type(
typename=PQName(segments=[NameSpecifier(name="Type1")])
),
name=PQName(segments=[NameSpecifier(name="operator")]),
parameters=[],
has_body=True,
access="public",
const=True,
operator="conversion",
),
Method(
return_type=Type(
typename=PQName(segments=[NameSpecifier(name="Type2")])
),
name=PQName(segments=[NameSpecifier(name="operator")]),
parameters=[],
access="public",
const=True,
explicit=True,
operator="conversion",
),
Method(
return_type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="bool")]
)
),
name=PQName(segments=[NameSpecifier(name="operator")]),
parameters=[],
access="public",
const=True,
virtual=True,
operator="conversion",
),
],
)
]
)
)
def test_conversion_operators_decorated() -> None:
content = """
struct S {
operator const native_handle_t*() const;
operator const native_handle_t&() const;
operator const native_handle_t&&() const;
};
"""
data = parse_string(content, cleandoc=True)
assert data == ParsedData(
namespace=NamespaceScope(
classes=[
ClassScope(
class_decl=ClassDecl(
typename=PQName(
segments=[NameSpecifier(name="S")], classkey="struct"
)
),
methods=[
Method(
return_type=Pointer(
ptr_to=Type(
typename=PQName(
segments=[NameSpecifier(name="native_handle_t")]
),
const=True,
)
),
name=PQName(segments=[NameSpecifier(name="operator")]),
parameters=[],
access="public",
const=True,
operator="conversion",
),
Method(
return_type=Reference(
ref_to=Type(
typename=PQName(
segments=[NameSpecifier(name="native_handle_t")]
),
const=True,
)
),
name=PQName(segments=[NameSpecifier(name="operator")]),
parameters=[],
access="public",
const=True,
operator="conversion",
),
Method(
return_type=MoveReference(
moveref_to=Type(
typename=PQName(
segments=[NameSpecifier(name="native_handle_t")]
),
const=True,
)
),
name=PQName(segments=[NameSpecifier(name="operator")]),
parameters=[],
access="public",
const=True,
operator="conversion",
),
],
)
]
)
)
def test_free_operator() -> None:
content = """
std::ostream& operator<<(std::ostream& os, const MyDate& dt);
"""
data = parse_string(content, cleandoc=True)
assert data == ParsedData(
namespace=NamespaceScope(
functions=[
Function(
return_type=Reference(
ref_to=Type(
typename=PQName(
segments=[
NameSpecifier(name="std"),
NameSpecifier(name="ostream"),
]
)
)
),
name=PQName(segments=[NameSpecifier(name="operator<<")]),
parameters=[
Parameter(
type=Reference(
ref_to=Type(
typename=PQName(
segments=[
NameSpecifier(name="std"),
NameSpecifier(name="ostream"),
]
)
)
),
name="os",
),
Parameter(
type=Reference(
ref_to=Type(
typename=PQName(
segments=[NameSpecifier(name="MyDate")]
),
const=True,
)
),
name="dt",
),
],
operator="<<",
)
]
)
)