aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/generator/shiboken2
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/generator/shiboken2')
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp131
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.h5
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp3
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h3
4 files changed, 129 insertions, 13 deletions
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 06300fc00..6334834d3 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -348,6 +348,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
QTextStream md(&methodsDefinitions);
QString singleMethodDefinitions;
QTextStream smd(&singleMethodDefinitions);
+ QString signaturesString;
+ QTextStream signatureStream(&signaturesString);
s << endl << "// Target ---------------------------------------------------------" << endl << endl;
s << "extern \"C\" {" << endl;
@@ -383,10 +385,13 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (classContext.forSmartPointer())
continue;
writeConstructorWrapper(s, overloads, classContext);
+ writeSignatureInfo(signatureStream, overloads);
}
// call operators
- else if (rfunc->name() == QLatin1String("operator()"))
+ else if (rfunc->name() == QLatin1String("operator()")) {
writeMethodWrapper(s, overloads, classContext);
+ writeSignatureInfo(signatureStream, overloads);
+ }
else if (!rfunc->isOperatorOverload()) {
if (classContext.forSmartPointer()) {
@@ -417,6 +422,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
}
writeMethodWrapper(s, overloads, classContext);
+ writeSignatureInfo(signatureStream, overloads);
if (OverloadData::hasStaticAndInstanceFunctions(overloads)) {
QString methDefName = cpythonMethodDefinitionName(rfunc);
smd << "static PyMethodDef " << methDefName << " = {" << endl;
@@ -431,8 +437,10 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
QString className = cpythonTypeName(metaClass);
className.remove(QRegExp(QLatin1String("_Type$")));
- if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer())
+ if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
writeCopyFunction(s, classContext);
+ signatureStream << INDENT << metaClass->fullName() << ".__copy__()" << endl;
+ }
// Write single method definitions
s << singleMethodDefinitions;
@@ -495,6 +503,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
continue;
writeMethodWrapper(s, overloads, classContext);
+ writeSignatureInfo(signatureStream, overloads);
}
}
@@ -567,7 +576,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << endl;
writeConverterFunctions(s, metaClass, classContext);
- writeClassRegister(s, metaClass, classContext);
+ writeClassRegister(s, metaClass, classContext, signatureStream);
// class inject-code native/end
if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
@@ -1976,7 +1985,7 @@ void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData)
strArg = QLatin1String("str");
else if (strArg == QLatin1String("PyBytes"))
strArg = QLatin1String("\" SBK_STR_NAME \"");
- else if (strArg == QLatin1String("PySequece"))
+ else if (strArg == QLatin1String("PySequence"))
strArg = QLatin1String("list");
else if (strArg == QLatin1String("PyTuple"))
strArg = QLatin1String("tuple");
@@ -4302,6 +4311,69 @@ void CppGenerator::writeMethodDefinition(QTextStream& s, const AbstractMetaFunct
s << ',' << endl;
}
+static QString resolveRetOrArgType(const AbstractMetaType *someType)
+{
+ QString strRetArg;
+ if (CppGenerator::isCString(someType)) {
+ strRetArg = QLatin1String("str");
+ } else if (someType->isPrimitive()) {
+ const PrimitiveTypeEntry* ptp = static_cast<const PrimitiveTypeEntry*>(someType->typeEntry());
+ while (ptp->referencedTypeEntry())
+ ptp = ptp->referencedTypeEntry();
+ strRetArg = ptp->name();
+ } else {
+ strRetArg = someType->fullName();
+ }
+ strRetArg.replace(QLatin1String("::"), QLatin1String("."));
+ return strRetArg;
+}
+
+void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunctionList &overloads)
+{
+ OverloadData overloadData(overloads, this);
+ const AbstractMetaFunction* rfunc = overloadData.referenceFunction();
+ QString funcName = fullPythonFunctionName(rfunc);
+
+ int idx = overloads.length() - 1;
+ bool multiple = idx > 0;
+
+// after merging, the #if may be removed!
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ for (const AbstractMetaFunction *f : overloads) {
+ QStringList args;
+ const AbstractMetaArgumentList &arguments = f->arguments();
+ for (AbstractMetaArgument *arg : arguments) {
+#else
+ foreach (const AbstractMetaFunction *f, overloads) {
+ QStringList args;
+ const AbstractMetaArgumentList &arguments = f->arguments();
+ foreach (const AbstractMetaArgument *arg, arguments) {
+#endif
+ QString strArg = resolveRetOrArgType(arg->type());
+ if (!arg->defaultValueExpression().isEmpty()) {
+ strArg += QLatin1Char('=');
+ QString e = arg->defaultValueExpression();
+ e.replace(QLatin1String("::"), QLatin1String("."));
+ // the tests insert stuff like Str("<unknown>"):
+ e.replace(QLatin1Char('"'), QLatin1String("\\\""));
+ strArg += e;
+ }
+ args << arg->name() + QLatin1Char(':') + strArg;
+ }
+ s << INDENT;
+ // mark the multiple signatures as such, to make it easier to generate different code
+ if (multiple)
+ s << idx-- << ':';
+ // now calculate the return type.
+ s << funcName << '(' << args.join(QLatin1Char(',')) << ')';
+ AbstractMetaType *returnType = getTypeWithoutContainer(f->type());
+ if (returnType) {
+ s << "->" << resolveRetOrArgType(returnType);
+ }
+ s << endl;
+ }
+}
+
void CppGenerator::writeEnumsInitialization(QTextStream& s, AbstractMetaEnumList& enums)
{
if (enums.isEmpty())
@@ -4604,7 +4676,8 @@ QString CppGenerator::getInitFunctionName(GeneratorContext &context) const
void CppGenerator::writeClassRegister(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &classContext)
+ GeneratorContext &classContext,
+ QTextStream &signatureStream)
{
const ComplexTypeEntry* classTypeEntry = metaClass->typeEntry();
@@ -4614,6 +4687,21 @@ void CppGenerator::writeClassRegister(QTextStream &s,
QString pyTypeName = cpythonTypeName(metaClass);
QString initFunctionName = getInitFunctionName(classContext);
+
+ // PYSIDE-510: Create a signatures string for the introspection feature.
+ s << "// The signatures string for the functions." << endl;
+ s << "// Multiple signatures have their index \"n:\" in front." << endl;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ s << "const char " << initFunctionName << "_SignaturesString[] = R\"\"\"(\n"
+ << signatureStream.readAll() << ")\"\"\";" << endl << endl;
+#else
+ s << "const char " << initFunctionName << "_SignaturesString[] = \"\"" << endl;
+ QString line;
+ while (signatureStream.readLineInto(&line)) {
+ s << '"' << line << "\\n\"" << endl;
+ }
+ s << ';' << endl << endl;
+#endif
s << "void init_" << initFunctionName;
s << "(PyObject* " << enclosingObjectVariable << ")" << endl;
s << '{' << endl;
@@ -4640,11 +4728,11 @@ void CppGenerator::writeClassRegister(QTextStream &s,
}
if (!classContext.forSmartPointer())
- s << INDENT << cpythonTypeNameExt(classTypeEntry);
+ s << INDENT << cpythonTypeNameExt(classTypeEntry) << endl;
else
- s << INDENT << cpythonTypeNameExt(classContext.preciseType());
+ s << INDENT << cpythonTypeNameExt(classContext.preciseType()) << endl;
- s << " = reinterpret_cast<PyTypeObject*>(&" << pyTypeName << ");" << endl;
+ s << INDENT << " = reinterpret_cast<PyTypeObject*>(&" << pyTypeName << ");" << endl;
s << endl;
// Multiple inheritance
@@ -4681,7 +4769,8 @@ void CppGenerator::writeClassRegister(QTextStream &s,
s << "\"," << endl;
{
Indentation indent(INDENT);
- s << INDENT << "&" << pyTypeName;
+ s << INDENT << "&" << pyTypeName << "," << endl;
+ s << INDENT << initFunctionName << "_SignaturesString";
// Set destructor function
if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
@@ -5069,6 +5158,8 @@ bool CppGenerator::finishGeneration()
QTextStream s_globalFunctionImpl(&globalFunctionImpl);
QString globalFunctionDecl;
QTextStream s_globalFunctionDef(&globalFunctionDecl);
+ QString signaturesString;
+ QTextStream signatureStream(&signaturesString);
Indentation indent(INDENT);
@@ -5089,6 +5180,7 @@ bool CppGenerator::finishGeneration()
// Dummy context to satisfy the API.
GeneratorContext classContext;
writeMethodWrapper(s_globalFunctionImpl, overloads, classContext);
+ writeSignatureInfo(signatureStream, overloads);
writeMethodDefinition(s_globalFunctionDef, overloads);
}
@@ -5152,6 +5244,7 @@ bool CppGenerator::finishGeneration()
if (usePySideExtensions()) {
s << includeQDebug;
s << "#include <pyside.h>" << endl;
+ s << "#include <signature.h>" << endl;
}
s << "#include \"" << getModuleHeaderFileName() << '"' << endl << endl;
@@ -5458,7 +5551,25 @@ bool CppGenerator::finishGeneration()
}
// cleanup staticMetaObject attribute
- s << INDENT << "PySide::registerCleanupFunction(cleanTypesAttributes);" << endl;
+ s << INDENT << "PySide::registerCleanupFunction(cleanTypesAttributes);" << endl << endl;
+
+ // PYSIDE-510: Create a signatures string for the introspection feature.
+ s << "// The signatures string for the global functions." << endl;
+ s << "// Multiple signatures have their index \"n:\" in front." << endl;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ s << "const char " << moduleName() << "_SignaturesString[] = R\"\"\"(\n"
+ << signatureStream.readAll() << ")\"\"\";" << endl << endl;
+#else
+ s << "const char " << moduleName() << "_SignaturesString[] = \"\"" << endl;
+ QString line;
+ while (signatureStream.readLineInto(&line)) {
+ s << '"' << line << "\\n\"" << endl;
+ }
+ s << ';' << endl;
+#endif
+ // finish the rest of __signature__ initialization.
+ s << INDENT << "FinishSignatureInitialization(module, " << moduleName()
+ << "_SignaturesString);" << endl << endl;
}
s << "SBK_MODULE_INIT_FUNCTION_END" << endl;
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h
index 5dc3f5a15..4877a1694 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.h
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h
@@ -231,13 +231,14 @@ private:
void writeClassRegister(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &classContext);
+ GeneratorContext &classContext,
+ QTextStream &signatureStream);
void writeClassDefinition(QTextStream &s,
const AbstractMetaClass *metaClass,
GeneratorContext &classContext);
void writeMethodDefinitionEntry(QTextStream& s, const AbstractMetaFunctionList overloads);
void writeMethodDefinition(QTextStream& s, const AbstractMetaFunctionList overloads);
-
+ void writeSignatureInfo(QTextStream &s, const AbstractMetaFunctionList &overloads);
/// Writes the implementation of all methods part of python sequence protocol
void writeSequenceMethods(QTextStream &s,
const AbstractMetaClass *metaClass,
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 7b664e105..670659854 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -324,6 +324,9 @@ QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction* fu
else
funcName.prepend(fullName + QLatin1Char('.'));
}
+ else {
+ funcName = packageName() + QLatin1Char('.') + func->name();
+ }
return funcName;
}
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index 837e7d640..d36962cf1 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -294,7 +294,8 @@ public:
QString wrapperName(const AbstractMetaClass* metaClass) const;
QString wrapperName(const AbstractMetaType *metaType) const;
- static QString fullPythonFunctionName(const AbstractMetaFunction* func);
+ QString fullPythonFunctionName(const AbstractMetaFunction* func);
+
static QString protectedEnumSurrogateName(const AbstractMetaEnum* metaEnum);
static QString protectedFieldGetterName(const AbstractMetaField* field);
static QString protectedFieldSetterName(const AbstractMetaField* field);