diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index ecfbd3769aa..a79ca304ee6 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -1261,26 +1261,58 @@ void CMakeBuildSystem::setupCMakeSymbolsHash() m_projectKeywords.functions.clear(); m_projectKeywords.variables.clear(); - for (const auto &cmakeFile : std::as_const(m_cmakeFiles)) { - for (const auto &func : cmakeFile.cmakeListFile.Functions) { - if (func.LowerCaseName() != "function" && func.LowerCaseName() != "macro" - && func.LowerCaseName() != "option") - continue; + auto handleFunctionMacroOption = [&](const CMakeFileInfo &cmakeFile, + const cmListFileFunction &func) { + if (func.LowerCaseName() != "function" && func.LowerCaseName() != "macro" + && func.LowerCaseName() != "option") + return; - if (func.Arguments().size() == 0) - continue; - auto arg = func.Arguments()[0]; + if (func.Arguments().size() == 0) + return; + auto arg = func.Arguments()[0]; + Utils::Link link; + link.targetFilePath = cmakeFile.path; + link.targetLine = arg.Line; + link.targetColumn = arg.Column - 1; + m_cmakeSymbolsHash.insert(QString::fromUtf8(arg.Value), link); + + if (func.LowerCaseName() == "option") + m_projectKeywords.variables[QString::fromUtf8(arg.Value)] = FilePath(); + else + 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(QString::fromUtf8(arg.Value), link); + m_cmakeSymbolsHash.insert(targetName, link); + } + }; - if (func.LowerCaseName() == "option") - m_projectKeywords.variables[QString::fromUtf8(arg.Value)] = FilePath(); - else - m_projectKeywords.functions[QString::fromUtf8(arg.Value)] = FilePath(); + for (const auto &cmakeFile : std::as_const(m_cmakeFiles)) { + for (const auto &func : cmakeFile.cmakeListFile.Functions) { + handleFunctionMacroOption(cmakeFile, func); + handleImportedTargets(cmakeFile, func); } } } diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h index cc27c599db5..a8f2a66308b 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h @@ -121,6 +121,7 @@ public: const QHash &cmakeSymbolsHash() const { return m_cmakeSymbolsHash; } CMakeKeywords projectKeywords() const { return m_projectKeywords; } + QStringList projectImportedTargets() const { return m_projectImportedTargets; } signals: void configurationCleared(); @@ -227,6 +228,7 @@ private: QSet m_cmakeFiles; QHash m_cmakeSymbolsHash; CMakeKeywords m_projectKeywords; + QStringList m_projectImportedTargets; QHash m_filesToBeRenamed; diff --git a/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp index dbaf380d250..80bd513fd6d 100644 --- a/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp +++ b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,7 @@ public: const QIcon m_genexIcon; const QIcon m_moduleIcon; const QIcon m_targetsIcon; + const QIcon m_importedTargetIcon; TextEditor::SnippetAssistCollector m_snippetCollector; }; @@ -61,10 +63,15 @@ CMakeFileCompletionAssist::CMakeFileCompletionAssist() , m_genexIcon(CodeModelIcon::iconForType(CodeModelIcon::Class)) , m_moduleIcon( 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, FileIconProvider::icon(FilePath::fromString("CMakeLists.txt"))) - {} static bool isInComment(const AssistInterface *interface) @@ -239,7 +246,6 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync() { CMakeKeywords keywords; CMakeKeywords projectKeywords; - Project *project = nullptr; const FilePath &filePath = interface()->filePath(); if (!filePath.isEmpty() && filePath.isFile()) { if (auto tool = CMakeToolManager::defaultProjectOrDefaultCMakeTool()) @@ -247,14 +253,13 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync() } QStringList buildTargets; - if (project && project->activeTarget()) { - const auto bs = qobject_cast(project->activeTarget()->buildSystem()); - if (bs) { - for (const auto &target : std::as_const(bs->buildTargets())) - if (target.targetType != TargetType::UtilityType) - buildTargets << target.title; - projectKeywords = bs->projectKeywords(); - } + QStringList importedTargets; + if (auto bs = qobject_cast(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(); } if (isInComment(interface())) @@ -339,9 +344,12 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync() if ((functionName.contains("target") || functionName == "install" || functionName == "add_dependencies" || functionName == "set_property" - || functionName == "export" || functionName == "cmake_print_properties") - && !onlyFileItems()) + || functionName == "export" || functionName == "cmake_print_properties" + || functionName == "if" || functionName == "elseif") + && !onlyFileItems()) { items.append(generateList(buildTargets, m_targetsIcon)); + items.append(generateList(importedTargets, m_importedTargetIcon)); + } if (keywords.functionArgs.contains(functionName) && !onlyFileItems()) { QStringList functionSymbols = keywords.functionArgs.value(functionName); @@ -364,6 +372,7 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync() items.append(generateList(keywords.properties, m_propertyIcon)); items.append(generateList(buildTargets, m_targetsIcon)); + items.append(generateList(importedTargets, m_importedTargetIcon)); } }