CMakePM: Add imported targets to code completion / navigation

This allows e.g. Qt6::Core to be specified as argument for
target_link_libraries and navigation via F2.

Also fixes a bug introduced with
695952f84b which removed the project
specific features due to project being nullptr.

Change-Id: I5efa28c498d337e6bab564533a5445e6c364b26b
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Cristian Adam
2023-09-27 17:55:43 +02:00
parent 1723af0206
commit d915e22adb
3 changed files with 69 additions and 26 deletions

View File

@@ -1261,14 +1261,14 @@ void CMakeBuildSystem::setupCMakeSymbolsHash()
m_projectKeywords.functions.clear(); m_projectKeywords.functions.clear();
m_projectKeywords.variables.clear(); m_projectKeywords.variables.clear();
for (const auto &cmakeFile : std::as_const(m_cmakeFiles)) { auto handleFunctionMacroOption = [&](const CMakeFileInfo &cmakeFile,
for (const auto &func : cmakeFile.cmakeListFile.Functions) { const cmListFileFunction &func) {
if (func.LowerCaseName() != "function" && func.LowerCaseName() != "macro" if (func.LowerCaseName() != "function" && func.LowerCaseName() != "macro"
&& func.LowerCaseName() != "option") && func.LowerCaseName() != "option")
continue; return;
if (func.Arguments().size() == 0) if (func.Arguments().size() == 0)
continue; return;
auto arg = func.Arguments()[0]; auto arg = func.Arguments()[0];
Utils::Link link; Utils::Link link;
@@ -1281,6 +1281,38 @@ void CMakeBuildSystem::setupCMakeSymbolsHash()
m_projectKeywords.variables[QString::fromUtf8(arg.Value)] = FilePath(); m_projectKeywords.variables[QString::fromUtf8(arg.Value)] = FilePath();
else else
m_projectKeywords.functions[QString::fromUtf8(arg.Value)] = FilePath(); m_projectKeywords.functions[QString::fromUtf8(arg.Value)] = FilePath();
};
m_projectImportedTargets.clear();
auto handleImportedTargets = [&](const CMakeFileInfo &cmakeFile,
const cmListFileFunction &func) {
if (func.LowerCaseName() != "add_library")
return;
if (func.Arguments().size() == 0)
return;
auto arg = func.Arguments()[0];
const QString targetName = QString::fromUtf8(arg.Value);
const bool haveImported = Utils::contains(func.Arguments(), [](const auto &arg) {
return arg.Value == "IMPORTED";
});
if (haveImported && !targetName.contains("${")) {
m_projectImportedTargets << targetName;
// Allow navigation to the imported target
Utils::Link link;
link.targetFilePath = cmakeFile.path;
link.targetLine = arg.Line;
link.targetColumn = arg.Column - 1;
m_cmakeSymbolsHash.insert(targetName, link);
}
};
for (const auto &cmakeFile : std::as_const(m_cmakeFiles)) {
for (const auto &func : cmakeFile.cmakeListFile.Functions) {
handleFunctionMacroOption(cmakeFile, func);
handleImportedTargets(cmakeFile, func);
} }
} }
} }

View File

@@ -121,6 +121,7 @@ public:
const QHash<QString, Utils::Link> &cmakeSymbolsHash() const { return m_cmakeSymbolsHash; } const QHash<QString, Utils::Link> &cmakeSymbolsHash() const { return m_cmakeSymbolsHash; }
CMakeKeywords projectKeywords() const { return m_projectKeywords; } CMakeKeywords projectKeywords() const { return m_projectKeywords; }
QStringList projectImportedTargets() const { return m_projectImportedTargets; }
signals: signals:
void configurationCleared(); void configurationCleared();
@@ -227,6 +228,7 @@ private:
QSet<CMakeFileInfo> m_cmakeFiles; QSet<CMakeFileInfo> m_cmakeFiles;
QHash<QString, Utils::Link> m_cmakeSymbolsHash; QHash<QString, Utils::Link> m_cmakeSymbolsHash;
CMakeKeywords m_projectKeywords; CMakeKeywords m_projectKeywords;
QStringList m_projectImportedTargets;
QHash<QString, ProjectFileArgumentPosition> m_filesToBeRenamed; QHash<QString, ProjectFileArgumentPosition> m_filesToBeRenamed;

View File

