/**************************************************************************** ** ** 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 #include #include #include QT_FORWARD_DECLARE_CLASS(QDebug) class AbstractMetaTypeData; class TypeEntry; class AbstractMetaType { Q_GADGET public: using Indirections = QList; enum TypeUsagePattern { 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 NonTypeTemplateArgument // '2' in in std::array }; Q_ENUM(TypeUsagePattern) AbstractMetaType(); explicit AbstractMetaType(const TypeEntry *t); AbstractMetaType(const AbstractMetaType &); AbstractMetaType &operator=(const AbstractMetaType &); AbstractMetaType(AbstractMetaType &&); AbstractMetaType &operator=(AbstractMetaType &&); ~AbstractMetaType(); 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 indicated an object by the TypeEntry bool isObjectType() const; // 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(); /// Builds an AbstractMetaType object from a QString. /// Returns nullopt if no type could be built from the string. /// \param typeSignature The string describing the type to be built. /// \return A new AbstractMetaType object or nullopt in case of failure. static std::optional fromString(QString typeSignature, QString *errorMessage = nullptr); /// Creates an AbstractMetaType object from a TypeEntry. static AbstractMetaType fromTypeEntry(const TypeEntry *typeEntry); /// Creates an AbstractMetaType object from an AbstractMetaClass. static AbstractMetaType fromAbstractMetaClass(const AbstractMetaClass *metaClass); static void dereference(QString *type); // "foo" -> "(*foo)" static bool stripDereference(QString *type); // "(*foo)" -> "foo" // Query functions for generators /// Check if type is a pointer. bool isPointer() const; /// Helper for field setters: Check for "const QWidget *" (settable field), /// but not "int *const" (read-only field). bool isPointerToConst() const; /// Returns true if the type is a C string (const char *). bool isCString() const; /// Returns true if the type is a void pointer. bool isVoidPointer() const; /// Returns true if the type is a primitive but not a C++ primitive. bool isUserPrimitive() const; /// Returns true if it is an Object Type used as a value. bool isObjectTypeUsedAsValueType() const; /// Returns true if the type passed has a Python wrapper for it. /// Although namespace has a Python wrapper, it's not considered a type. bool isWrapperType() const; /// Checks if the type is an Object/QObject or pointer to Value Type. /// In other words, tells if the type is "T*" and T has a Python wrapper. bool isPointerToWrapperType() const; /// Wrapper type passed by reference bool isWrapperPassedByReference() const; /// Checks if the meta type of an argument should be dereferenced by the Python /// method wrapper passing it to C++. bool shouldDereferenceArgument() const; /// Returns true if the type is a C++ integral primitive, /// i.e. bool, char, int, long, and their unsigned counterparts. bool isCppIntegralPrimitive() const; /// Returns true if the type is an extended C++ primitive, a void*, /// a const char*, or a std::string (cf isCppPrimitive()). bool isExtendedCppPrimitive() const; /// Returns whether the underlying type is a value type with copy constructor only bool isValueTypeWithCopyConstructorOnly() const; /// Returns whether the type (function argument) is a value type with /// copy constructor only is passed as value or const-ref and thus /// no default value can be constructed. bool valueTypeWithCopyConstructorOnlyPassed() const; #ifndef QT_NO_DEBUG_STREAM void formatDebug(QDebug &debug) const; #endif private: friend class AbstractMetaTypeData; QSharedDataPointer 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