diff options
Diffstat (limited to 'sources/shiboken6/ApiExtractor/abstractmetafunction.h')
-rw-r--r-- | sources/shiboken6/ApiExtractor/abstractmetafunction.h | 487 |
1 files changed, 487 insertions, 0 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.h b/sources/shiboken6/ApiExtractor/abstractmetafunction.h new file mode 100644 index 000000000..e252e439d --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.h @@ -0,0 +1,487 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef ABSTRACTMETAFUNCTION_H +#define ABSTRACTMETAFUNCTION_H + +#include "abstractmetalang_enums.h" +#include "abstractmetalang_typedefs.h" +#include "typesystem_enums.h" +#include "modifications_typedefs.h" +#include "typesystem_typedefs.h" +#include "parser/codemodel_enums.h" + +#include <QtCore/QMetaObject> +#include <QtCore/QScopedPointer> + +#include <optional> + +QT_FORWARD_DECLARE_CLASS(QDebug) +QT_FORWARD_DECLARE_CLASS(QRegularExpression) + +class AbstractMetaFunctionPrivate; +class AbstractMetaType; +class FunctionTypeEntry; +class Documentation; +class SourceLocation; + +struct ArgumentOwner; +struct ReferenceCount; + +class AbstractMetaFunction +{ + Q_GADGET +public: + Q_DISABLE_COPY_MOVE(AbstractMetaFunction) + + enum FunctionType { + ConstructorFunction, + CopyConstructorFunction, + MoveConstructorFunction, + AssignmentOperatorFunction, + MoveAssignmentOperatorFunction, + DestructorFunction, + NormalFunction, + SignalFunction, + EmptyFunction, + SlotFunction, + GetAttroFunction, + SetAttroFunction, + CallOperator, + FirstOperator = CallOperator, + ConversionOperator, + DereferenceOperator, // Iterator's operator * + ReferenceOperator, // operator & + ArrowOperator, + ArithmeticOperator, + IncrementOperator, + DecrementOperator, + BitwiseOperator, + LogicalOperator, + ShiftOperator, + SubscriptOperator, + ComparisonOperator, + LastOperator = ComparisonOperator + }; + Q_ENUM(FunctionType) + + enum ComparisonOperatorType { + OperatorEqual, OperatorNotEqual, OperatorLess, OperatorLessEqual, + OperatorGreater, OperatorGreaterEqual + }; + Q_ENUM(ComparisonOperatorType) + + enum CompareResultFlag { + EqualName = 0x00000001, + EqualArguments = 0x00000002, + EqualAttributes = 0x00000004, + EqualImplementor = 0x00000008, + EqualReturnType = 0x00000010, + EqualDefaultValueOverload = 0x00000020, + EqualModifiedName = 0x00000040, + + NameLessThan = 0x00001000, + + PrettySimilar = EqualName | EqualArguments, + Equal = 0x0000001f, + NotEqual = 0x00001000 + }; + Q_DECLARE_FLAGS(CompareResult, CompareResultFlag) + Q_FLAG(CompareResultFlag) + + enum Attribute { + None = 0x00000000, + + ClassMethod = 0x00000008, + + GetterFunction = 0x00000020, + SetterFunction = 0x00000040, + + PropertyReader = 0x00000100, + PropertyWriter = 0x00000200, + PropertyResetter = 0x00000400, + PropertyNotify = 0x00000800, + + // Add by meta builder (implicit constructors, inherited methods, etc) + AddedMethod = 0x001000000, + }; + Q_DECLARE_FLAGS(Attributes, Attribute) + Q_FLAG(Attribute) + + Attributes attributes() const; + void setAttributes(Attributes attributes); + + void operator+=(Attribute attribute); + void operator-=(Attribute attribute); + + FunctionAttributes cppAttributes() const; + void setCppAttributes(FunctionAttributes a); + void setCppAttribute(FunctionAttribute a, bool on = true); + + enum class Flag { // Internal flags not relevant for comparing functions + // Binary operator whose leading/trailing argument was removed by metabuilder + OperatorLeadingClassArgumentRemoved = 0x1, + OperatorTrailingClassArgumentRemoved = 0x2, + OperatorClassArgumentByValue = 0x4, // The removed class argument was passed by value + InheritedFromTemplate = 0x8, // Inherited from a template in metabuilder + HiddenFriend = 0x10, + PrivateSignal = 0x20 // Private Qt signal (cannot emit from client code) + }; + Q_DECLARE_FLAGS(Flags, Flag) + + Flags flags() const; + void setFlags(Flags f); + + bool isAbstract() const; + bool isClassMethod() const; + bool isStatic() const; + bool isPropertyReader() const; + bool isPropertyWriter() const; + bool isPropertyResetter() const; + + AbstractMetaFunction(); + explicit AbstractMetaFunction(const QString &name); + explicit AbstractMetaFunction(const AddedFunctionPtr &addedFunc); + ~AbstractMetaFunction(); + + QString name() const; + void setName(const QString &name); + + // Names under which the function will be registered to Python. + QStringList definitionNames() const; + + QString originalName() const; + + void setOriginalName(const QString &name); + + Access access() const; + void setAccess(Access a); + void modifyAccess(Access a); + + bool isPrivate() const { return access() == Access::Private; } + bool isProtected() const { return access() == Access::Protected; } + bool isPublic() const { return access() == Access::Public; } + bool wasPrivate() const; + bool wasProtected() const; + bool wasPublic() const; + + const Documentation &documentation() const; + void setDocumentation(const Documentation& doc); + + bool isReverseOperator() const; + void setReverseOperator(bool reverse); + + /// Returns true if this is a binary operator and the "self" operand is a + /// pointer, e.g. class Foo {}; operator+(SomeEnum, Foo*); + /// (not to be mixed up with DereferenceOperator). + bool isPointerOperator() const; + void setPointerOperator(bool value); + + + /** + * Says if the function (a constructor) was declared as explicit in C++. + * \return true if the function was declared as explicit in C++ + */ + bool isExplicit() const; + void setExplicit(bool isExplicit); + + bool returnsBool() const; + bool isOperatorBool() const; + static bool isConversionOperator(const QString& funcName); + + ExceptionSpecification exceptionSpecification() const; + void setExceptionSpecification(ExceptionSpecification e); + + bool generateExceptionHandling() const; + + bool isConversionOperator() const; + + static bool isOperatorOverload(const QString& funcName); + bool isOperatorOverload() const; + + bool isArithmeticOperator() const; + bool isBitwiseOperator() const; // Includes shift operator + bool isComparisonOperator() const; + /// Returns whether this is a comparison accepting owner class + /// (bool operator==(QByteArray,QByteArray) but not bool operator==(QByteArray,const char *) + bool isSymmetricalComparisonOperator() const; + bool isIncDecrementOperator() const; + bool isLogicalOperator() const; + bool isAssignmentOperator() const; // Assignment or move assignment + bool isGetter() const; + /// Returns whether it is a Qt-style isNull() method suitable for nb_bool + bool isQtIsNullMethod() const; + + /** + * Informs the arity of the operator or -1 if the function is not + * an operator overload. + * /return the arity of the operator or -1 + */ + int arityOfOperator() const; + bool isUnaryOperator() const { return arityOfOperator() == 1; } + bool isBinaryOperator() const { return arityOfOperator() == 2; } + bool isInplaceOperator() const; + + bool isVirtual() const; + bool allowThread() const; + QString modifiedName() const; + + QString minimalSignature() const; + /// List of signatures matched for modifications + QStringList modificationSignatures() const; + // Signature with replaced argument types and return type for overload + // decisor comment. + QString signatureComment() const; + QString debugSignature() const; // including virtual/override/final, etc., for debugging only. + + bool isModifiedRemoved(AbstractMetaClassCPtr cls = {}) const; + bool isModifiedFinal(AbstractMetaClassCPtr cls = {}) const; + + bool isVoid() const; + + const AbstractMetaType &type() const; + void setType(const AbstractMetaType &type); + + // The class that has this function as a member. + AbstractMetaClassCPtr ownerClass() const; + void setOwnerClass(const AbstractMetaClassCPtr &cls); + + // Owner excluding invisible namespaces + AbstractMetaClassCPtr targetLangOwner() const; + + // The first class in a hierarchy that declares the function + AbstractMetaClassCPtr declaringClass() const; + void setDeclaringClass(const AbstractMetaClassCPtr &cls); + + // The class that actually implements this function + AbstractMetaClassCPtr implementingClass() const; + void setImplementingClass(const AbstractMetaClassCPtr &cls); + + const AbstractMetaArgumentList &arguments() const; + AbstractMetaArgumentList &arguments(); + void setArguments(const AbstractMetaArgumentList &arguments); + void addArgument(const AbstractMetaArgument &argument); + int actualMinimumArgumentCount() const; + // Return the argument index accounting for the isModifiedRemoved arguments [0..n-1] + int actualArgumentIndex(int index) const; + + bool isDeprecated() const; + bool isDestructor() const { return functionType() == DestructorFunction; } + bool isConstructor() const; + bool isCopyConstructor() const { return functionType() == CopyConstructorFunction; } + bool isDefaultConstructor() const; + bool needsReturnType() const; + bool isInGlobalScope() const; + bool isSignal() const { return functionType() == SignalFunction; } + bool isSlot() const { return functionType() == SlotFunction; } + bool isEmptyFunction() const { return functionType() == EmptyFunction; } + bool maybeAccessor() const; + FunctionType functionType() const; + void setFunctionType(FunctionType type); + + std::optional<ComparisonOperatorType> comparisonOperatorType() const; + + bool usesRValueReferences() const; + bool generateBinding() const; + // Returns whether the function is contained in the positive list of the + // type entry if one is specified. + bool isWhiteListed() const; + + QString signature() const; + /// Return a signature qualified by class name, for error reporting. + QString classQualifiedSignature() const; + + /// Signature with unresolved typedefs as seen by the code parser + QString unresolvedSignature() const; + void setUnresolvedSignature(const QString &); + + bool isConstant() const; + void setConstant(bool constant); + + /// Returns true if the AbstractMetaFunction was added by the user via the type system description. + bool isUserAdded() const; + bool isUserAddedPythonOverride() const; + /// Returns true if the AbstractMetaFunction was declared by the user via + /// the type system description. + bool isUserDeclared() const; + + CompareResult compareTo(const AbstractMetaFunction *other) const; + bool isConstOverloadOf(const AbstractMetaFunction *other) const; + + bool operator <(const AbstractMetaFunction &a) const; + + AbstractMetaFunction *copy() const; + + QString conversionRule(TypeSystem::Language language, int idx) const; + bool hasConversionRule(TypeSystem::Language language, int idx) const; + QList<ReferenceCount> + referenceCounts(const AbstractMetaClassCPtr &cls, int idx = -2) const; + ArgumentOwner argumentOwner(const AbstractMetaClassCPtr &cls, int idx) const; + + // Returns the ownership rules for the given argument (target lang). + TypeSystem::Ownership + argumentTargetOwnership(const AbstractMetaClassCPtr &cls, int idx) const; + + const QString &modifiedTypeName() const; + bool isTypeModified() const { return !modifiedTypeName().isEmpty(); } + bool generateOpaqueContainerReturn() const; + + bool isModifiedToArray(int argumentIndex) const; + + void applyTypeModifications(); + + /// Return the (modified) type for the signature; modified-pyi-type, modified-type + QString pyiTypeReplaced(int argumentIndex) const; + + bool argumentRemoved(int) const; + /** + * Verifies if any modification to the function is an inject code. + * \return true if there is inject code modifications to the function. + */ + bool hasInjectedCode() const; + /** + * Returns a list of code snips for this function. + * The code snips can be filtered by position and language. + * \return list of code snips + */ + CodeSnipList injectedCodeSnips(TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny, + TypeSystem::Language language = TypeSystem::All) const; + bool injectedCodeContains(const QRegularExpression &pattern, + TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny, + TypeSystem::Language language = TypeSystem::All) const; + bool injectedCodeContains(QStringView pattern, + TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny, + TypeSystem::Language language = TypeSystem::All) const; + + /** + * Verifies if any modification to the function alters/removes its + * arguments types or default values. + * \return true if there is some modification to function signature + */ + bool hasSignatureModifications() const; + + const FunctionModificationList &modifications(AbstractMetaClassCPtr implementor = {}) const; + void clearModificationsCache(); + + const DocModificationList addedFunctionDocModifications() const; + + static FunctionModificationList findClassModifications(const AbstractMetaFunction *f, + AbstractMetaClassCPtr implementor); + static FunctionModificationList findGlobalModifications(const AbstractMetaFunction *f); + + /** + * Return the argument name if there is a modification the renamed value will be returned + */ + QString argumentName(int index, bool create = true, AbstractMetaClassCPtr cl = {}) const; + + int propertySpecIndex() const; + void setPropertySpecIndex(int i); + + FunctionTypeEntryPtr typeEntry() const; + void setTypeEntry(const FunctionTypeEntryPtr &typeEntry); + + QString targetLangPackage() const; + + bool isCallOperator() const; + + static AbstractMetaFunctionCPtr + find(const AbstractMetaFunctionCList &haystack, QAnyStringView needle); + + bool matches(OperatorQueryOptions) const; + + // for the meta builder only + void setAllowThreadModification(TypeSystem::AllowThread am); + void setExceptionHandlingModification(TypeSystem::ExceptionHandling em); + + int overloadNumber() const; + + TypeSystem::SnakeCase snakeCase() const; + + // Query functions for generators + /// Verifies if any of the function's code injections of the "native" + /// type needs the type system variable "%PYSELF". + /// \return true if the function's native code snippets use "%PYSELF" + bool injectedCodeUsesPySelf() const; + + /// Verifies if any of the function's code injections of the "native" class makes a + /// call to the C++ method. This is used by the generator to avoid writing calls to + /// Python overrides of C++ virtual methods when the user custom code already does this. + /// \param func the function to check + /// \return true if the function's code snippets call the Python override for a C++ virtual method + bool injectedCodeCallsPythonOverride() const; + + /// Verifies if any of the function's code injections attributes values to + /// the return variable (%0 or %PYARG_0). + /// \param language the kind of code snip + /// \return true if the function's code attributes values to "%0" or "%PYARG_0" + bool injectedCodeHasReturnValueAttribution(TypeSystem::Language language = + TypeSystem::TargetLangCode) const; + + /// Verifies if any of the function's code injections uses the type system variable + /// for function arguments of a given index. + bool injectedCodeUsesArgument(int argumentIndex) const; + + bool isVisibilityModifiedToPrivate() const; + +#ifndef QT_NO_DEBUG_STREAM + void formatDebugBrief(QDebug &debug) const; + void formatDebugVerbose(QDebug &debug) const; +#endif + + SourceLocation sourceLocation() const; + void setSourceLocation(const SourceLocation &sourceLocation); + + static const char *pythonRichCompareOpCode(ComparisonOperatorType ct); + static const char *cppComparisonOperator(ComparisonOperatorType ct); + +private: + template <class Predicate> + bool traverseCodeSnips(Predicate predicate, + TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny, + TypeSystem::Language language = TypeSystem::All) const; + bool autoDetectAllowThread() const; + + QScopedPointer<AbstractMetaFunctionPrivate> d; +}; + +inline bool AbstractMetaFunction::isAbstract() const +{ + return cppAttributes().testFlag(FunctionAttribute::Abstract); +} + +inline bool AbstractMetaFunction::isStatic() const +{ + return cppAttributes().testFlag(FunctionAttribute::Static); +} + +inline bool AbstractMetaFunction::isClassMethod() const +{ + return attributes().testFlag(ClassMethod); +} + +inline bool AbstractMetaFunction::isPropertyReader() const +{ + return attributes().testFlag(PropertyReader); +} + +inline bool AbstractMetaFunction::isPropertyWriter() const +{ + return attributes().testFlag(PropertyWriter); +} + +inline bool AbstractMetaFunction::isPropertyResetter() const +{ + return attributes().testFlag(PropertyResetter); +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::CompareResult) + +Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::Attributes); + +Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::Flags); + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const AbstractMetaFunction *af); +#endif + +#endif // ABSTRACTMETAFUNCTION_H |