aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/libshiboken/signature/signature_helper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/libshiboken/signature/signature_helper.cpp')
-rw-r--r--sources/shiboken2/libshiboken/signature/signature_helper.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/sources/shiboken2/libshiboken/signature/signature_helper.cpp b/sources/shiboken2/libshiboken/signature/signature_helper.cpp
index 7e92a9861..2b360c786 100644
--- a/sources/shiboken2/libshiboken/signature/signature_helper.cpp
+++ b/sources/shiboken2/libshiboken/signature/signature_helper.cpp
@@ -150,6 +150,28 @@ static PyObject *compute_name_key(PyObject *ob)
return Py_BuildValue("(OO)", type_key.object(), func_name.object());
}
+static PyObject *_func_with_new_name(PyTypeObject *type,
+ PyMethodDef *meth,
+ const char *new_name)
+{
+ /*
+ * Create a function with a lower case name.
+ * Note: This is similar to feature_select's methodWithNewName,
+ * but does not create a descriptor.
+ * XXX Maybe we can get rid of this, completely?
+ */
+ auto obtype = reinterpret_cast<PyObject *>(type);
+ int len = strlen(new_name);
+ auto name = new char[len + 1];
+ strcpy(name, new_name);
+ auto new_meth = new PyMethodDef;
+ new_meth->ml_name = name;
+ new_meth->ml_meth = meth->ml_meth;
+ new_meth->ml_flags = meth->ml_flags;
+ new_meth->ml_doc = meth->ml_doc;
+ return PyCFunction_NewEx(new_meth, obtype, nullptr);
+}
+
static int build_name_key_to_func(PyObject *obtype)
{
auto *type = reinterpret_cast<PyTypeObject *>(obtype);
@@ -167,6 +189,17 @@ static int build_name_key_to_func(PyObject *obtype)
|| PyDict_SetItem(pyside_globals->map_dict, name_key, func) < 0)
return -1;
}
+ // PYSIDE-1019: Now we repeat the same for snake case names.
+ meth = type->tp_methods;
+ for (; meth->ml_name != nullptr; meth++) {
+ const char *name = String::toCString(String::getSnakeCaseName(meth->ml_name, true));
+ AutoDecRef func(_func_with_new_name(type, meth, name));
+ AutoDecRef func_name(get_funcname(func));
+ AutoDecRef name_key(Py_BuildValue("(OO)", type_key.object(), func_name.object()));
+ if (func.isNull() || name_key.isNull()
+ || PyDict_SetItem(pyside_globals->map_dict, name_key, func) < 0)
+ return -1;
+ }
return 0;
}
@@ -198,6 +231,46 @@ PyObject *name_key_to_func(PyObject *ob)
return ret;
}
+static PyObject *_build_new_entry(PyObject *new_name, PyObject *value)
+{
+ PyObject *new_value = PyDict_Copy(value);
+ PyObject *multi = PyDict_GetItem(value, PyName::multi());
+ if (multi != nullptr && Py_TYPE(multi) == &PyList_Type) {
+ ssize_t len = PyList_Size(multi);
+ AutoDecRef list(PyList_New(len));
+ if (list.isNull())
+ return nullptr;
+ for (int idx = 0; idx < len; ++idx) {
+ auto multi_entry = PyList_GetItem(multi, idx);
+ auto dup = PyDict_Copy(multi_entry);
+ if (PyDict_SetItem(dup, PyName::name(), new_name) < 0)
+ return nullptr;
+ if (PyList_SetItem(list, idx, dup) < 0)
+ return nullptr;
+ }
+ if (PyDict_SetItem(new_value, PyName::multi(), list) < 0)
+ return nullptr;
+ } else {
+ if (PyDict_SetItem(new_value, PyName::name(), new_name) < 0)
+ return nullptr;
+ }
+ return new_value;
+}
+
+int insert_snake_case_variants(PyObject *dict)
+{
+ AutoDecRef snake_dict(PyDict_New());
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(dict, &pos, &key, &value)) {
+ AutoDecRef name(String::getSnakeCaseName(key, true));
+ AutoDecRef new_value(_build_new_entry(name, value));
+ if (PyDict_SetItem(snake_dict, name, new_value) < 0)
+ return -1;
+ }
+ return PyDict_Merge(dict, snake_dict, 0);
+}
+
PyObject *_get_class_of_cf(PyObject *ob_cf)
{
PyObject *selftype = PyCFunction_GET_SELF(ob_cf);