@@ -16,6 +16,7 @@
#include <projectexplorer/projectexplorericons.h> #include <projectexplorer/projectexplorericons.h>
#include <projectexplorer/projectmanager.h> #include <projectexplorer/projectmanager.h>
#include <projectexplorer/projectnodes.h> #include <projectexplorer/projectnodes.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <texteditor/codeassist/assistinterface.h> #include <texteditor/codeassist/assistinterface.h>
@@ -47,6 +48,7 @@ public:
const QIcon m_genexIcon; const QIcon m_genexIcon;
const QIcon m_moduleIcon; const QIcon m_moduleIcon;
const QIcon m_targetsIcon; const QIcon m_targetsIcon;
const QIcon m_importedTargetIcon;
TextEditor::SnippetAssistCollector m_snippetCollector; TextEditor::SnippetAssistCollector m_snippetCollector;
}; };
@@ -61,10 +63,15 @@ CMakeFileCompletionAssist::CMakeFileCompletionAssist()
, m_genexIcon(CodeModelIcon::iconForType(CodeModelIcon::Class)) , m_genexIcon(CodeModelIcon::iconForType(CodeModelIcon::Class))
, m_moduleIcon( , m_moduleIcon(
ProjectExplorer::DirectoryIcon(ProjectExplorer::Constants::FILEOVERLAY_MODULES).icon()) ProjectExplorer::DirectoryIcon(ProjectExplorer::Constants::FILEOVERLAY_MODULES).icon())
, m_targetsIcon(ProjectExplorer::Icons::BUILD.icon()) , m_targetsIcon(ProjectExplorer::Icons::BUILD_SMALL.icon())
, m_importedTargetIcon(Icon({{":/projectexplorer/images/buildhammerhandle.png",
Theme::IconsCodeModelKeywordColor},
{":/projectexplorer/images/buildhammerhead.png",
Theme::IconsCodeModelKeywordColor}},
Icon::MenuTintedStyle)
.icon())
, m_snippetCollector(Constants::CMAKE_SNIPPETS_GROUP_ID, , m_snippetCollector(Constants::CMAKE_SNIPPETS_GROUP_ID,
FileIconProvider::icon(FilePath::fromString("CMakeLists.txt"))) FileIconProvider::icon(FilePath::fromString("CMakeLists.txt")))
{} {}
static bool isInComment(const AssistInterface *interface) static bool isInComment(const AssistInterface *interface)
@@ -239,7 +246,6 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync()
{ {
CMakeKeywords keywords; CMakeKeywords keywords;
CMakeKeywords projectKeywords; CMakeKeywords projectKeywords;
Project *project = nullptr;
const FilePath &filePath = interface()->filePath(); const FilePath &filePath = interface()->filePath();
if (!filePath.isEmpty() && filePath.isFile()) { if (!filePath.isEmpty() && filePath.isFile()) {
if (auto tool = CMakeToolManager::defaultProjectOrDefaultCMakeTool()) if (auto tool = CMakeToolManager::defaultProjectOrDefaultCMakeTool())
@@ -247,14 +253,13 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync()
} }
QStringList buildTargets; QStringList buildTargets;
if (project && project->activeTarget()) { QStringList importedTargets;
const auto bs = qobject_cast<CMakeBuildSystem *>(project->activeTarget()->buildSystem()); if (auto bs = qobject_cast<CMakeBuildSystem *>(ProjectTree::currentBuildSystem())) {
if (bs) {
for (const auto &target : std::as_const(bs->buildTargets())) for (const auto &target : std::as_const(bs->buildTargets()))
if (target.targetType != TargetType::UtilityType) if (target.targetType != TargetType::UtilityType)
buildTargets << target.title; buildTargets << target.title;
projectKeywords = bs->projectKeywords(); projectKeywords = bs->projectKeywords();
} importedTargets = bs->projectImportedTargets();
} }
if (isInComment(interface())) if (isInComment(interface()))
@@ -339,9 +344,12 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync()
if ((functionName.contains("target") || functionName == "install" if ((functionName.contains("target") || functionName == "install"
|| functionName == "add_dependencies" || functionName == "set_property" || functionName == "add_dependencies" || functionName == "set_property"
|| functionName == "export" || functionName == "cmake_print_properties") || functionName == "export" || functionName == "cmake_print_properties"
&& !onlyFileItems()) || functionName == "if" || functionName == "elseif")
&& !onlyFileItems()) {
items.append(generateList(buildTargets, m_targetsIcon)); items.append(generateList(buildTargets, m_targetsIcon));
items.append(generateList(importedTargets, m_importedTargetIcon));
}
if (keywords.functionArgs.contains(functionName) && !onlyFileItems()) { if (keywords.functionArgs.contains(functionName) && !onlyFileItems()) {
QStringList functionSymbols = keywords.functionArgs.value(functionName); QStringList functionSymbols = keywords.functionArgs.value(functionName);
@@ -364,6 +372,7 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync()
items.append(generateList(keywords.properties, m_propertyIcon)); items.append(generateList(keywords.properties, m_propertyIcon));
items.append(generateList(buildTargets, m_targetsIcon)); items.append(generateList(buildTargets, m_targetsIcon));
items.append(generateList(importedTargets, m_importedTargetIcon));
} }
} }