diff options
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
26 files changed, 1325 insertions, 1096 deletions
diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt index cbe3310a4..043f3830d 100644 --- a/sources/shiboken2/ApiExtractor/CMakeLists.txt +++ b/sources/shiboken2/ApiExtractor/CMakeLists.txt @@ -8,6 +8,7 @@ set(CMAKE_AUTOMOC ON) set(apiextractor_SRC apiextractor.cpp abstractmetabuilder.cpp +abstractmetatype.cpp abstractmetalang.cpp fileout.cpp graph.cpp diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 75fd6af5b..1f126ba57 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -225,12 +225,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentMod AbstractMetaClass *currentClass) { AbstractMetaClass *returned = nullptr; - AbstractMetaType *type = translateType(argument->type(), currentClass); - if (type && type->typeEntry() && type->typeEntry()->isComplex()) { - const TypeEntry *entry = type->typeEntry(); + AbstractMetaType type = translateType(argument->type(), currentClass); + if (type && type.typeEntry() && type.typeEntry()->isComplex()) { + const TypeEntry *entry = type.typeEntry(); returned = AbstractMetaClass::findClass(m_metaClasses, entry); } - delete type; return returned; } @@ -294,8 +293,8 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte baseoperandClass = argumentToClass(arguments.at(1), currentClass); firstArgumentIsSelf = false; } else { - AbstractMetaType *type = translateType(item->type(), currentClass); - const TypeEntry *retType = type ? type->typeEntry() : nullptr; + AbstractMetaType type = translateType(item->type(), currentClass); + const TypeEntry *retType = type ? type.typeEntry() : nullptr; AbstractMetaClass *otherArgClass = argumentToClass(arguments.at(1), currentClass); if (otherArgClass && retType && (retType->isValue() || retType->isObject()) @@ -304,7 +303,6 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte baseoperandClass = AbstractMetaClass::findClass(m_metaClasses, retType); firstArgumentIsSelf = false; } - delete type; } if (baseoperandClass) { @@ -314,7 +312,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte AbstractMetaArgumentList arguments = metaFunction->arguments(); if (firstArgumentIsSelf || unaryOperator) { AbstractMetaArgument *first = arguments.takeFirst(); - if (!unaryOperator && first->type()->indirections()) + if (!unaryOperator && first->type().indirections()) metaFunction->setPointerOperator(true); delete first; metaFunction->setArguments(arguments); @@ -325,7 +323,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte // All operator overloads that operate over a class are already // being added as member functions of that class by the API Extractor. AbstractMetaArgument *last = arguments.takeLast(); - if (last->type()->indirections()) + if (last->type().indirections()) metaFunction->setPointerOperator(true); delete last; @@ -1005,11 +1003,11 @@ void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs() // mapping the instantiations to the typedef entry. // Synthesize a AbstractMetaType which would be found by an // instantiation. - auto sourceType = new AbstractMetaType; - sourceType->setTypeEntry(metaClass->templateBaseClass()->typeEntry()); - sourceType->setInstantiations(metaClass->templateBaseClassInstantiations()); - sourceType->decideUsagePattern(); - m_typeSystemTypeDefs.append({AbstractMetaTypeCPtr(sourceType), metaClass}); + AbstractMetaType sourceType; + sourceType.setTypeEntry(metaClass->templateBaseClass()->typeEntry()); + sourceType.setInstantiations(metaClass->templateBaseClassInstantiations()); + sourceType.decideUsagePattern(); + m_typeSystemTypeDefs.append({sourceType, metaClass}); } } } @@ -1200,7 +1198,7 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModel metaField->setEnclosingClass(cls); TypeInfo fieldType = field->type(); - AbstractMetaType *metaType = translateType(fieldType, cls); + AbstractMetaType metaType = translateType(fieldType, cls); if (!metaType) { const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(colonColon()); @@ -1278,9 +1276,9 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF if (!retType) return; - auto metaType = new AbstractMetaType(retType); - metaType->decideUsagePattern(); - metaFunction->replaceType(metaType); + AbstractMetaType metaType(retType); + metaType.decideUsagePattern(); + metaFunction->setType(metaType); } AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem, @@ -1320,7 +1318,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, QPropertySpec *read = nullptr; if (!metaFunction->isSignal() && (read = metaClass->propertySpecForRead(metaFunction->name()))) { // Property reader must be in the form "<type> name()" - if (read->typeEntry() == metaFunction->type()->typeEntry() + if (read->typeEntry() == metaFunction->type().typeEntry() && metaFunction->arguments().isEmpty()) { *metaFunction += AbstractMetaAttributes::PropertyReader; metaFunction->setPropertySpec(read); @@ -1330,7 +1328,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, // Make sure the function was created with all arguments; some argument can be // missing during the parsing because of errors in the typesystem. if (metaFunction->isVoid() && metaFunction->arguments().size() == 1 - && (write->typeEntry() == metaFunction->arguments().at(0)->type()->typeEntry())) { + && (write->typeEntry() == metaFunction->arguments().at(0)->type().typeEntry())) { *metaFunction += AbstractMetaAttributes::PropertyWriter; metaFunction->setPropertySpec(write); } @@ -1536,7 +1534,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu { QString errorMessage; - AbstractMetaType *returnType = translateType(addedFunc->returnType(), &errorMessage); + AbstractMetaType returnType = translateType(addedFunc->returnType(), &errorMessage); if (!returnType) { qCWarning(lcShiboken, "%s", qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(), @@ -1554,7 +1552,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu for (int i = 0; i < args.count(); ++i) { const AddedFunction::TypeInfo& typeInfo = args.at(i).typeInfo; auto *metaArg = new AbstractMetaArgument; - AbstractMetaType *type = translateType(typeInfo, &errorMessage); + AbstractMetaType type = translateType(typeInfo, &errorMessage); if (Q_UNLIKELY(!type)) { qCWarning(lcShiboken, "%s", qPrintable(msgAddedFunctionInvalidArgType(addedFunc->name(), @@ -1563,7 +1561,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu delete metaFunction; return nullptr; } - type->decideUsagePattern(); + type.decideUsagePattern(); if (!args.at(i).name.isEmpty()) metaArg->setName(args.at(i).name); metaArg->setType(type); @@ -1579,7 +1577,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu qCWarning(lcShiboken) << "An operator overload need to have 0, 1 or 2 arguments if it's reverse."; } else if (metaArguments.size() == 2) { // Check if it's a reverse operator - if (metaArguments[1]->type()->typeEntry() == metaClass->typeEntry()) { + if (metaArguments[1]->type().typeEntry() == metaClass->typeEntry()) { metaFunction->setReverseOperator(true); // we need to call these two function to cache the old signature (with two args) // we do this buggy behaviour to comply with the original apiextractor buggy behaviour. @@ -1615,7 +1613,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu if (metaFunction->name() == metaClass->name()) { metaFunction->setFunctionType(AbstractMetaFunction::ConstructorFunction); if (fargs.size() == 1) { - const TypeEntry *te = fargs.constFirst()->type()->typeEntry(); + const TypeEntry *te = fargs.constFirst()->type().typeEntry(); if (te->isCustom()) metaFunction->setExplicit(true); if (te->name() == metaFunction->name()) @@ -1718,10 +1716,12 @@ static bool applyArrayArgumentModifications(const FunctionModificationList &func QLatin1String("Index out of range.")); return false; } - if (!func->arguments().at(i)->type()->applyArrayModification(errorMessage)) { + auto t = func->arguments().at(i)->type(); + if (!t.applyArrayModification(errorMessage)) { *errorMessage = msgCannotSetArrayUsage(func->minimalSignature(), i, *errorMessage); return false; } + func->arguments()[i]->setType(t); } } } @@ -1839,7 +1839,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return nullptr; } - AbstractMetaType *type = translateType(returnType, currentClass, {}, &errorMessage); + AbstractMetaType type = translateType(returnType, currentClass, {}, &errorMessage); if (!type) { const QString reason = msgUnmatchedReturnType(functionItem, errorMessage); qCWarning(lcShiboken, "%s", @@ -1874,7 +1874,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return nullptr; } - AbstractMetaType *metaType = translateType(arg->type(), currentClass, {}, &errorMessage); + AbstractMetaType metaType = translateType(arg->type(), currentClass, {}, &errorMessage); if (!metaType) { // If an invalid argument has a default value, simply remove it // unless the function is virtual (since the override in the @@ -1886,7 +1886,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio } break; } - Q_ASSERT(metaType == nullptr); + Q_ASSERT(!metaType); const QString reason = msgUnmatchedParameterType(arg, i, errorMessage); qCWarning(lcShiboken, "%s", qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason))); @@ -1899,13 +1899,13 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio // Add view substitution for simple view types of function arguments // std::string_view -> std::string for foo(std::string_view) - auto viewOnTypeEntry = metaType->typeEntry()->viewOn(); - if (viewOnTypeEntry != nullptr && metaType->indirections() == 0 - && metaType->arrayElementType() == nullptr - && !metaType->hasInstantiations()) { - auto viewOn = new AbstractMetaType(*metaType); - viewOn->setTypeEntry(viewOnTypeEntry); - metaType->setViewOn(viewOn); + auto viewOnTypeEntry = metaType.typeEntry()->viewOn(); + if (viewOnTypeEntry != nullptr && metaType.indirections() == 0 + && metaType.arrayElementType() == nullptr + && !metaType.hasInstantiations()) { + auto viewOn = metaType; + viewOn.setTypeEntry(viewOnTypeEntry); + metaType.setViewOn(viewOn); } auto *metaArgument = new AbstractMetaArgument; @@ -1964,15 +1964,15 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio // Determine class special functions if (currentClass && metaFunction->arguments().size() == 1) { - const AbstractMetaType *argType = metaFunction->arguments().constFirst()->type(); - if (argType->typeEntry() == currentClass->typeEntry() && argType->indirections() == 0) { + const AbstractMetaType &argType = metaFunction->arguments().constFirst()->type(); + if (argType.typeEntry() == currentClass->typeEntry() && argType.indirections() == 0) { if (metaFunction->name() == QLatin1String("operator=")) { - switch (argType->referenceType()) { + switch (argType.referenceType()) { case NoReference: metaFunction->setFunctionType(AbstractMetaFunction::AssignmentOperatorFunction); break; case LValueReference: - if (argType->isConstant()) + if (argType.isConstant()) metaFunction->setFunctionType(AbstractMetaFunction::AssignmentOperatorFunction); break; case RValueReference: @@ -1985,7 +1985,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return metaFunction; } -AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo, +AbstractMetaType AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo, QString *errorMessage) { Q_ASSERT(!typeInfo.name.isEmpty()); @@ -2007,7 +2007,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: QStringList parsedType = parseTemplateType(typeInfo.name); if (parsedType.isEmpty()) { *errorMessage = QStringLiteral("Template type parsing failed for '%1'").arg(typeInfo.name); - return nullptr; + return {}; } const QString name = parsedType.takeFirst(); templateArgs = parsedType; @@ -2040,25 +2040,25 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: for (const QString& candidate : qAsConst(candidates)) str << " " << candidate << '\n'; } - return nullptr; + return {}; } // These are only implicit and should not appear in code... - auto *metaType = new AbstractMetaType(type); - metaType->setIndirections(typeInfo.indirections); + AbstractMetaType metaType(type); + metaType.setIndirections(typeInfo.indirections); if (typeInfo.isReference) - metaType->setReferenceType(LValueReference); - metaType->setConstant(typeInfo.isConstant); + metaType.setReferenceType(LValueReference); + metaType.setConstant(typeInfo.isConstant); if (isTemplate) { for (const QString& templateArg : qAsConst(templateArgs)) { - AbstractMetaType *metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage); + AbstractMetaType metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage); if (!metaArgType) - return nullptr; - metaType->addInstantiation(metaArgType); + return {}; + metaType.addInstantiation(metaArgType); } - metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); + metaType.setTypeUsagePattern(AbstractMetaType::ContainerPattern); } else { - metaType->decideUsagePattern(); + metaType.decideUsagePattern(); } return metaType; @@ -2124,10 +2124,10 @@ TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualified // Reverse lookup of AbstractMetaType representing a template specialization // found during traversing function arguments to its type system typedef'ed // class. -const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(const AbstractMetaType *t) const +const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(const AbstractMetaType &t) const { - if (t->hasInstantiations()) { - auto pred = [t](const TypeClassEntry &e) { return e.type->compare(*t); }; + if (t.hasInstantiations()) { + auto pred = [t](const TypeClassEntry &e) { return e.type.equals(t); }; auto it = std::find_if(m_typeSystemTypeDefs.cbegin(), m_typeSystemTypeDefs.cend(), pred); if (it != m_typeSystemTypeDefs.cend()) return it->klass; @@ -2135,7 +2135,7 @@ const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(co return nullptr; } -AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei, +AbstractMetaType AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei, AbstractMetaClass *currentClass, TranslateTypeFlags flags, QString *errorMessage) @@ -2149,7 +2149,7 @@ static bool isNumber(const QString &s) [](QChar c) { return c.isDigit(); }); } -AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei, +AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei, AbstractMetaClass *currentClass, AbstractMetaBuilderPrivate *d, TranslateTypeFlags flags, @@ -2162,7 +2162,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo // type system const bool resolveType = !flags.testFlag(AbstractMetaBuilder::DontResolveType); if (resolveType) { - AbstractMetaType *resolved = + AbstractMetaType resolved = translateTypeStatic(_typei, currentClass, d, flags | AbstractMetaBuilder::DontResolveType, errorMessageIn); @@ -2189,7 +2189,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo if (typeInfo.isFunctionPointer()) { if (errorMessageIn) *errorMessageIn = msgUnableToTranslateType(_typei, QLatin1String("Unsupported function pointer.")); - return nullptr; + return {}; } QString errorMessage; @@ -2225,18 +2225,18 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo newInfo.setReferenceType(typeInfo.referenceType()); newInfo.setVolatile(typeInfo.isVolatile()); - AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage); + AbstractMetaType elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage); if (!elementType) { if (errorMessageIn) { errorMessage.prepend(QLatin1String("Unable to translate array element: ")); *errorMessageIn = msgUnableToTranslateType(_typei, errorMessage); } - return nullptr; + return {}; } for (int i = typeInfo.arrayElements().size() - 1; i >= 0; --i) { - auto *arrayType = new AbstractMetaType; - arrayType->setArrayElementType(elementType); + AbstractMetaType arrayType; + arrayType.setArrayElementType(elementType); const QString &arrayElement = typeInfo.arrayElements().at(i); if (!arrayElement.isEmpty()) { bool _ok; @@ -2244,12 +2244,12 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo ? d->findOutValueFromString(arrayElement, _ok) : arrayElement.toLongLong(&_ok, 0); if (_ok) - arrayType->setArrayElementCount(int(elems)); + arrayType.setArrayElementCount(int(elems)); } - auto elementTypeEntry = elementType->typeEntry(); - arrayType->setTypeEntry(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(), - elementTypeEntry->parent())); - arrayType->decideUsagePattern(); + auto elementTypeEntry = elementType.typeEntry(); + arrayType.setTypeEntry(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(), + elementTypeEntry->parent())); + arrayType.decideUsagePattern(); elementType = arrayType; } @@ -2264,7 +2264,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo *errorMessageIn = errorMessage; else qCWarning(lcShiboken,"%s", qPrintable(errorMessage)); - return nullptr; + return {}; } QString qualifiedName = qualifierList.join(colonColon()); @@ -2282,23 +2282,23 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo *errorMessageIn = msgUnableToTranslateType(_typei, msgCannotFindTypeEntry(qualifiedName)); } - return nullptr; + return {}; } const TypeEntry *type = types.constFirst(); const TypeEntry::Type typeEntryType = type->type(); - QScopedPointer<AbstractMetaType> metaType(new AbstractMetaType); - metaType->setIndirectionsV(typeInfo.indirectionsV()); - metaType->setReferenceType(typeInfo.referenceType()); - metaType->setConstant(typeInfo.isConstant()); - metaType->setVolatile(typeInfo.isVolatile()); - metaType->setOriginalTypeDescription(_typei.toString()); + AbstractMetaType metaType; + metaType.setIndirectionsV(typeInfo.indirectionsV()); + metaType.setReferenceType(typeInfo.referenceType()); + metaType.setConstant(typeInfo.isConstant()); + metaType.setVolatile(typeInfo.isVolatile()); + metaType.setOriginalTypeDescription(_typei.toString()); const auto &templateArguments = typeInfo.instantiations(); for (int t = 0, size = templateArguments.size(); t < size; ++t) { const TypeInfo &ti = templateArguments.at(t); - AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage); + AbstractMetaType targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage); // For non-type template parameters, create a dummy type entry on the fly // as is done for classes. if (!targType) { @@ -2311,10 +2311,10 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo if (!targType) { if (errorMessageIn) *errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage); - return nullptr; + return {}; } - metaType->addInstantiation(targType, true); + metaType.addInstantiation(targType); } if (types.size() > 1) { @@ -2324,7 +2324,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo if (!sameType) { if (errorMessageIn) *errorMessageIn = msgAmbiguousVaryingTypesFound(qualifiedName, types); - return nullptr; + return {}; } // Ambiguous primitive/smart pointer types are possible (when // including type systems). @@ -2332,18 +2332,18 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo && typeEntryType != TypeEntry::SmartPointerType) { if (errorMessageIn) *errorMessageIn = msgAmbiguousTypesFound(qualifiedName, types); - return nullptr; + return {}; } } if (typeEntryType == TypeEntry::SmartPointerType) { // Find a matching instantiation - if (metaType->instantiations().size() != 1) { + if (metaType.instantiations().size() != 1) { if (errorMessageIn) *errorMessageIn = msgInvalidSmartPointerType(_typei); - return nullptr; + return {}; } - auto instantiationType = metaType->instantiations().constFirst()->typeEntry(); + auto instantiationType = metaType.instantiations().constFirst().typeEntry(); if (instantiationType->type() == TypeEntry::TemplateArgumentType) { // Member functions of the template itself, SharedPtr(const SharedPtr &) type = instantiationType; @@ -2356,47 +2356,47 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo if (it == types.cend()) { if (errorMessageIn) *errorMessageIn = msgCannotFindSmartPointerInstantion(_typei); - return nullptr; + return {}; } type =*it; } } - metaType->setTypeEntry(type); + metaType.setTypeEntry(type); // The usage pattern *must* be decided *after* the possible template // instantiations have been determined, or else the absence of // such instantiations will break the caching scheme of // AbstractMetaType::cppSignature(). - metaType->decideUsagePattern(); + metaType.decideUsagePattern(); if (d) { // Reverse lookup of type system typedefs. Replace by class. - if (auto klass = d->resolveTypeSystemTypeDef(metaType.data())) { - metaType.reset(new AbstractMetaType); - metaType->setTypeEntry(klass->typeEntry()); - metaType->decideUsagePattern(); + if (auto klass = d->resolveTypeSystemTypeDef(metaType)) { + metaType = AbstractMetaType{}; + metaType.setTypeEntry(klass->typeEntry()); + metaType.decideUsagePattern(); } } - Q_ASSERT(metaType->typeUsagePattern() != AbstractMetaType::InvalidPattern); - return metaType.take(); + Q_ASSERT(metaType.typeUsagePattern() != AbstractMetaType::InvalidPattern); + return metaType; } -AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei, - AbstractMetaClass *currentClass, - TranslateTypeFlags flags, - QString *errorMessage) +AbstractMetaType AbstractMetaBuilder::translateType(const TypeInfo &_typei, + AbstractMetaClass *currentClass, + TranslateTypeFlags flags, + QString *errorMessage) { return AbstractMetaBuilderPrivate::translateTypeStatic(_typei, currentClass, nullptr, flags, errorMessage); } -AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t, - AbstractMetaClass *currentClass, - TranslateTypeFlags flags, - QString *errorMessageIn) +AbstractMetaType AbstractMetaBuilder::translateType(const QString &t, + AbstractMetaClass *currentClass, + TranslateTypeFlags flags, + QString *errorMessageIn) { QString errorMessage; TypeInfo typeInfo = TypeParser::parse(t, &errorMessage); @@ -2406,7 +2406,7 @@ AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t, *errorMessageIn = errorMessage; else qCWarning(lcShiboken, "%s", qPrintable(errorMessage)); - return nullptr; + return {}; } return translateType(typeInfo, currentClass, flags, errorMessageIn); } @@ -2449,7 +2449,7 @@ qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringV } QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &item, - AbstractMetaType *type, + const AbstractMetaType &type, AbstractMetaFunction *fnc, AbstractMetaClass *implementingClass, int /* argumentIndex */) @@ -2459,8 +2459,8 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite return expr; if (type) { - if (type->isPrimitive()) { - if (type->name() == QLatin1String("boolean")) { + if (type.isPrimitive()) { + if (type.name() == QLatin1String("boolean")) { if (expr != QLatin1String("false") && expr != QLatin1String("true")) { bool ok = false; int number = expr.toInt(&ok); @@ -2474,7 +2474,7 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite // translation untill all namespaces are completly // processed. This is done in figureOutEnumValues() } - } else if (type->isFlags() || type->isEnum()) { + } else if (type.isFlags() || type.isEnum()) { bool isNumber; expr.toInt(&isNumber); if (!isNumber && expr.indexOf(colonColon()) < 0) { @@ -2482,14 +2482,14 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite // from other contexts beside its owner class hierarchy static const QRegularExpression typeRegEx(QStringLiteral("[^<]*[<]([^:]*::).*")); Q_ASSERT(typeRegEx.isValid()); - const QRegularExpressionMatch match = typeRegEx.match(type->minimalSignature()); + const QRegularExpressionMatch match = typeRegEx.match(type.minimalSignature()); if (match.hasMatch()) expr.prepend(match.captured(1)); } - } else if (type->isContainer() && expr.contains(QLatin1Char('<'))) { + } else if (type.isContainer() && expr.contains(QLatin1Char('<'))) { static const QRegularExpression typeRegEx(QStringLiteral("[^<]*<(.*)>")); Q_ASSERT(typeRegEx.isValid()); - const QRegularExpressionMatch typeMatch = typeRegEx.match(type->minimalSignature()); + const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature()); static const QRegularExpression defaultRegEx(QLatin1String("([^<]*<).*(>[^>]*)")); Q_ASSERT(defaultRegEx.isValid()); const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr); @@ -2511,7 +2511,7 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite // use of namespaces/scopes from the type string. static const QRegularExpression typeRegEx(QLatin1String("^(?:const[\\s]+|)([\\w:]*::|)([A-Za-z_]\\w*)\\s*[&\\*]?$")); Q_ASSERT(typeRegEx.isValid()); - const QRegularExpressionMatch typeMatch = typeRegEx.match(type->minimalSignature()); + const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature()); QString typeNamespace = typeMatch.hasMatch() ? typeMatch.captured(1) : QString(); QString typeCtorName = typeMatch.hasMatch() ? typeMatch.captured(2) : QString(); @@ -2621,48 +2621,47 @@ bool AbstractMetaBuilderPrivate::ancestorHasPrivateCopyConstructor(const Abstrac return false; } -AbstractMetaType * - AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractMetaTypeList &templateTypes, - const AbstractMetaType *metaType) +AbstractMetaType AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractMetaTypeList &templateTypes, + const AbstractMetaType &metaType) { Q_ASSERT(metaType); - QScopedPointer<AbstractMetaType> returned(metaType->copy()); + auto returned = metaType; - if (!metaType->typeEntry()->isTemplateArgument() && !metaType->hasInstantiations()) - return returned.take(); + if (!metaType.typeEntry()->isTemplateArgument() && !metaType.hasInstantiations()) + return returned; - returned->setOriginalTemplateType(metaType); + returned.setOriginalTemplateType(metaType); - if (returned->typeEntry()->isTemplateArgument()) { - const auto *tae = static_cast<const TemplateArgumentEntry*>(returned->typeEntry()); + if (returned.typeEntry()->isTemplateArgument()) { + const auto *tae = static_cast<const TemplateArgumentEntry*>(returned.typeEntry()); // If the template is intantiated with void we special case this as rejecting the functions that use this // parameter from the instantiation. - const AbstractMetaType *templateType = templateTypes.value(tae->ordinal()); - if (!templateType || templateType->typeEntry()->isVoid()) - return nullptr; + const AbstractMetaType &templateType = templateTypes.value(tae->ordinal()); + if (!templateType || templateType.typeEntry()->isVoid()) + return {}; - AbstractMetaType* t = returned->copy(); - t->setTypeEntry(templateType->typeEntry()); - t->setIndirections(templateType->indirections() + t->indirections() ? 1 : 0); - t->decideUsagePattern(); + AbstractMetaType t = returned; + t.setTypeEntry(templateType.typeEntry()); + t.setIndirections(templateType.indirections() + t.indirections() ? 1 : 0); + t.decideUsagePattern(); return inheritTemplateType(templateTypes, t); } - if (returned->hasInstantiations()) { - AbstractMetaTypeList instantiations = returned->instantiations(); + if (returned.hasInstantiations()) { + AbstractMetaTypeList instantiations = returned.instantiations(); for (int i = 0; i < instantiations.count(); ++i) { instantiations[i] = inheritTemplateType(templateTypes, instantiations.at(i)); if (!instantiations.at(i)) - return nullptr; + return {}; } - returned->setInstantiations(instantiations, true); + returned.setInstantiations(instantiations); } - return returned.take(); + return returned; } bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, @@ -2702,11 +2701,11 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, } if (t) { - auto *temporaryType = new AbstractMetaType(t); - temporaryType->setConstant(i.isConstant()); - temporaryType->setReferenceType(i.referenceType()); - temporaryType->setIndirectionsV(i.indirectionsV()); - temporaryType->decideUsagePattern(); + AbstractMetaType temporaryType(t); + temporaryType.setConstant(i.isConstant()); + temporaryType.setReferenceType(i.referenceType()); + temporaryType.setIndirectionsV(i.indirectionsV()); + temporaryType.decideUsagePattern(); templateTypes << temporaryType; } else { qCWarning(lcShiboken).noquote().nospace() @@ -2751,19 +2750,19 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub f->setArguments(AbstractMetaArgumentList()); if (!function->isVoid()) { - AbstractMetaType *returnType = inheritTemplateType(templateTypes, function->type()); + AbstractMetaType returnType = inheritTemplateType(templateTypes, function->type()); if (!returnType) continue; - f->replaceType(returnType); + f->setType(returnType); } const AbstractMetaArgumentList &arguments = function->arguments(); for (AbstractMetaArgument *argument : arguments) { - AbstractMetaType *argType = inheritTemplateType(templateTypes, argument->type()); + AbstractMetaType argType = inheritTemplateType(templateTypes, argument->type()); if (!argType) break; AbstractMetaArgument *arg = argument->copy(); - arg->replaceType(argType); + arg->setType(argType); f->addArgument(arg); } @@ -2833,10 +2832,10 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub QScopedPointer<AbstractMetaField> f(field->copy()); f->setEnclosingClass(subclass); - AbstractMetaType *fieldType = inheritTemplateType(templateTypes, field->type()); + AbstractMetaType fieldType = inheritTemplateType(templateTypes, field->type()); if (!fieldType) continue; - f->replaceType(fieldType); + f->setType(fieldType); subclass->addField(f.take()); } } @@ -2927,7 +2926,7 @@ void AbstractMetaBuilderPrivate::setupExternalConversion(AbstractMetaClass *cls) for (AbstractMetaFunction *func : convOps) { if (func->isModifiedRemoved()) continue; - AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, func->type()->typeEntry()); + AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, func->type().typeEntry()); if (!metaClass) continue; metaClass->addExternalConversionOperator(func); @@ -3084,8 +3083,8 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const // Check methods with default args: If a class is instantiated by value, // ("QString s = QString()"), add a dependency. if (!arg->originalDefaultValueExpression().isEmpty() - && arg->type()->isValue()) { - addClassDependency(arg->type()->typeEntry(), clazz, classIndex, + && arg->type().isValue()) { + addClassDependency(arg->type().typeEntry(), clazz, classIndex, map, &graph); } } @@ -3093,7 +3092,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const // Member fields need to be initialized const AbstractMetaFieldList &fields = clazz->fields(); for (AbstractMetaField *field : fields) { - addClassDependency(field->type()->typeEntry(), clazz, classIndex, + addClassDependency(field->type().typeEntry(), clazz, classIndex, map, &graph); } } diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h index d2dc080a2..09c49b4fb 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h @@ -97,14 +97,14 @@ public: }; Q_DECLARE_FLAGS(TranslateTypeFlags, TranslateTypeFlag); - static AbstractMetaType *translateType(const TypeInfo &_typei, - AbstractMetaClass *currentClass = nullptr, - TranslateTypeFlags flags = {}, - QString *errorMessage = nullptr); - static AbstractMetaType *translateType(const QString &t, - AbstractMetaClass *currentClass = nullptr, - TranslateTypeFlags flags = {}, - QString *errorMessage = nullptr); + static AbstractMetaType translateType(const TypeInfo &_typei, + AbstractMetaClass *currentClass = nullptr, + TranslateTypeFlags flags = {}, + QString *errorMessage = nullptr); + static AbstractMetaType translateType(const QString &t, + AbstractMetaClass *currentClass = nullptr, + TranslateTypeFlags flags = {}, + QString *errorMessage = nullptr); #ifndef QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index 846895089..1854b8b56 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -46,7 +46,7 @@ class AbstractMetaBuilderPrivate public: struct TypeClassEntry { - AbstractMetaTypeCPtr type; + AbstractMetaType type; const AbstractMetaClass *klass; }; @@ -139,20 +139,20 @@ public: void setupFunctionDefaults(AbstractMetaFunction *metaFunction, AbstractMetaClass *metaClass); - QString fixDefaultValue(const ArgumentModelItem &item, AbstractMetaType *type, + QString fixDefaultValue(const ArgumentModelItem &item, const AbstractMetaType &type, AbstractMetaFunction *fnc, AbstractMetaClass *, int argumentIndex); - AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo, - QString *errorMessage); - AbstractMetaType *translateType(const TypeInfo &type, - AbstractMetaClass *currentClass, - TranslateTypeFlags flags = {}, - QString *errorMessage = nullptr); - static AbstractMetaType *translateTypeStatic(const TypeInfo &type, - AbstractMetaClass *current, - AbstractMetaBuilderPrivate *d = nullptr, - TranslateTypeFlags flags = {}, - QString *errorMessageIn = nullptr); + AbstractMetaType translateType(const AddedFunction::TypeInfo &typeInfo, + QString *errorMessage); + AbstractMetaType translateType(const TypeInfo &type, + AbstractMetaClass *currentClass, + TranslateTypeFlags flags = {}, + QString *errorMessage = nullptr); + static AbstractMetaType translateTypeStatic(const TypeInfo &type, + AbstractMetaClass *current, + AbstractMetaBuilderPrivate *d = nullptr, + TranslateTypeFlags flags = {}, + QString *errorMessageIn = nullptr); static TypeEntries findTypeEntries(const QString &qualifiedName, const QString &name, AbstractMetaClass *currentClass = nullptr, AbstractMetaBuilderPrivate *d = nullptr); @@ -169,8 +169,8 @@ public: const AbstractMetaClass *templateClass, const TypeInfo &info); void inheritTemplateFunctions(AbstractMetaClass *subclass); - AbstractMetaType *inheritTemplateType(const AbstractMetaTypeList &templateTypes, - const AbstractMetaType *metaType); + AbstractMetaType inheritTemplateType(const AbstractMetaTypeList &templateTypes, + const AbstractMetaType &metaType); bool isQObject(const FileModelItem &dom, const QString &qualifiedName); bool isEnum(const FileModelItem &dom, const QStringList &qualifiedName); @@ -181,7 +181,7 @@ public: void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods); void fillAddedFunctions(AbstractMetaClass *metaClass); - const AbstractMetaClass *resolveTypeSystemTypeDef(const AbstractMetaType *t) const; + const AbstractMetaClass *resolveTypeSystemTypeDef(const AbstractMetaType &t) const; AbstractMetaBuilder *q; AbstractMetaClassList m_metaClasses; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index c0b6fa481..4ffe24cb3 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -41,6 +41,7 @@ #endif #include <QtCore/QRegularExpression> +#include <QtCore/QSharedData> #include <QtCore/QStack> #include <algorithm> @@ -137,16 +138,13 @@ void Documentation::setFormat(Documentation::Format f) AbstractMetaVariable::AbstractMetaVariable() = default; -AbstractMetaVariable::~AbstractMetaVariable() -{ - delete m_type; -} +AbstractMetaVariable::~AbstractMetaVariable() = default; void AbstractMetaVariable::assignMetaVariable(const AbstractMetaVariable &other) { m_originalName = other.m_originalName; m_name = other.m_name; - m_type = other.m_type->copy(); + m_type = other.m_type; m_hasName = other.m_hasName; m_doc = other.m_doc; } @@ -159,7 +157,7 @@ QDebug operator<<(QDebug d, const AbstractMetaVariable *av) d.nospace(); d << "AbstractMetaVariable("; if (av) { - d << av->type()->name() << ' ' << av->name(); + d << av->type().name() << ' ' << av->name(); } else { d << '0'; } @@ -183,301 +181,6 @@ void AbstractMetaAttributes::assignMetaAttributes(const AbstractMetaAttributes & } /******************************************************************************* - * AbstractMetaType - */ - -AbstractMetaType::AbstractMetaType(const TypeEntry *t) : - m_typeEntry(t), - m_constant(false), - m_volatile(false), - m_cppInstantiation(true), - m_reserved(0) -{ -} - -AbstractMetaType::AbstractMetaType(const AbstractMetaType &rhs) = default; - -AbstractMetaType::~AbstractMetaType() -{ - qDeleteAll(m_children); - m_instantiations.clear(); - delete m_viewOn; -} - -QString AbstractMetaType::package() const -{ - return m_typeEntry->targetLangPackage(); -} - -QString AbstractMetaType::name() const -{ - return m_typeEntry->targetLangEntryName(); -} - -QString AbstractMetaType::fullName() const -{ - return m_typeEntry->qualifiedTargetLangName(); -} - -AbstractMetaType *AbstractMetaType::copy() const -{ - auto *cpy = new AbstractMetaType(typeEntry()); - - cpy->setTypeUsagePattern(typeUsagePattern()); - cpy->setConstant(isConstant()); - cpy->setVolatile(isVolatile()); - cpy->setReferenceType(referenceType()); - cpy->setIndirectionsV(indirectionsV()); - cpy->setInstantiations(instantiations()); - cpy->setArrayElementCount(arrayElementCount()); - cpy->setOriginalTypeDescription(originalTypeDescription()); - cpy->setOriginalTemplateType(originalTemplateType() ? originalTemplateType()->copy() : nullptr); - - cpy->setArrayElementType(arrayElementType() ? arrayElementType()->copy() : nullptr); - - return cpy; -} - -// For applying the <array> function argument modification: change into a type -// where "int *" becomes "int[]". -bool AbstractMetaType::applyArrayModification(QString *errorMessage) -{ - if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) { - *errorMessage = QLatin1String("<array> modification already applied."); - return false; - } - if (m_arrayElementType != nullptr) { - QTextStream(errorMessage) << "The type \"" << cppSignature() - << "\" is an array of " << m_arrayElementType->name() << '.'; - return false; - } - if (m_indirections.isEmpty()) { - QTextStream(errorMessage) << "The type \"" << cppSignature() - << "\" does not have indirections."; - return false; - } - // Element type to be used for ArrayHandle<>, strip constness. - auto elementType = copy(); - elementType->m_indirections.pop_front(); - elementType->setConstant(false); - elementType->setVolatile(false); - elementType->decideUsagePattern(); - m_arrayElementType = elementType; - setTypeUsagePattern(AbstractMetaType::NativePointerAsArrayPattern); - return true; -} - -AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const -{ - AbstractMetaTypeCList result; - switch (m_pattern) { - case ArrayPattern: - for (const AbstractMetaType *t = this; t->typeUsagePattern() == ArrayPattern; ) { - const AbstractMetaType *elt = t->arrayElementType(); - result.append(elt); - t = elt; - } - break; - case NativePointerAsArrayPattern: - result.append(m_arrayElementType); - break; - default: - break; - } - return result; -} - -bool AbstractMetaType::passByConstRef() const -{ - return isConstant() && m_referenceType == LValueReference && indirections() == 0; -} - -bool AbstractMetaType::passByValue() const -{ - return m_referenceType == NoReference && indirections() == 0; -} - -QString AbstractMetaType::cppSignature() const -{ - if (m_cachedCppSignature.isEmpty()) - m_cachedCppSignature = formatSignature(false); - return m_cachedCppSignature; -} - -QString AbstractMetaType::pythonSignature() const -{ - // PYSIDE-921: Handle container returntypes correctly. - // This is now a clean reimplementation. - if (m_cachedPythonSignature.isEmpty()) - m_cachedPythonSignature = formatPythonSignature(); - return m_cachedPythonSignature; -} - -AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() const -{ - if (m_typeEntry->isTemplateArgument()) - return TemplateArgument; - - if (m_typeEntry->type() == TypeEntry::ConstantValueType) - return NonTypeTemplateArgument; - - if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || passByConstRef())) - return PrimitivePattern; - - if (m_typeEntry->isVoid()) { - return m_arrayElementCount < 0 && m_referenceType == NoReference - && m_indirections.isEmpty() && m_constant == 0 && m_volatile == 0 - ? VoidPattern : NativePointerPattern; - } - - if (m_typeEntry->isVarargs()) - return VarargsPattern; - - if (m_typeEntry->isEnum() && (actualIndirections() == 0 || passByConstRef())) - return EnumPattern; - - if (m_typeEntry->isObject()) { - if (indirections() == 0 && m_referenceType == NoReference) - return ValuePattern; - return ObjectPattern; - } - - if (m_typeEntry->isContainer() && indirections() == 0) - return ContainerPattern; - - if (m_typeEntry->isSmartPointer() && indirections() == 0) - return SmartPointerPattern; - - if (m_typeEntry->isFlags() && (actualIndirections() == 0 || passByConstRef())) - return FlagsPattern; - - if (m_typeEntry->isArray()) - return ArrayPattern; - - if (m_typeEntry->isValue()) - return indirections() == 1 ? ValuePointerPattern : ValuePattern; - - return NativePointerPattern; -} - -void AbstractMetaType::decideUsagePattern() -{ - TypeUsagePattern pattern = determineUsagePattern(); - if (m_typeEntry->isObject() && indirections() == 1 - && m_referenceType == LValueReference && isConstant()) { - // const-references to pointers can be passed as pointers - setReferenceType(NoReference); - setConstant(false); - pattern = ObjectPattern; - } - setTypeUsagePattern(pattern); -} - -bool AbstractMetaType::hasTemplateChildren() const -{ - QStack<AbstractMetaType *> children; - children << m_children; - - // Recursively iterate over the children / descendants of the type, to check if any of them - // corresponds to a template argument type. - while (!children.isEmpty()) { - AbstractMetaType *child = children.pop(); - if (child->typeEntry()->isTemplateArgument()) - return true; - children << child->m_children; - } - - return false; -} - -bool AbstractMetaType::compare(const AbstractMetaType &rhs, ComparisonFlags flags) const -{ - if (m_typeEntry != rhs.m_typeEntry - || m_indirections != rhs.m_indirections - || m_instantiations.size() != rhs.m_instantiations.size() - || m_arrayElementCount != rhs.m_arrayElementCount) { - return false; - } - - if (m_constant != rhs.m_constant || m_referenceType != rhs.m_referenceType) { - if (!flags.testFlag(ConstRefMatchesValue) - || !(passByValue() || passByConstRef()) - || !(rhs.passByValue() || rhs.passByConstRef())) { - return false; - } - } - - if ((m_arrayElementType != nullptr) != (rhs.m_arrayElementType != nullptr) - || (m_arrayElementType != nullptr && !m_arrayElementType->compare(*rhs.m_arrayElementType, flags))) { - return false; - } - for (int i = 0, size = m_instantiations.size(); i < size; ++i) { - if (!m_instantiations.at(i)->compare(*rhs.m_instantiations.at(i), flags)) - return false; - } - return true; -} - -AbstractMetaType *AbstractMetaType::createVoid() -{ - static const TypeEntry *voidTypeEntry = TypeDatabase::instance()->findType(QLatin1String("void")); - Q_ASSERT(voidTypeEntry); - auto *metaType = new AbstractMetaType(voidTypeEntry); - metaType->decideUsagePattern(); - return metaType; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaType *at) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaType("; - if (at) { - d << at->name(); - if (d.verbosity() > 2) { - d << ", typeEntry=" << at->typeEntry() << ", signature=\"" - << at->cppSignature() << "\", pattern=" - << at->typeUsagePattern(); - const auto indirections = at->indirectionsV(); - if (!indirections.isEmpty()) { - d << ", indirections="; - for (auto i : indirections) - d << ' ' << TypeInfo::indirectionKeyword(i); - } - if (at->referenceType()) - d << ", reftype=" << at->referenceType(); - if (at->isConstant()) - d << ", [const]"; - if (at->isVolatile()) - d << ", [volatile]"; - if (at->isArray()) { - d << ", array of \"" << at->arrayElementType()->cppSignature() - << "\", arrayElementCount=" << at->arrayElementCount(); - } - const auto &instantiations = at->instantiations(); - if (const int instantiationsSize = instantiations.size()) { - d << ", instantiations[" << instantiationsSize << "]=<"; - for (int i = 0; i < instantiationsSize; ++i) { - if (i) - d << ", "; - d << instantiations.at(i); - } - } - d << '>'; - if (at->viewOn()) - d << ", views " << at->viewOn()->name(); - } - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -/******************************************************************************* * AbstractMetaArgument */ @@ -553,7 +256,6 @@ AbstractMetaFunction::AbstractMetaFunction() AbstractMetaFunction::~AbstractMetaFunction() { qDeleteAll(m_arguments); - delete m_type; } /******************************************************************************* @@ -596,9 +298,7 @@ AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const Abstra result |= EqualAttributes; // Compare types - AbstractMetaType *t = type(); - AbstractMetaType *ot = other->type(); - if ((!t && !ot) || ((t && ot && t->name() == ot->name()))) + if (type().name() == other->type().name()) result |= EqualReturnType; // Compare names @@ -632,7 +332,7 @@ AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const Abstra if (i < minCount) { const AbstractMetaArgument *min_arg = minArguments.at(i); const AbstractMetaArgument *max_arg = maxArguments.at(i); - if (min_arg->type()->name() != max_arg->type()->name() + if (min_arg->type().name() != max_arg->type().name() && (min_arg->defaultValueExpression().isEmpty() || max_arg->defaultValueExpression().isEmpty())) { same = false; break; @@ -661,7 +361,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const cpy->setImplementingClass(implementingClass()); cpy->setFunctionType(functionType()); cpy->setDeclaringClass(declaringClass()); - cpy->setType(type()->copy()); + cpy->setType(type()); cpy->setConstant(isConstant()); cpy->setExceptionSpecification(m_exceptionSpecification); cpy->setAllowThreadModification(m_allowThreadModification); @@ -670,9 +370,6 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const for (AbstractMetaArgument *arg : m_arguments) cpy->addArgument(arg->copy()); - - Q_ASSERT(type()->instantiations() == cpy->type()->instantiations()); - return cpy; } @@ -680,10 +377,10 @@ bool AbstractMetaFunction::usesRValueReferences() const { if (m_functionType == MoveConstructorFunction || m_functionType == MoveAssignmentOperatorFunction) return true; - if (m_type->referenceType() == RValueReference) + if (m_type.referenceType() == RValueReference) return true; for (const AbstractMetaArgument *a : m_arguments) { - if (a->type()->referenceType() == RValueReference) + if (a->type().referenceType() == RValueReference) return true; } return false; @@ -699,7 +396,7 @@ QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStrin QStringList returned; AbstractMetaArgument *argument = arguments.at(resolvedArguments.size()); - QStringList minimalTypeSignature = argument->type()->minimalSignature().split(QLatin1String("::")); + QStringList minimalTypeSignature = argument->type().minimalSignature().split(QLatin1String("::")); for (int i = 0; i < minimalTypeSignature.size(); ++i) { returned += introspectionCompatibleSignatures(QStringList(resolvedArguments) << QStringList(minimalTypeSignature.mid(minimalTypeSignature.size() - i - 1)).join(QLatin1String("::"))); @@ -717,11 +414,11 @@ QString AbstractMetaFunction::signature() const for (int i = 0; i < m_arguments.count(); ++i) { AbstractMetaArgument *a = m_arguments.at(i); - AbstractMetaType *t = a->type(); - if (t) { + const AbstractMetaType &t = a->type(); + if (!t.isVoid()) { if (i > 0) m_cachedSignature += QLatin1String(", "); - m_cachedSignature += t->cppSignature(); + m_cachedSignature += t.cppSignature(); // We need to have the argument names in the qdoc files m_cachedSignature += QLatin1Char(' '); m_cachedSignature += a->name(); @@ -963,11 +660,11 @@ QString AbstractMetaFunction::minimalSignature() const AbstractMetaArgumentList arguments = this->arguments(); for (int i = 0; i < arguments.count(); ++i) { - AbstractMetaType *t = arguments.at(i)->type(); - if (t) { + const AbstractMetaType &t = arguments.at(i)->type(); + if (!t.isVoid()) { if (i > 0) minimalSignature += QLatin1Char(','); - minimalSignature += t->minimalSignature(); + minimalSignature += t.minimalSignature(); } else { qCWarning(lcShiboken).noquote().nospace() << QString::fromLatin1("No abstract meta type found for argument '%1' while constructing" @@ -1420,7 +1117,6 @@ AbstractMetaClass::~AbstractMetaClass() qDeleteAll(m_fields); qDeleteAll(m_enums); qDeleteAll(m_propertySpecs); - qDeleteAll(m_baseTemplateInstantiations); } /******************************************************************************* @@ -1844,7 +1540,7 @@ static void formatMetaAttributes(QDebug &d, AbstractMetaAttributes::Attributes v static void formatMetaField(QDebug &d, const AbstractMetaField *af) { formatMetaAttributes(d, af->attributes()); - d << ' ' << af->type()->name() << " \"" << af->name() << '"'; + d << ' ' << af->type().name() << " \"" << af->name() << '"'; } QDebug operator<<(QDebug d, const AbstractMetaField *af) @@ -1958,10 +1654,10 @@ void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate) f->setFunctionType(AbstractMetaFunction::CopyConstructorFunction); f->setDeclaringClass(this); - auto argType = new AbstractMetaType(typeEntry()); - argType->setReferenceType(LValueReference); - argType->setConstant(true); - argType->setTypeUsagePattern(AbstractMetaType::ValuePattern); + AbstractMetaType argType(typeEntry()); + argType.setReferenceType(LValueReference); + argType.setConstant(true); + argType.setTypeUsagePattern(AbstractMetaType::ValuePattern); auto arg = new AbstractMetaArgument; arg->setType(argType); @@ -2172,13 +1868,11 @@ void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(Abstrac } } -static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType *type) +static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType &type) { - if (!type) - return; Q_ASSERT(metaClass); - const TypeEntry *entry = (type ? type->typeEntry() : nullptr); + const TypeEntry *entry = type.typeEntry(); if (entry && entry->isComplex()) { const auto *centry = static_cast<const ComplexTypeEntry *>(entry); ComplexTypeEntry *class_entry = metaClass->typeEntry(); @@ -2186,8 +1880,8 @@ static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractM class_entry->addExtraInclude(centry->include()); } - if (type->hasInstantiations()) { - for (const AbstractMetaType *instantiation : type->instantiations()) + if (type.hasInstantiations()) { + for (const AbstractMetaType &instantiation : type.instantiations()) addExtraIncludeForType(metaClass, instantiation); } } @@ -2396,121 +2090,6 @@ void AbstractMetaClass::fixFunctions() setFunctions(funcs); } -static inline QString formatArraySize(int e) -{ - QString result; - result += QLatin1Char('['); - if (e >= 0) - result += QString::number(e); - result += QLatin1Char(']'); - return result; -} - -QString AbstractMetaType::formatSignature(bool minimal) const -{ - QString result; - if (isConstant()) - result += QLatin1String("const "); - if (isVolatile()) - result += QLatin1String("volatile "); - if (isArray()) { - // Build nested array dimensions a[2][3] in correct order - result += m_arrayElementType->minimalSignature(); - const int arrayPos = result.indexOf(QLatin1Char('[')); - if (arrayPos != -1) - result.insert(arrayPos, formatArraySize(m_arrayElementCount)); - else - result.append(formatArraySize(m_arrayElementCount)); - } else { - result += typeEntry()->qualifiedCppName(); - } - if (!m_instantiations.isEmpty()) { - result += QLatin1Char('<'); - if (minimal) - result += QLatin1Char(' '); - for (int i = 0, size = m_instantiations.size(); i < size; ++i) { - if (i > 0) - result += QLatin1Char(','); - result += m_instantiations.at(i)->minimalSignature(); - } - result += QLatin1String(" >"); - } - - if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference)) - result += QLatin1Char(' '); - for (Indirection i : m_indirections) - result += TypeInfo::indirectionKeyword(i); - switch (referenceType()) { - case NoReference: - break; - case LValueReference: - result += QLatin1Char('&'); - break; - case RValueReference: - result += QLatin1String("&&"); - break; - } - return result; -} - -QString AbstractMetaType::formatPythonSignature() const -{ - /* - * This is a version of the above, more suitable for Python. - * We avoid extra keywords that are not needed in Python. - * We prepend the package name, unless it is a primitive type. - * - * Primitive types like 'int', 'char' etc.: - * When we have a primitive with an indirection, we use that '*' - * character for later postprocessing, since those indirections - * need to be modified into a result tuple. - * Smart pointer instantiations: Drop the package - */ - QString result; - if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) - result += QLatin1String("array "); - // We no longer use the "const" qualifier for heuristics. Instead, - // NativePointerAsArrayPattern indicates when we have <array> in XML. - // if (m_typeEntry->isPrimitive() && isConstant()) - // result += QLatin1String("const "); - if (!m_typeEntry->isPrimitive() && !m_typeEntry->isSmartPointer() && !package().isEmpty()) - result += package() + QLatin1Char('.'); - if (isArray()) { - // Build nested array dimensions a[2][3] in correct order - result += m_arrayElementType->formatPythonSignature(); - const int arrayPos = result.indexOf(QLatin1Char('[')); - if (arrayPos != -1) - result.insert(arrayPos, formatArraySize(m_arrayElementCount)); - else - result.append(formatArraySize(m_arrayElementCount)); - } else { - result += typeEntry()->targetLangName(); - } - if (!m_instantiations.isEmpty()) { - result += QLatin1Char('['); - for (int i = 0, size = m_instantiations.size(); i < size; ++i) { - if (i > 0) - result += QLatin1String(", "); - result += m_instantiations.at(i)->formatPythonSignature(); - } - result += QLatin1Char(']'); - } - if (m_typeEntry->isPrimitive()) - for (Indirection i : m_indirections) - result += TypeInfo::indirectionKeyword(i); - // If it is a flags type, we replace it with the full name: - // "PySide2.QtCore.Qt.ItemFlags" instead of "PySide2.QtCore.QFlags<Qt.ItemFlag>" - if (m_typeEntry->isFlags()) - result = fullName(); - result.replace(QLatin1String("::"), QLatin1String(".")); - return result; -} - -bool AbstractMetaType::isCppPrimitive() const -{ - return m_pattern == PrimitivePattern && m_typeEntry->isCppPrimitive(); -} - /******************************************************************************* * Other stuff... */ @@ -2635,7 +2214,7 @@ void AbstractMetaClass::format(QDebug &d) const const auto &instantiatedTypes = templateBaseClassInstantiations(); d << ", instantiates \"" << templateBase->name(); for (int i = 0, count = instantiatedTypes.size(); i < count; ++i) - d << (i ? ',' : '<') << instantiatedTypes.at(i)->name(); + d << (i ? ',' : '<') << instantiatedTypes.at(i).name(); d << ">\""; } if (const int count = m_propertySpecs.size()) { diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 49078b07f..4f5b1476b 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -30,6 +30,7 @@ #define ABSTRACTMETALANG_H #include "abstractmetalang_typedefs.h" +#include "abstractmetatype.h" #include "sourcelocation.h" #include "typesystem_enums.h" #include "typesystem_typedefs.h" @@ -39,6 +40,7 @@ #include <QtCore/qobjectdefs.h> #include <QtCore/QStringList> +#include <QtCore/QSharedDataPointer> #include <QtCore/QMap> QT_FORWARD_DECLARE_CLASS(QDebug) @@ -47,7 +49,6 @@ class AbstractMeta; class AbstractMetaClass; class AbstractMetaField; class AbstractMetaFunction; -class AbstractMetaType; class AbstractMetaVariable; class AbstractMetaArgument; class AbstractMetaEnumValue; @@ -274,315 +275,6 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaAttributes::Attributes) QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa); #endif -class AbstractMetaType -{ - Q_GADGET -public: - using Indirections = QVector<Indirection>; - - enum TypeUsagePattern { - InvalidPattern, - PrimitivePattern, - FlagsPattern, - EnumPattern, - ValuePattern, - ObjectPattern, - ValuePointerPattern, - NativePointerPattern, - NativePointerAsArrayPattern, // "int*" as "int[]" - ContainerPattern, - SmartPointerPattern, - VarargsPattern, - ArrayPattern, - VoidPattern, // Plain "void", no "void *" or similar. - TemplateArgument, // 'T' in std::array<T,2> - NonTypeTemplateArgument // '2' in in std::array<T,2> - }; - Q_ENUM(TypeUsagePattern) - - enum ComparisonFlag { - ConstRefMatchesValue = 0x1 - }; - Q_DECLARE_FLAGS(ComparisonFlags, ComparisonFlag); - - explicit AbstractMetaType(const TypeEntry *t = nullptr); - AbstractMetaType(const AbstractMetaType &); - ~AbstractMetaType(); - - QString package() const; - QString name() const; - QString fullName() const; - - void setTypeUsagePattern(TypeUsagePattern pattern) - { - m_pattern = pattern; - } - TypeUsagePattern typeUsagePattern() const - { - return m_pattern; - } - - // true when use pattern is container - bool hasInstantiations() const - { - return !m_instantiations.isEmpty(); - } - - void addInstantiation(AbstractMetaType* inst, bool owner = false) - { - if (owner) - m_children << inst; - m_instantiations << inst; - } - - void setInstantiations(const AbstractMetaTypeList &insts, bool owner = false) - { - m_instantiations = insts; - if (owner) { - m_children.clear(); - m_children = insts; - } - } - - const AbstractMetaTypeList &instantiations() const - { - return m_instantiations; - } - - void setInstantiationInCpp(bool incpp) - { - m_cppInstantiation = incpp; - } - - QString minimalSignature() const { return formatSignature(true); } - - // returns true if the typs is used as a non complex primitive, no & or *'s - bool isPrimitive() const - { - return m_pattern == PrimitivePattern; - } - - bool isCppPrimitive() const; - - // returns true if the type is used as an enum - bool isEnum() const - { - return m_pattern == EnumPattern; - } - - // returns true if the type is used as an object, e.g. Xxx * - bool isObject() const - { - return m_pattern == ObjectPattern; - } - - // returns true if the type is used as an array, e.g. Xxx[42] - bool isArray() const - { - return m_pattern == ArrayPattern; - } - - // returns true if the type is used as a value type (X or const X &) - bool isValue() const - { - return m_pattern == ValuePattern; - } - - bool isValuePointer() const - { - return m_pattern == ValuePointerPattern; - } - - // returns true for more complex types... - bool isNativePointer() const - { - return m_pattern == NativePointerPattern; - } - - // return true if the type was originally a varargs - bool isVarargs() const - { - return m_pattern == VarargsPattern; - } - - // returns true if the type was used as a container - bool isContainer() const - { - return m_pattern == ContainerPattern; - } - - // returns true if the type was used as a smart pointer - bool isSmartPointer() const { return m_pattern == SmartPointerPattern; } - - // returns true if the type was used as a flag - bool isFlags() const - { - return m_pattern == FlagsPattern; - } - - bool isVoid() const { return m_pattern == VoidPattern; } - - bool isConstant() const - { - return m_constant; - } - void setConstant(bool constant) - { - m_constant = constant; - } - - bool isVolatile() const { return m_volatile; } - void setVolatile(bool v) { m_volatile = v; } - - bool passByConstRef() const; - bool passByValue() const; - - ReferenceType referenceType() const { return m_referenceType; } - void setReferenceType(ReferenceType ref) { m_referenceType = ref; } - - int actualIndirections() const - { - return m_indirections.size() + (m_referenceType == LValueReference ? 1 : 0); - } - - Indirections indirectionsV() const { return m_indirections; } - void setIndirectionsV(const Indirections &i) { m_indirections = i; } - void clearIndirections() { m_indirections.clear(); } - - // "Legacy"? - int indirections() const { return m_indirections.size(); } - void setIndirections(int indirections) - { - m_indirections = Indirections(indirections, Indirection::Pointer); - } - void addIndirection(Indirection i = Indirection::Pointer) - { m_indirections.append(i); } - - void setArrayElementCount(int n) - { - m_arrayElementCount = n; - } - int arrayElementCount() const - { - return m_arrayElementCount; - } - - const AbstractMetaType *arrayElementType() const - { - return m_arrayElementType; - } - void setArrayElementType(const AbstractMetaType *t) - { - m_arrayElementType = t; - } - - AbstractMetaTypeCList nestedArrayTypes() const; - - QString cppSignature() const; - - QString pythonSignature() const; - - AbstractMetaType *copy() const; - bool applyArrayModification(QString *errorMessage); - - const TypeEntry *typeEntry() const - { - return m_typeEntry; - } - void setTypeEntry(const TypeEntry *type) - { - m_typeEntry = type; - } - - void setOriginalTypeDescription(const QString &otd) - { - m_originalTypeDescription = otd; - } - QString originalTypeDescription() const - { - return m_originalTypeDescription; - } - - void setOriginalTemplateType(const AbstractMetaType *type) - { - m_originalTemplateType = type; - } - const AbstractMetaType *originalTemplateType() const - { - return m_originalTemplateType; - } - - AbstractMetaType *getSmartPointerInnerType() const - { - Q_ASSERT(isSmartPointer()); - const AbstractMetaTypeList &instantiations = this->instantiations(); - Q_ASSERT(!instantiations.isEmpty()); - AbstractMetaType *innerType = instantiations.at(0); - return innerType; - } - - QString getSmartPointerInnerTypeName() const - { - Q_ASSERT(isSmartPointer()); - AbstractMetaType *innerType = getSmartPointerInnerType(); - Q_ASSERT(innerType); - return innerType->name(); - } - - /// Decides and sets the proper usage patter for the current meta type. - void decideUsagePattern(); - - bool hasTemplateChildren() const; - - bool compare(const AbstractMetaType &rhs, ComparisonFlags = {}) const; - - // View on: Type to use for function argument conversion, fex - // std::string_view -> std::string for foo(std::string_view); - // cf TypeEntry::viewOn() - const AbstractMetaType *viewOn() const { return m_viewOn; } - void setViewOn(const AbstractMetaType *v) { m_viewOn = v; } - - static AbstractMetaType *createVoid(); - -private: - TypeUsagePattern determineUsagePattern() const; - QString formatSignature(bool minimal) const; - QString formatPythonSignature() const; - - const TypeEntry *m_typeEntry; - AbstractMetaTypeList m_instantiations; - QString m_package; - mutable QString m_cachedCppSignature; - mutable QString m_cachedPythonSignature; - QString m_originalTypeDescription; - - int m_arrayElementCount = -1; - const AbstractMetaType *m_arrayElementType = nullptr; - const AbstractMetaType *m_originalTemplateType = nullptr; - const AbstractMetaType *m_viewOn = nullptr; - Indirections m_indirections; - - TypeUsagePattern m_pattern = InvalidPattern; - uint m_constant : 1; - uint m_volatile : 1; - uint m_cppInstantiation : 1; - uint m_reserved : 29; // unused - - ReferenceType m_referenceType = NoReference; - AbstractMetaTypeList m_children; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaType::ComparisonFlags); - -inline bool operator==(const AbstractMetaType &t1, const AbstractMetaType &t2) -{ return t1.compare(t2); } -inline bool operator!=(const AbstractMetaType &t1, const AbstractMetaType &t2) -{ return !t1.compare(t2); } - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaType *at); -#endif - class AbstractMetaVariable { Q_DISABLE_COPY(AbstractMetaVariable) @@ -591,18 +283,12 @@ public: virtual ~AbstractMetaVariable(); - AbstractMetaType *type() const + const AbstractMetaType &type() const { return m_type; } - void setType(AbstractMetaType *type) - { - Q_ASSERT(m_type == nullptr); - m_type = type; - } - void replaceType(AbstractMetaType *type) + void setType(const AbstractMetaType &type) { - delete m_type; m_type = type; } @@ -642,7 +328,7 @@ protected: private: QString m_originalName; QString m_name; - AbstractMetaType *m_type = nullptr; + AbstractMetaType m_type; bool m_hasName = false; Documentation m_doc; @@ -686,7 +372,7 @@ public: QString toString() const { - return type()->name() + QLatin1Char(' ') + AbstractMetaVariable::name() + + return type().name() + QLatin1Char(' ') + AbstractMetaVariable::name() + (m_expression.isEmpty() ? QString() : QLatin1String(" = ") + m_expression); } @@ -894,20 +580,13 @@ public: bool isModifiedRemoved(int types = TypeSystem::All) const; - bool isVoid() const { return m_type->isVoid(); } - AbstractMetaType *type() const + bool isVoid() const { return m_type.isVoid(); } + const AbstractMetaType &type() const { return m_type; } - void setType(AbstractMetaType *type) - { - Q_ASSERT(m_type == nullptr); - m_type = type; - } - - void replaceType(AbstractMetaType *type) + void setType(const AbstractMetaType &type) { - delete m_type; m_type = type; } @@ -1113,7 +792,7 @@ private: FunctionTypeEntry* m_typeEntry = nullptr; FunctionType m_functionType = NormalFunction; - AbstractMetaType *m_type = nullptr; + AbstractMetaType m_type; const AbstractMetaClass *m_class = nullptr; const AbstractMetaClass *m_implementingClass = nullptr; const AbstractMetaClass *m_declaringClass = nullptr; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h b/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h index f8bca07c1..418b9ba09 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h @@ -46,8 +46,6 @@ using AbstractMetaEnumList = QVector<AbstractMetaEnum *>; using AbstractMetaEnumValueList = QVector<AbstractMetaEnumValue *>; using AbstractMetaFieldList = QVector<AbstractMetaField *>; using AbstractMetaFunctionList = QVector<AbstractMetaFunction *>; -using AbstractMetaTypeCPtr = QSharedPointer<const AbstractMetaType>; -using AbstractMetaTypeList = QVector<AbstractMetaType *>; -using AbstractMetaTypeCList = QVector<const AbstractMetaType *>; +using AbstractMetaTypeList = QVector<AbstractMetaType>; #endif // ABSTRACTMETALANG_TYPEDEFS_H diff --git a/sources/shiboken2/ApiExtractor/abstractmetatype.cpp b/sources/shiboken2/ApiExtractor/abstractmetatype.cpp new file mode 100644 index 000000000..8ad2a937f --- /dev/null +++ b/sources/shiboken2/ApiExtractor/abstractmetatype.cpp @@ -0,0 +1,752 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "abstractmetatype.h" +#include "typedatabase.h" +#include "typesystem.h" +#include "parser/codemodel.h" + +#ifndef QT_NO_DEBUG_STREAM +# include <QtCore/QDebug> +#endif + +#include <QtCore/QSharedData> +#include <QtCore/QSharedPointer> +#include <QtCore/QStack> + +using AbstractMetaTypeCPtr = QSharedPointer<const AbstractMetaType>; + +class AbstractMetaTypeData : public QSharedData +{ +public: + AbstractMetaTypeData(const TypeEntry *t); + + int actualIndirections() const; + bool passByConstRef() const; + bool passByValue() const; + AbstractMetaType::TypeUsagePattern determineUsagePattern() const; + bool hasTemplateChildren() const; + QString formatSignature(bool minimal) const; + QString formatPythonSignature() const; + bool equals(const AbstractMetaTypeData &rhs) const; + + const TypeEntry *m_typeEntry; + AbstractMetaTypeList m_instantiations; + mutable QString m_cachedCppSignature; + mutable QString m_cachedPythonSignature; + QString m_originalTypeDescription; + + int m_arrayElementCount = -1; + AbstractMetaTypeCPtr m_arrayElementType; + AbstractMetaTypeCPtr m_originalTemplateType; + AbstractMetaTypeCPtr m_viewOn; + AbstractMetaType::Indirections m_indirections; + + AbstractMetaType::TypeUsagePattern m_pattern = AbstractMetaType::InvalidPattern; + uint m_constant : 1; + uint m_volatile : 1; + uint m_signaturesDirty : 1; + uint m_reserved : 29; // unused + + ReferenceType m_referenceType = NoReference; + AbstractMetaTypeList m_children; +}; + +AbstractMetaTypeData::AbstractMetaTypeData(const TypeEntry *t) : + m_typeEntry(t), + m_constant(false), + m_volatile(false), + m_signaturesDirty(true), + m_reserved(0) +{ +} + +AbstractMetaType::AbstractMetaType(const TypeEntry *t) : d(new AbstractMetaTypeData(t)) +{ +} + +AbstractMetaType::AbstractMetaType() : d(new AbstractMetaTypeData(nullptr)) +{ +} + +AbstractMetaType &AbstractMetaType::operator=(const AbstractMetaType &) = default; + +AbstractMetaType::AbstractMetaType(const AbstractMetaType &rhs) = default; + +AbstractMetaType::AbstractMetaType(AbstractMetaType &&) = default; + +AbstractMetaType &AbstractMetaType::operator=(AbstractMetaType &&) = default; + +AbstractMetaType::~AbstractMetaType() = default; + +bool AbstractMetaType::isValid() const +{ + return d->m_pattern != AbstractMetaType::InvalidPattern; +} + +QString AbstractMetaType::package() const +{ + return d->m_typeEntry->targetLangPackage(); +} + +QString AbstractMetaType::name() const +{ + return d->m_typeEntry->targetLangEntryName(); +} + +QString AbstractMetaType::fullName() const +{ + return d->m_typeEntry->qualifiedTargetLangName(); +} + +void AbstractMetaType::setTypeUsagePattern(AbstractMetaType::TypeUsagePattern pattern) +{ + if (d->m_pattern != pattern) + d->m_pattern = pattern; +} + +AbstractMetaType::TypeUsagePattern AbstractMetaType::typeUsagePattern() const +{ + return d->m_pattern; +} + +bool AbstractMetaType::hasInstantiations() const +{ + return !d->m_instantiations.isEmpty(); +} + +void AbstractMetaType::addInstantiation(const AbstractMetaType &inst) +{ + d->m_instantiations << inst; +} + +void AbstractMetaType::setInstantiations(const AbstractMetaTypeList &insts) +{ + if (insts != d->m_instantiations) + d->m_instantiations = insts; +} + +const AbstractMetaTypeList &AbstractMetaType::instantiations() const +{ + return d->m_instantiations; +} + +// For applying the <array> function argument modification: change into a type +// where "int *" becomes "int[]". +bool AbstractMetaType::applyArrayModification(QString *errorMessage) +{ + + if (d->m_pattern == AbstractMetaType::NativePointerAsArrayPattern) { + *errorMessage = QLatin1String("<array> modification already applied."); + return false; + } + if (!d->m_arrayElementType.isNull()) { + QTextStream(errorMessage) << "The type \"" << cppSignature() + << "\" is an array of " << d->m_arrayElementType->name() << '.'; + return false; + } + if (d->m_indirections.isEmpty()) { + QTextStream(errorMessage) << "The type \"" << cppSignature() + << "\" does not have indirections."; + return false; + } + // Element type to be used for ArrayHandle<>, strip constness. + + auto elementType = new AbstractMetaType(*this); + auto indir = indirectionsV(); + indir.pop_front(); + elementType->setIndirectionsV(indir); + elementType->setConstant(false); + elementType->setVolatile(false); + elementType->decideUsagePattern(); + d->m_arrayElementType.reset(elementType); + d->m_pattern = AbstractMetaType::NativePointerAsArrayPattern; + return true; +} + +const TypeEntry *AbstractMetaType::typeEntry() const +{ + return d->m_typeEntry; +} + +void AbstractMetaType::setTypeEntry(const TypeEntry *type) +{ + if (d->m_typeEntry != type) + d->m_typeEntry = type; +} + +void AbstractMetaType::setOriginalTypeDescription(const QString &otd) +{ + if (d->m_originalTypeDescription != otd) + d->m_originalTypeDescription = otd; +} + +QString AbstractMetaType::originalTypeDescription() const +{ + return d->m_originalTypeDescription; +} + +void AbstractMetaType::setOriginalTemplateType(const AbstractMetaType &type) +{ + if (d->m_originalTemplateType.isNull() || *d->m_originalTemplateType != type) + d->m_originalTemplateType.reset(new AbstractMetaType(type)); +} + +const AbstractMetaType *AbstractMetaType::originalTemplateType() const +{ + return d->m_originalTemplateType.data(); +} + +AbstractMetaType AbstractMetaType::getSmartPointerInnerType() const +{ + Q_ASSERT(isSmartPointer()); + Q_ASSERT(!d->m_instantiations.isEmpty()); + AbstractMetaType innerType = d->m_instantiations.at(0); + return innerType; +} + +QString AbstractMetaType::getSmartPointerInnerTypeName() const +{ + Q_ASSERT(isSmartPointer()); + return getSmartPointerInnerType().name(); +} + +AbstractMetaTypeList AbstractMetaType::nestedArrayTypes() const +{ + AbstractMetaTypeList result; + switch (d->m_pattern) { + case ArrayPattern: + for (AbstractMetaType t = *this; t.typeUsagePattern() == ArrayPattern; ) { + const AbstractMetaType *elt = t.arrayElementType(); + result.append(*elt); + t = *elt; + } + break; + case NativePointerAsArrayPattern: + result.append(*d->m_arrayElementType.data()); + break; + default: + break; + } + return result; +} + +bool AbstractMetaTypeData::passByConstRef() const +{ + return m_constant && m_referenceType == LValueReference && m_indirections.isEmpty(); +} + +bool AbstractMetaType::passByConstRef() const +{ + return d->passByConstRef(); +} + +bool AbstractMetaTypeData::passByValue() const +{ + return m_referenceType == NoReference && m_indirections.isEmpty(); +} + +bool AbstractMetaType::passByValue() const +{ + return d->passByValue(); +} + +ReferenceType AbstractMetaType::referenceType() const +{ + return d->m_referenceType; +} + +void AbstractMetaType::setReferenceType(ReferenceType ref) +{ + if (d->m_referenceType != ref) { + d->m_referenceType = ref; + d->m_signaturesDirty = true; + } +} + +int AbstractMetaTypeData::actualIndirections() const +{ + return m_indirections.size() + (m_referenceType == LValueReference ? 1 : 0); +} + +int AbstractMetaType::actualIndirections() const +{ + return d->actualIndirections(); +} + +AbstractMetaType::Indirections AbstractMetaType::indirectionsV() const +{ + return d->m_indirections; +} + +void AbstractMetaType::setIndirectionsV(const AbstractMetaType::Indirections &i) +{ + if (d->m_indirections != i) { + d->m_indirections = i; + d->m_signaturesDirty = true; + } +} + +void AbstractMetaType::clearIndirections() +{ + if (!d->m_indirections.isEmpty()) { + d->m_indirections.clear(); + d->m_signaturesDirty = true; + } +} + +int AbstractMetaType::indirections() const +{ + return d->m_indirections.size(); +} + +void AbstractMetaType::setIndirections(int indirections) +{ + const Indirections newValue(indirections, Indirection::Pointer); + if (d->m_indirections != newValue) { + d->m_indirections = newValue; + d->m_signaturesDirty = true; + } +} + +void AbstractMetaType::addIndirection(Indirection i) +{ + d->m_indirections.append(i); +} + +void AbstractMetaType::setArrayElementCount(int n) +{ + if (d->m_arrayElementCount != n) { + d->m_arrayElementCount = n; + d->m_signaturesDirty = true; + } +} + +int AbstractMetaType::arrayElementCount() const +{ + return d->m_arrayElementCount; +} + +const AbstractMetaType *AbstractMetaType::arrayElementType() const +{ + return d->m_arrayElementType.data(); +} + +void AbstractMetaType::setArrayElementType(const AbstractMetaType &t) +{ + if (d->m_arrayElementType.isNull() || *d->m_arrayElementType != t) { + d->m_arrayElementType.reset(new AbstractMetaType(t)); + d->m_signaturesDirty = true; + } +} + +QString AbstractMetaType::cppSignature() const +{ + const AbstractMetaTypeData *cd = d.constData(); + if (cd->m_cachedCppSignature.isEmpty() || cd->m_signaturesDirty) + cd->m_cachedCppSignature = formatSignature(false); + return cd->m_cachedCppSignature; +} + +QString AbstractMetaType::pythonSignature() const +{ + // PYSIDE-921: Handle container returntypes correctly. + // This is now a clean reimplementation. + const AbstractMetaTypeData *cd = d.constData(); + if (cd->m_cachedPythonSignature.isEmpty() || cd->m_signaturesDirty) + cd->m_cachedPythonSignature = formatPythonSignature(); + return cd->m_cachedPythonSignature; +} + +AbstractMetaType::TypeUsagePattern AbstractMetaTypeData::determineUsagePattern() const +{ + if (m_typeEntry->isTemplateArgument()) + return AbstractMetaType::TemplateArgument; + + if (m_typeEntry->type() == TypeEntry::ConstantValueType) + return AbstractMetaType::NonTypeTemplateArgument; + + if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || passByConstRef())) + return AbstractMetaType::PrimitivePattern; + + if (m_typeEntry->isVoid()) { + return m_arrayElementCount < 0 && m_referenceType == NoReference + && m_indirections.isEmpty() && m_constant == 0 && m_volatile == 0 + ? AbstractMetaType::VoidPattern : AbstractMetaType::NativePointerPattern; + } + + if (m_typeEntry->isVarargs()) + return AbstractMetaType::VarargsPattern; + + if (m_typeEntry->isEnum() && (actualIndirections() == 0 || passByConstRef())) + return AbstractMetaType::EnumPattern; + + if (m_typeEntry->isObject()) { + if (m_indirections.isEmpty() && m_referenceType == NoReference) + return AbstractMetaType::ValuePattern; + return AbstractMetaType::ObjectPattern; + } + + if (m_typeEntry->isContainer() && m_indirections.isEmpty()) + return AbstractMetaType::ContainerPattern; + + if (m_typeEntry->isSmartPointer() && m_indirections.isEmpty()) + return AbstractMetaType::SmartPointerPattern; + + if (m_typeEntry->isFlags() && (actualIndirections() == 0 || passByConstRef())) + return AbstractMetaType::FlagsPattern; + + if (m_typeEntry->isArray()) + return AbstractMetaType::ArrayPattern; + + if (m_typeEntry->isValue()) + return m_indirections.size() == 1 ? AbstractMetaType::ValuePointerPattern : AbstractMetaType::ValuePattern; + + return AbstractMetaType::NativePointerPattern; +} + +AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() const +{ + return d->determineUsagePattern(); +} + +void AbstractMetaType::decideUsagePattern() +{ + TypeUsagePattern pattern = determineUsagePattern(); + if (d->m_typeEntry->isObject() && indirections() == 1 + && d->m_referenceType == LValueReference && isConstant()) { + // const-references to pointers can be passed as pointers + setReferenceType(NoReference); + setConstant(false); + pattern = ObjectPattern; + } + setTypeUsagePattern(pattern); +} + +bool AbstractMetaTypeData::hasTemplateChildren() const +{ + QStack<AbstractMetaType> children; + children << m_instantiations; + + // Recursively iterate over the children / descendants of the type, to check if any of them + // corresponds to a template argument type. + while (!children.isEmpty()) { + AbstractMetaType child = children.pop(); + if (child.typeEntry()->isTemplateArgument()) + return true; + children << child.instantiations(); + } + return false; +} + +bool AbstractMetaType::hasTemplateChildren() const +{ + return d->hasTemplateChildren(); +} + +static inline QString formatArraySize(int e) +{ + QString result; + result += QLatin1Char('['); + if (e >= 0) + result += QString::number(e); + result += QLatin1Char(']'); + return result; +} + +QString AbstractMetaTypeData::formatSignature(bool minimal) const +{ + QString result; + if (m_constant) + result += QLatin1String("const "); + if (m_volatile) + result += QLatin1String("volatile "); + if (m_pattern == AbstractMetaType::ArrayPattern) { + // Build nested array dimensions a[2][3] in correct order + result += m_arrayElementType->minimalSignature(); + const int arrayPos = result.indexOf(QLatin1Char('[')); + if (arrayPos != -1) + result.insert(arrayPos, formatArraySize(m_arrayElementCount)); + else + result.append(formatArraySize(m_arrayElementCount)); + } else { + result += m_typeEntry->qualifiedCppName(); + } + if (!m_instantiations.isEmpty()) { + result += QLatin1Char('<'); + if (minimal) + result += QLatin1Char(' '); + for (int i = 0, size = m_instantiations.size(); i < size; ++i) { + if (i > 0) + result += QLatin1Char(','); + result += m_instantiations.at(i).minimalSignature(); + } + result += QLatin1String(" >"); + } + + if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference)) + result += QLatin1Char(' '); + for (Indirection i : m_indirections) + result += TypeInfo::indirectionKeyword(i); + switch (m_referenceType) { + case NoReference: + break; + case LValueReference: + result += QLatin1Char('&'); + break; + case RValueReference: + result += QLatin1String("&&"); + break; + } + return result; +} + +QString AbstractMetaType::formatSignature(bool minimal) const +{ + return d->formatSignature(minimal); +} + +QString AbstractMetaTypeData::formatPythonSignature() const +{ + /* + * This is a version of the above, more suitable for Python. + * We avoid extra keywords that are not needed in Python. + * We prepend the package name, unless it is a primitive type. + * + * Primitive types like 'int', 'char' etc.: + * When we have a primitive with an indirection, we use that '*' + * character for later postprocessing, since those indirections + * need to be modified into a result tuple. + * Smart pointer instantiations: Drop the package + */ + QString result; + if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) + result += QLatin1String("array "); + // We no longer use the "const" qualifier for heuristics. Instead, + // NativePointerAsArrayPattern indicates when we have <array> in XML. + // if (m_typeEntry->isPrimitive() && isConstant()) + // result += QLatin1String("const "); + if (!m_typeEntry->isPrimitive() && !m_typeEntry->isSmartPointer()) { + const QString package = m_typeEntry->targetLangPackage(); + if (!package.isEmpty()) + result += package + QLatin1Char('.'); + } + if (m_pattern == AbstractMetaType::ArrayPattern) { + // Build nested array dimensions a[2][3] in correct order + result += m_arrayElementType->formatPythonSignature(); + const int arrayPos = result.indexOf(QLatin1Char('[')); + if (arrayPos != -1) + result.insert(arrayPos, formatArraySize(m_arrayElementCount)); + else + result.append(formatArraySize(m_arrayElementCount)); + } else { + result += m_typeEntry->targetLangName(); + } + if (!m_instantiations.isEmpty()) { + result += QLatin1Char('['); + for (int i = 0, size = m_instantiations.size(); i < size; ++i) { + if (i > 0) + result += QLatin1String(", "); + result += m_instantiations.at(i).formatPythonSignature(); + } + result += QLatin1Char(']'); + } + if (m_typeEntry->isPrimitive()) + for (Indirection i : m_indirections) + result += TypeInfo::indirectionKeyword(i); + // If it is a flags type, we replace it with the full name: + // "PySide2.QtCore.Qt.ItemFlags" instead of "PySide2.QtCore.QFlags<Qt.ItemFlag>" + if (m_typeEntry->isFlags()) + result = m_typeEntry->qualifiedTargetLangName(); + result.replace(QLatin1String("::"), QLatin1String(".")); + return result; +} + +QString AbstractMetaType::formatPythonSignature() const +{ + return d->formatPythonSignature(); +} + +bool AbstractMetaType::isCppPrimitive() const +{ + return d->m_pattern == PrimitivePattern && d->m_typeEntry->isCppPrimitive(); +} + +bool AbstractMetaType::isConstant() const +{ + return d->m_constant; +} + +void AbstractMetaType::setConstant(bool constant) +{ + if (d->m_constant != constant) { + d->m_constant = constant; + d->m_signaturesDirty = true; + } +} + +bool AbstractMetaType::isVolatile() const +{ + return d->m_volatile; +} + +void AbstractMetaType::setVolatile(bool v) +{ + if (d->m_volatile != v) { + d->m_volatile = v; + d->m_signaturesDirty = true;\ + } +} + +static bool equalsCPtr(const AbstractMetaTypeCPtr &t1, const AbstractMetaTypeCPtr &t2) +{ + if (t1.isNull() != t2.isNull()) + return false; + return t1.isNull() || *t1 == *t2; +} + +bool AbstractMetaTypeData::equals(const AbstractMetaTypeData &rhs) const +{ + if (m_typeEntry != rhs.m_typeEntry + || m_indirections != rhs.m_indirections + || m_arrayElementCount != rhs.m_arrayElementCount) { + return false; + } + + if (m_constant != rhs.m_constant || m_volatile != rhs.m_volatile + || m_referenceType != rhs.m_referenceType) { + return false; + } + + if (!equalsCPtr(m_arrayElementType, rhs.m_arrayElementType)) + return false; + + if (!equalsCPtr(m_viewOn, rhs.m_viewOn)) + return false; + + if (m_instantiations != rhs.m_instantiations) + return false; + return true; +} + +bool AbstractMetaType::equals(const AbstractMetaType &rhs) const +{ + return d->equals(*rhs.d); +} + +const AbstractMetaType *AbstractMetaType::viewOn() const +{ + return d->m_viewOn.data(); +} + +void AbstractMetaType::setViewOn(const AbstractMetaType &v) +{ + if (d->m_viewOn.isNull() || *d->m_viewOn != v) + d->m_viewOn.reset(new AbstractMetaType(v)); +} + +AbstractMetaType AbstractMetaType::createVoid() +{ + static QScopedPointer<AbstractMetaType> metaType; + if (metaType.isNull()) { + static const TypeEntry *voidTypeEntry = TypeDatabase::instance()->findType(QLatin1String("void")); + Q_ASSERT(voidTypeEntry); + metaType.reset(new AbstractMetaType(voidTypeEntry)); + metaType->decideUsagePattern(); + } + return *metaType.data(); +} + +#ifndef QT_NO_DEBUG_STREAM +void AbstractMetaType::formatDebug(QDebug &debug) const +{ + debug << '"' << name() << '"'; + if (debug.verbosity() > 2) { + auto te = typeEntry(); + debug << ", typeEntry="; + if (debug.verbosity() > 3) + debug << te; + else + debug << "(\"" << te->qualifiedCppName() << "\", " << te->type() << ')'; + debug << ", signature=\"" << cppSignature() << "\", pattern=" + << typeUsagePattern(); + const auto indirections = indirectionsV(); + if (!indirections.isEmpty()) { + debug << ", indirections="; + for (auto i : indirections) + debug << ' ' << TypeInfo::indirectionKeyword(i); + } + if (referenceType()) + debug << ", reftype=" << referenceType(); + if (isConstant()) + debug << ", [const]"; + if (isVolatile()) + debug << ", [volatile]"; + if (isArray()) { + debug << ", array of \"" << arrayElementType()->cppSignature() + << "\", arrayElementCount=" << arrayElementCount(); + } + const auto &instantiations = this->instantiations(); + if (const int instantiationsSize = instantiations.size()) { + debug << ", instantiations[" << instantiationsSize << "]=<"; + for (int i = 0; i < instantiationsSize; ++i) { + if (i) + debug << ", "; + instantiations.at(i).formatDebug(debug); + } + } + debug << '>'; + if (viewOn()) + debug << ", views " << viewOn()->name(); + } +} + +QDebug operator<<(QDebug d, const AbstractMetaType &at) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + d << "AbstractMetaType("; + at.formatDebug(d); + d << ')'; + return d; +} + +QDebug operator<<(QDebug d, const AbstractMetaType *at) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + if (at) + d << *at; + else + d << "AbstractMetaType(0)"; + return d; +} + +#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/abstractmetatype.h b/sources/shiboken2/ApiExtractor/abstractmetatype.h new file mode 100644 index 000000000..c92a7652a --- /dev/null +++ b/sources/shiboken2/ApiExtractor/abstractmetatype.h @@ -0,0 +1,221 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ABSTRACTMETATYPE_H +#define ABSTRACTMETATYPE_H + +#include "abstractmetalang_typedefs.h" +#include "parser/codemodel_enums.h" + +#include <QtCore/qobjectdefs.h> +#include <QtCore/QSharedDataPointer> +#include <QtCore/QVector> + +QT_FORWARD_DECLARE_CLASS(QDebug) + +class AbstractMetaTypeData; +class TypeEntry; + +class AbstractMetaType +{ + Q_GADGET +public: + using Indirections = QVector<Indirection>; + + enum TypeUsagePattern { + InvalidPattern, + PrimitivePattern, + FlagsPattern, + EnumPattern, + ValuePattern, + ObjectPattern, + ValuePointerPattern, + NativePointerPattern, + NativePointerAsArrayPattern, // "int*" as "int[]" + ContainerPattern, + SmartPointerPattern, + VarargsPattern, + ArrayPattern, + VoidPattern, // Plain "void", no "void *" or similar. + TemplateArgument, // 'T' in std::array<T,2> + NonTypeTemplateArgument // '2' in in std::array<T,2> + }; + Q_ENUM(TypeUsagePattern) + + AbstractMetaType(); + explicit AbstractMetaType(const TypeEntry *t); + AbstractMetaType(const AbstractMetaType &); + AbstractMetaType &operator=(const AbstractMetaType &); + AbstractMetaType(AbstractMetaType &&); + AbstractMetaType &operator=(AbstractMetaType &&); + ~AbstractMetaType(); + + bool isValid() const; + operator bool() const { return isValid(); } + + QString package() const; + QString name() const; + QString fullName() const; + + void setTypeUsagePattern(TypeUsagePattern pattern); + TypeUsagePattern typeUsagePattern() const; + + // true when use pattern is container + bool hasInstantiations() const; + + const AbstractMetaTypeList &instantiations() const; + void addInstantiation(const AbstractMetaType &inst); + void setInstantiations(const AbstractMetaTypeList &insts); + + QString minimalSignature() const { return formatSignature(true); } + + // returns true if the typs is used as a non complex primitive, no & or *'s + bool isPrimitive() const { return typeUsagePattern() == PrimitivePattern; } + + bool isCppPrimitive() const; + + // returns true if the type is used as an enum + bool isEnum() const { return typeUsagePattern() == EnumPattern; } + + // returns true if the type is used as an object, e.g. Xxx * + bool isObject() const { return typeUsagePattern() == ObjectPattern; } + + // returns true if the type is used as an array, e.g. Xxx[42] + bool isArray() const { return typeUsagePattern() == ArrayPattern; } + + // returns true if the type is used as a value type (X or const X &) + bool isValue() const { return typeUsagePattern() == ValuePattern; } + + bool isValuePointer() const { return typeUsagePattern() == ValuePointerPattern; } + + // returns true for more complex types... + bool isNativePointer() const { return typeUsagePattern() == NativePointerPattern; } + + // return true if the type was originally a varargs + bool isVarargs() const { return typeUsagePattern() == VarargsPattern; } + + // returns true if the type was used as a container + bool isContainer() const { return typeUsagePattern() == ContainerPattern; } + + // returns true if the type was used as a smart pointer + bool isSmartPointer() const { return typeUsagePattern() == SmartPointerPattern; } + + // returns true if the type was used as a flag + bool isFlags() const { return typeUsagePattern() == FlagsPattern; } + + bool isVoid() const { return typeUsagePattern() == VoidPattern; } + + bool isConstant() const; + void setConstant(bool constant); + + bool isVolatile() const; + void setVolatile(bool v); + + bool passByConstRef() const; + bool passByValue() const; + + ReferenceType referenceType() const; + void setReferenceType(ReferenceType ref); + + int actualIndirections() const; + + Indirections indirectionsV() const; + void setIndirectionsV(const Indirections &i); + void clearIndirections(); + + // "Legacy"? + int indirections() const; + void setIndirections(int indirections); + void addIndirection(Indirection i = Indirection::Pointer); + + void setArrayElementCount(int n); + int arrayElementCount() const; + + const AbstractMetaType *arrayElementType() const; + void setArrayElementType(const AbstractMetaType &t); + + AbstractMetaTypeList nestedArrayTypes() const; + + QString cppSignature() const; + + QString pythonSignature() const; + + bool applyArrayModification(QString *errorMessage); + + const TypeEntry *typeEntry() const; + void setTypeEntry(const TypeEntry *type); + + void setOriginalTypeDescription(const QString &otd); + QString originalTypeDescription() const; + + void setOriginalTemplateType(const AbstractMetaType &type); + const AbstractMetaType *originalTemplateType() const; + + AbstractMetaType getSmartPointerInnerType() const; + + QString getSmartPointerInnerTypeName() const; + + /// Decides and sets the proper usage patter for the current meta type. + void decideUsagePattern(); + + bool hasTemplateChildren() const; + + bool equals(const AbstractMetaType &rhs) const; + + // View on: Type to use for function argument conversion, fex + // std::string_view -> std::string for foo(std::string_view); + // cf TypeEntry::viewOn() + const AbstractMetaType *viewOn() const; + void setViewOn(const AbstractMetaType &v); + + static AbstractMetaType createVoid(); + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &debug) const; +#endif + +private: + friend class AbstractMetaTypeData; + QSharedDataPointer<AbstractMetaTypeData> d; + + TypeUsagePattern determineUsagePattern() const; + QString formatSignature(bool minimal) const; + QString formatPythonSignature() const; +}; + +inline bool operator==(const AbstractMetaType &t1, const AbstractMetaType &t2) +{ return t1.equals(t2); } +inline bool operator!=(const AbstractMetaType &t1, const AbstractMetaType &t2) +{ return !t1.equals(t2); } + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const AbstractMetaType &at); +QDebug operator<<(QDebug d, const AbstractMetaType *at); +#endif + +#endif // ABSTRACTMETALANG_H diff --git a/sources/shiboken2/ApiExtractor/doxygenparser.cpp b/sources/shiboken2/ApiExtractor/doxygenparser.cpp index cf152720e..c6bc3b440 100644 --- a/sources/shiboken2/ApiExtractor/doxygenparser.cpp +++ b/sources/shiboken2/ApiExtractor/doxygenparser.cpp @@ -138,15 +138,15 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass) int i = 1; const AbstractMetaArgumentList &arguments = func->arguments(); for (AbstractMetaArgument *arg : arguments) { - if (!arg->type()->isPrimitive()) { + if (!arg->type().isPrimitive()) { query += QLatin1String("/../param[") + QString::number(i) + QLatin1String("]/type/ref[text()=\"") - + arg->type()->cppSignature().toHtmlEscaped() + + arg->type().cppSignature().toHtmlEscaped() + QLatin1String("\"]/../.."); } else { query += QLatin1String("/../param[") + QString::number(i) + QLatin1String("]/type[text(), \"") - + arg->type()->cppSignature().toHtmlEscaped() + + arg->type().cppSignature().toHtmlEscaped() + QLatin1String("\"]/.."); } ++i; diff --git a/sources/shiboken2/ApiExtractor/propertyspec.cpp b/sources/shiboken2/ApiExtractor/propertyspec.cpp index f86a31d5b..d15647fda 100644 --- a/sources/shiboken2/ApiExtractor/propertyspec.cpp +++ b/sources/shiboken2/ApiExtractor/propertyspec.cpp @@ -42,7 +42,7 @@ #include <algorithm> QPropertySpec::QPropertySpec(const TypeSystemProperty &ts, - const AbstractMetaType *type) : + const AbstractMetaType &type) : m_name(ts.name), m_read(ts.read), m_write(ts.write), @@ -53,19 +53,16 @@ QPropertySpec::QPropertySpec(const TypeSystemProperty &ts, { } -QPropertySpec::~QPropertySpec() -{ - delete m_type; -} +QPropertySpec::~QPropertySpec() = default; bool QPropertySpec::isValid() const { - return m_type != nullptr && !m_name.isEmpty() && !m_read.isEmpty(); + return m_type.isValid() && !m_name.isEmpty() && !m_read.isEmpty(); } const TypeEntry *QPropertySpec::typeEntry() const { - return m_type->typeEntry(); + return m_type.typeEntry(); } // Parse a Q_PROPERTY macro @@ -161,10 +158,10 @@ QPropertySpec *QPropertySpec::fromTypeSystemProperty(AbstractMetaBuilderPrivate return nullptr; } - AbstractMetaType *type = b->translateType(info, metaClass, {}, &typeError); + AbstractMetaType type = b->translateType(info, metaClass, {}, &typeError); if (!type) { const QStringList qualifiedName = info.qualifiedName(); - for (int j = scopes.size(); j >= 0 && type == nullptr; --j) { + for (int j = scopes.size(); j >= 0 && !type; --j) { info.setQualifiedName(scopes.mid(0, j) + qualifiedName); type = b->translateType(info, metaClass, {}, &typeError); } @@ -195,7 +192,7 @@ QPropertySpec *QPropertySpec::parseQ_Property(AbstractMetaBuilderPrivate *b, #ifndef QT_NO_DEBUG_STREAM void QPropertySpec::formatDebug(QDebug &d) const { - d << '#' << m_index << " \"" << m_name << "\" (" << m_type->cppSignature(); + d << '#' << m_index << " \"" << m_name << "\" (" << m_type.cppSignature(); d << "), read=" << m_read; if (!m_write.isEmpty()) d << ", write=" << m_write; diff --git a/sources/shiboken2/ApiExtractor/propertyspec.h b/sources/shiboken2/ApiExtractor/propertyspec.h index 611d4726e..d26f7e826 100644 --- a/sources/shiboken2/ApiExtractor/propertyspec.h +++ b/sources/shiboken2/ApiExtractor/propertyspec.h @@ -29,6 +29,8 @@ #ifndef PROPERTYSPEC_H #define PROPERTYSPEC_H +#include "abstractmetatype.h" + #include <QtCore/QStringList> class AbstractMetaClass; @@ -46,7 +48,7 @@ public: Q_DISABLE_COPY_MOVE(QPropertySpec) explicit QPropertySpec(const TypeSystemProperty &ts, - const AbstractMetaType *type); + const AbstractMetaType &type); ~QPropertySpec(); static TypeSystemProperty typeSystemPropertyFromQ_Property(const QString &declarationIn, @@ -66,8 +68,8 @@ public: bool isValid() const; - const AbstractMetaType *type() const { return m_type; } - void setType(AbstractMetaType *t) { m_type = t; } + const AbstractMetaType &type() const { return m_type; } + void setType(const AbstractMetaType &t) { m_type = t; } const TypeEntry *typeEntry() const; @@ -103,7 +105,7 @@ private: QString m_write; QString m_designable; QString m_reset; - const AbstractMetaType *m_type = nullptr; + AbstractMetaType m_type; int m_index = -1; // Indicates whether actual code is generated instead of relying on libpyside. bool m_generateGetSetDef = false; diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp index d439b3fd5..9318ef18b 100644 --- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp +++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp @@ -48,49 +48,49 @@ Documentation QtDocParser::retrieveModuleDocumentation() static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgument *arg) { - const AbstractMetaType *metaType = arg->type(); - if (metaType->isConstant()) + const AbstractMetaType &metaType = arg->type(); + if (metaType.isConstant()) str << "const " ; - switch (metaType->typeUsagePattern()) { + switch (metaType.typeUsagePattern()) { case AbstractMetaType::FlagsPattern: { // Modify qualified name "QFlags<Qt::AlignmentFlag>" with name "Alignment" // to "Qt::Alignment" as seen by qdoc. - const auto *flagsEntry = static_cast<const FlagsTypeEntry *>(metaType->typeEntry()); + const auto *flagsEntry = static_cast<const FlagsTypeEntry *>(metaType.typeEntry()); QString name = flagsEntry->qualifiedCppName(); if (name.endsWith(QLatin1Char('>')) && name.startsWith(QLatin1String("QFlags<"))) { const int lastColon = name.lastIndexOf(QLatin1Char(':')); if (lastColon != -1) { - name.replace(lastColon + 1, name.size() - lastColon - 1, metaType->name()); + name.replace(lastColon + 1, name.size() - lastColon - 1, metaType.name()); name.remove(0, 7); } else { - name = metaType->name(); // QFlags<> of enum in global namespace + name = metaType.name(); // QFlags<> of enum in global namespace } } str << name; } break; case AbstractMetaType::ContainerPattern: { // QVector<int> - str << metaType->typeEntry()->qualifiedCppName() << '<'; - const auto instantiations = metaType->instantiations(); + str << metaType.typeEntry()->qualifiedCppName() << '<'; + const auto instantiations = metaType.instantiations(); for (int i = 0, size = instantiations.size(); i < size; ++i) { if (i) str << ", "; - str << instantiations.at(i)->typeEntry()->qualifiedCppName(); + str << instantiations.at(i).typeEntry()->qualifiedCppName(); } str << '>'; } break; default: // Fully qualify enums (Qt::AlignmentFlag), nested classes, etc. - str << metaType->typeEntry()->qualifiedCppName(); + str << metaType.typeEntry()->qualifiedCppName(); break; } - if (metaType->referenceType() == LValueReference) + if (metaType.referenceType() == LValueReference) str << " &"; - else if (metaType->referenceType() == RValueReference) + else if (metaType.referenceType() == RValueReference) str << " &&"; - else if (metaType->indirections()) - str << ' ' << QByteArray(metaType->indirections(), '*'); + else if (metaType.indirections()) + str << ' ' << QByteArray(metaType.indirections(), '*'); } enum FunctionMatchFlags diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp index 980d08489..cbbda70b8 100644 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp @@ -74,20 +74,20 @@ void TestAbstractMetaType::testConstCharPtrType() QVERIFY(!builder.isNull()); QCOMPARE(builder->globalFunctions().size(), 1); AbstractMetaFunction *func = builder->globalFunctions().constFirst(); - AbstractMetaType* rtype = func->type(); + AbstractMetaType rtype = func->type(); // Test properties of const char* QVERIFY(rtype); - QCOMPARE(rtype->package(), QLatin1String("Foo")); - QCOMPARE(rtype->name(), QLatin1String("char")); - QVERIFY(rtype->isConstant()); - QVERIFY(!rtype->isArray()); - QVERIFY(!rtype->isContainer()); - QVERIFY(!rtype->isObject()); - QVERIFY(!rtype->isPrimitive()); // const char* differs from char, so it's not considered a primitive type by apiextractor - QVERIFY(rtype->isNativePointer()); - QCOMPARE(rtype->referenceType(), NoReference); - QVERIFY(!rtype->isValue()); - QVERIFY(!rtype->isValuePointer()); + QCOMPARE(rtype.package(), QLatin1String("Foo")); + QCOMPARE(rtype.name(), QLatin1String("char")); + QVERIFY(rtype.isConstant()); + QVERIFY(!rtype.isArray()); + QVERIFY(!rtype.isContainer()); + QVERIFY(!rtype.isObject()); + QVERIFY(!rtype.isPrimitive()); // const char* differs from char, so it's not considered a primitive type by apiextractor + QVERIFY(rtype.isNativePointer()); + QCOMPARE(rtype.referenceType(), NoReference); + QVERIFY(!rtype.isValue()); + QVERIFY(!rtype.isValuePointer()); } void TestAbstractMetaType::testApiVersionSupported() @@ -147,20 +147,20 @@ void TestAbstractMetaType::testCharType() AbstractMetaFunctionList functions = builder->globalFunctions(); QCOMPARE(functions.size(), 1); AbstractMetaFunction *func = functions.constFirst(); - AbstractMetaType* rtype = func->type(); + AbstractMetaType rtype = func->type(); // Test properties of const char* QVERIFY(rtype); - QCOMPARE(rtype->package(), QLatin1String("Foo")); - QCOMPARE(rtype->name(), QLatin1String("char")); - QVERIFY(!rtype->isConstant()); - QVERIFY(!rtype->isArray()); - QVERIFY(!rtype->isContainer()); - QVERIFY(!rtype->isObject()); - QVERIFY(rtype->isPrimitive()); - QVERIFY(!rtype->isNativePointer()); - QCOMPARE(rtype->referenceType(), NoReference); - QVERIFY(!rtype->isValue()); - QVERIFY(!rtype->isValuePointer()); + QCOMPARE(rtype.package(), QLatin1String("Foo")); + QCOMPARE(rtype.name(), QLatin1String("char")); + QVERIFY(!rtype.isConstant()); + QVERIFY(!rtype.isArray()); + QVERIFY(!rtype.isContainer()); + QVERIFY(!rtype.isObject()); + QVERIFY(rtype.isPrimitive()); + QVERIFY(!rtype.isNativePointer()); + QCOMPARE(rtype.referenceType(), NoReference); + QVERIFY(!rtype.isValue()); + QVERIFY(!rtype.isValuePointer()); } void TestAbstractMetaType::testTypedef() @@ -210,8 +210,8 @@ void TestAbstractMetaType::testTypedefWithTemplates() AbstractMetaArgumentList args = function->arguments(); QCOMPARE(args.count(), 1); AbstractMetaArgument *arg = args.constFirst(); - AbstractMetaType* metaType = arg->type(); - QCOMPARE(metaType->cppSignature(), QLatin1String("A<B >")); + AbstractMetaType metaType = arg->type(); + QCOMPARE(metaType.cppSignature(), QLatin1String("A<B >")); } @@ -238,10 +238,10 @@ void TestAbstractMetaType::testObjectTypeUsedAsValue() AbstractMetaArgumentList args = method->arguments(); QCOMPARE(args.count(), 1); AbstractMetaArgument* arg = args.constFirst(); - AbstractMetaType* metaType = arg->type(); - QCOMPARE(metaType->cppSignature(), QLatin1String("A")); - QVERIFY(metaType->isValue()); - QVERIFY(metaType->typeEntry()->isObject()); + AbstractMetaType metaType = arg->type(); + QCOMPARE(metaType.cppSignature(), QLatin1String("A")); + QVERIFY(metaType.isValue()); + QVERIFY(metaType.typeEntry()->isObject()); } QTEST_APPLESS_MAIN(TestAbstractMetaType) diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp index 46307f94c..4289b4e49 100644 --- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp @@ -112,13 +112,13 @@ struct A { QVERIFY(!addedFunc->isSlot()); QVERIFY(!addedFunc->isStatic()); - AbstractMetaType* returnType = addedFunc->type(); - QCOMPARE(returnType->typeEntry(), typeDb->findPrimitiveType(QLatin1String("int"))); + AbstractMetaType returnType = addedFunc->type(); + QCOMPARE(returnType.typeEntry(), typeDb->findPrimitiveType(QLatin1String("int"))); AbstractMetaArgumentList args = addedFunc->arguments(); QCOMPARE(args.count(), 3); - QCOMPARE(args[0]->type()->typeEntry(), returnType->typeEntry()); + QCOMPARE(args[0]->type().typeEntry(), returnType.typeEntry()); QCOMPARE(args[1]->defaultValueExpression(), QLatin1String("4.6")); - QCOMPARE(args[2]->type()->typeEntry(), typeDb->findType(QLatin1String("B"))); + QCOMPARE(args[2]->type().typeEntry(), typeDb->findType(QLatin1String("B"))); auto addedCallOperator = classA->findFunction(QLatin1String("operator()")); QVERIFY(addedCallOperator); @@ -313,8 +313,8 @@ void TestAddFunction::testAddFunctionWithVarargs() const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func")); QVERIFY(addedFunc); const AbstractMetaArgument *arg = addedFunc->arguments().constLast(); - QVERIFY(arg->type()->isVarargs()); - QVERIFY(arg->type()->typeEntry()->isVarargs()); + QVERIFY(arg->type().isVarargs()); + QVERIFY(arg->type().typeEntry()->isVarargs()); } void TestAddFunction::testAddStaticFunction() @@ -460,7 +460,7 @@ void TestAddFunction::testAddFunctionWithTemplateArg() QCOMPARE(builder->globalFunctions().size(), 1); AbstractMetaFunction *func = builder->globalFunctions().constFirst(); AbstractMetaArgument *arg = func->arguments().constFirst(); - QCOMPARE(arg->type()->instantiations().count(), 1); + QCOMPARE(arg->type().instantiations().count(), 1); } QTEST_APPLESS_MAIN(TestAddFunction) diff --git a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp index b7b5ead17..ab05802b3 100644 --- a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp @@ -53,9 +53,9 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByInteger() QVERIFY(classA); const AbstractMetaArgument *arg = classA->functions().constLast()->arguments().constFirst(); - QVERIFY(arg->type()->isArray()); - QCOMPARE(arg->type()->arrayElementCount(), 3); - QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double")); + QVERIFY(arg->type().isArray()); + QCOMPARE(arg->type().arrayElementCount(), 3); + QCOMPARE(arg->type().arrayElementType()->name(), QLatin1String("double")); } static QString functionMinimalSignature(const AbstractMetaClass *c, const QString &name) @@ -132,9 +132,9 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValue() QVERIFY(nvalues); const AbstractMetaArgument *arg = classA->functions().constLast()->arguments().constFirst(); - QVERIFY(arg->type()->isArray()); - QCOMPARE(arg->type()->arrayElementCount(), nvalues->value().value()); - QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double")); + QVERIFY(arg->type().isArray()); + QCOMPARE(arg->type().arrayElementCount(), nvalues->value().value()); + QCOMPARE(arg->type().arrayElementType()->name(), QLatin1String("double")); }; void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnum() @@ -163,9 +163,9 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnu QVERIFY(nvalues); const AbstractMetaArgument *arg = classA->functions().constLast()->arguments().constFirst(); - QVERIFY(arg->type()->isArray()); - QCOMPARE(arg->type()->arrayElementCount(), nvalues->value().value()); - QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double")); + QVERIFY(arg->type().isArray()); + QCOMPARE(arg->type().arrayElementCount(), nvalues->value().value()); + QCOMPARE(arg->type().arrayElementType()->name(), QLatin1String("double")); }; QTEST_APPLESS_MAIN(TestArrayArgument) diff --git a/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp b/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp index 0da16924a..3c33c7d1e 100644 --- a/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp @@ -91,17 +91,17 @@ void TestContainer::testListOfValueType() const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); QVERIFY(classA); QCOMPARE(classA->templateBaseClassInstantiations().count(), 1); - const AbstractMetaType *templateInstanceType = + const AbstractMetaType templateInstanceType = classA->templateBaseClassInstantiations().constFirst(); QVERIFY(templateInstanceType); - QCOMPARE(templateInstanceType->indirections(), 0); - QVERIFY(!templateInstanceType->typeEntry()->isObject()); - QVERIFY(templateInstanceType->typeEntry()->isValue()); - QCOMPARE(templateInstanceType->referenceType(), NoReference); - QVERIFY(!templateInstanceType->isObject()); - QVERIFY(!templateInstanceType->isValuePointer()); - QVERIFY(templateInstanceType->isValue()); + QCOMPARE(templateInstanceType.indirections(), 0); + QVERIFY(!templateInstanceType.typeEntry()->isObject()); + QVERIFY(templateInstanceType.typeEntry()->isValue()); + QCOMPARE(templateInstanceType.referenceType(), NoReference); + QVERIFY(!templateInstanceType.isObject()); + QVERIFY(!templateInstanceType.isValuePointer()); + QVERIFY(templateInstanceType.isValue()); } QTEST_APPLESS_MAIN(TestContainer) diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp index 2af427294..8e4eebcb5 100644 --- a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp @@ -148,12 +148,12 @@ void TestConversionOperator::testConversionOperatorReturningReference() QCOMPARE(classA->functions().count(), 2); QCOMPARE(classB->functions().count(), 3); QCOMPARE(classA->externalConversionOperators().count(), 1); - QCOMPARE(classA->externalConversionOperators().constFirst()->type()->cppSignature(), + QCOMPARE(classA->externalConversionOperators().constFirst()->type().cppSignature(), QLatin1String("A")); QCOMPARE(classA->externalConversionOperators().constFirst()->ownerClass()->name(), QLatin1String("B")); QCOMPARE(classA->implicitConversions().count(), 1); - QCOMPARE(classA->implicitConversions().constFirst()->type()->cppSignature(), + QCOMPARE(classA->implicitConversions().constFirst()->type().cppSignature(), QLatin1String("A")); QCOMPARE(classA->implicitConversions().constFirst()->ownerClass()->name(), QLatin1String("B")); @@ -182,12 +182,12 @@ void TestConversionOperator::testConversionOperatorReturningConstReference() QCOMPARE(classA->functions().count(), 2); QCOMPARE(classB->functions().count(), 3); QCOMPARE(classA->externalConversionOperators().count(), 1); - QCOMPARE(classA->externalConversionOperators().constFirst()->type()->cppSignature(), + QCOMPARE(classA->externalConversionOperators().constFirst()->type().cppSignature(), QLatin1String("A")); QCOMPARE(classA->externalConversionOperators().constFirst()->ownerClass()->name(), QLatin1String("B")); QCOMPARE(classA->implicitConversions().count(), 1); - QCOMPARE(classA->implicitConversions().constFirst()->type()->cppSignature(), + QCOMPARE(classA->implicitConversions().constFirst()->type().cppSignature(), QLatin1String("A")); QCOMPARE(classA->implicitConversions().constFirst()->ownerClass()->name(), QLatin1String("B")); diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.cpp b/sources/shiboken2/ApiExtractor/tests/testenum.cpp index 82cdd291c..607a8f627 100644 --- a/sources/shiboken2/ApiExtractor/tests/testenum.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testenum.cpp @@ -64,7 +64,7 @@ void TestEnum::testEnumCppSignature() AbstractMetaFunctionList functions = builder->globalFunctions(); QCOMPARE(functions.count(), 1); QCOMPARE(functions.constFirst()->arguments().count(), 1); - QCOMPARE(functions.constFirst()->arguments().constFirst()->type()->cppSignature(), + QCOMPARE(functions.constFirst()->arguments().constFirst()->type().cppSignature(), QLatin1String("A::ClassEnum")); // enum as parameter of a method @@ -75,12 +75,12 @@ void TestEnum::testEnumCppSignature() AbstractMetaFunction *method = funcs.constFirst(); QVERIFY(method); AbstractMetaArgument *arg = method->arguments().constFirst(); - QCOMPARE(arg->type()->name(), QLatin1String("ClassEnum")); - QCOMPARE(arg->type()->cppSignature(), QLatin1String("A::ClassEnum")); + QCOMPARE(arg->type().name(), QLatin1String("ClassEnum")); + QCOMPARE(arg->type().cppSignature(), QLatin1String("A::ClassEnum")); QCOMPARE(functions.constFirst()->arguments().count(), 1); arg = functions.constFirst()->arguments().constFirst(); - QCOMPARE(arg->type()->name(), QLatin1String("ClassEnum")); - QCOMPARE(arg->type()->cppSignature(), QLatin1String("A::ClassEnum")); + QCOMPARE(arg->type().name(), QLatin1String("ClassEnum")); + QCOMPARE(arg->type().cppSignature(), QLatin1String("A::ClassEnum")); AbstractMetaEnumList classEnums = classA->enums(); QCOMPARE(classEnums.constFirst()->name(), QLatin1String("ClassEnum")); diff --git a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp index f960fca2f..a48298bf7 100644 --- a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp @@ -59,7 +59,7 @@ void TestImplicitConversions::testWithPrivateCtors() const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C")); AbstractMetaFunctionList implicitConvs = classA->implicitConversions(); QCOMPARE(implicitConvs.count(), 1); - QCOMPARE(implicitConvs.constFirst()->arguments().constFirst()->type()->typeEntry(), + QCOMPARE(implicitConvs.constFirst()->arguments().constFirst()->type().typeEntry(), classC->typeEntry()); } @@ -89,7 +89,7 @@ void TestImplicitConversions::testWithModifiedVisibility() const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); AbstractMetaFunctionList implicitConvs = classA->implicitConversions(); QCOMPARE(implicitConvs.count(), 1); - QCOMPARE(implicitConvs.constFirst()->arguments().constFirst()->type()->typeEntry(), + QCOMPARE(implicitConvs.constFirst()->arguments().constFirst()->type().typeEntry(), classB->typeEntry()); } diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp index 77bc6b5c9..cca0370e6 100644 --- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp @@ -312,7 +312,7 @@ void TestModifyFunction::testGlobalFunctionModification() QVERIFY(func); QCOMPARE(func->arguments().count(), 1); const AbstractMetaArgument *arg = func->arguments().constFirst(); - QCOMPARE(arg->type()->cppSignature(), QLatin1String("A *")); + QCOMPARE(arg->type().cppSignature(), QLatin1String("A *")); QCOMPARE(arg->originalDefaultValueExpression(), QLatin1String("0")); QCOMPARE(arg->defaultValueExpression(), QLatin1String("A()")); } diff --git a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp index 446c6f431..43d4b2f33 100644 --- a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp @@ -75,7 +75,8 @@ void TestNestedTypes::testNestedTypesModifications() QVERIFY(addedFunc->isUserAdded()); QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Public); QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction); - QCOMPARE(addedFunc->type()->minimalSignature(), QLatin1String("OuterNamespace::InnerNamespace::SomeClass")); + QCOMPARE(addedFunc->type().minimalSignature(), + QLatin1String("OuterNamespace::InnerNamespace::SomeClass")); QCOMPARE(addedFunc->modifications().size(), 1); QVERIFY(addedFunc->modifications().constFirst().isCodeInjection()); diff --git a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp index 03129073a..ab91e2c3b 100644 --- a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp @@ -60,17 +60,17 @@ void TestNumericalTypedef::testNumericalTypedef() QCOMPARE(funcDouble->minimalSignature(), QLatin1String("funcDouble(double)")); QCOMPARE(funcReal->minimalSignature(), QLatin1String("funcReal(real)")); - const AbstractMetaType *doubleType = funcDouble->arguments().constFirst()->type(); + const AbstractMetaType doubleType = funcDouble->arguments().constFirst()->type(); QVERIFY(doubleType); - QCOMPARE(doubleType->cppSignature(), QLatin1String("double")); - QVERIFY(doubleType->isPrimitive()); - QVERIFY(doubleType->typeEntry()->isCppPrimitive()); + QCOMPARE(doubleType.cppSignature(), QLatin1String("double")); + QVERIFY(doubleType.isPrimitive()); + QVERIFY(doubleType.typeEntry()->isCppPrimitive()); - const AbstractMetaType *realType = funcReal->arguments().constFirst()->type(); + const AbstractMetaType realType = funcReal->arguments().constFirst()->type(); QVERIFY(realType); - QCOMPARE(realType->cppSignature(), QLatin1String("real")); - QVERIFY(realType->isPrimitive()); - QVERIFY(realType->typeEntry()->isCppPrimitive()); + QCOMPARE(realType.cppSignature(), QLatin1String("real")); + QVERIFY(realType.isPrimitive()); + QVERIFY(realType.typeEntry()->isCppPrimitive()); } void TestNumericalTypedef::testUnsignedNumericalTypedef() @@ -102,17 +102,17 @@ void TestNumericalTypedef::testUnsignedNumericalTypedef() QCOMPARE(funcUnsignedShort->minimalSignature(), QLatin1String("funcUnsignedShort(unsigned short)")); QCOMPARE(funcUShort->minimalSignature(), QLatin1String("funcUShort(custom_ushort)")); - const AbstractMetaType *unsignedShortType = funcUnsignedShort->arguments().constFirst()->type(); + const AbstractMetaType unsignedShortType = funcUnsignedShort->arguments().constFirst()->type(); QVERIFY(unsignedShortType); - QCOMPARE(unsignedShortType->cppSignature(), QLatin1String("unsigned short")); - QVERIFY(unsignedShortType->isPrimitive()); - QVERIFY(unsignedShortType->typeEntry()->isCppPrimitive()); + QCOMPARE(unsignedShortType.cppSignature(), QLatin1String("unsigned short")); + QVERIFY(unsignedShortType.isPrimitive()); + QVERIFY(unsignedShortType.typeEntry()->isCppPrimitive()); - const AbstractMetaType *ushortType = funcUShort->arguments().constFirst()->type(); + const AbstractMetaType ushortType = funcUShort->arguments().constFirst()->type(); QVERIFY(ushortType); - QCOMPARE(ushortType->cppSignature(), QLatin1String("custom_ushort")); - QVERIFY(ushortType->isPrimitive()); - QVERIFY(ushortType->typeEntry()->isCppPrimitive()); + QCOMPARE(ushortType.cppSignature(), QLatin1String("custom_ushort")); + QVERIFY(ushortType.isPrimitive()); + QVERIFY(ushortType.typeEntry()->isCppPrimitive()); } QTEST_APPLESS_MAIN(TestNumericalTypedef) diff --git a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp index 228bfaecd..b9997b90e 100644 --- a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp @@ -51,7 +51,7 @@ void TestReferenceToPointer::testReferenceToPointerArgument() QVERIFY(classB); const AbstractMetaFunction* func = classB->findFunction(QLatin1String("dummy")); QVERIFY(func); - QCOMPARE(func->arguments().constFirst()->type()->minimalSignature(), QLatin1String("A*&")); + QCOMPARE(func->arguments().constFirst()->type().minimalSignature(), QLatin1String("A*&")); } QTEST_APPLESS_MAIN(TestReferenceToPointer) diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp index 20170089a..e3ea3cbb0 100644 --- a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp @@ -63,7 +63,7 @@ void TestRemoveImplConv::testRemoveImplConv() QVERIFY(classC); AbstractMetaFunctionList implConv = classC->implicitConversions(); QCOMPARE(implConv.count(), 1); - QCOMPARE(implConv.constFirst()->arguments().constFirst()->type()->typeEntry(), + QCOMPARE(implConv.constFirst()->arguments().constFirst()->type().typeEntry(), classB->typeEntry()); } diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp index f6c70a651..217b31256 100644 --- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp @@ -76,9 +76,9 @@ namespace Internet { AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("Bookmarks")); QVERIFY(classB); const AbstractMetaFunction* func = classB->findFunction(QLatin1String("list")); - AbstractMetaType* funcType = func->type(); + AbstractMetaType funcType = func->type(); QVERIFY(funcType); - QCOMPARE(funcType->cppSignature(), QLatin1String("QList<Internet::Url >")); + QCOMPARE(funcType.cppSignature(), QLatin1String("QList<Internet::Url >")); } void TestTemplates::testTemplateOnContainers() @@ -115,17 +115,17 @@ namespace Namespace { QVERIFY(!classB->baseClass()); QVERIFY(classB->baseClassName().isEmpty()); const AbstractMetaFunction* func = classB->findFunction(QLatin1String("foo")); - AbstractMetaType* argType = func->arguments().constFirst()->type(); - QCOMPARE(argType->instantiations().count(), 1); - QCOMPARE(argType->typeEntry()->qualifiedCppName(), QLatin1String("QList")); + AbstractMetaType argType = func->arguments().constFirst()->type(); + QCOMPARE(argType.instantiations().count(), 1); + QCOMPARE(argType.typeEntry()->qualifiedCppName(), QLatin1String("QList")); - const AbstractMetaType* instance1 = argType->instantiations().constFirst(); - QCOMPARE(instance1->instantiations().count(), 1); - QCOMPARE(instance1->typeEntry()->qualifiedCppName(), QLatin1String("Namespace::A")); + const AbstractMetaType &instance1 = argType.instantiations().constFirst(); + QCOMPARE(instance1.instantiations().count(), 1); + QCOMPARE(instance1.typeEntry()->qualifiedCppName(), QLatin1String("Namespace::A")); - const AbstractMetaType* instance2 = instance1->instantiations().constFirst(); - QCOMPARE(instance2->instantiations().count(), 0); - QCOMPARE(instance2->typeEntry()->qualifiedCppName(), QLatin1String("Namespace::E1")); + const AbstractMetaType &instance2 = instance1.instantiations().constFirst(); + QCOMPARE(instance2.instantiations().count(), 0); + QCOMPARE(instance2.typeEntry()->qualifiedCppName(), QLatin1String("Namespace::E1")); } void TestTemplates::testTemplateValueAsArgument() @@ -149,7 +149,7 @@ void func(List<int> arg) {} AbstractMetaFunction *func = globalFuncs.constFirst(); QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>)")); - QCOMPARE(func->arguments().constFirst()->type()->cppSignature(), + QCOMPARE(func->arguments().constFirst()->type().cppSignature(), QLatin1String("List<int >")); } @@ -174,7 +174,7 @@ void func(List<int>* arg) {} AbstractMetaFunction* func = globalFuncs.constFirst(); QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>*)")); - QCOMPARE(func->arguments().constFirst()->type()->cppSignature(), + QCOMPARE(func->arguments().constFirst()->type().cppSignature(), QLatin1String("List<int > *")); } @@ -199,7 +199,7 @@ void func(List<int>& arg) {} AbstractMetaFunction* func = globalFuncs.constFirst(); QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>&)")); - QCOMPARE(func->arguments().constFirst()->type()->cppSignature(), + QCOMPARE(func->arguments().constFirst()->type().cppSignature(), QLatin1String("List<int > &")); } @@ -231,13 +231,13 @@ struct List { const AbstractMetaFunction *append = list->findFunction(QStringLiteral("append")); QVERIFY(append); QCOMPARE(append->arguments().size(), 1); - QCOMPARE(append->arguments().at(0)->type()->cppSignature(), QLatin1String("List<T >")); + QCOMPARE(append->arguments().at(0)->type().cppSignature(), QLatin1String("List<T >")); // Verify that the parameter of "void erase(Iterator)" is not modified const AbstractMetaFunction *erase = list->findFunction(QStringLiteral("erase")); QVERIFY(erase); QCOMPARE(erase->arguments().size(), 1); QEXPECT_FAIL("", "Clang: Some other code changes the parameter type", Abort); - QCOMPARE(erase->arguments().at(0)->type()->cppSignature(), QLatin1String("List::Iterator")); + QCOMPARE(erase->arguments().at(0)->type().cppSignature(), QLatin1String("List::Iterator")); } void TestTemplates::testInheritanceFromContainterTemplate() @@ -394,12 +394,12 @@ typedef BaseTemplateClass<TypeOne> TypeOneClass; QVERIFY(one->hasTemplateBaseClassInstantiations()); AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations(); QCOMPARE(instantiations.count(), 1); - const AbstractMetaType *inst = instantiations.constFirst(); + const AbstractMetaType &inst = instantiations.constFirst(); QVERIFY(inst); - QVERIFY(!inst->isEnum()); - QVERIFY(!inst->typeEntry()->isEnum()); - QVERIFY(inst->typeEntry()->isEnumValue()); - QCOMPARE(inst->cppSignature(), QLatin1String("NSpace::TypeOne")); + QVERIFY(!inst.isEnum()); + QVERIFY(!inst.typeEntry()->isEnum()); + QVERIFY(inst.typeEntry()->isEnumValue()); + QCOMPARE(inst.cppSignature(), QLatin1String("NSpace::TypeOne")); } void TestTemplates::testContainerTypeIncompleteArgument() @@ -445,7 +445,7 @@ typedef Vector<int> IntVector; QVERIFY(otherMethod); QCOMPARE(otherMethod->signature(), QLatin1String("otherMethod()")); QVERIFY(otherMethod->type()); - QCOMPARE(otherMethod->type()->cppSignature(), QLatin1String("Vector<int >")); + QCOMPARE(otherMethod->type().cppSignature(), QLatin1String("Vector<int >")); } void TestTemplates::testNonTypeTemplates() @@ -474,7 +474,7 @@ Array<int, 2> foo(); QCOMPARE(functions.count(), 1); auto foo = functions.constFirst(); QCOMPARE(foo->name(), QLatin1String("foo")); - QCOMPARE(foo->type()->name(), QLatin1String("Array")); + QCOMPARE(foo->type().name(), QLatin1String("Array")); } // Perform checks on template inheritance; a typedef of a template class @@ -574,25 +574,25 @@ void TestTemplates::testTemplateTypeDefs() const AbstractMetaFunction *valueMethod = optionalInt->findFunction(QLatin1String("value")); QVERIFY(valueMethod); - QCOMPARE(valueMethod->type()->cppSignature(), QLatin1String("int")); + QCOMPARE(valueMethod->type().cppSignature(), QLatin1String("int")); // ditto for typesystem XML const AbstractMetaFunction *xmlValueMethod = xmlOptionalInt->findFunction(QLatin1String("value")); QVERIFY(xmlValueMethod); - QCOMPARE(xmlValueMethod->type()->cppSignature(), QLatin1String("int")); + QCOMPARE(xmlValueMethod->type().cppSignature(), QLatin1String("int")); // Check whether the m_value field is of type 'int' const AbstractMetaField *valueField = optionalInt->findField(QLatin1String("m_value")); QVERIFY(valueField); - QCOMPARE(valueField->type()->cppSignature(), QLatin1String("int")); + QCOMPARE(valueField->type().cppSignature(), QLatin1String("int")); // ditto for typesystem XML const AbstractMetaField *xmlValueField = xmlOptionalInt->findField(QLatin1String("m_value")); QVERIFY(xmlValueField); - QCOMPARE(xmlValueField->type()->cppSignature(), QLatin1String("int")); + QCOMPARE(xmlValueField->type().cppSignature(), QLatin1String("int")); } void TestTemplates::testTemplateTypeAliases() @@ -635,8 +635,8 @@ public: auto fields = testClass->fields(); QCOMPARE(fields.count(), 1); auto fieldType = testClass->fields().at(0)->type(); - QCOMPARE(fieldType->name(), QLatin1String("Container1")); - QCOMPARE(fieldType->instantiations().size(), 1); + QCOMPARE(fieldType.name(), QLatin1String("Container1")); + QCOMPARE(fieldType.instantiations().size(), 1); auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived")); QVERIFY(derived); |