Skip to content

Commit

Permalink
Allow renaming constructor overloads to static methods
Browse files Browse the repository at this point in the history
  • Loading branch information
auscompgeek committed Dec 30, 2024
1 parent a2989c4 commit 0b8d972
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 24 deletions.
4 changes: 4 additions & 0 deletions robotpy_build/autowrap/cxxparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,9 @@ def _on_class_method(

# Update class-specific method attributes
fctx.is_constructor = is_constructor
if is_constructor and method_data.rename and not method_data.cpp_code:
fctx.cpp_return_type = cctx.full_cpp_name
self._on_fn_make_lambda(method_data, fctx)
if operator:
fctx.operator = operator
self.hctx.need_operators_h = True
Expand Down Expand Up @@ -1581,6 +1584,7 @@ def _on_fn_make_lambda(self, data: FunctionData, fctx: FunctionContext):
* When an 'out' parameter is detected (a pointer receiving a value)
* When a buffer + size parameter exists (either in or out)
* When "renaming" a constructor overload to a static method
"""

# Statements to insert before calling the function
Expand Down
71 changes: 49 additions & 22 deletions robotpy_build/autowrap/render_pybind11.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Documentation,
EnumContext,
FunctionContext,
GeneratedLambda,
PropContext,
)

Expand Down Expand Up @@ -67,6 +68,22 @@ def _genmethod(
elif fn.is_constructor:
if fn.cpp_code:
r.writeln(f".def(py::init({fn.cpp_code})")
elif fn.genlambda:
genlambda = fn.genlambda
arg_params = genlambda.in_params
lam_params = [param.decl for param in arg_params]
# TODO: trampoline
assert cls_qualname is not None
call_qual = cls_qualname
_gen_method_lambda(
r,
fn,
genlambda,
call_qual,
tmpl,
f'.def_static("{fn.py_name}"',
lam_params,
)
elif trampoline_qualname:
r.writeln(
f".def(py::init_alias<{', '.join(param.full_cpp_type for param in arg_params)}>()"
Expand All @@ -93,29 +110,14 @@ def _genmethod(
if cls_qualname:
lam_params = [f"{cls_qualname} &self"] + lam_params

r.writeln(f"{fn_def}, []({', '.join(lam_params)}) {{")

with r.indent():
if genlambda.pre:
r.writeln(genlambda.pre)

if trampoline_qualname:
call_qual = f"(({trampoline_qualname}*)&self)->"
elif cls_qualname:
call_qual = f"(({cls_qualname}*)&self)->"
else:
call_qual = f"{fn.namespace}::"

call_params = ", ".join(p.call_name for p in fn.all_params)

r.writeln(
f"{genlambda.call_start}{call_qual}{fn.cpp_name}{tmpl}({call_params});"
)

if genlambda.ret:
r.writeln(genlambda.ret)
if trampoline_qualname:
call_qual = f"(({trampoline_qualname}*)&self)->{fn.cpp_name}"
elif cls_qualname:
call_qual = f"(({cls_qualname}*)&self)->{fn.cpp_name}"
else:
call_qual = f"{fn.namespace}::{fn.cpp_name}"

r.writeln("}")
_gen_method_lambda(r, fn, genlambda, call_qual, tmpl, fn_def, lam_params)

else:
if trampoline_qualname:
Expand Down Expand Up @@ -172,6 +174,31 @@ def _genmethod(
r.writeln(f"#endif // {fn.ifndef}\n")


def _gen_method_lambda(
r: RenderBuffer,
fn: FunctionContext,
genlambda: GeneratedLambda,
call_qual: str,
tmpl: str,
fn_def: str,
lam_params: T.List[str],
):
r.writeln(f"{fn_def}, []({', '.join(lam_params)}) {{")

with r.indent():
if genlambda.pre:
r.writeln(genlambda.pre)

call_params = ", ".join(p.call_name for p in fn.all_params)

r.writeln(f"{genlambda.call_start}{call_qual}{tmpl}({call_params});")

if genlambda.ret:
r.writeln(genlambda.ret)

r.writeln("}")


def genmethod(
r: RenderBuffer,
cls_qualname: T.Optional[str],
Expand Down
7 changes: 6 additions & 1 deletion tests/cpp/gen/ft/rename.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,15 @@ classes:
Param1:
rename: P1
methods:
OriginalClass:
overloads:
'':
int:
rename: new
fnOriginal:
rename: fnRenamed
fnRenamedParam:
param_override:
x:
name: y
setProp:
setProp:
5 changes: 4 additions & 1 deletion tests/cpp/rpytest/ft/include/rename.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ int fnRenamedParam(int x) { return x; }

// class
struct OriginalClass {
// constructor
OriginalClass() = default;
explicit OriginalClass(int prop) : originalProp(prop) {};

// class function
int fnOriginal() { return 0x2; }
Expand All @@ -37,4 +40,4 @@ struct OriginalClass {
// enums
enum OriginalEnum {
Original1 = 1
};
};
4 changes: 4 additions & 0 deletions tests/test_ft_rename.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def test_rename_cls():
assert not hasattr(c.ClassRenamedEnum, "Param1")
assert c.ClassRenamedEnum.P1 == 1

n = ft.RenamedClass.new(1)
assert isinstance(n, ft.RenamedClass)
assert n.renamedProp == 1


def test_rename_enums():
assert not hasattr(ft._rpytest_ft, "OriginalEnum")
Expand Down

0 comments on commit 0b8d972

Please sign in to comment.