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
70 qWarning(
"Pro-JSON-generator error: Cannot read %s: %s",
qPrintable(resourceFile),
74 const ReadQrcResult rqr = readQrcFile(resourceFile, content);
76 qWarning(
"Pro-JSON-generator error: %s:%lld: %s",
qPrintable(resourceFile), rqr.line,
85 QStringList vPaths = visitor.absolutePathValues(QLatin1String(vvar), projectDir);
87 vPaths.removeDuplicates();
88 return visitor.absoluteFileValues(QLatin1String(var), projectDir, vPaths, 0);
94 QStringList baseVPaths;
95 baseVPaths += visitor.absolutePathValues(
"VPATH"_L1, projectDir);
96 baseVPaths << projectDir;
97 baseVPaths.removeDuplicates();
99 QStringList sourceFiles;
102 sourceFiles += getSources(
"SOURCES",
"VPATH_SOURCES", baseVPaths, projectDir, visitor);
103 sourceFiles += getSources(
"HEADERS",
"VPATH_HEADERS", baseVPaths, projectDir, visitor);
105 sourceFiles += getSources(
"FORMS",
"VPATH_FORMS", baseVPaths, projectDir, visitor);
107 const QStringList resourceFiles =
108 getSources(
"RESOURCES",
"VPATH_RESOURCES", baseVPaths, projectDir, visitor);
109 for (
const QString &resource : resourceFiles)
110 sourceFiles += getResources(resource, vfs);
112 QStringList installs = visitor.values(
"INSTALLS"_L1) + visitor.values(
"DEPLOYMENT"_L1);
113 installs.removeDuplicates();
114 QDir baseDir(projectDir);
115 for (
const QString &inst : std::as_const(installs)) {
116 for (
const QString &file : visitor.values(inst +
".files"_L1)) {
117 QFileInfo info(file);
118 if (!info.isAbsolute())
119 info.setFile(baseDir.absoluteFilePath(file));
120 QStringList nameFilter;
123 nameFilter <<
"*"_L1;
124 searchPath = info.filePath();
126 nameFilter << info.fileName();
127 searchPath = info.path();
130 QDirIterator iterator(searchPath, nameFilter,
131 QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks,
132 QDirIterator::Subdirectories);
133 while (iterator.hasNext()) {
135 QFileInfo cfi = iterator.fileInfo();
136 if (isSupportedExtension(cfi.suffix()))
137 sourceFiles << cfi.filePath();
142 sourceFiles.removeDuplicates();
149 const QStringList trExcludes = visitor.values(
"TR_EXCLUDE"_L1);
150 QStringList excludes;
151 excludes.reserve(trExcludes.size());
152 const QDir projectDir(projectDirPath);
153 for (
const QString &ex : trExcludes)
154 excludes << QDir::cleanPath(projectDir.absoluteFilePath(ex));
160 for (
const QString &ex : visitor.values(
"TR_EXCLUDE"_L1)) {
161 QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(ex));
162 for (
auto it = subProjects->begin(); it != subProjects->end(); ) {
163 if (rx.match(*it).hasMatch())
164 it = subProjects->erase(it);
178 return QJsonValue(s);
183 return QJsonArray::fromStringList(lst);
187static void setValue(QJsonObject &obj,
const char *key, T value)
189 obj[QLatin1String(key)] = toJsonValue(value);
193 const QStringList &translationsVariables,
203 QStringList tmp = visitor.values(
"CODECFORSRC"_L1);
206 QString proPath = QFileInfo(proFile).path();
208 QStringList subProjects = visitor.values(
"SUBDIRS"_L1);
209 excludeProjects(visitor, &subProjects);
210 QStringList subProFiles;
211 QDir proDir(proPath);
212 for (
const QString &subdir : std::as_const(subProjects)) {
213 QString realdir = visitor.value(subdir +
".subdir"_L1);
214 if (realdir.isEmpty())
215 realdir = visitor.value(subdir +
".file"_L1);
216 if (realdir.isEmpty())
218 QString subPro = QDir::cleanPath(proDir.absoluteFilePath(realdir));
219 QFileInfo subInfo(subPro);
220 if (subInfo.isDir()) {
221 subProFiles << (subPro + u'/' + subInfo.fileName() +
".pro"_L1);
223 subProFiles << subPro;
226 QJsonArray subResults = processProjects(
false, subProFiles, translationsVariables,
227 QHash<QString, QString>(), option, vfs, parser,
228 evalHandler,
nullptr);
229 if (!subResults.isEmpty())
230 setValue(result,
"subProjects", subResults);
232 const QStringList sourceFiles = getSources(visitor, proPath, vfs);
233 setValue(result,
"includePaths", visitor.absolutePathValues(
"INCLUDEPATH"_L1, proPath));
234 setValue(result,
"excluded", getExcludes(visitor, proPath));
235 setValue(result,
"sources", sourceFiles);
241 const QStringList &translationsVariables,
247 for (
const QString &proFile : proFiles) {
248 if (!outDirMap.isEmpty())
249 option->setDirectories(QFileInfo(proFile).path(), outDirMap[proFile]);
252 if (!(pro = parser->parsedProFile(proFile,
253 topLevel ? QMakeParser::ParseReportMissing
254 : QMakeParser::ParseDefault))) {
255 if (topLevel && fail)
259 ProFileEvaluator visitor(option, parser, vfs, evalHandler);
260 visitor.setCumulative(
true);
261 visitor.setOutputDir(option->shadowedPath(pro->directoryName()));
262 if (!visitor.accept(pro)) {
263 if (topLevel && fail)
269 QJsonObject prj = processProject(proFile, translationsVariables, option, vfs, parser,
270 evalHandler, visitor);
271 setValue(prj,
"projectFile", proFile);
273 for (
const QString &varName : translationsVariables) {
274 if (!visitor.contains(varName))
276 QDir proDir(QFileInfo(proFile).path());
277 const QStringList translations = visitor.values(varName);
278 for (
const QString &tsFile : translations)
279 tsFiles << proDir.filePath(tsFile);
281 if (!tsFiles.isEmpty())
282 setValue(prj,
"translations", tsFiles);
283 if (visitor.contains(
"LUPDATE_COMPILE_COMMANDS_PATH"_L1)) {
284 const QStringList thepathjson = visitor.values(
"LUPDATE_COMPILE_COMMANDS_PATH"_L1);
285 setValue(prj,
"compileCommands", thepathjson.value(0));
295 const QHash<QString, QString> &outDirMap,
int proDebug,
bool verbose)
299 option.qmake_abslocation = QString::fromLocal8Bit(qgetenv(
"QMAKE"));
300 if (option.qmake_abslocation.isEmpty()) {
301 option.qmake_abslocation = QLibraryInfo::paths(QLibraryInfo::BinariesPath).value(0) +
"/qmake"_L1;
303 option.debugLevel = proDebug;
304 option.initProperties();
305 option.setCommandLineArguments(QDir::currentPath(), {
"CONFIG+=lupdate_run"_L1 });
312 QJsonArray json = processProjects(
true, proFiles, translationsVariables, outDirMap, &option,
313 &vfs, &parser, &evalHandler, &fail);
314 std::optional<QJsonArray> result;
316 result.emplace(
std::move(json));
323Projects generateProjects(
const QStringList &proFiles,
const QStringList &translationsVariables,
324 const QHash<QString, QString> &outDirMap,
int proDebug,
bool verbose,
325 QString *errorString, QJsonArray *resultJson)
327 errorString->clear();
329 std::optional<QJsonArray> jsonResults = generateProjectDescription(proFiles, translationsVariables, outDirMap,
332 *errorString =
"Failed to generate project description from .pro files"_L1;
337 *resultJson = *jsonResults;
339 Projects projects = projectDescriptionFromJson(*jsonResults, errorString);
340 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, bool utf8=false)
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)