diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2017-09-28 11:09:30 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2017-09-28 11:09:37 +0200 |
commit | e062958e59129bb4cdfa2056f8023b1ba4dc9670 (patch) | |
tree | 1fe3f4424a59f7e8317d29c50c8ffe8d46c498d6 /sources/shiboken2/generator | |
parent | e479a2a973820e9d1bf6585e0640a334c8824038 (diff) | |
parent | 67ac7e473e312298eeb2deb16f2a50644b5f76e7 (diff) |
Merge remote-tracking branch 'origin/5.6' into 5.9
Change-Id: I47521e21977b1f17fcc65590f565270b2440a48b
Diffstat (limited to 'sources/shiboken2/generator')
4 files changed, 118 insertions, 13 deletions
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 7317947d5..122128497 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -364,6 +364,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; @@ -399,10 +401,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()) { @@ -433,6 +438,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; @@ -446,8 +452,10 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) const QString className = chopType(cpythonTypeName(metaClass)); - 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; @@ -510,6 +518,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) continue; writeMethodWrapper(s, overloads, classContext); + writeSignatureInfo(signatureStream, overloads); } } @@ -583,7 +592,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()) { @@ -2012,7 +2021,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"); @@ -4385,6 +4394,68 @@ 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; + } + // 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()) @@ -4690,7 +4761,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(); @@ -4700,6 +4772,16 @@ 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; + s << "const char " << initFunctionName << "_SignaturesString[] = \"\"" << endl; + QString line; + while (signatureStream.readLineInto(&line)) { + s << INDENT << '"' << line << "\\n\"" << endl; + } + s << ';' << endl << endl; s << "void init_" << initFunctionName; s << "(PyObject* " << enclosingObjectVariable << ")" << endl; s << '{' << endl; @@ -4726,11 +4808,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 @@ -4767,7 +4849,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()) { @@ -5160,6 +5243,8 @@ bool CppGenerator::finishGeneration() QTextStream s_globalFunctionImpl(&globalFunctionImpl); QString globalFunctionDecl; QTextStream s_globalFunctionDef(&globalFunctionDecl); + QString signaturesString; + QTextStream signatureStream(&signaturesString); Indentation indent(INDENT); @@ -5180,6 +5265,7 @@ bool CppGenerator::finishGeneration() // Dummy context to satisfy the API. GeneratorContext classContext; writeMethodWrapper(s_globalFunctionImpl, overloads, classContext); + writeSignatureInfo(signatureStream, overloads); writeMethodDefinition(s_globalFunctionDef, overloads); } @@ -5244,6 +5330,7 @@ bool CppGenerator::finishGeneration() if (usePySideExtensions()) { s << includeQDebug; s << "#include <pyside.h>" << endl; + s << "#include <signature.h>" << endl; } s << "#include \"" << getModuleHeaderFileName() << '"' << endl << endl; @@ -5555,7 +5642,20 @@ 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; + s << "const char " << moduleName() << "_SignaturesString[] = \"\"" << endl; + QString line; + while (signatureStream.readLineInto(&line)) { + s << INDENT << '"' << line << "\\n\"" << endl; + } + s << ';' << endl; + // 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 c3ca48307..cce1842ab 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 cf264f14c..530d9b143 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp @@ -330,6 +330,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 497ff4e34..a8a270612 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h @@ -296,7 +296,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); |