aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmltyperegistrar/qqmltyperegistrarutils.cpp
blob: 312ff90e68da630fb9b08a896c200a31796fa839 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#include "qqmltyperegistrarutils_p.h"

#include "qanystringviewutils_p.h"
#include "qqmltyperegistrarconstants_p.h"
#include "qqmltyperegistrarconstants_p.h"
#include "qmetatypesjsonprocessor_p.h"

#include <QtCore/qcborarray.h>
#include <QtCore/qcbormap.h>
#include <QtCore/qcborvalue.h>
#include <QtCore/qdebug.h>
#include <QtCore/qfile.h>
#include <QtCore/qdiriterator.h>
#include <QtCore/private/qduplicatetracker_p.h>
#include <QtCore/qtextstream.h>

using namespace Qt::Literals::StringLiterals;

QT_BEGIN_NAMESPACE

QTypeRevision handleInMinorVersion(QTypeRevision revision, int majorVersion)
{
    if (!revision.hasMajorVersion() && revision.hasMinorVersion()) {
        // this version has been obtained by QML_{ADDED,REMOVED}_IN_MINOR_VERSION
        revision = QTypeRevision::fromVersion(majorVersion, revision.minorVersion());
    }
    return revision;
}

QAnyStringView interfaceName(const Interface &iface)
{
    return iface.className;
}

static QDebug message(QDebug base, QAnyStringView message, QAnyStringView fileName, int lineNumber)
{
    // Formatted such that it becomes a link in QtCreator (even with "::" ending)
    const QString lineString = lineNumber ? QString::number(lineNumber) : QString();
    return (base.noquote().nospace()
            << message << ": " << fileName << ":" << lineString << ":").space();
}

QDebug warning(QAnyStringView fileName, int lineNumber)
{
    return message(qWarning(), "Warning", fileName, lineNumber);
}

QDebug warning(const MetaType &classDef)
{
    const QAnyStringView file = classDef.inputFile();
    int lineNo = classDef.lineNumber();
    if (!file.isEmpty())
        return warning(file, lineNo);

    return warning(classDef.qualifiedClassName());
}

QDebug error(QAnyStringView fileName, int lineNumber)
{
    return message(qCritical(), "Error", fileName, lineNumber);
}

/*!
    \internal
    \a pathToList points to a file listing all qt.parts.conf files
    In any given directory, there might be more than one qt.parts.conf file (especially on Winodws).
    We need to merge all import paths for a a given folder (but want to avoid duplicate entries).
 */
int mergeQtConfFiles(const QString &pathToList)
{
    QFile listFile(pathToList);
    if (!listFile.open(QFile::ReadOnly | QFile::Text))
        return EXIT_FAILURE;
    QMultiHash<QString, QString> directoryToNecessaryImports;
    while (!listFile.atEnd()) {
        QByteArray partFilePath = listFile.readLine().trimmed();
        QString directoryPath = QFileInfo(QString::fromUtf8(partFilePath)).absolutePath();
        QDirIterator dirIt(directoryPath, { "*_qt.part.conf"_L1 }, QDir::Filter::Files );
        while (dirIt.hasNext()) {
            QFile partialFile(dirIt.next());
            if (!partialFile.open(QFile::ReadOnly | QFile::Text)) {
                qDebug() << "could not open" << partialFile.fileName();
                return EXIT_FAILURE;
            }
            while (!partialFile.atEnd()) {
                QByteArray import = partialFile.readLine().trimmed();
                directoryToNecessaryImports.insert(directoryPath, QString::fromUtf8(import));
            }
        }
    }
    for (const QString &directoryPath: directoryToNecessaryImports.keys()) {
        QFile consolidatedQtConfFile(directoryPath + QDir::separator() + u"qt.conf");
        if (!consolidatedQtConfFile.open(QFile::WriteOnly | QFile::Text)) {
            qDebug() << "could not open" << consolidatedQtConfFile.fileName();
            return EXIT_FAILURE;
        }
        QTextStream out(&consolidatedQtConfFile);
        QStringList allIncludes = directoryToNecessaryImports.values(directoryPath);
        allIncludes.removeDuplicates();
        out << "[Config]\nMergeQtConf = true\n"
            << "[Paths]\nQmlImports = "
            << allIncludes.join(u",") << Qt::endl;
    }
    QFile outfile(pathToList + u".done");
    if (!outfile.open(QFile::WriteOnly | QFile::Text))
        return EXIT_FAILURE;
    outfile.write(QByteArray::number(QDateTime::currentSecsSinceEpoch()));
    return EXIT_SUCCESS;
}

QT_END_NAMESPACE