Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qmlutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "qmlutils.h"
5#include "utils.h"
6
7#include <QtCore/QDir>
8#include <QtCore/QFileInfo>
9#include <QtCore/QCoreApplication>
10#include <QtCore/QJsonDocument>
11#include <QtCore/QJsonObject>
12#include <QtCore/QJsonArray>
13#include <QtCore/QJsonParseError>
14
16
17using namespace Qt::StringLiterals;
18
20{
21 return m1.className.isEmpty() ? m1.name == m2.name : m1.className == m2.className;
22}
23
24// Return install path (cp -r semantics)
25QString QmlImportScanResult::Module::installPath(const QString &root) const
26{
27 QString result = root;
28 const qsizetype lastSlashPos = relativePath.lastIndexOf(u'/');
29 if (lastSlashPos != -1) {
30 result += u'/';
31 result += QStringView{relativePath}.left(lastSlashPos);
32 }
33 return result;
34}
35
36static QString qmlDirectoryRecursion(Platform platform, const QString &path)
37{
38 QDir dir(path);
39 if (!dir.entryList(QStringList(QStringLiteral("*.qml")), QDir::Files, QDir::NoSort).isEmpty())
40 return dir.path();
41 const QFileInfoList &subDirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot, QDir::NoSort);
42 for (const QFileInfo &subDirFi : subDirs) {
43 if (!isBuildDirectory(platform, subDirFi.fileName())) {
44 const QString subPath = qmlDirectoryRecursion(platform, subDirFi.absoluteFilePath());
45 if (!subPath.isEmpty())
46 return subPath;
47 }
48 }
49 return QString();
50}
51
52// Find a directory containing QML files in the project
53QString findQmlDirectory(Platform platform, const QString &startDirectoryName)
54{
55 QDir startDirectory(startDirectoryName);
56 if (isBuildDirectory(platform, startDirectory.dirName()))
57 startDirectory.cdUp();
58 return qmlDirectoryRecursion(platform, startDirectory.path());
59}
60
61static void findFileRecursion(const QDir &directory, Platform platform,
62 DebugMatchMode debugMatchMode, QStringList *matches)
63{
64 const QStringList &dlls = findSharedLibraries(directory, platform, debugMatchMode);
65 for (const QString &dll : dlls)
66 matches->append(directory.filePath(dll));
67 const QFileInfoList &subDirs = directory.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
68 for (const QFileInfo &subDirFi : subDirs) {
69 QDir subDirectory(subDirFi.absoluteFilePath());
70 // Don't enter other QML modules when recursing!
71 if (subDirectory.isReadable() && !subDirectory.exists(QStringLiteral("qmldir")))
72 findFileRecursion(subDirectory, platform, debugMatchMode, matches);
73 }
74}
75
76QmlImportScanResult runQmlImportScanner(const QString &directory, const QStringList &qmlImportPaths,
77 bool usesWidgets, int platform, DebugMatchMode debugMatchMode,
78 QString *errorMessage, int timeout)
79{
80 Q_UNUSED(usesWidgets);
82 QStringList arguments;
83 for (const QString &importPath : qmlImportPaths)
84 arguments << QStringLiteral("-importPath") << importPath;
85 arguments << QStringLiteral("-rootPath") << directory;
86 unsigned long exitCode;
87 QByteArray stdOut;
88 QByteArray stdErr;
89 const QString binary = QStringLiteral("qmlimportscanner");
90 if (!runProcess(binary, arguments, QDir::currentPath(), &exitCode, &stdOut, &stdErr,
91 errorMessage, timeout))
92 return result;
93 if (exitCode) {
94 *errorMessage = binary + QStringLiteral(" returned ") + QString::number(exitCode)
95 + QStringLiteral(": ") + QString::fromLocal8Bit(stdErr);
96 return result;
97 }
98 QJsonParseError jsonParseError{};
99 const QJsonDocument data = QJsonDocument::fromJson(stdOut, &jsonParseError);
100 if (data.isNull() ) {
101 *errorMessage = binary + QStringLiteral(" returned invalid JSON output: ")
102 + jsonParseError.errorString() + QStringLiteral(" :\"")
103 + QString::fromLocal8Bit(stdOut) + u'"';
104 return result;
105 }
106 const QJsonArray array = data.array();
107 const int childCount = array.count();
108 for (int c = 0; c < childCount; ++c) {
109 const QJsonObject object = array.at(c).toObject();
110 if (object.value(QStringLiteral("type")).toString() == "module"_L1) {
111 const QString path = object.value(QStringLiteral("path")).toString();
112 if (!path.isEmpty()) {
114 module.name = object.value(QStringLiteral("name")).toString();
115 module.className = object.value(QStringLiteral("classname")).toString();
116 module.sourcePath = path;
117 module.relativePath = object.value(QStringLiteral("relativePath")).toString();
118 result.modules.append(module);
119 findFileRecursion(QDir(path), Platform(platform), debugMatchMode, &result.plugins);
120 }
121 }
122 }
123 result.ok = true;
124 return result;
125}
126
128{
129 for (const QmlImportScanResult::Module &module : other.modules) {
130 if (std::find(modules.cbegin(), modules.cend(), module) == modules.cend())
131 modules.append(module);
132 }
133 for (const QString &plugin : other.plugins) {
134 if (!plugins.contains(plugin))
135 plugins.append(plugin);
136 }
137}
138
139QT_END_NAMESPACE
static void findFileRecursion(const QDir &directory, Platform platform, DebugMatchMode debugMatchMode, QStringList *matches)
Definition qmlutils.cpp:61
QString findQmlDirectory(Platform platform, const QString &startDirectoryName)
Definition qmlutils.cpp:53
static QString qmlDirectoryRecursion(Platform platform, const QString &path)
Definition qmlutils.cpp:36
bool operator==(const QmlImportScanResult::Module &m1, const QmlImportScanResult::Module &m2)
Definition qmlutils.cpp:19
QmlImportScanResult runQmlImportScanner(const QString &directory, const QStringList &qmlImportPaths, bool usesWidgets, int platform, DebugMatchMode debugMatchMode, QString *errorMessage, int timeout)
Definition qmlutils.cpp:76
QString installPath(const QString &root) const
Definition qmlutils.cpp:25
void append(const QmlImportScanResult &other)
Definition qmlutils.cpp:127
DebugMatchMode
Definition utils.h:158