224 lines
5.9 KiB
C++
Raw Normal View History

2019-09-23 16:46:57 +03:00
/*
2019-12-08 13:57:20 +03:00
* Copyright (C) 2018-2020 QuasarApp.
2019-09-23 16:46:57 +03:00
* Distributed under the lgplv3 software license, see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
2019-03-26 22:12:20 +03:00
#include "qml.h"
#include <QDir>
#include <QFile>
2020-11-05 12:57:41 +03:00
#include "quasarapp.h"
#include "deploycore.h"
#include "deployconfig.h"
2019-03-26 22:12:20 +03:00
2021-03-27 11:14:14 +03:00
QStringList QML::extractImportLine(const QString& line) const {
QStringList result;
QStringList list = line.split(" ", QString::SkipEmptyParts);
if (list.count() == 3 || (list.count() == 5 && list[3] == "as")) {
if (list[2] == "auto" || (_qtVersion & QtMajorVersion::Qt6)) {
2021-03-27 11:14:14 +03:00
// qt6
result << (list[1].replace(".", "/"));
return result;
2021-03-27 11:14:14 +03:00
}
// qt5
result << (list[2][0] + "#" + list[1].replace(".", "/"));
} else if (list.count() == 2 || (list.count() == 4 && list[2] == "as")) {
// qt6
result << (list[1].replace(".", "/"));
}
return result;
}
QStringList QML::extractImportsFromFile(const QString &filepath) const {
2019-03-26 22:12:20 +03:00
QStringList imports;
QFile F(filepath);
if (!F.open(QIODevice::ReadOnly)) return QStringList();
QString content = F.readAll();
content.remove(QRegExp("\\{(.*)\\}"));
content.remove(QRegExp("/\\*(.*)\\*/"));
for (const QString &line : content.split("\n"))
for (QString &word : line.split(";", QString::SkipEmptyParts))
{
word = word.simplified();
if (word.startsWith("//")) continue;
if (!word.startsWith("import")) continue;
2021-03-27 11:14:14 +03:00
imports += extractImportLine(word);
2019-03-26 22:12:20 +03:00
}
return imports;
}
2019-03-28 16:11:13 +03:00
bool QML::extractImportsFromDir(const QString &path, bool recursive) {
2019-03-26 22:12:20 +03:00
QDir dir(path);
2019-04-06 14:42:22 +03:00
if (!dir.isReadable()) {
return false;
}
2019-03-26 22:12:20 +03:00
2019-04-06 14:42:22 +03:00
auto files = dir.entryInfoList(QStringList() << "*.qml" << "*.QML", QDir::Files);
2021-03-27 11:14:14 +03:00
auto qmlmodule = dir.entryInfoList(QStringList() << "qmldir", QDir::Files);
2019-04-06 14:42:22 +03:00
auto dirs = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs);
2020-01-12 16:43:03 +03:00
for (const auto &info: files) {
2019-04-06 14:42:22 +03:00
auto imports = extractImportsFromFile(info.absoluteFilePath());
for (auto import : imports) {
if (!_imports.contains(import)) {
_imports.insert(import);
extractImportsFromDir(getPathFromImport(import), recursive);
2019-03-28 16:11:13 +03:00
}
2019-04-06 14:42:22 +03:00
}
}
2021-03-27 11:14:14 +03:00
for (const auto& module: qAsConst(qmlmodule)) {
QStringList imports = extractImportsFromQmlModule(module.absoluteFilePath());
for (auto import : imports) {
if (!_imports.contains(import)) {
_imports.insert(import);
extractImportsFromDir(getPathFromImport(import), recursive);
}
}
}
2019-04-06 14:42:22 +03:00
if (recursive) {
2020-01-12 16:43:03 +03:00
for (const auto &info: dirs) {
2019-03-28 16:11:13 +03:00
extractImportsFromDir(info.absoluteFilePath(), recursive);
2019-03-26 22:12:20 +03:00
}
}
return true;
}
2020-05-13 18:08:50 +03:00
QString QML::getPathFromImport(const QString &import, bool checkVersions) {
if (!import.contains("#")) {
// qt 6
auto info = QFileInfo(_qmlRoot + "/" + import);
return info.absoluteFilePath();
2020-11-05 12:57:41 +03:00
}
2019-03-28 16:11:13 +03:00
auto importData = import.split("#");
2019-03-29 23:02:39 +03:00
int index;
if (importData.size() == 2)
index = 1;
else if (!importData.isEmpty()) {
index = 0;
} else {
return "";
}
auto words = importData.value(index).split(QRegExp("[/\\\\]"));
2020-05-13 18:08:50 +03:00
const bool isSecond = importData.first() == "2" && checkVersions;
bool secondVersion = isSecond;
2019-03-28 16:11:13 +03:00
QString path;
for (auto i = words.rbegin(); i != words.rend(); ++i) {
QString word = *i;
2020-05-13 18:08:50 +03:00
if (secondVersion && secondVersions.contains(word)) {
secondVersion = false;
2019-03-28 16:11:13 +03:00
word.push_back(".2");
}
path.push_front(word + "/");
}
2020-05-13 18:08:50 +03:00
auto info = QFileInfo(_qmlRoot + "/" + path);
if (isSecond && !info.exists()) {
return getPathFromImport(import, false);
}
2019-03-28 16:11:13 +03:00
2020-05-13 18:08:50 +03:00
return info.absoluteFilePath();
2019-03-28 16:11:13 +03:00
}
bool QML::deployPath(const QString &path, QStringList &res) {
QDir dir(path);
auto infoList = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
for (auto info : infoList) {
if (DeployCore::isDebugFile(info.fileName())) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("sciped debug lib " +
info.absoluteFilePath());
2019-03-28 16:11:13 +03:00
continue;
}
res.push_back(info.absoluteFilePath());
}
2019-03-26 22:12:20 +03:00
2019-03-28 16:11:13 +03:00
return true;
2019-03-26 22:12:20 +03:00
}
2019-03-28 13:16:00 +03:00
bool QML::scanQmlTree(const QString &qmlTree) {
QDir dir(qmlTree);
if (!dir.isReadable()) {
return false;
}
auto list = dir.entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot);
2020-01-12 16:43:03 +03:00
for (const auto &info : list) {
2019-04-06 14:42:22 +03:00
if (info.fileName().contains(".2")) {
secondVersions.insert(info.fileName().left(info.fileName().size() - 2));
}
scanQmlTree(info.absoluteFilePath());
2019-03-29 23:02:39 +03:00
2019-03-28 13:16:00 +03:00
}
return true;
}
2021-03-27 11:14:14 +03:00
QStringList QML::extractImportsFromQmlModule(const QString &module) const {
QStringList imports;
QFile F(module);
if (!F.open(QIODevice::ReadOnly)) return QStringList();
QString content = F.readAll();
for (QString line : content.split("\n")) {
line = line.simplified();
if (line.startsWith("//") || line.startsWith("#")) continue;
if (!line.startsWith("depends")) continue;
2019-03-28 16:11:13 +03:00
2021-03-27 11:14:14 +03:00
QStringList list = line.split(" ", QString::SkipEmptyParts);
imports += extractImportLine(line);
}
return imports;
2019-03-28 16:11:13 +03:00
}
void QML::setQtVersion(const QtMajorVersion &qtVersion) {
_qtVersion = qtVersion;
}
QML::QML(const QString &qmlRoot, QtMajorVersion qtVersion) {
2019-03-26 22:12:20 +03:00
_qmlRoot = qmlRoot;
setQtVersion(qtVersion);
2019-03-28 16:11:13 +03:00
}
bool QML::scan(QStringList &res, const QString& _qmlProjectDir) {
if (!scanQmlTree(_qmlRoot)) {
return false;
}
if (!extractImportsFromDir(_qmlProjectDir, true)) {
return false;
}
2020-01-12 16:43:03 +03:00
for (const auto &import : _imports) {
2019-03-31 21:47:48 +03:00
res.push_back(getPathFromImport(import));
2019-03-28 16:11:13 +03:00
}
return true;
2019-03-26 22:12:20 +03:00
}