forked from qt-creator/qt-creator
CMakePM: Improve support for adding translation files
There are more ways to add translation files to a cmake project, so support the common ways. Task-number: QTCREATORBUG-29775 Change-Id: I15f0d7a13303a1845760dbfc830c6f773f634ce0 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -393,13 +393,115 @@ static expected_str<bool> insertSnippetSilently(const FilePath &cmakeFile,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void findLastRelevantArgument(const cmListFileFunction &function,
|
||||||
|
std::size_t minimumArgPos,
|
||||||
|
const QSet<QString> &lowerCaseStopParams,
|
||||||
|
QString *lastRelevantArg,
|
||||||
|
int *lastRelevantPos)
|
||||||
|
{
|
||||||
|
const std::vector<cmListFileArgument> args = function.Arguments();
|
||||||
|
*lastRelevantPos = args.size() - 1;
|
||||||
|
for (int i = minimumArgPos, end = args.size(); i < end; ++i) {
|
||||||
|
const QString lowerArg = QString::fromStdString(args.at(i).Value).toLower();
|
||||||
|
if (lowerCaseStopParams.contains(lowerArg)) {
|
||||||
|
*lastRelevantPos = i - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*lastRelevantArg = lowerArg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::optional<cmListFileFunction> findSetFunctionFor(const cmListFile &cmakeListFile,
|
||||||
|
const QString &lowerVariableName)
|
||||||
|
{
|
||||||
|
auto findSetFunc = [lowerVariableName](const auto &func) {
|
||||||
|
if (func.LowerCaseName() != "set")
|
||||||
|
return false;
|
||||||
|
std::vector<cmListFileArgument> args = func.Arguments();
|
||||||
|
return args.size()
|
||||||
|
&& QString::fromStdString(args.front().Value).toLower() == lowerVariableName;
|
||||||
|
};
|
||||||
|
return findFunction(cmakeListFile, findSetFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::optional<cmListFileFunction> handleTSAddVariant(const cmListFile &cmakeListFile,
|
||||||
|
const QSet<QString> &lowerFunctionNames,
|
||||||
|
std::optional<QString> targetName,
|
||||||
|
const QSet<QString> &stopParams,
|
||||||
|
int *lastArgumentPos)
|
||||||
|
{
|
||||||
|
std::optional<cmListFileFunction> function;
|
||||||
|
auto currentFunc = findFunction(cmakeListFile, [lowerFunctionNames, targetName](const auto &func) {
|
||||||
|
auto lower = QString::fromStdString(func.LowerCaseName());
|
||||||
|
if (lowerFunctionNames.contains(lower)) {
|
||||||
|
if (!targetName)
|
||||||
|
return true;
|
||||||
|
const std::vector<cmListFileArgument> args = func.Arguments();
|
||||||
|
if (args.size())
|
||||||
|
return *targetName == QString::fromStdString(args.front().Value);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
if (currentFunc) {
|
||||||
|
QString lastRelevant;
|
||||||
|
const int argsMinimumPos = targetName.has_value() ? 2 : 1;
|
||||||
|
|
||||||
|
findLastRelevantArgument(*currentFunc, argsMinimumPos, stopParams,
|
||||||
|
&lastRelevant, lastArgumentPos);
|
||||||
|
// handle argument
|
||||||
|
if (!lastRelevant.isEmpty() && lastRelevant.startsWith('$')) {
|
||||||
|
QString var = lastRelevant.mid(1);
|
||||||
|
if (var.startsWith('{') && var.endsWith('}'))
|
||||||
|
var = var.mid(1, var.size() - 2);
|
||||||
|
if (!var.isEmpty()) {
|
||||||
|
std::optional<cmListFileFunction> setFunc = findSetFunctionFor(cmakeListFile, var);
|
||||||
|
if (setFunc) {
|
||||||
|
function = *setFunc;
|
||||||
|
*lastArgumentPos = function->Arguments().size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!function.has_value()) // no variable used or we failed to find respective SET()
|
||||||
|
function = currentFunc;
|
||||||
|
}
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::optional<cmListFileFunction> handleQtAddTranslations(const cmListFile &cmakeListFile,
|
||||||
|
std::optional<QString> targetName,
|
||||||
|
int *lastArgumentPos)
|
||||||
|
{
|
||||||
|
const QSet<QString> stopParams{"resource_prefix", "output_targets",
|
||||||
|
"qm_files_output_variable", "sources", "include_directories",
|
||||||
|
"lupdate_options", "lrelease_options"};
|
||||||
|
return handleTSAddVariant(cmakeListFile, {"qt6_add_translations", "qt_add_translations"},
|
||||||
|
targetName, stopParams, lastArgumentPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::optional<cmListFileFunction> handleQtAddLupdate(const cmListFile &cmakeListFile,
|
||||||
|
std::optional<QString> targetName,
|
||||||
|
int *lastArgumentPos)
|
||||||
|
{
|
||||||
|
const QSet<QString> stopParams{"sources", "include_directories", "no_global_target", "options"};
|
||||||
|
return handleTSAddVariant(cmakeListFile, {"qt6_add_lupdate", "qt_add_lupdate"},
|
||||||
|
targetName, stopParams, lastArgumentPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::optional<cmListFileFunction> handleQtCreateTranslation(const cmListFile &cmakeListFile,
|
||||||
|
int *lastArgumentPos)
|
||||||
|
{
|
||||||
|
return handleTSAddVariant(cmakeListFile, {"qt_create_translation", "qt5_create_translation"},
|
||||||
|
std::nullopt, {"options"}, lastArgumentPos);
|
||||||
|
}
|
||||||
|
|
||||||
bool CMakeBuildSystem::addTsFiles(Node *context, const FilePaths &filePaths, FilePaths *notAdded)
|
bool CMakeBuildSystem::addTsFiles(Node *context, const FilePaths &filePaths, FilePaths *notAdded)
|
||||||
{
|
{
|
||||||
if (notAdded)
|
if (notAdded)
|
||||||
notAdded->append(filePaths);
|
notAdded->append(filePaths);
|
||||||
|
|
||||||
if (auto n = dynamic_cast<CMakeTargetNode *>(context)) {
|
if (auto n = dynamic_cast<CMakeTargetNode *>(context)) {
|
||||||
const std::optional<Link> cmakeFile = cmakeFileForBuildKey(n->buildKey(), buildTargets());
|
const QString targetName = n->buildKey();
|
||||||
|
const std::optional<Link> cmakeFile = cmakeFileForBuildKey(targetName, buildTargets());
|
||||||
if (!cmakeFile.has_value())
|
if (!cmakeFile.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -408,18 +510,19 @@ bool CMakeBuildSystem::addTsFiles(Node *context, const FilePaths &filePaths, Fil
|
|||||||
if (!cmakeListFile.has_value())
|
if (!cmakeListFile.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto findTs = [](const auto &func) {
|
int lastArgumentPos = -1;
|
||||||
if (func.LowerCaseName() != "set")
|
std::optional<cmListFileFunction> function
|
||||||
return false;
|
= handleQtAddTranslations(*cmakeListFile, targetName, &lastArgumentPos);
|
||||||
std::vector<cmListFileArgument> args = func.Arguments();
|
|
||||||
return args.size() && args.front().Value == "TS_FILES";
|
|
||||||
};
|
|
||||||
std::optional<cmListFileFunction> function = findFunction(*cmakeListFile, findTs);
|
|
||||||
if (!function.has_value())
|
if (!function.has_value())
|
||||||
|
function = handleQtAddLupdate(*cmakeListFile, targetName, &lastArgumentPos);
|
||||||
|
if (!function.has_value())
|
||||||
|
function = handleQtCreateTranslation(*cmakeListFile, &lastArgumentPos);
|
||||||
|
|
||||||
|
if (!function.has_value()) // we failed to find any pre-existing, TODO add one ourself
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const QString filesToAdd = relativeFilePaths(filePaths, n->filePath().canonicalPath());
|
const QString filesToAdd = relativeFilePaths(filePaths, n->filePath().canonicalPath());
|
||||||
auto lastArgument = function->Arguments().back();
|
auto lastArgument = function->Arguments().at(lastArgumentPos);
|
||||||
const int lastArgLength = static_cast<int>(lastArgument.Value.size()) - 1;
|
const int lastArgLength = static_cast<int>(lastArgument.Value.size()) - 1;
|
||||||
SnippetAndLocation snippetLocation{QString("\n%1").arg(filesToAdd),
|
SnippetAndLocation snippetLocation{QString("\n%1").arg(filesToAdd),
|
||||||
lastArgument.Line, lastArgument.Column + lastArgLength};
|
lastArgument.Line, lastArgument.Column + lastArgLength};
|
||||||
|
Reference in New Issue
Block a user