From f30d27b10f28279505be2f39220032eacdbc7992 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 19 Mar 2019 16:03:36 +0100 Subject: [PATCH] QmakePM: Find prf files for CONFIG values ... in the pro file editor. When the user selects "Jump to file under cursor" (e.g. via F2), and the string under the cursor is not resolvable as a local file path, we assume it is a CONFIG value and try to locate a corresponding prf file. To this end, we expose the "feature roots" information of the qmake evaluator in the QmakeProFile class. Fixes: QTCREATORBUG-15753 Change-Id: Ibdc6e194a40f07030a5d21f2ddc7b92b63d1765b Reviewed-by: Joerg Bornemann --- .../qmakeprojectmanager/profileeditor.cpp | 42 ++++++++++++++++++- .../qmakeprojectmanager/qmakeparsernodes.cpp | 1 + .../qmakeprojectmanager/qmakeparsernodes.h | 2 + src/shared/proparser/profileevaluator.cpp | 5 +++ src/shared/proparser/profileevaluator.h | 1 + 5 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp index cb261427674..c2a6a3e89c8 100644 --- a/src/plugins/qmakeprojectmanager/profileeditor.cpp +++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp @@ -28,6 +28,8 @@ #include "profilecompletionassist.h" #include "profilehighlighter.h" #include "profilehoverhandler.h" +#include "qmakenodes.h" +#include "qmakeproject.h" #include "qmakeprojectmanager.h" #include "qmakeprojectmanagerconstants.h" #include "qmakeprojectmanagerconstants.h" @@ -36,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +51,7 @@ #include +using namespace ProjectExplorer; using namespace TextEditor; using namespace Utils; @@ -56,12 +60,14 @@ namespace Internal { class ProFileEditorWidget : public TextEditorWidget { -protected: +private: void findLinkAt(const QTextCursor &, Utils::ProcessLinkCallback &&processLinkCallback, bool resolveTarget = true, bool inNextSplit = false) override; void contextMenuEvent(QContextMenuEvent *) override; + + QString checkForPrfFile(const QString &baseName) const; }; static bool isValidFileNameChar(const QChar &c) @@ -74,6 +80,36 @@ static bool isValidFileNameChar(const QChar &c) || c == QLatin1Char('\\'); } +QString ProFileEditorWidget::checkForPrfFile(const QString &baseName) const +{ + const FileName projectFile = textDocument()->filePath(); + const QmakePriFileNode *projectNode = nullptr; + for (const Project * const project : SessionManager::projects()) { + if (project->isParsing()) + continue; + projectNode = dynamic_cast(project->rootProjectNode() + ->findProjectNode([&projectFile](const ProjectNode *pn) { + return pn->filePath() == projectFile; + })); + if (projectNode) + break; + } + if (!projectNode) + return QString(); + const QmakeProFileNode * const proFileNode = projectNode->proFileNode(); + if (!proFileNode) + return QString(); + const QmakeProFile * const proFile = proFileNode->proFile(); + if (!proFile) + return QString(); + for (const QString &featureRoot : proFile->featureRoots()) { + const QFileInfo candidate(featureRoot + '/' + baseName + ".prf"); + if (candidate.exists()) + return candidate.filePath(); + } + return QString(); +} + void ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, Utils::ProcessLinkCallback &&processLinkCallback, bool /*resolveTarget*/, @@ -189,6 +225,10 @@ void ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, return processLinkCallback(link); } link.targetFileName = QDir::cleanPath(fileName); + } else { + link.targetFileName = checkForPrfFile(buffer); + } + if (!link.targetFileName.isEmpty()) { link.linkTextStart = cursor.position() - positionInBlock + beginPos + 1; link.linkTextEnd = cursor.position() - positionInBlock + endPos; } diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 671cd5bfecf..1e8ff76337b 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -1616,6 +1616,7 @@ void QmakeProFile::applyEvaluate(QmakeEvalResult *evalResult) m_varValues = result->newVarValues; m_displayName = singleVariableValue(Variable::QmakeProjectName); + m_featureRoots = m_readerExact->featureRoots(); } // result == EvalOk if (!result->directoriesWithWildcards.isEmpty()) { diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h index 6f0e13a5c95..d166690badc 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h @@ -309,6 +309,7 @@ public: TargetInformation targetInformation() const; InstallsList installsList() const; + const QStringList featureRoots() const { return m_featureRoots; } QByteArray cxxDefines() const; @@ -368,6 +369,7 @@ private: TargetInformation m_qmakeTargetInformation; Utils::FileNameList m_subProjectsNotToDeploy; InstallsList m_installsList; + QStringList m_featureRoots; std::unique_ptr m_wildcardWatcher; diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 22f3ee5b4e1..3b816f01cd3 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -124,6 +124,11 @@ QStringList ProFileEvaluator::sourcesToFiles(const QVectorm_featureRoots->paths; +} + // VFS note: all search paths are assumed to be real. QStringList ProFileEvaluator::absolutePathValues( const QString &variable, const QString &baseDirectory) const diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h index a67d4b5a74f..0251f8458cd 100644 --- a/src/shared/proparser/profileevaluator.h +++ b/src/shared/proparser/profileevaluator.h @@ -89,6 +89,7 @@ public: QHash *handled, QSet &directoriesWithWildcards) const; QString propertyValue(const QString &val) const; static QStringList sourcesToFiles(const QVector &sources); + QStringList featureRoots() const; private: QMakeEvaluator *d;