aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristian Adam <[email protected]>2023-09-27 20:20:46 +0200
committerCristian Adam <[email protected]>2023-09-28 10:49:56 +0000
commit776c8670d7e8124c8b78dc505b85a94d51372e54 (patch)
treeaa36c168060eb569bfc7e09a3b6b5dfd426fa7b4
parentd08f1c6e9415c6aa2e47410c9c8763580e28b046 (diff)
CMakePM: Handle project FindPackage package variables
For example find_package(ZLIB QUEIT) will result in the package variables ZLIB_LIBRARY ZLIB_INCLUDE_DIR. The variables are available for both code completion and navigation. Change-Id: I4ea6090f44a980dc91632fcabbda16987b0f0285 Reviewed-by: Alessandro Portale <[email protected]>
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp45
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.h2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeeditor.cpp4
-rw-r--r--src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp5
4 files changed, 56 insertions, 0 deletions
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index 8d5f9823245..a055d07149c 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -1337,13 +1337,58 @@ void CMakeBuildSystem::setupCMakeSymbolsHash()
m_cmakeSymbolsHash.insert(QString::fromUtf8(arg.Value), link);
};
+ // Gather the exported variables for the Find<Package> CMake packages
+ m_projectFindPackageVariables.clear();
+
+ const std::string fphsFunctionName = "find_package_handle_standard_args";
+ CMakeKeywords keywords;
+ if (auto tool = CMakeKitAspect::cmakeTool(target()->kit()))
+ keywords = tool->keywords();
+ QSet<std::string> fphsFunctionArgs;
+ if (keywords.functionArgs.contains(QString::fromStdString(fphsFunctionName))) {
+ const QList<std::string> args
+ = Utils::transform(keywords.functionArgs.value(QString::fromStdString(fphsFunctionName)),
+ &QString::toStdString);
+ fphsFunctionArgs = Utils::toSet(args);
+ }
+
+ auto handleFindPackageVariables = [&](const CMakeFileInfo &cmakeFile, const cmListFileFunction &func) {
+ if (func.LowerCaseName() != fphsFunctionName)
+ return;
+
+ if (func.Arguments().size() == 0)
+ return;
+ auto firstArgument = func.Arguments()[0];
+ const auto filteredArguments = Utils::filtered(func.Arguments(), [&](const auto &arg) {
+ return !fphsFunctionArgs.contains(arg.Value) && arg != firstArgument;
+ });
+
+ for (const auto &arg : filteredArguments) {
+ const QString value = QString::fromUtf8(arg.Value);
+ if (value.contains("${") || (value.startsWith('"') && value.endsWith('"'))
+ || (value.startsWith("'") && value.endsWith("'")))
+ continue;
+
+ m_projectFindPackageVariables << value;
+
+ Utils::Link link;
+ link.targetFilePath = cmakeFile.path;
+ link.targetLine = arg.Line;
+ link.targetColumn = arg.Column - 1;
+ m_cmakeSymbolsHash.insert(value, link);
+ }
+ };
+
for (const auto &cmakeFile : std::as_const(m_cmakeFiles)) {
for (const auto &func : cmakeFile.cmakeListFile.Functions) {
handleFunctionMacroOption(cmakeFile, func);
handleImportedTargets(cmakeFile, func);
handleProjectTargets(cmakeFile, func);
+ handleFindPackageVariables(cmakeFile, func);
}
}
+
+ m_projectFindPackageVariables.removeDuplicates();
}
void CMakeBuildSystem::ensureBuildDirectory(const BuildDirParameters &parameters)
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
index a8f2a66308b..d29ee777d41 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
@@ -122,6 +122,7 @@ public:
const QHash<QString, Utils::Link> &cmakeSymbolsHash() const { return m_cmakeSymbolsHash; }
CMakeKeywords projectKeywords() const { return m_projectKeywords; }
QStringList projectImportedTargets() const { return m_projectImportedTargets; }
+ QStringList projectFindPackageVariables() const { return m_projectFindPackageVariables; }
signals:
void configurationCleared();
@@ -229,6 +230,7 @@ private:
QHash<QString, Utils::Link> m_cmakeSymbolsHash;
CMakeKeywords m_projectKeywords;
QStringList m_projectImportedTargets;
+ QStringList m_projectFindPackageVariables;
QHash<QString, ProjectFileArgumentPosition> m_filesToBeRenamed;
diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
index 86f8823fdee..beed0d2ebe5 100644
--- a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
@@ -248,6 +248,10 @@ void CMakeEditorWidget::findLinkAt(const QTextCursor &cursor,
// Check if the symbols is a user defined function or macro
const CMakeBuildSystem *cbs = static_cast<const CMakeBuildSystem *>(bs);
+ // Strip variable coating
+ if (buffer.startsWith("${") && buffer.endsWith("}"))
+ buffer = buffer.mid(2, buffer.size() - 3);
+
if (cbs->cmakeSymbolsHash().contains(buffer)) {
link = cbs->cmakeSymbolsHash().value(buffer);
addTextStartEndToLink(link);
diff --git a/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp
index 80bd513fd6d..93c00509c0c 100644
--- a/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp
@@ -254,12 +254,14 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync()
QStringList buildTargets;
QStringList importedTargets;
+ QStringList findPackageVariables;
if (auto bs = qobject_cast<CMakeBuildSystem *>(ProjectTree::currentBuildSystem())) {
for (const auto &target : std::as_const(bs->buildTargets()))
if (target.targetType != TargetType::UtilityType)
buildTargets << target.title;
projectKeywords = bs->projectKeywords();
importedTargets = bs->projectImportedTargets();
+ findPackageVariables = bs->projectFindPackageVariables();
}
if (isInComment(interface()))
@@ -296,6 +298,7 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync()
if (varGenexToken == "${") {
items.append(generateList(keywords.variables, m_variableIcon));
items.append(generateList(projectKeywords.variables, m_projectVariableIcon));
+ items.append(generateList(findPackageVariables, m_projectVariableIcon));
}
if (varGenexToken == "$<")
items.append(generateList(keywords.generatorExpressions, m_genexIcon));
@@ -311,6 +314,7 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync()
|| functionName == "cmake_print_variables") {
items.append(generateList(keywords.variables, m_variableIcon));
items.append(generateList(projectKeywords.variables, m_projectVariableIcon));
+ items.append(generateList(findPackageVariables, m_projectVariableIcon));
items.append(generateList(localVariables, m_variableIcon));
}
@@ -369,6 +373,7 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync()
items.append(generateList(keywords.variables, m_variableIcon));
items.append(generateList(projectKeywords.variables, m_projectVariableIcon));
items.append(generateList(localVariables, m_variableIcon));
+ items.append(generateList(findPackageVariables, m_projectVariableIcon));
items.append(generateList(keywords.properties, m_propertyIcon));
items.append(generateList(buildTargets, m_targetsIcon));