Skip to content

Commit 0b8d972

Browse files
committed
Allow renaming constructor overloads to static methods
1 parent a2989c4 commit 0b8d972

File tree

5 files changed

+67
-24
lines changed

5 files changed

+67
-24
lines changed

robotpy_build/autowrap/cxxparser.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,9 @@ def _on_class_method(
10721072

10731073
# Update class-specific method attributes
10741074
fctx.is_constructor = is_constructor
1075+
if is_constructor and method_data.rename and not method_data.cpp_code:
1076+
fctx.cpp_return_type = cctx.full_cpp_name
1077+
self._on_fn_make_lambda(method_data, fctx)
10751078
if operator:
10761079
fctx.operator = operator
10771080
self.hctx.need_operators_h = True
@@ -1581,6 +1584,7 @@ def _on_fn_make_lambda(self, data: FunctionData, fctx: FunctionContext):
15811584
15821585
* When an 'out' parameter is detected (a pointer receiving a value)
15831586
* When a buffer + size parameter exists (either in or out)
1587+
* When "renaming" a constructor overload to a static method
15841588
"""
15851589

15861590
# Statements to insert before calling the function

robotpy_build/autowrap/render_pybind11.py

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Documentation,
88
EnumContext,
99
FunctionContext,
10+
GeneratedLambda,
1011
PropContext,
1112
)
1213

@@ -67,6 +68,22 @@ def _genmethod(
6768
elif fn.is_constructor:
6869
if fn.cpp_code:
6970
r.writeln(f".def(py::init({fn.cpp_code})")
71+
elif fn.genlambda:
72+
genlambda = fn.genlambda
73+
arg_params = genlambda.in_params
74+
lam_params = [param.decl for param in arg_params]
75+
# TODO: trampoline
76+
assert cls_qualname is not None
77+
call_qual = cls_qualname
78+
_gen_method_lambda(
79+
r,
80+
fn,
81+
genlambda,
82+
call_qual,
83+
tmpl,
84+
f'.def_static("{fn.py_name}"',
85+
lam_params,
86+
)
7087
elif trampoline_qualname:
7188
r.writeln(
7289
f".def(py::init_alias<{', '.join(param.full_cpp_type for param in arg_params)}>()"
@@ -93,29 +110,14 @@ def _genmethod(
93110
if cls_qualname:
94111
lam_params = [f"{cls_qualname} &self"] + lam_params
95112

96-
r.writeln(f"{fn_def}, []({', '.join(lam_params)}) {{")
97-
98-
with r.indent():
99-
if genlambda.pre:
100-
r.writeln(genlambda.pre)
101-
102-
if trampoline_qualname:
103-
call_qual = f"(({trampoline_qualname}*)&self)->"
104-
elif cls_qualname:
105-
call_qual = f"(({cls_qualname}*)&self)->"
106-
else:
107-
call_qual = f"{fn.namespace}::"
108-
109-
call_params = ", ".join(p.call_name for p in fn.all_params)
110-
111-
r.writeln(
112-
f"{genlambda.call_start}{call_qual}{fn.cpp_name}{tmpl}({call_params});"
113-
)
114-
115-
if genlambda.ret:
116-
r.writeln(genlambda.ret)
113+
if trampoline_qualname:
114+
call_qual = f"(({trampoline_qualname}*)&self)->{fn.cpp_name}"
115+
elif cls_qualname:
116+
call_qual = f"(({cls_qualname}*)&self)->{fn.cpp_name}"
117+
else:
118+
call_qual = f"{fn.namespace}::{fn.cpp_name}"
117119

118-
r.writeln("}")
120+
_gen_method_lambda(r, fn, genlambda, call_qual, tmpl, fn_def, lam_params)
119121

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

174176

177+
def _gen_method_lambda(
178+
r: RenderBuffer,
179+
fn: FunctionContext,
180+
genlambda: GeneratedLambda,
181+
call_qual: str,
182+
tmpl: str,
183+
fn_def: str,
184+
lam_params: T.List[str],
185+
):
186+
r.writeln(f"{fn_def}, []({', '.join(lam_params)}) {{")
187+
188+
with r.indent():
189+
if genlambda.pre:
190+
r.writeln(genlambda.pre)
191+
192+
call_params = ", ".join(p.call_name for p in fn.all_params)
193+
194+
r.writeln(f"{genlambda.call_start}{call_qual}{tmpl}({call_params});")
195+
196+
if genlambda.ret:
197+
r.writeln(genlambda.ret)
198+
199+
r.writeln("}")
200+
201+
175202
def genmethod(
176203
r: RenderBuffer,
177204
cls_qualname: T.Optional[str],

tests/cpp/gen/ft/rename.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,15 @@ classes:
2626
Param1:
2727
rename: P1
2828
methods:
29+
OriginalClass:
30+
overloads:
31+
'':
32+
int:
33+
rename: new
2934
fnOriginal:
3035
rename: fnRenamed
3136
fnRenamedParam:
3237
param_override:
3338
x:
3439
name: y
35-
setProp:
40+
setProp:

tests/cpp/rpytest/ft/include/rename.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ int fnRenamedParam(int x) { return x; }
1212

1313
// class
1414
struct OriginalClass {
15+
// constructor
16+
OriginalClass() = default;
17+
explicit OriginalClass(int prop) : originalProp(prop) {};
1518

1619
// class function
1720
int fnOriginal() { return 0x2; }
@@ -37,4 +40,4 @@ struct OriginalClass {
3740
// enums
3841
enum OriginalEnum {
3942
Original1 = 1
40-
};
43+
};

tests/test_ft_rename.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ def test_rename_cls():
3030
assert not hasattr(c.ClassRenamedEnum, "Param1")
3131
assert c.ClassRenamedEnum.P1 == 1
3232

33+
n = ft.RenamedClass.new(1)
34+
assert isinstance(n, ft.RenamedClass)
35+
assert n.renamedProp == 1
36+
3337

3438
def test_rename_enums():
3539
assert not hasattr(ft._rpytest_ft, "OriginalEnum")

0 commit comments

Comments
 (0)