aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsimporter_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmlcompiler/qqmljsimporter_p.h')
-rw-r--r--src/qmlcompiler/qqmljsimporter_p.h223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/qmlcompiler/qqmljsimporter_p.h b/src/qmlcompiler/qqmljsimporter_p.h
new file mode 100644
index 0000000000..290ea71605
--- /dev/null
+++ b/src/qmlcompiler/qqmljsimporter_p.h
@@ -0,0 +1,223 @@
+// 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 QQMLJSIMPORTER_P_H
+#define QQMLJSIMPORTER_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 <qtqmlcompilerexports.h>
+
+#include "qqmljscontextualtypes_p.h"
+#include "qqmljsscope_p.h"
+#include "qqmljsresourcefilemapper_p.h"
+#include <QtQml/private/qqmldirparser_p.h>
+#include <QtQml/private/qqmljsast_p.h>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+
+namespace QQmlJS {
+class Import
+{
+public:
+ Import() = default;
+ Import(QString prefix, QString name, QTypeRevision version, bool isFile, bool isDependency);
+
+ bool isValid() const;
+
+ QString prefix() const { return m_prefix; }
+ QString name() const { return m_name; }
+ QTypeRevision version() const { return m_version; }
+ bool isFile() const { return m_isFile; }
+ bool isDependency() const { return m_isDependency; }
+
+private:
+ QString m_prefix;
+ QString m_name;
+ QTypeRevision m_version;
+ bool m_isFile = false;
+ bool m_isDependency = false;
+
+ friend inline size_t qHash(const Import &key, size_t seed = 0) noexcept
+ {
+ return qHashMulti(seed, key.m_prefix, key.m_name, key.m_version,
+ key.m_isFile, key.m_isDependency);
+ }
+
+ friend inline bool operator==(const Import &a, const Import &b)
+ {
+ return a.m_prefix == b.m_prefix && a.m_name == b.m_name && a.m_version == b.m_version
+ && a.m_isFile == b.m_isFile && a.m_isDependency == b.m_isDependency;
+ }
+};
+}
+
+class QQmlJSImportVisitor;
+class QQmlJSLogger;
+class Q_QMLCOMPILER_EXPORT QQmlJSImporter
+{
+public:
+ using ImportedTypes = QQmlJS::ContextualTypes;
+
+ QQmlJSImporter(const QStringList &importPaths, QQmlJSResourceFileMapper *mapper,
+ bool useOptionalImports = false);
+
+ QQmlJSResourceFileMapper *resourceFileMapper() const { return m_mapper; }
+ void setResourceFileMapper(QQmlJSResourceFileMapper *mapper) { m_mapper = mapper; }
+
+ QQmlJSResourceFileMapper *metaDataMapper() const { return m_metaDataMapper; }
+ void setMetaDataMapper(QQmlJSResourceFileMapper *mapper) { m_metaDataMapper = mapper; }
+
+ ImportedTypes importBuiltins();
+ void importQmldirs(const QStringList &qmltypesFiles);
+
+ QQmlJSScope::Ptr importFile(const QString &file);
+ ImportedTypes importDirectory(const QString &directory, const QString &prefix = QString());
+
+ // ### qmltc needs this. once re-written, we no longer need to expose this
+ QHash<QString, QQmlJSScope::Ptr> importedFiles() const { return m_importedFiles; }
+
+ ImportedTypes importModule(const QString &module, const QString &prefix = QString(),
+ QTypeRevision version = QTypeRevision(),
+ QStringList *staticModuleList = nullptr);
+
+ ImportedTypes builtinInternalNames();
+
+ QList<QQmlJS::DiagnosticMessage> takeWarnings()
+ {
+ const auto result = std::move(m_warnings);
+ m_warnings.clear();
+ return result;
+ }
+
+ QList<QQmlJS::DiagnosticMessage> takeGlobalWarnings()
+ {
+ const auto result = std::move(m_globalWarnings);
+ m_globalWarnings.clear();
+ return result;
+ }
+
+ QStringList importPaths() const { return m_importPaths; }
+ void setImportPaths(const QStringList &importPaths);
+
+ void clearCache();
+
+ QQmlJSScope::ConstPtr jsGlobalObject() const;
+
+ struct ImportVisitorPrerequisites
+ {
+ ImportVisitorPrerequisites(QQmlJSScope::Ptr target, QQmlJSLogger *logger,
+ const QString &implicitImportDirectory = {},
+ const QStringList &qmldirFiles = {})
+ : m_target(target),
+ m_logger(logger),
+ m_implicitImportDirectory(implicitImportDirectory),
+ m_qmldirFiles(qmldirFiles)
+ {
+ Q_ASSERT(target && logger);
+ }
+
+ QQmlJSScope::Ptr m_target;
+ QQmlJSLogger *m_logger;
+ QString m_implicitImportDirectory;
+ QStringList m_qmldirFiles;
+ };
+ void runImportVisitor(QQmlJS::AST::Node *rootNode,
+ const ImportVisitorPrerequisites &prerequisites);
+
+ /*!
+ \internal
+ When a qml file gets lazily loaded, it will be lexed and parsed and finally be constructed
+ via an ImportVisitor. By default, this is done via the QQmlJSImportVisitor, but can also be done
+ via other import visitors like QmltcVisitor, which is used by qmltc to compile a QML file, or
+ QQmlDomAstCreatorWithQQmlJSScope, which is used to construct the Dom of lazily loaded QML files.
+ */
+ using ImportVisitor = std::function<void(QQmlJS::AST::Node *rootNode, QQmlJSImporter *self,
+ const ImportVisitorPrerequisites &prerequisites)>;
+
+ void setImportVisitor(ImportVisitor visitor) { m_importVisitor = visitor; }
+
+private:
+ friend class QDeferredFactory<QQmlJSScope>;
+
+ struct AvailableTypes
+ {
+ AvailableTypes(ImportedTypes builtins)
+ : cppNames(std::move(builtins))
+ , qmlNames(QQmlJS::ContextualTypes::QML, {}, cppNames.arrayType())
+ {
+ }
+
+ // C++ names used in qmltypes files for non-composite types
+ ImportedTypes cppNames;
+
+ // Names the importing component sees, including any prefixes
+ ImportedTypes qmlNames;
+
+ // Static modules included here
+ QStringList staticModules;
+
+ // Whether a system module has been imported
+ bool hasSystemModule = false;
+ };
+
+ struct Import {
+ QString name;
+ bool isStaticModule = false;
+ bool isSystemModule = false;
+
+ QList<QQmlJSExportedScope> objects;
+ QHash<QString, QQmlJSExportedScope> scripts;
+ QList<QQmlDirParser::Import> imports;
+ QList<QQmlDirParser::Import> dependencies;
+ };
+
+ AvailableTypes builtinImportHelper();
+ bool importHelper(const QString &module, AvailableTypes *types,
+ const QString &prefix = QString(), QTypeRevision version = QTypeRevision(),
+ bool isDependency = false, bool isFile = false);
+ void processImport(const QQmlJS::Import &importDescription, const Import &import,
+ AvailableTypes *types);
+ void importDependencies(const QQmlJSImporter::Import &import, AvailableTypes *types,
+ const QString &prefix = QString(),
+ QTypeRevision version = QTypeRevision(), bool isDependency = false);
+ QQmlDirParser createQmldirParserForFile(const QString &filename);
+ void readQmltypes(const QString &filename, QList<QQmlJSExportedScope> *objects,
+ QList<QQmlDirParser::Import> *dependencies);
+ Import readQmldir(const QString &dirname);
+ Import readDirectory(const QString &directory);
+
+ QQmlJSScope::Ptr localFile2ScopeTree(const QString &filePath);
+ static void setQualifiedNamesOn(const Import &import);
+
+ QStringList m_importPaths;
+
+ QHash<QPair<QString, QTypeRevision>, QString> m_seenImports;
+ QHash<QQmlJS::Import, QSharedPointer<AvailableTypes>> m_cachedImportTypes;
+ QHash<QString, Import> m_seenQmldirFiles;
+
+ QHash<QString, QQmlJSScope::Ptr> m_importedFiles;
+ QList<QQmlJS::DiagnosticMessage> m_globalWarnings;
+ QList<QQmlJS::DiagnosticMessage> m_warnings;
+ std::optional<AvailableTypes> m_builtins;
+
+ QQmlJSResourceFileMapper *m_mapper = nullptr;
+ QQmlJSResourceFileMapper *m_metaDataMapper = nullptr;
+ bool m_useOptionalImports;
+
+ ImportVisitor m_importVisitor;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLJSIMPORTER_P_H