7#include "qmake-parser/profileevaluator.h"
8#include "qmake-parser/qmakeparser.h"
9#include "qmake-parser/qmakevfs.h"
13#include <QtCore/QDirIterator>
14#include <QtCore/QFile>
15#include <QtCore/QFileInfo>
16#include <QtCore/QJsonArray>
17#include <QtCore/QJsonDocument>
18#include <QtCore/QJsonObject>
19#include <QtCore/QLibraryInfo>
20#include <QtCore/QRegularExpression>
22using namespace Qt::StringLiterals;
35 void message(
int type,
const QString &msg,
const QString &fileName,
int lineNo)
override
69 qWarning(
"Pro-JSON-generator error: Cannot read %s: %s",
qPrintable(resourceFile),
73 const ReadQrcResult rqr = readQrcFile(resourceFile, content);
75 qWarning(
"Pro-JSON-generator error: %s:%lld: %s",
qPrintable(resourceFile), rqr.line,
84 QStringList vPaths = visitor.absolutePathValues(QLatin1String(vvar), projectDir);
86 vPaths.removeDuplicates();
87 return visitor.absoluteFileValues(QLatin1String(var), projectDir, vPaths, 0);
93 QStringList baseVPaths;
94 baseVPaths += visitor.absolutePathValues(
"VPATH"_L1, projectDir);
95 baseVPaths << projectDir;
96 baseVPaths.removeDuplicates();
98 QStringList sourceFiles;
101 sourceFiles += getSources(
"SOURCES",
"VPATH_SOURCES", baseVPaths, projectDir, visitor);
102 sourceFiles += getSources(
"HEADERS",
"VPATH_HEADERS", baseVPaths, projectDir, visitor);
104 sourceFiles += getSources(
"FORMS",
"VPATH_FORMS", baseVPaths, projectDir, visitor);
106 const QStringList resourceFiles =
107 getSources(
"RESOURCES",
"VPATH_RESOURCES", baseVPaths, projectDir, visitor);
108 for (
const QString &resource : resourceFiles)
109 sourceFiles += getResources(resource, vfs);
111 QStringList installs = visitor.values(
"INSTALLS"_L1) + visitor.values(
"DEPLOYMENT"_L1);
112 installs.removeDuplicates();
113 QDir baseDir(projectDir);
114 for (
const QString &inst : std::as_const(installs)) {
115 for (
const QString &file : visitor.values(inst +
".files"_L1)) {
116 QFileInfo info(file);
117 if (!info.isAbsolute())
118 info.setFile(baseDir.absoluteFilePath(file));
119 QStringList nameFilter;
122 nameFilter <<
"*"_L1;
123 searchPath = info.filePath();
125 nameFilter << info.fileName();
126 searchPath = info.path();
129 QDirIterator iterator(searchPath, nameFilter,
130 QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks,
131 QDirIterator::Subdirectories);
132 while (iterator.hasNext()) {
134 QFileInfo cfi = iterator.fileInfo();
135 if (isSupportedExtension(cfi.suffix()))
136 sourceFiles << cfi.filePath();
141 sourceFiles.removeDuplicates();
148 const QStringList trExcludes = visitor.values(
"TR_EXCLUDE"_L1);
149 QStringList excludes;
150 excludes.reserve(trExcludes.size());
151 const QDir projectDir(projectDirPath);
152 for (
const QString &ex : trExcludes)
153 excludes << QDir::cleanPath(projectDir.absoluteFilePath(ex));
159 for (
const QString &ex : visitor.values(
"TR_EXCLUDE"_L1)) {
160 QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(ex));
161 for (
auto it = subProjects->begin(); it != subProjects->end(); ) {
162 if (rx.match(*it).hasMatch())
163 it = subProjects->erase(it);
177 return QJsonValue(s);
182 return QJsonArray::fromStringList(lst);
186static void setValue(QJsonObject &obj,
const char *key, T value)
188 obj[QLatin1String(key)] = toJsonValue(value);
192 const QStringList &translationsVariables,
202 QStringList tmp = visitor.values(
"CODECFORSRC"_L1);
205 QString proPath = QFileInfo(proFile).path();
207 QStringList subProjects = visitor.values(
"SUBDIRS"_L1);
208 excludeProjects(visitor, &subProjects);
209 QStringList subProFiles;
210 QDir proDir(proPath);
211 for (
const QString &subdir : std::as_const(subProjects)) {
212 QString realdir = visitor.value(subdir +
".subdir"_L1);
213 if (realdir.isEmpty())
214 realdir = visitor.value(subdir +
".file"_L1);
215 if (realdir.isEmpty())
217 QString subPro = QDir::cleanPath(proDir.absoluteFilePath(realdir));
218 QFileInfo subInfo(subPro);
219 if (subInfo.isDir()) {
220 subProFiles << (subPro + u'/' + subInfo.fileName() +
".pro"_L1);
222 subProFiles << subPro;
225 QJsonArray subResults = processProjects(
false, subProFiles, translationsVariables,
226 QHash<QString, QString>(), option, vfs, parser,
227 evalHandler,
nullptr);
228 if (!subResults.isEmpty())
229 setValue(result,
"subProjects", subResults);
231 const QStringList sourceFiles = getSources(visitor, proPath, vfs);
232 setValue(result,
"includePaths", visitor.absolutePathValues(
"INCLUDEPATH"_L1, proPath));
233 setValue(result,
"excluded", getExcludes(visitor, proPath));
234 setValue(result,
"sources", sourceFiles);
240 const QStringList &translationsVariables,
246 for (
const QString &proFile : proFiles) {
247 if (!outDirMap.isEmpty())
248 option->setDirectories(QFileInfo(proFile).path(), outDirMap[proFile]);
251 if (!(pro = parser->parsedProFile(proFile,
252 topLevel ? QMakeParser::ParseReportMissing
253 : QMakeParser::ParseDefault))) {
254 if (topLevel && fail)
258 ProFileEvaluator visitor(option, parser, vfs, evalHandler);
259 visitor.setCumulative(
true);
260 visitor.setOutputDir(option->shadowedPath(pro->directoryName()));
261 if (!visitor.accept(pro)) {
262 if (topLevel && fail)
268 QJsonObject prj = processProject(proFile, translationsVariables, option, vfs, parser,
269 evalHandler, visitor);
270 setValue(prj,
"projectFile", proFile);
272 for (
const QString &varName : translationsVariables) {
273 if (!visitor.contains(varName))
275 QDir proDir(QFileInfo(proFile).path());
276 const QStringList translations = visitor.values(varName);
277 for (
const QString &tsFile : translations)
278 tsFiles << proDir.filePath(tsFile);
280 if (!tsFiles.isEmpty())
281 setValue(prj,
"translations", tsFiles);
282 if (visitor.contains(
"LUPDATE_COMPILE_COMMANDS_PATH"_L1)) {
283 const QStringList thepathjson = visitor.values(
"LUPDATE_COMPILE_COMMANDS_PATH"_L1);
284 setValue(prj,
"compileCommands", thepathjson.value(0));
294 const QHash<QString, QString> &outDirMap,
int proDebug,
bool verbose)
298 option.qmake_abslocation = QString::fromLocal8Bit(qgetenv(
"QMAKE"));
299 if (option.qmake_abslocation.isEmpty()) {
300 option.qmake_abslocation = QLibraryInfo::path(QLibraryInfo::BinariesPath) +
"/qmake"_L1;
302 option.debugLevel = proDebug;
303 option.initProperties();
304 option.setCommandLineArguments(QDir::currentPath(), {
"CONFIG+=lupdate_run"_L1 });
311 QJsonArray json = processProjects(
true, proFiles, translationsVariables, outDirMap, &option,
312 &vfs, &parser, &evalHandler, &fail);
313 std::optional<QJsonArray> result;
315 result.emplace(
std::move(json));
322Projects generateProjects(
const QStringList &proFiles,
const QStringList &translationsVariables,
323 const QHash<QString, QString> &outDirMap,
int proDebug,
bool verbose,
324 QString *errorString, QJsonArray *resultJson)
326 errorString->clear();
328 std::optional<QJsonArray> jsonResults = generateProjectDescription(proFiles, translationsVariables, outDirMap,
331 *errorString =
"Failed to generate project description from .pro files"_L1;
336 *resultJson = *jsonResults;
338 Projects projects = projectDescriptionFromJson(*jsonResults, errorString);
339 if (!errorString->isEmpty())
void message(int type, const QString &msg, const QString &fileName, int lineNo) override
void fileMessage(int type, const QString &msg) override
void doneWithEval(ProFile *) override
void aboutToEval(ProFile *, ProFile *, EvalFileType) override
ProFileEvaluator::TemplateType templateType() const
ReadResult readFile(int id, QString *contents, QString *errStr)
const QString & asString(const QString &s)
static QStringList getExcludes(const ProFileEvaluator &visitor, const QString &projectDirPath)
static QStringList getSources(const ProFileEvaluator &visitor, const QString &projectDir, QMakeVfs *vfs)
static void excludeProjects(const ProFileEvaluator &visitor, QStringList *subProjects)
static QJsonValue toJsonValue(const QString &s)
static QJsonObject processProject(const QString &proFile, const QStringList &translationsVariables, ProFileGlobals *option, QMakeVfs *vfs, QMakeParser *parser, EvalHandler *evalHandler, ProFileEvaluator &visitor)
static QJsonValue toJsonValue(const QJsonValue &v)
static QStringList getSources(const char *var, const char *vvar, const QStringList &baseVPaths, const QString &projectDir, const ProFileEvaluator &visitor)
static QStringList getResources(const QString &resourceFile, QMakeVfs *vfs)
static void setValue(QJsonObject &obj, const char *key, T value)
static QJsonArray processProjects(bool topLevel, const QStringList &proFiles, const QStringList &translationsVariables, const QHash< QString, QString > &outDirMap, ProFileGlobals *option, QMakeVfs *vfs, QMakeParser *parser, EvalHandler *evalHandler, bool *fail)
static std::optional< QJsonArray > generateProjectDescription(const QStringList &proFiles, const QStringList &translationsVariables, const QHash< QString, QString > &outDirMap, int proDebug, bool verbose)
#define qPrintable(string)
#define QStringLiteral(str)