aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/generator/shiboken2/shibokengenerator.cpp')
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp377
1 files changed, 242 insertions, 135 deletions
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index fd75c620e..0f5f09d60 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -27,9 +27,11 @@
****************************************************************************/
#include "shibokengenerator.h"
+#include "ctypenames.h"
#include <abstractmetalang.h>
#include <messages.h>
#include "overloaddata.h"
+#include "propertyspec.h"
#include <reporthandler.h>
#include <typedatabase.h>
#include <abstractmetabuilder.h>
@@ -47,6 +49,7 @@ static const char RETURN_VALUE_HEURISTIC[] = "enable-return-value-heuristic";
static const char ENABLE_PYSIDE_EXTENSIONS[] = "enable-pyside-extensions";
static const char DISABLE_VERBOSE_ERROR_MESSAGES[] = "disable-verbose-error-messages";
static const char USE_ISNULL_AS_NB_NONZERO[] = "use-isnull-as-nb_nonzero";
+static const char WRAPPER_DIAGNOSTICS[] = "wrapper-diagnostics";
const char *CPP_ARG = "cppArg";
const char *CPP_ARG_REMOVED = "removed_cppArg";
@@ -96,7 +99,7 @@ static QString resolveScopePrefix(const QStringList &scopeList, const QString &v
static inline QStringList splitClassScope(const AbstractMetaClass *scope)
{
- return scope->qualifiedCppName().split(QLatin1String("::"), QString::SkipEmptyParts);
+ return scope->qualifiedCppName().split(QLatin1String("::"), Qt::SkipEmptyParts);
}
static QString resolveScopePrefix(const AbstractMetaClass *scope, const QString &value)
@@ -194,8 +197,8 @@ void ShibokenGenerator::initPrimitiveTypesCorrespondences()
m_pythonPrimitiveTypeName.insert(QLatin1String(intType), QStringLiteral("PyInt"));
// PyFloat
- m_pythonPrimitiveTypeName.insert(QLatin1String("double"), QLatin1String("PyFloat"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("float"), QLatin1String("PyFloat"));
+ m_pythonPrimitiveTypeName.insert(doubleT(), QLatin1String("PyFloat"));
+ m_pythonPrimitiveTypeName.insert(floatT(), QLatin1String("PyFloat"));
// PyLong
const char *longTypes[] = {
@@ -255,18 +258,18 @@ void ShibokenGenerator::initPrimitiveTypesCorrespondences()
m_formatUnits.clear();
m_formatUnits.insert(QLatin1String("char"), QLatin1String("b"));
m_formatUnits.insert(QLatin1String("unsigned char"), QLatin1String("B"));
- m_formatUnits.insert(QLatin1String("int"), QLatin1String("i"));
+ m_formatUnits.insert(intT(), QLatin1String("i"));
m_formatUnits.insert(QLatin1String("unsigned int"), QLatin1String("I"));
- m_formatUnits.insert(QLatin1String("short"), QLatin1String("h"));
- m_formatUnits.insert(QLatin1String("unsigned short"), QLatin1String("H"));
- m_formatUnits.insert(QLatin1String("long"), QLatin1String("l"));
- m_formatUnits.insert(QLatin1String("unsigned long"), QLatin1String("k"));
- m_formatUnits.insert(QLatin1String("long long"), QLatin1String("L"));
+ m_formatUnits.insert(shortT(), QLatin1String("h"));
+ m_formatUnits.insert(unsignedShortT(), QLatin1String("H"));
+ m_formatUnits.insert(longT(), QLatin1String("l"));
+ m_formatUnits.insert(unsignedLongLongT(), QLatin1String("k"));
+ m_formatUnits.insert(longLongT(), QLatin1String("L"));
m_formatUnits.insert(QLatin1String("__int64"), QLatin1String("L"));
- m_formatUnits.insert(QLatin1String("unsigned long long"), QLatin1String("K"));
+ m_formatUnits.insert(unsignedLongLongT(), QLatin1String("K"));
m_formatUnits.insert(QLatin1String("unsigned __int64"), QLatin1String("K"));
- m_formatUnits.insert(QLatin1String("double"), QLatin1String("d"));
- m_formatUnits.insert(QLatin1String("float"), QLatin1String("f"));
+ m_formatUnits.insert(doubleT(), QLatin1String("d"));
+ m_formatUnits.insert(floatT(), QLatin1String("f"));
}
void ShibokenGenerator::initKnownPythonTypes()
@@ -322,53 +325,22 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass *metaCl
return result;
}
-void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList &enumList, const AbstractMetaClass *metaClass)
+bool ShibokenGenerator::shouldWriteVirtualMethodNative(const AbstractMetaFunction *func)
{
- Q_ASSERT(metaClass);
- // if a scope is not to be generated, collect its enums into the parent scope
- if (metaClass->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass) {
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (AbstractMetaEnum *metaEnum : enums) {
- if (!metaEnum->isPrivate() && metaEnum->typeEntry()->generateCode()
- && !enumList.contains(metaEnum)) {
- enumList.append(metaEnum);
- }
- }
- }
-}
-
-static const AbstractMetaClass *getProperEnclosingClass(const AbstractMetaClass *metaClass)
-{
- if (!metaClass)
- return nullptr;
-
- if (metaClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)
- return metaClass;
-
- return getProperEnclosingClass(metaClass->enclosingClass());
-}
-
-const AbstractMetaClass *ShibokenGenerator::getProperEnclosingClassForEnum(const AbstractMetaEnum *metaEnum)
-{
- return getProperEnclosingClass(metaEnum->enclosingClass());
+ // PYSIDE-803: Extracted this because it is used multiple times.
+ const AbstractMetaClass *metaClass = func->ownerClass();
+ return (!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
+ && ((func->isVirtual() || func->isAbstract())
+ && (func->attributes() & AbstractMetaAttributes::FinalCppMethod) == 0);
}
QString ShibokenGenerator::wrapperName(const AbstractMetaClass *metaClass) const
{
- if (shouldGenerateCppWrapper(metaClass)) {
- QString result = metaClass->name();
- if (metaClass->enclosingClass()) // is a inner class
- result.replace(QLatin1String("::"), QLatin1String("_"));
-
- result += QLatin1String("Wrapper");
- return result;
- }
- return metaClass->qualifiedCppName();
-}
-
-QString ShibokenGenerator::wrapperName(const AbstractMetaType *metaType) const
-{
- return metaType->cppSignature();
+ Q_ASSERT(shouldGenerateCppWrapper(metaClass));
+ QString result = metaClass->name();
+ if (metaClass->enclosingClass()) // is a inner class
+ result.replace(QLatin1String("::"), QLatin1String("_"));
+ return result + QLatin1String("Wrapper");
}
QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClass)
@@ -376,14 +348,15 @@ QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClas
QString fullClassName = metaClass->name();
const AbstractMetaClass *enclosing = metaClass->enclosingClass();
while (enclosing) {
- fullClassName.prepend(enclosing->name() + QLatin1Char('.'));
+ if (NamespaceTypeEntry::isVisibleScope(enclosing->typeEntry()))
+ fullClassName.prepend(enclosing->name() + QLatin1Char('.'));
enclosing = enclosing->enclosingClass();
}
fullClassName.prepend(packageName() + QLatin1Char('.'));
return fullClassName;
}
-QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *func)
+QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *func, bool forceFunc)
{
QString funcName;
if (func->isOperatorOverload())
@@ -392,10 +365,14 @@ QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *fu
funcName = func->name();
if (func->ownerClass()) {
QString fullClassName = fullPythonClassName(func->ownerClass());
- if (func->isConstructor())
+ if (func->isConstructor()) {
funcName = fullClassName;
- else
+ if (forceFunc)
+ funcName.append(QLatin1String(".__init__"));
+ }
+ else {
funcName.prepend(fullClassName + QLatin1Char('.'));
+ }
}
else {
funcName = packageName() + QLatin1Char('.') + func->name();
@@ -465,14 +442,38 @@ QString ShibokenGenerator::cpythonGetattroFunctionName(const AbstractMetaClass *
return cpythonBaseName(metaClass) + QLatin1String("_getattro");
}
+QString ShibokenGenerator::cpythonGetterFunctionName(const QString &name,
+ const AbstractMetaClass *enclosingClass)
+{
+ return cpythonBaseName(enclosingClass) + QStringLiteral("_get_") + name;
+}
+
+QString ShibokenGenerator::cpythonSetterFunctionName(const QString &name,
+ const AbstractMetaClass *enclosingClass)
+{
+ return cpythonBaseName(enclosingClass) + QStringLiteral("_set_") + name;
+}
+
QString ShibokenGenerator::cpythonGetterFunctionName(const AbstractMetaField *metaField)
{
- return QStringLiteral("%1_get_%2").arg(cpythonBaseName(metaField->enclosingClass()), metaField->name());
+ return cpythonGetterFunctionName(metaField->name(), metaField->enclosingClass());
}
QString ShibokenGenerator::cpythonSetterFunctionName(const AbstractMetaField *metaField)
{
- return QStringLiteral("%1_set_%2").arg(cpythonBaseName(metaField->enclosingClass()), metaField->name());
+ return cpythonSetterFunctionName(metaField->name(), metaField->enclosingClass());
+}
+
+QString ShibokenGenerator::cpythonGetterFunctionName(const QPropertySpec *property,
+ const AbstractMetaClass *metaClass)
+{
+ return cpythonGetterFunctionName(property->name(), metaClass);
+}
+
+QString ShibokenGenerator::cpythonSetterFunctionName(const QPropertySpec *property,
+ const AbstractMetaClass *metaClass)
+{
+ return cpythonSetterFunctionName(property->name(), metaClass);
}
static QString cpythonEnumFlagsName(const QString &moduleName,
@@ -571,7 +572,7 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction
{
QString value = arg->defaultValueExpression();
- if (value.isEmpty()
+ if (value.isEmpty() || value == QLatin1String("{}")
|| arg->hasModifiedDefaultValueExpression()
|| isPointer(arg->type())) {
return value;
@@ -595,7 +596,7 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction
const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes(), arg->type()->typeEntry());
if (enumValueRegEx.match(value).hasMatch() && value != QLatin1String("NULL"))
prefix = resolveScopePrefix(metaClass, value);
- } else if (arg->type()->isPrimitive() && arg->type()->name() == QLatin1String("int")) {
+ } else if (arg->type()->isPrimitive() && arg->type()->name() == intT()) {
if (enumValueRegEx.match(value).hasMatch() && func->implementingClass())
prefix = resolveScopePrefix(func->implementingClass(), value);
} else if(arg->type()->isPrimitive()) {
@@ -659,13 +660,13 @@ QString ShibokenGenerator::cpythonSpecialCastFunctionName(const AbstractMetaClas
}
QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaClass *metaClass,
- const QString &argName)
+ const QString &argName) const
{
return cpythonWrapperCPtr(metaClass->typeEntry(), argName);
}
QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType *metaType,
- const QString &argName)
+ const QString &argName) const
{
if (!ShibokenGenerator::isWrapperType(metaType->typeEntry()))
return QString();
@@ -675,7 +676,7 @@ QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType *metaType,
}
QString ShibokenGenerator::cpythonWrapperCPtr(const TypeEntry *type,
- const QString &argName)
+ const QString &argName) const
{
if (!ShibokenGenerator::isWrapperType(type))
return QString();
@@ -803,7 +804,7 @@ QString ShibokenGenerator::cpythonBaseName(const TypeEntry *type)
baseName = cpythonFlagsName(static_cast<const FlagsTypeEntry *>(type));
} else if (type->isContainer()) {
const auto *ctype = static_cast<const ContainerTypeEntry *>(type);
- switch (ctype->type()) {
+ switch (ctype->containerKind()) {
case ContainerTypeEntry::ListContainer:
case ContainerTypeEntry::StringListContainer:
case ContainerTypeEntry::LinkedListContainer:
@@ -844,7 +845,7 @@ QString ShibokenGenerator::cpythonTypeName(const TypeEntry *type)
return cpythonBaseName(type) + QLatin1String("_TypeF()");
}
-QString ShibokenGenerator::cpythonTypeNameExt(const TypeEntry *type)
+QString ShibokenGenerator::cpythonTypeNameExt(const TypeEntry *type) const
{
return cppApiVariableName(type->targetLangPackage()) + QLatin1Char('[')
+ getTypeIndexVariableName(type) + QLatin1Char(']');
@@ -863,7 +864,7 @@ QString ShibokenGenerator::converterObject(const AbstractMetaType *type)
+ QLatin1String(">(") + QString::number(nestedArrayTypes.size())
+ QLatin1Char(')');
}
- if (type->typeEntry()->isContainer()) {
+ if (type->typeEntry()->isContainer() || type->typeEntry()->isSmartPointer()) {
return convertersVariableName(type->typeEntry()->targetLangPackage())
+ QLatin1Char('[') + getTypeIndexVariableName(type) + QLatin1Char(']');
}
@@ -897,7 +898,7 @@ QString ShibokenGenerator::converterObject(const TypeEntry *type)
+ QLatin1Char('[') + getTypeIndexVariableName(type) + QLatin1Char(']');
}
-QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType *type)
+QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType *type) const
{
return cppApiVariableName(type->typeEntry()->targetLangPackage()) + QLatin1Char('[')
+ getTypeIndexVariableName(type) + QLatin1Char(']');
@@ -932,7 +933,7 @@ QString ShibokenGenerator::fixedCppTypeName(const TypeEntry *type, QString typeN
{
if (typeName.isEmpty())
typeName = type->qualifiedCppName();
- if (!(type->codeGeneration() & TypeEntry::GenerateTargetLang)) {
+ if (!type->generateCode()) {
typeName.prepend(QLatin1Char('_'));
typeName.prepend(type->targetLangPackage());
}
@@ -1159,6 +1160,12 @@ bool ShibokenGenerator::visibilityModifiedToPrivate(const AbstractMetaFunction *
return false;
}
+bool ShibokenGenerator::isNullPtr(const QString &value)
+{
+ return value == QLatin1String("0") || value == QLatin1String("nullptr")
+ || value == QLatin1String("NULLPTR") || value == QLatin1String("{}");
+}
+
QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType *metaType, bool genericNumberType)
{
QString customCheck;
@@ -1178,10 +1185,11 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType *metaType
return QLatin1String("PyObject_Check");
return cpythonCheckFunction(metaType->typeEntry(), genericNumberType);
}
- if (metaType->typeEntry()->isContainer()) {
+ auto typeEntry = metaType->typeEntry();
+ if (typeEntry->isContainer()) {
QString typeCheck = QLatin1String("Shiboken::Conversions::");
- ContainerTypeEntry::Type type =
- static_cast<const ContainerTypeEntry *>(metaType->typeEntry())->type();
+ ContainerTypeEntry::ContainerKind type =
+ static_cast<const ContainerTypeEntry *>(typeEntry)->containerKind();
if (type == ContainerTypeEntry::ListContainer
|| type == ContainerTypeEntry::StringListContainer
|| type == ContainerTypeEntry::LinkedListContainer
@@ -1220,7 +1228,7 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType *metaType
}
return typeCheck;
}
- return cpythonCheckFunction(metaType->typeEntry(), genericNumberType);
+ return cpythonCheckFunction(typeEntry, genericNumberType);
}
QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type, bool genericNumberType)
@@ -1468,6 +1476,16 @@ void ShibokenGenerator::writeFunctionArguments(QTextStream &s,
}
}
+GeneratorContext ShibokenGenerator::contextForClass(const AbstractMetaClass *c) const
+{
+ GeneratorContext result = Generator::contextForClass(c);
+ if (shouldGenerateCppWrapper(c)) {
+ result.m_type = GeneratorContext::WrappedClass;
+ result.m_wrappername = wrapperName(c);
+ }
+ return result;
+}
+
QString ShibokenGenerator::functionReturnType(const AbstractMetaFunction *func, Options options) const
{
QString modifiedReturnType = QString(func->typeReplaced(0));
@@ -1548,19 +1566,37 @@ void ShibokenGenerator::writeFunctionCall(QTextStream &s,
void ShibokenGenerator::writeUnusedVariableCast(QTextStream &s, const QString &variableName)
{
- s << INDENT << "SBK_UNUSED(" << variableName<< ')' << endl;
+ s << INDENT << "SBK_UNUSED(" << variableName<< ")\n";
+}
+
+static bool filterFunction(const AbstractMetaFunction *func, bool avoidProtectedHack)
+{
+ switch (func->functionType()) {
+ case AbstractMetaFunction::DestructorFunction:
+ case AbstractMetaFunction::SignalFunction:
+ case AbstractMetaFunction::GetAttroFunction:
+ case AbstractMetaFunction::SetAttroFunction:
+ return false;
+ default:
+ break;
+ }
+ if (func->usesRValueReferences())
+ return false;
+ if (func->isModifiedRemoved() && !func->isAbstract()
+ && (!avoidProtectedHack || !func->isProtected())) {
+ return false;
+ }
+ return true;
}
AbstractMetaFunctionList ShibokenGenerator::filterFunctions(const AbstractMetaClass *metaClass)
{
AbstractMetaFunctionList result;
const AbstractMetaFunctionList &funcs = metaClass->functions();
+ result.reserve(funcs.size());
for (AbstractMetaFunction *func : funcs) {
- if (func->isSignal() || func->isDestructor() || func->usesRValueReferences()
- || (func->isModifiedRemoved() && !func->isAbstract()
- && (!avoidProtectedHack() || !func->isProtected())))
- continue;
- result << func;
+ if (filterFunction(func, avoidProtectedHack()))
+ result.append(func);
}
return result;
}
@@ -1568,8 +1604,7 @@ AbstractMetaFunctionList ShibokenGenerator::filterFunctions(const AbstractMetaCl
ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverters() const
{
ExtendedConverterData extConvs;
- const AbstractMetaClassList &classList = classes();
- for (const AbstractMetaClass *metaClass : classList) {
+ for (const AbstractMetaClass *metaClass : classes()) {
// Use only the classes for the current module.
if (!shouldGenerate(metaClass))
continue;
@@ -1578,8 +1613,7 @@ ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverter
// Get only the conversion operators that return a type from another module,
// that are value-types and were not removed in the type system.
const TypeEntry *convType = convOp->type()->typeEntry();
- if ((convType->codeGeneration() & TypeEntry::GenerateTargetLang)
- || !convType->isValue()
+ if (convType->generateCode() || !convType->isValue()
|| convOp->isModifiedRemoved())
continue;
extConvs[convType].append(convOp->ownerClass());
@@ -1645,17 +1679,24 @@ QString ShibokenGenerator::getCodeSnippets(const CodeSnipList &codeSnips,
}
return code;
}
-void ShibokenGenerator::processCodeSnip(QString &code, const AbstractMetaClass *context)
+
+void ShibokenGenerator::processClassCodeSnip(QString &code, const GeneratorContext &context)
{
- if (context) {
- // Replace template variable by the Python Type object
- // for the class context in which the variable is used.
- code.replace(QLatin1String("%PYTHONTYPEOBJECT"),
- cpythonTypeName(context) + QLatin1String("->type"));
- code.replace(QLatin1String("%TYPE"), wrapperName(context));
- code.replace(QLatin1String("%CPPTYPE"), context->name());
- }
+ auto metaClass = context.metaClass();
+ // Replace template variable by the Python Type object
+ // for the class context in which the variable is used.
+ code.replace(QLatin1String("%PYTHONTYPEOBJECT"),
+ cpythonTypeName(metaClass) + QLatin1String("->type"));
+ const QString className = context.useWrapper()
+ ? context.wrapperName() : metaClass->qualifiedCppName();
+ code.replace(QLatin1String("%TYPE"), className);
+ code.replace(QLatin1String("%CPPTYPE"), metaClass->name());
+ processCodeSnip(code);
+}
+
+void ShibokenGenerator::processCodeSnip(QString &code)
+{
// replace "toPython" converters
replaceConvertToPythonTypeSystemVariable(code);
@@ -1721,19 +1762,33 @@ ShibokenGenerator::ArgumentVarReplacementList ShibokenGenerator::getArgumentRepl
return argReplacements;
}
-void ShibokenGenerator::writeCodeSnips(QTextStream &s,
+void ShibokenGenerator::writeClassCodeSnips(QTextStream &s,
const CodeSnipList &codeSnips,
TypeSystem::CodeSnipPosition position,
TypeSystem::Language language,
- const AbstractMetaClass *context)
+ const GeneratorContext &context)
{
QString code = getCodeSnippets(codeSnips, position, language);
if (code.isEmpty())
return;
- processCodeSnip(code, context);
- s << INDENT << "// Begin code injection" << endl;
+ processClassCodeSnip(code, context);
+ s << INDENT << "// Begin code injection\n";
s << code;
- s << INDENT << "// End of code injection" << endl;
+ s << INDENT << "// End of code injection\n\n";
+}
+
+void ShibokenGenerator::writeCodeSnips(QTextStream &s,
+ const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language)
+{
+ QString code = getCodeSnippets(codeSnips, position, language);
+ if (code.isEmpty())
+ return;
+ processCodeSnip(code);
+ s << INDENT << "// Begin code injection\n";
+ s << code;
+ s << INDENT << "// End of code injection\n\n";
}
void ShibokenGenerator::writeCodeSnips(QTextStream &s,
@@ -1811,7 +1866,7 @@ void ShibokenGenerator::writeCodeSnips(QTextStream &s,
if (func->isConstructor()) {
code.replace(QLatin1String("%0."), QLatin1String("cptr->"));
code.replace(QLatin1String("%0"), QLatin1String("cptr"));
- } else if (func->type()) {
+ } else if (!func->isVoid()) {
QString returnValueOp = isPointerToWrapperType(func->type())
? QLatin1String("%1->") : QLatin1String("%1.");
if (ShibokenGenerator::isWrapperType(func->type()))
@@ -1958,9 +2013,9 @@ void ShibokenGenerator::writeCodeSnips(QTextStream &s,
replaceTemplateVariables(code, func);
processCodeSnip(code);
- s << INDENT << "// Begin code injection" << endl;
+ s << INDENT << "// Begin code injection\n";
s << code;
- s << INDENT << "// End of code injection" << endl;
+ s << INDENT << "// End of code injection\n\n";
}
// Returns true if the string is an expression,
@@ -2054,7 +2109,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
qFatal("%s", qPrintable(msgConversionTypesDiffer(varType, conversionSignature)));
c << getFullTypeName(conversionType) << ' ' << varName;
writeMinimalConstructorExpression(c, conversionType);
- c << ';' << endl;
+ c << ";\n";
Indentation indent(INDENT);
c << INDENT;
}
@@ -2119,13 +2174,17 @@ bool ShibokenGenerator::injectedCodeUsesPySelf(const AbstractMetaFunction *func)
return false;
}
-bool ShibokenGenerator::injectedCodeCallsCppFunction(const AbstractMetaFunction *func)
+bool ShibokenGenerator::injectedCodeCallsCppFunction(const GeneratorContext &context,
+ const AbstractMetaFunction *func)
{
QString funcCall = func->originalName() + QLatin1Char('(');
QString wrappedCtorCall;
if (func->isConstructor()) {
funcCall.prepend(QLatin1String("new "));
- wrappedCtorCall = QStringLiteral("new %1(").arg(wrapperName(func->ownerClass()));
+ const auto owner = func->ownerClass();
+ const QString className = context.useWrapper()
+ ? context.wrapperName() : owner->qualifiedCppName();
+ wrappedCtorCall = QLatin1String("new ") + className + QLatin1Char('(');
}
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode);
for (const CodeSnip &snip : qAsConst(snips)) {
@@ -2182,9 +2241,40 @@ bool ShibokenGenerator::injectedCodeUsesArgument(const AbstractMetaFunction *fun
return false;
}
-bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass *metaClass)
+bool ShibokenGenerator::useOverrideCaching(const AbstractMetaClass *metaClass)
{
- return getGeneratorClassInfo(metaClass).needsGetattroFunction;
+ return metaClass->isPolymorphic();
+}
+
+ShibokenGenerator::AttroCheck ShibokenGenerator::checkAttroFunctionNeeds(const AbstractMetaClass *metaClass) const
+{
+ AttroCheck result;
+ if (metaClass->typeEntry()->isSmartPointer()) {
+ result |= AttroCheckFlag::GetattroSmartPointer | AttroCheckFlag::SetattroSmartPointer;
+ } else {
+ if (getGeneratorClassInfo(metaClass).needsGetattroFunction)
+ result |= AttroCheckFlag::GetattroOverloads;
+ if (metaClass->queryFirstFunction(metaClass->functions(),
+ AbstractMetaClass::GetAttroFunction)) {
+ result |= AttroCheckFlag::GetattroUser;
+ }
+ if (usePySideExtensions() && metaClass->qualifiedCppName() == qObjectT())
+ result |= AttroCheckFlag::SetattroQObject;
+ if (useOverrideCaching(metaClass))
+ result |= AttroCheckFlag::SetattroMethodOverride;
+ if (metaClass->queryFirstFunction(metaClass->functions(),
+ AbstractMetaClass::SetAttroFunction)) {
+ result |= AttroCheckFlag::SetattroUser;
+ }
+ // PYSIDE-1255: If setattro is generated for a class inheriting
+ // QObject, the property code needs to be generated, too.
+ if ((result & AttroCheckFlag::SetattroMask) != 0
+ && !result.testFlag(AttroCheckFlag::SetattroQObject)
+ && metaClass->isQObject()) {
+ result |= AttroCheckFlag::SetattroQObject;
+ }
+ }
+ return result;
}
bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClass *metaClass)
@@ -2211,13 +2301,6 @@ bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClass *
return false;
}
-bool ShibokenGenerator::classNeedsSetattroFunction(const AbstractMetaClass *metaClass)
-{
- if (!metaClass)
- return false;
- return metaClass->typeEntry()->isSmartPointer();
-}
-
AbstractMetaFunctionList ShibokenGenerator::getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClass *metaClass)
{
AbstractMetaFunctionList methods;
@@ -2327,8 +2410,7 @@ AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromTypeEntry(const Ty
typeName.remove(0, 2);
if (m_metaTypeFromStringCache.contains(typeName))
return m_metaTypeFromStringCache.value(typeName);
- auto *metaType = new AbstractMetaType;
- metaType->setTypeEntry(typeEntry);
+ auto *metaType = new AbstractMetaType(typeEntry);
metaType->clearIndirections();
metaType->setReferenceType(NoReference);
metaType->setConstant(false);
@@ -2360,22 +2442,38 @@ static void dumpFunction(AbstractMetaFunctionList lst)
static bool isGroupable(const AbstractMetaFunction *func)
{
- if (func->isSignal() || func->isDestructor() || (func->isModifiedRemoved() && !func->isAbstract()))
+ switch (func->functionType()) {
+ case AbstractMetaFunction::DestructorFunction:
+ case AbstractMetaFunction::SignalFunction:
+ case AbstractMetaFunction::GetAttroFunction:
+ case AbstractMetaFunction::SetAttroFunction:
+ return false;
+ default:
+ break;
+ }
+ if (func->isModifiedRemoved() && !func->isAbstract())
return false;
// weird operator overloads
if (func->name() == QLatin1String("operator[]") || func->name() == QLatin1String("operator->")) // FIXME: what about cast operators?
- return false;;
+ return false;
return true;
}
-ShibokenGenerator::FunctionGroups ShibokenGenerator::getGlobalFunctionGroups() const
+static void insertIntoFunctionGroups(const AbstractMetaFunctionList &lst,
+ ShibokenGenerator::FunctionGroups *results)
{
- const AbstractMetaFunctionList &lst = globalFunctions();
- FunctionGroups results;
for (AbstractMetaFunction *func : lst) {
if (isGroupable(func))
- results[func->name()].append(func);
+ (*results)[func->name()].append(func);
}
+}
+
+ShibokenGenerator::FunctionGroups ShibokenGenerator::getGlobalFunctionGroups() const
+{
+ FunctionGroups results;
+ insertIntoFunctionGroups(globalFunctions(), &results);
+ for (auto nsp : invisibleTopNamespaces())
+ insertIntoFunctionGroups(nsp->functions(), &results);
return results;
}
@@ -2399,7 +2497,8 @@ ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroups(const Abs
ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroupsImpl(const AbstractMetaClass *scope)
{
- const AbstractMetaFunctionList &lst = scope->functions();
+ AbstractMetaFunctionList lst = scope->functions();
+ scope->getFunctionsFromInvisibleNamespacesToBeGenerated(&lst);
FunctionGroups results;
for (AbstractMetaFunction *func : lst) {
@@ -2484,7 +2583,9 @@ Generator::OptionDescriptions ShibokenGenerator::options() const
"(USE WITH CAUTION!)"))
<< qMakePair(QLatin1String(USE_ISNULL_AS_NB_NONZERO),
QLatin1String("If a class have an isNull() const method, it will be used to compute\n"
- "the value of boolean casts"));
+ "the value of boolean casts"))
+ << qMakePair(QLatin1String(WRAPPER_DIAGNOSTICS),
+ QLatin1String("Generate diagnostic code around wrappers"));
}
bool ShibokenGenerator::handleOption(const QString &key, const QString & /* value */)
@@ -2501,6 +2602,8 @@ bool ShibokenGenerator::handleOption(const QString &key, const QString & /* valu
return (m_useIsNullAsNbNonZero = true);
if (key == QLatin1String(AVOID_PROTECTED_HACK))
return (m_avoidProtectedHack = true);
+ if (key == QLatin1String(WRAPPER_DIAGNOSTICS))
+ return (m_wrapperDiagnostics = true);
return false;
}
@@ -2538,8 +2641,7 @@ bool ShibokenGenerator::doSetup()
const ContainerTypeEntryList &containerTypeList = containerTypes();
for (const ContainerTypeEntry *type : containerTypeList)
getCode(snips, type);
- const AbstractMetaClassList &classList = classes();
- for (const AbstractMetaClass *metaClass : classList)
+ for (const AbstractMetaClass *metaClass : classes())
getCode(snips, metaClass->typeEntry());
const TypeSystemTypeEntry *moduleEntry = TypeDatabase::instance()->defaultTypeSystemType();
@@ -2565,13 +2667,19 @@ void ShibokenGenerator::collectContainerTypesFromConverterMacros(const QString &
QString convMacro = toPythonMacro ? QLatin1String("%CONVERTTOPYTHON[") : QLatin1String("%CONVERTTOCPP[");
int offset = toPythonMacro ? sizeof("%CONVERTTOPYTHON") : sizeof("%CONVERTTOCPP");
int start = 0;
+ QString errorMessage;
while ((start = code.indexOf(convMacro, start)) != -1) {
int end = code.indexOf(QLatin1Char(']'), start);
start += offset;
if (code.at(start) != QLatin1Char('%')) {
QString typeString = code.mid(start, end - start);
- AbstractMetaType *type = buildAbstractMetaTypeFromString(typeString);
- addInstantiatedContainersAndSmartPointers(type, type->originalTypeDescription());
+ if (AbstractMetaType *type =
+ buildAbstractMetaTypeFromString(typeString, &errorMessage)) {
+ addInstantiatedContainersAndSmartPointers(type, type->originalTypeDescription());
+ } else {
+ qFatal("%s: Cannot translate type \"%s\": %s", __FUNCTION__,
+ qPrintable(typeString), qPrintable(errorMessage));
+ }
}
start = end;
}
@@ -2632,8 +2740,7 @@ QString ShibokenGenerator::convertersVariableName(const QString &moduleName) con
static QString processInstantiationsVariableName(const AbstractMetaType *type)
{
QString res = QLatin1Char('_') + _fixedCppTypeName(type->typeEntry()->qualifiedCppName()).toUpper();
- const AbstractMetaTypeList &instantiations = type->instantiations();
- for (const AbstractMetaType *instantiation : instantiations) {
+ for (const auto *instantiation : type->instantiations()) {
res += instantiation->isContainer()
? processInstantiationsVariableName(instantiation)
: QLatin1Char('_') + _fixedCppTypeName(instantiation->cppSignature()).toUpper();
@@ -2648,7 +2755,8 @@ static void appendIndexSuffix(QString *s)
s->append(QStringLiteral("IDX"));
}
-QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass *metaClass, bool alternativeTemplateName)
+QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass *metaClass,
+ bool alternativeTemplateName) const
{
if (alternativeTemplateName) {
const AbstractMetaClass *templateBaseClass = metaClass->templateBaseClass();
@@ -2656,15 +2764,14 @@ QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass *met
return QString();
QString result = QLatin1String("SBK_")
+ _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper();
- const AbstractMetaTypeList &templateBaseClassInstantiations = metaClass->templateBaseClassInstantiations();
- for (const AbstractMetaType *instantiation : templateBaseClassInstantiations)
+ for (const auto *instantiation : metaClass->templateBaseClassInstantiations())
result += processInstantiationsVariableName(instantiation);
appendIndexSuffix(&result);
return result;
}
return getTypeIndexVariableName(metaClass->typeEntry());
}
-QString ShibokenGenerator::getTypeIndexVariableName(const TypeEntry *type)
+QString ShibokenGenerator::getTypeIndexVariableName(const TypeEntry *type) const
{
if (type->isCppPrimitive()) {
const auto *trueType = static_cast<const PrimitiveTypeEntry *>(type);
@@ -2682,7 +2789,7 @@ QString ShibokenGenerator::getTypeIndexVariableName(const TypeEntry *type)
appendIndexSuffix(&result);
return result;
}
-QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaType *type)
+QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaType *type) const
{
QString result = QLatin1String("SBK");
if (type->typeEntry()->isContainer())
@@ -2743,7 +2850,7 @@ void ShibokenGenerator::writeMinimalConstructorExpression(QTextStream &s, const
} else {
const QString message = msgCouldNotFindMinimalConstructor(QLatin1String(__FUNCTION__), type->qualifiedCppName());
qCWarning(lcShiboken()).noquote() << message;
- s << ";\n#error " << message << endl;
+ s << ";\n#error " << message << Qt::endl;
}
}