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
qqmltyperegistrarutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:critical reason:data-parser
4
7
8#include <QtCore/qcborarray.h>
9#include <QtCore/qcbormap.h>
10#include <QtCore/qcborvalue.h>
11#include <QtCore/qdebug.h>
12#include <QtCore/qfile.h>
13#include <QtCore/qdiriterator.h>
14#include <QtCore/private/qduplicatetracker_p.h>
15#include <QtCore/qtextstream.h>
16
17using namespace Qt::Literals::StringLiterals;
18
19QT_BEGIN_NAMESPACE
20
21QTypeRevision handleInMinorVersion(QTypeRevision revision, int majorVersion)
22{
23 if (!revision.hasMajorVersion() && revision.hasMinorVersion()) {
24 // this version has been obtained by QML_{ADDED,REMOVED}_IN_MINOR_VERSION
25 revision = QTypeRevision::fromVersion(majorVersion, revision.minorVersion());
26 }
27 return revision;
28}
29
31{
32 return iface.className;
33}
34
35static QDebug message(QDebug base, QAnyStringView message, QAnyStringView fileName, int lineNumber)
36{
37 // Formatted such that it becomes a link in QtCreator (even with "::" ending)
38 const QString lineString = lineNumber ? QString::number(lineNumber) : QString();
39 return (base.noquote().nospace()
40 << message << ": " << fileName << ":" << lineString << ":").space();
41}
42
43QDebug warning(QAnyStringView fileName, int lineNumber)
44{
45 return message(qWarning(), "Warning", fileName, lineNumber);
46}
47
48QDebug warning(const MetaType &classDef)
49{
50 const QAnyStringView file = classDef.inputFile();
51 int lineNo = classDef.lineNumber();
52 if (!file.isEmpty())
53 return warning(file, lineNo);
54
55 return warning(classDef.qualifiedClassName());
56}
57
58QDebug error(QAnyStringView fileName, int lineNumber)
59{
60 return message(qCritical(), "Error", fileName, lineNumber);
61}
62
63/*!
64 \internal
65 \a pathToList points to a file listing all qt.parts.conf files
66 \a pathToFinalQtConfsList points to a file that lists the final merged qt.conf file location
67 for each qt.parts.conf file
68 In any given directory, there might be more than one qt.parts.conf file (especially on Winodws).
69 We need to merge all import paths for a given folder (but want to avoid duplicate entries).
70 */
71int mergeQtConfFiles(const QString &pathToList, const QString &pathToMergedQtConfsList)
72{
73 QFile listFile(pathToList);
74 if (!listFile.open(QFile::ReadOnly | QFile::Text))
75 return EXIT_FAILURE;
76 QMultiHash<QString, QString> directoryToNecessaryImports;
77 while (!listFile.atEnd()) {
78 QByteArray partFilePath = listFile.readLine().trimmed();
79 QString directoryPath = QFileInfo(QString::fromUtf8(partFilePath)).absolutePath();
80 QDirIterator dirIt(directoryPath, { "*_qt.part.conf"_L1 }, QDir::Filter::Files );
81 while (dirIt.hasNext()) {
82 QFile partialFile(dirIt.next());
83 if (!partialFile.open(QFile::ReadOnly | QFile::Text)) {
84 qCritical() << "could not open" << partialFile.fileName();
85 return EXIT_FAILURE;
86 }
87 while (!partialFile.atEnd()) {
88 QByteArray import = partialFile.readLine().trimmed();
89 directoryToNecessaryImports.insert(directoryPath, QString::fromUtf8(import));
90 }
91 }
92 }
93
94 // Collect the merged qt paths.
95 QFile mergedPathsListFile(pathToMergedQtConfsList);
96 if (!mergedPathsListFile.open(QFile::ReadOnly | QFile::Text)) {
97 qCritical() << "could not open" << mergedPathsListFile.fileName();
98 return EXIT_FAILURE;
99 }
100 QHash<QString, QString> partialPathToMergedPath;
101 while (!mergedPathsListFile.atEnd()) {
102 QByteArray row = mergedPathsListFile.readLine().trimmed();
103 QList<QByteArray> parts = row.split(';');
104 Q_ASSERT(parts.size() == 2);
105 const QString partialFileDirectoryPath =
106 QFileInfo(QString::fromUtf8(parts[0])).absolutePath();
107 const QString mergedFilePath = QString::fromUtf8(parts[1]);
108 partialPathToMergedPath.insert(partialFileDirectoryPath, mergedFilePath);
109 }
110
111 for (const QString &directoryPath: directoryToNecessaryImports.keys()) {
112 if (!partialPathToMergedPath.contains(directoryPath)) {
113 qCritical() << "no merged qt.conf file found for directory" << directoryPath;
114 return EXIT_FAILURE;
115 }
116 const QString mergedQtConfFilePath = partialPathToMergedPath.value(directoryPath);
117
118 // Pre-create the directory in case it doesn't exist yet. Especially relevant for the
119 // 'Resources' subdirectory for macOS bundles.
120 QDir().mkpath(QFileInfo(mergedQtConfFilePath).absolutePath());
121
122 QFile consolidatedQtConfFile(mergedQtConfFilePath);
123 if (!consolidatedQtConfFile.open(QFile::WriteOnly | QFile::Text)) {
124 qCritical() << "could not open" << consolidatedQtConfFile.fileName();
125 return EXIT_FAILURE;
126 }
127 QTextStream out(&consolidatedQtConfFile);
128 QStringList allIncludes = directoryToNecessaryImports.values(directoryPath);
129 allIncludes.removeDuplicates();
130 out << "[Config]\nMergeQtConf = true\n"
131 << "[Paths]\nQmlImports = "
132 << allIncludes.join(u",") << Qt::endl;
133 }
134 QFile outfile(pathToList + u".done");
135 if (!outfile.open(QFile::WriteOnly | QFile::Text))
136 return EXIT_FAILURE;
137 outfile.write(QByteArray::number(QDateTime::currentSecsSinceEpoch()));
138 return EXIT_SUCCESS;
139}
140
141QT_END_NAMESPACE
static QDebug message(QDebug base, QAnyStringView message, QAnyStringView fileName, int lineNumber)
QAnyStringView interfaceName(const Interface &iface)
QDebug warning(const MetaType &classDef)
int mergeQtConfFiles(const QString &pathToList, const QString &pathToMergedQtConfsList)
QDebug error(QAnyStringView fileName, int lineNumber=0)
QDebug warning(QAnyStringView fileName, int lineNumber=0)