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.h207
1 files changed, 151 insertions, 56 deletions
diff --git a/src/qmlcompiler/qqmljsimporter_p.h b/src/qmlcompiler/qqmljsimporter_p.h
index 02da8b7b46..290ea71605 100644
--- a/src/qmlcompiler/qqmljsimporter_p.h
+++ b/src/qmlcompiler/qqmljsimporter_p.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $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$
-**
-****************************************************************************/
+// 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
@@ -39,34 +14,82 @@
//
// 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
-class QQmlJSImporter
+namespace QQmlJS {
+class Import
{
public:
- using ImportedTypes = QHash<QString, QQmlJSScope::ConstPtr>;
+ Import() = default;
+ Import(QString prefix, QString name, QTypeRevision version, bool isFile, bool isDependency);
+
+ bool isValid() const;
- QQmlJSImporter(const QStringList &importPaths, QQmlJSResourceFileMapper *mapper)
- : m_importPaths(importPaths)
- , m_builtins({})
- , m_mapper(mapper)
- {}
+ 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;
- QQmlJSResourceFileMapper *resourceFileMapper() { return m_mapper; }
+ 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();
- ImportedTypes importQmltypes(const QStringList &qmltypesFiles);
+ void importQmldirs(const QStringList &qmltypesFiles);
QQmlJSScope::Ptr importFile(const QString &file);
ImportedTypes importDirectory(const QString &directory, const QString &prefix = QString());
- ImportedTypes importModule(
- const QString &module, const QString &prefix = QString(),
- QTypeRevision version = QTypeRevision());
+ // ### 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();
@@ -77,50 +100,122 @@ public:
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(QHash<QString, QQmlJSScope::ConstPtr> builtins)
+ AvailableTypes(ImportedTypes builtins)
: cppNames(std::move(builtins))
- {}
+ , qmlNames(QQmlJS::ContextualTypes::QML, {}, cppNames.arrayType())
+ {
+ }
// C++ names used in qmltypes files for non-composite types
- QHash<QString, QQmlJSScope::ConstPtr> cppNames;
+ ImportedTypes cppNames;
// Names the importing component sees, including any prefixes
- QHash<QString, QQmlJSScope::ConstPtr> qmlNames;
+ ImportedTypes qmlNames;
+
+ // Static modules included here
+ QStringList staticModules;
+
+ // Whether a system module has been imported
+ bool hasSystemModule = false;
};
struct Import {
- QHash<QString, QQmlJSScope::Ptr> objects;
- QHash<QString, QQmlJSScope::Ptr> scripts;
+ 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();
- void importHelper(const QString &module, AvailableTypes *types,
- const QString &prefix = QString(),
- QTypeRevision version = QTypeRevision());
- void processImport(const Import &import, AvailableTypes *types,
- const QString &prefix = QString());
- void importDependencies(const QQmlJSImporter::Import &import,
- AvailableTypes *types,
+ 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());
- void readQmltypes(const QString &filename, QHash<QString, QQmlJSScope::Ptr> *objects,
+ 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>, Import> m_seenImports;
+
+ 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;
- AvailableTypes m_builtins;
+ std::optional<AvailableTypes> m_builtins;
+
QQmlJSResourceFileMapper *m_mapper = nullptr;
+ QQmlJSResourceFileMapper *m_metaDataMapper = nullptr;
+ bool m_useOptionalImports;
+
+ ImportVisitor m_importVisitor;
};
QT_END_NAMESPACE