in src/tool/python/code_writers.h [902:1071]
void write_method_functions(writer& w, TypeDef const& type)
{
// create a map of methods to determine overloads + ensure all overloads match instance/static
std::map<std::string_view, bool> method_map{};
enumerate_methods(w, type, [&](auto const& method)
{
XLANG_ASSERT(contains(method_map, method.Name()) ? method_map[method.Name()] == is_static(method) : true);
method_map[method.Name()] = is_static(method);
});
for (auto&&[method_name, method_is_static] : method_map)
{
w.write("\nstatic PyObject* @_%(%, PyObject* args) noexcept\n{\n",
type.TypeName(),
method_name,
bind<write_method_self_param>(type, method_is_static));
{
writer::indent_guard g{ w };
if (is_ptype(type))
{
w.write("return self->obj->%(args);\n", method_name);
}
else
{
write_method_overloads(w, type, method_name);
}
}
w.write("}\n");
}
enumerate_properties(w, type, [&](auto const& prop)
{
auto&&[get_method, put_method] = get_property_methods(prop);
write_get_property_function(w, type, get_method);
write_put_property_function(w, type, put_method);
});
enumerate_events(w, type, [&](auto const& evt)
{
auto&&[add_method, remove_method] = get_event_methods(evt);
write_event_function(w, type, add_method);
write_event_function(w, type, remove_method);
});
if (!(is_ptype(type) || is_static_class(type)))
{
w.write("\nstatic PyObject* _from_@(PyObject* /*unused*/, PyObject* arg) noexcept\n{\n", type.TypeName());
{
writer::indent_guard g{ w };
write_try_catch(w, [&](writer& w)
{
auto format = "auto return_value = py::convert_to<winrt::Windows::Foundation::IInspectable>(arg);\nreturn py::convert(return_value.as<%>());\n";
w.write(format, type);
});
}
w.write("}\n");
}
if (implements_iclosable(type))
{
w.write(strings::enter_function, type.TypeName(), bind<write_pywrapper_type>(type));
w.write("\nstatic PyObject* _exit_@(%* self) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
writer::indent_guard g{ w };
write_try_catch(w, [](auto& w) { w.write("self->obj.Close();\nPy_RETURN_FALSE;\n"); });
}
w.write("}\n");
}
if (implements_istringable(type))
{
w.write("\nstatic PyObject* _str_@(%* self) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
writer::indent_guard g{ w };
write_try_catch(w, [](auto& w) { w.write("return py::convert(self->obj.ToString());\n"); });
}
w.write("}\n");
}
auto write_ptype_body = [&](std::string_view ptype_func_call, std::function<void(writer&)> ctype_func)
{
writer::indent_guard g{ w };
if (is_ptype(type))
{
w.write("return self->obj->%;\n", ptype_func_call);
}
else
{
ctype_func(w);
}
};
if (implements_iasync(type))
{
w.write("\nstatic PyObject* _await_@(%* self) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
write_ptype_body("dunder_await()", [&](auto& w) { w.write("return py::dunder_await(self->obj);\n"); });
}
w.write("}\n");
}
if (implements_iiterable(type) || implements_iiterator(type))
{
w.write("\nstatic PyObject* _iterator_@(%* self) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
write_ptype_body("dunder_iter()", [&](auto& w) { write_dunder_iter_body(w, type); });
}
w.write("}\n");
}
if (implements_iiterator(type))
{
w.write("\nstatic PyObject* _iterator_next_@(%* self) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
write_ptype_body("dunder_iternext()", [&](auto& w) { write_dunder_iter_next_body(w, type); });
}
w.write("}\n");
}
if (implements_sequence(type))
{
w.write("\nstatic Py_ssize_t _seq_length_@(%* self) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
write_ptype_body("seq_length()", [&](auto& w) { write_seq_length_body(w, type); });
}
w.write("}\n");
w.write("\nstatic PyObject* _seq_item_@(%* self, Py_ssize_t i) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
write_ptype_body("seq_item(i)", [&](auto& w) { write_seq_item_body(w, type); });
}
w.write("}\n");
if (implements_ivector(type))
{
w.write("\nstatic int _seq_assign_@(%* self, Py_ssize_t i, PyObject* value) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
write_ptype_body("seq_assign(i, value)", [&](auto& w) { write_seq_assign_body(w, type); });
}
w.write("}\n");
}
}
if (implements_mapping(type))
{
w.write("\nstatic Py_ssize_t _map_length_@(%* self) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
write_ptype_body("map_length()", [&](auto& w) { write_map_length_body(w, type); });
}
w.write("}\n");
w.write("\nstatic PyObject* _map_subscript_@(%* self, PyObject* key) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
write_ptype_body("map_subscript(key)", [&](auto& w) { write_map_subscript_body(w, type); });
}
w.write("}\n");
if (implements_imap(type))
{
w.write("\nstatic int _map_assign_@(%* self, PyObject* key, PyObject* value) noexcept\n{\n", type.TypeName(), bind<write_pywrapper_type>(type));
{
write_ptype_body("map_assign(key, value)", [&](auto& w) { write_map_assign_body(w, type); });
}
w.write("}\n");
}
}
}