aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljstyperesolver_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmlcompiler/qqmljstyperesolver_p.h')
-rw-r--r--src/qmlcompiler/qqmljstyperesolver_p.h329
1 files changed, 329 insertions, 0 deletions
diff --git a/src/qmlcompiler/qqmljstyperesolver_p.h b/src/qmlcompiler/qqmljstyperesolver_p.h
new file mode 100644
index 0000000000..9961c24842
--- /dev/null
+++ b/src/qmlcompiler/qqmljstyperesolver_p.h
@@ -0,0 +1,329 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef QQMLJSTYPERESOLVER_P_H
+#define QQMLJSTYPERESOLVER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include <memory>
+#include <qtqmlcompilerexports.h>
+
+#include <private/qqmlirbuilder_p.h>
+#include <private/qqmljsast_p.h>
+#include "qqmljsimporter_p.h"
+#include "qqmljslogger_p.h"
+#include "qqmljsregistercontent_p.h"
+#include "qqmljsresourcefilemapper_p.h"
+#include "qqmljsscope_p.h"
+#include "qqmljsscopesbyid_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQmlJSImportVisitor;
+class Q_QMLCOMPILER_EXPORT QQmlJSTypeResolver
+{
+public:
+ enum ParentMode { UseDocumentParent, UseParentProperty };
+ enum CloneMode { CloneTypes, DoNotCloneTypes };
+ enum ListMode { UseListProperty, UseQObjectList };
+
+ QQmlJSTypeResolver(QQmlJSImporter *importer);
+
+ // Note: must be called after the construction to read the QML program
+ void init(QQmlJSImportVisitor *visitor, QQmlJS::AST::Node *program);
+
+ QQmlJSScope::ConstPtr voidType() const { return m_voidType; }
+ QQmlJSScope::ConstPtr emptyType() const { return m_emptyType; }
+ QQmlJSScope::ConstPtr nullType() const { return m_nullType; }
+ QQmlJSScope::ConstPtr realType() const { return m_realType; }
+ QQmlJSScope::ConstPtr floatType() const { return m_floatType; }
+ QQmlJSScope::ConstPtr int8Type() const { return m_int8Type; }
+ QQmlJSScope::ConstPtr uint8Type() const { return m_uint8Type; }
+ QQmlJSScope::ConstPtr int16Type() const { return m_int16Type; }
+ QQmlJSScope::ConstPtr uint16Type() const { return m_uint16Type; }
+ QQmlJSScope::ConstPtr int32Type() const { return m_int32Type; }
+ QQmlJSScope::ConstPtr uint32Type() const { return m_uint32Type; }
+ QQmlJSScope::ConstPtr int64Type() const { return m_int64Type; }
+ QQmlJSScope::ConstPtr uint64Type() const { return m_uint64Type; }
+ QQmlJSScope::ConstPtr sizeType() const { return m_sizeType; }
+ QQmlJSScope::ConstPtr boolType() const { return m_boolType; }
+ QQmlJSScope::ConstPtr stringType() const { return m_stringType; }
+ QQmlJSScope::ConstPtr stringListType() const { return m_stringListType; }
+ QQmlJSScope::ConstPtr byteArrayType() const { return m_byteArrayType; }
+ QQmlJSScope::ConstPtr urlType() const { return m_urlType; }
+ QQmlJSScope::ConstPtr dateTimeType() const { return m_dateTimeType; }
+ QQmlJSScope::ConstPtr dateType() const { return m_dateType; }
+ QQmlJSScope::ConstPtr timeType() const { return m_timeType; }
+ QQmlJSScope::ConstPtr variantListType() const { return m_variantListType; }
+ QQmlJSScope::ConstPtr variantMapType() const { return m_variantMapType; }
+ QQmlJSScope::ConstPtr varType() const { return m_varType; }
+ QQmlJSScope::ConstPtr jsValueType() const { return m_jsValueType; }
+ QQmlJSScope::ConstPtr jsPrimitiveType() const { return m_jsPrimitiveType; }
+ QQmlJSScope::ConstPtr listPropertyType() const { return m_listPropertyType; }
+ QQmlJSScope::ConstPtr metaObjectType() const { return m_metaObjectType; }
+ QQmlJSScope::ConstPtr functionType() const { return m_functionType; }
+ QQmlJSScope::ConstPtr jsGlobalObject() const { return m_jsGlobalObject; }
+ QQmlJSScope::ConstPtr qObjectType() const { return m_qObjectType; }
+ QQmlJSScope::ConstPtr qObjectListType() const { return m_qObjectListType; }
+ QQmlJSScope::ConstPtr arrayPrototype() const { return m_arrayPrototype; }
+ QQmlJSScope::ConstPtr forInIteratorPtr() const { return m_forInIteratorPtr; }
+ QQmlJSScope::ConstPtr forOfIteratorPtr() const { return m_forOfIteratorPtr; }
+
+ QQmlJSScope::ConstPtr mathObject() const;
+ QQmlJSScope::ConstPtr consoleObject() const;
+
+ QQmlJSScope::ConstPtr scopeForLocation(const QV4::CompiledData::Location &location) const;
+
+ bool isPrefix(const QString &name) const
+ {
+ return m_imports.hasType(name) && !m_imports.type(name).scope;
+ }
+
+ const QHash<QString, QQmlJS::ImportedScope<QQmlJSScope::ConstPtr>> &importedTypes() const
+ {
+ return m_imports.types();
+ }
+ QQmlJSScope::ConstPtr typeForName(const QString &name) const
+ {
+ return m_imports.type(name).scope;
+ }
+ QString nameForType(const QQmlJSScope::ConstPtr &type) const
+ {
+ return m_imports.name(originalType(type));
+ }
+
+ QQmlJSScope::ConstPtr typeFromAST(QQmlJS::AST::Type *type) const;
+ QQmlJSScope::ConstPtr typeForConst(QV4::ReturnedValue rv) const;
+ QQmlJSRegisterContent typeForBinaryOperation(QSOperator::Op oper,
+ const QQmlJSRegisterContent &left,
+ const QQmlJSRegisterContent &right) const;
+
+ enum class UnaryOperator { Not, Plus, Minus, Increment, Decrement, Complement };
+ QQmlJSRegisterContent typeForArithmeticUnaryOperation(
+ UnaryOperator op, const QQmlJSRegisterContent &operand) const;
+
+ bool isPrimitive(const QQmlJSRegisterContent &type) const;
+ bool isPrimitive(const QQmlJSScope::ConstPtr &type) const;
+
+ bool isNumeric(const QQmlJSRegisterContent &type) const;
+ bool isIntegral(const QQmlJSRegisterContent &type) const;
+
+ bool canConvertFromTo(const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const;
+ bool canConvertFromTo(const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const;
+ QQmlJSRegisterContent merge(const QQmlJSRegisterContent &a,
+ const QQmlJSRegisterContent &b) const;
+
+ enum class ComponentIsGeneric { No, Yes };
+ QQmlJSScope::ConstPtr
+ genericType(const QQmlJSScope::ConstPtr &type,
+ ComponentIsGeneric allowComponent = ComponentIsGeneric::No) const;
+
+ QQmlJSRegisterContent builtinType(const QQmlJSScope::ConstPtr &type) const;
+ QQmlJSRegisterContent globalType(const QQmlJSScope::ConstPtr &type) const;
+ QQmlJSRegisterContent scopedType(const QQmlJSScope::ConstPtr &scope, const QString &name,
+ int lookupIndex = QQmlJSRegisterContent::InvalidLookupIndex,
+ QQmlJSScopesByIdOptions options = Default) const;
+ QQmlJSRegisterContent memberType(
+ const QQmlJSRegisterContent &type, const QString &name,
+ int lookupIndex = QQmlJSRegisterContent::InvalidLookupIndex) const;
+ QQmlJSRegisterContent valueType(const QQmlJSRegisterContent &list) const;
+ QQmlJSRegisterContent returnType(
+ const QQmlJSScope::ConstPtr &type, QQmlJSRegisterContent::ContentVariant variant,
+ const QQmlJSScope::ConstPtr &scope) const;
+
+ QQmlJSRegisterContent iteratorPointer(
+ const QQmlJSRegisterContent &listType, QQmlJS::AST::ForEachType type,
+ int lookupIndex) const;
+
+ bool registerIsStoredIn(const QQmlJSRegisterContent &reg,
+ const QQmlJSScope::ConstPtr &type) const;
+ bool registerContains(const QQmlJSRegisterContent &reg,
+ const QQmlJSScope::ConstPtr &type) const;
+ QQmlJSScope::ConstPtr containedType(const QQmlJSRegisterContent &container) const;
+ QString containedTypeName(const QQmlJSRegisterContent &container,
+ bool useFancyName = false) const;
+
+ QQmlJSRegisterContent tracked(const QQmlJSRegisterContent &type) const;
+ QQmlJSRegisterContent original(const QQmlJSRegisterContent &type) const;
+
+ QQmlJSScope::ConstPtr trackedContainedType(const QQmlJSRegisterContent &container) const;
+ QQmlJSScope::ConstPtr originalContainedType(const QQmlJSRegisterContent &container) const;
+
+ [[nodiscard]] bool adjustTrackedType(
+ const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const;
+ [[nodiscard]] bool adjustTrackedType(
+ const QQmlJSScope::ConstPtr &tracked,
+ const QList<QQmlJSScope::ConstPtr> &conversions) const;
+ void adjustOriginalType(
+ const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const;
+ void generalizeType(const QQmlJSScope::ConstPtr &type) const;
+
+ void setParentMode(ParentMode mode) { m_parentMode = mode; }
+ ParentMode parentMode() const { return m_parentMode; }
+
+ void setCloneMode(CloneMode mode) { m_cloneMode = mode; }
+ bool cloneMode() const { return m_cloneMode; }
+
+ QQmlJSScope::ConstPtr storedType(const QQmlJSScope::ConstPtr &type) const;
+ QQmlJSScope::ConstPtr originalType(const QQmlJSScope::ConstPtr &type) const;
+ QQmlJSScope::ConstPtr trackedType(const QQmlJSScope::ConstPtr &type) const;
+ QQmlJSScope::ConstPtr comparableType(const QQmlJSScope::ConstPtr &type) const;
+
+ const QQmlJSScopesById &objectsById() const { return m_objectsById; }
+ bool canCallJSFunctions() const { return m_objectsById.signaturesAreEnforced(); }
+ bool canAddressValueTypes() const { return m_objectsById.valueTypesAreAddressable(); }
+
+ const QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> &signalHandlers() const
+ {
+ return m_signalHandlers;
+ }
+
+ bool equals(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const;
+
+ QQmlJSRegisterContent convert(
+ const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const;
+ QQmlJSRegisterContent cast(
+ const QQmlJSRegisterContent &from, const QQmlJSScope::ConstPtr &to) const;
+
+ QQmlJSScope::ConstPtr merge(const QQmlJSScope::ConstPtr &a,
+ const QQmlJSScope::ConstPtr &b) const;
+
+ bool canHoldUndefined(const QQmlJSRegisterContent &content) const;
+ bool isOptionalType(const QQmlJSRegisterContent &content) const;
+ QQmlJSScope::ConstPtr extractNonVoidFromOptionalType(
+ const QQmlJSRegisterContent &content) const;
+
+ bool isNumeric(const QQmlJSScope::ConstPtr &type) const;
+ bool isIntegral(const QQmlJSScope::ConstPtr &type) const;
+ bool isSignedInteger(const QQmlJSScope::ConstPtr &type) const;
+ bool isUnsignedInteger(const QQmlJSScope::ConstPtr &type) const;
+ bool isNativeArrayIndex(const QQmlJSScope::ConstPtr &type) const;
+
+ bool canHold(const QQmlJSScope::ConstPtr &container,
+ const QQmlJSScope::ConstPtr &contained) const;
+
+ bool canPopulate(
+ const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument,
+ bool *isExtension) const;
+
+ QQmlJSMetaMethod selectConstructor(
+ const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument,
+ bool *isExtension) const;
+
+ bool areEquivalentLists(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const;
+
+ bool isTriviallyCopyable(const QQmlJSScope::ConstPtr &type) const;
+
+ bool inherits(const QQmlJSScope::ConstPtr &derived, const QQmlJSScope::ConstPtr &base) const;
+
+protected:
+
+ QQmlJSRegisterContent memberType(
+ const QQmlJSScope::ConstPtr &type, const QString &name,
+ int baseLookupIndex, int resultLookupIndex) const;
+ QQmlJSRegisterContent memberEnumType(const QQmlJSScope::ConstPtr &type,
+ const QString &name) const;
+ bool checkEnums(const QQmlJSScope::ConstPtr &scope, const QString &name,
+ QQmlJSRegisterContent *result, QQmlJSScope::ExtensionKind mode) const;
+ bool canPrimitivelyConvertFromTo(
+ const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const;
+ QQmlJSRegisterContent lengthProperty(bool isWritable, const QQmlJSScope::ConstPtr &scope) const;
+ QQmlJSRegisterContent transformed(
+ const QQmlJSRegisterContent &origin,
+ QQmlJSScope::ConstPtr (QQmlJSTypeResolver::*op)(const QQmlJSScope::ConstPtr &) const) const;
+
+ QQmlJSRegisterContent registerContentForName(
+ const QString &name,
+ const QQmlJSScope::ConstPtr &scopeType = QQmlJSScope::ConstPtr(),
+ bool hasObjectModuelPrefix = false) const;
+
+
+ QQmlJSScope::ConstPtr m_voidType;
+ QQmlJSScope::ConstPtr m_emptyType;
+ QQmlJSScope::ConstPtr m_nullType;
+ QQmlJSScope::ConstPtr m_numberPrototype;
+ QQmlJSScope::ConstPtr m_arrayPrototype;
+ QQmlJSScope::ConstPtr m_realType;
+ QQmlJSScope::ConstPtr m_floatType;
+ QQmlJSScope::ConstPtr m_int8Type;
+ QQmlJSScope::ConstPtr m_uint8Type;
+ QQmlJSScope::ConstPtr m_int16Type;
+ QQmlJSScope::ConstPtr m_uint16Type;
+ QQmlJSScope::ConstPtr m_int32Type;
+ QQmlJSScope::ConstPtr m_uint32Type;
+ QQmlJSScope::ConstPtr m_int64Type;
+ QQmlJSScope::ConstPtr m_uint64Type;
+ QQmlJSScope::ConstPtr m_sizeType;
+ QQmlJSScope::ConstPtr m_boolType;
+ QQmlJSScope::ConstPtr m_stringType;
+ QQmlJSScope::ConstPtr m_stringListType;
+ QQmlJSScope::ConstPtr m_byteArrayType;
+ QQmlJSScope::ConstPtr m_urlType;
+ QQmlJSScope::ConstPtr m_dateTimeType;
+ QQmlJSScope::ConstPtr m_dateType;
+ QQmlJSScope::ConstPtr m_timeType;
+ QQmlJSScope::ConstPtr m_variantListType;
+ QQmlJSScope::ConstPtr m_variantMapType;
+ QQmlJSScope::ConstPtr m_varType;
+ QQmlJSScope::ConstPtr m_jsValueType;
+ QQmlJSScope::ConstPtr m_jsPrimitiveType;
+ QQmlJSScope::ConstPtr m_listPropertyType;
+ QQmlJSScope::ConstPtr m_qObjectType;
+ QQmlJSScope::ConstPtr m_qObjectListType;
+ QQmlJSScope::ConstPtr m_qQmlScriptStringType;
+ QQmlJSScope::ConstPtr m_metaObjectType;
+ QQmlJSScope::ConstPtr m_functionType;
+ QQmlJSScope::ConstPtr m_jsGlobalObject;
+ QQmlJSScope::ConstPtr m_forInIteratorPtr;
+ QQmlJSScope::ConstPtr m_forOfIteratorPtr;
+
+ QQmlJSScopesById m_objectsById;
+ QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> m_objectsByLocation;
+ QQmlJSImporter::ImportedTypes m_imports;
+ QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
+
+ ParentMode m_parentMode = UseParentProperty;
+ CloneMode m_cloneMode = CloneTypes;
+ QQmlJSLogger *m_logger = nullptr;
+
+ struct TrackedType
+ {
+ // The type originally found via type analysis.
+ QQmlJSScope::ConstPtr original;
+
+ // Any later replacement used to overwrite the contents of the clone.
+ QQmlJSScope::ConstPtr replacement;
+
+ // A clone of original, used to track the type,
+ // contents possibly overwritten by replacement.
+ QQmlJSScope::Ptr clone;
+ };
+
+ std::unique_ptr<QHash<QQmlJSScope::ConstPtr, TrackedType>> m_trackedTypes;
+};
+
+/*!
+\internal
+
+QQmlJSTypeResolver expects to be outlived by its importer and mapper. It crashes when its importer
+or mapper gets destructed. Therefore, you can use this struct to extend the lifetime of its
+dependencies in case you need to store the resolver as a class member.
+*/
+struct QQmlJSTypeResolverDependencies
+{
+ std::shared_ptr<QQmlJSImporter> importer;
+ std::shared_ptr<QQmlJSResourceFileMapper> mapper;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLJSTYPERESOLVER_P_H