diff options
Diffstat (limited to 'src/plugins/cmakeprojectmanager/fileapiparser.cpp')
-rw-r--r-- | src/plugins/cmakeprojectmanager/fileapiparser.cpp | 85 |
1 files changed, 25 insertions, 60 deletions
diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.cpp b/src/plugins/cmakeprojectmanager/fileapiparser.cpp index e60040f703..b3c114f45d 100644 --- a/src/plugins/cmakeprojectmanager/fileapiparser.cpp +++ b/src/plugins/cmakeprojectmanager/fileapiparser.cpp @@ -26,13 +26,11 @@ #include "fileapiparser.h" #include <coreplugin/messagemanager.h> -#include <projectexplorer/headerpath.h> #include <projectexplorer/rawprojectpart.h> #include <utils/algorithm.h> #include <utils/qtcassert.h> -#include <QDir> #include <QJsonArray> #include <QJsonDocument> #include <QJsonObject> @@ -49,10 +47,17 @@ const char CMAKE_RELATIVE_QUERY_PATH[] = ".cmake/api/v1/query"; static Q_LOGGING_CATEGORY(cmakeFileApi, "qtc.cmake.fileApi", QtWarningMsg); +const QStringList CMAKE_QUERY_FILENAMES = {"cache-v2", "codemodel-v2", "cmakeFiles-v1"}; + // -------------------------------------------------------------------- // Helper: // -------------------------------------------------------------------- +static FilePath cmakeReplyDirectory(const FilePath &buildDirectory) +{ + return buildDirectory.pathAppended(CMAKE_RELATIVE_REPLY_PATH); +} + static void reportFileApiSetupFailure() { Core::MessageManager::write(QCoreApplication::translate( @@ -292,6 +297,7 @@ static std::vector<Project> extractProjects(const QJsonArray &projects, QString for (const QJsonValue &v : projects) { const QJsonObject obj = v.toObject(); if (obj.isEmpty()) { + qCDebug(cmakeFileApi) << "Empty project skipped!"; errorMessage = QCoreApplication::translate( "CMakeProjectManager::Internal", "Invalid codemodel file generated by CMake: Empty project object."); @@ -304,15 +310,15 @@ static std::vector<Project> extractProjects(const QJsonArray &projects, QString project.directories = indexList(obj.value("directoryIndexes")); project.targets = indexList(obj.value("targetIndexes")); - qCDebug(cmakeFileApi) << "Project read:" << project.name << project.directories; - if (project.directories.empty()) { + qCDebug(cmakeFileApi) << "Invalid project skipped!"; errorMessage = QCoreApplication::translate( "CMakeProjectManager::Internal", "Invalid codemodel file generated by CMake: Broken project data."); continue; } + qCDebug(cmakeFileApi) << "Project read:" << project.name << project.directories; result.emplace_back(std::move(project)); } return result; @@ -501,7 +507,7 @@ static std::vector<Configuration> readCodemodelFile(const QString &codemodelFile std::vector<FileApiDetails::FragmentInfo> extractFragments(const QJsonObject &obj) { const QJsonArray fragments = obj.value("commandFragments").toArray(); - return Utils::transform<std::vector>(fragments, [](const QJsonValue &v) { + return transform<std::vector>(fragments, [](const QJsonValue &v) { const QJsonObject o = v.toObject(); return FileApiDetails::FragmentInfo{o.value("fragment").toString(), o.value("role").toString()}; @@ -809,49 +815,26 @@ QString FileApiDetails::ReplyFileContents::jsonFile(const QString &kind, const Q // FileApi: // -------------------------------------------------------------------- -FileApiParser::FileApiParser(const FilePath &sourceDirectory, const FilePath &buildDirectory) - : m_sourceDirectory(sourceDirectory) - , m_buildDirectory(buildDirectory) -{ - setupCMakeFileApi(); - - QObject::connect(&m_watcher, - &FileSystemWatcher::directoryChanged, - this, - &FileApiParser::replyDirectoryHasChanged); - - m_watcher.addDirectory(cmakeReplyDirectory().toString(), FileSystemWatcher::WatchAllChanges); -} - -FilePath FileApiParser::cmakeReplyDirectory() const +bool FileApiParser::setupCMakeFileApi(const FilePath &buildDirectory, Utils::FileSystemWatcher &watcher) { - return m_buildDirectory.pathAppended(CMAKE_RELATIVE_REPLY_PATH); -} - -FileApiParser::~FileApiParser() = default; + const QDir buildDir = QDir(buildDirectory.toString()); + buildDir.mkpath( + QString::fromLatin1(CMAKE_RELATIVE_REPLY_PATH)); // So that we have a directory to watch! -void FileApiParser::setupCMakeFileApi() const -{ - const QDir buildDir = QDir(m_buildDirectory.toString()); const QString relativeQueryPath = QString::fromLatin1(CMAKE_RELATIVE_QUERY_PATH); - buildDir.mkpath(relativeQueryPath); - buildDir.mkpath( - QString::fromLatin1(CMAKE_RELATIVE_REPLY_PATH)); // So that we have a directory to watch! QDir queryDir = buildDir; queryDir.cd(relativeQueryPath); if (!queryDir.exists()) { reportFileApiSetupFailure(); - return; + return false; } QTC_ASSERT(queryDir.exists(), ); bool failedBefore = false; - for (const QString &fileName : cmakeQueryFileNames()) { - const QString filePath = queryDir.filePath(fileName); - + for (const QString &filePath : cmakeQueryFilePaths(buildDirectory)) { QFile f(filePath); if (!f.exists()) { f.open(QFile::WriteOnly); @@ -863,6 +846,9 @@ void FileApiParser::setupCMakeFileApi() const reportFileApiSetupFailure(); } } + + watcher.addDirectory(cmakeReplyDirectory(buildDirectory).toString(), FileSystemWatcher::WatchAllChanges); + return true; } static QStringList uniqueTargetFiles(const std::vector<Configuration> &configs) @@ -912,9 +898,9 @@ FileApiData FileApiParser::parseData(const QFileInfo &replyFileInfo, QString &er return result; } -QFileInfo FileApiParser::scanForCMakeReplyFile() const +QFileInfo FileApiParser::scanForCMakeReplyFile(const FilePath &buildDirectory) { - QDir replyDir(cmakeReplyDirectory().toString()); + QDir replyDir(cmakeReplyDirectory(buildDirectory).toString()); if (!replyDir.exists()) return {}; @@ -924,33 +910,12 @@ QFileInfo FileApiParser::scanForCMakeReplyFile() const return fis.isEmpty() ? QFileInfo() : fis.last(); } -QStringList FileApiParser::cmakeQueryFileNames() const -{ - return {"cache-v2", "codemodel-v2", "cmakeFiles-v1"}; -} - -QStringList FileApiParser::cmakeQueryFilePaths() const +QStringList FileApiParser::cmakeQueryFilePaths(const Utils::FilePath &buildDirectory) { - QDir queryDir(QDir::cleanPath(m_sourceDirectory.toString() + "/" - + QString::fromLatin1(CMAKE_RELATIVE_QUERY_PATH))); - return transform(cmakeQueryFileNames(), + QDir queryDir(QDir::cleanPath(buildDirectory.pathAppended(CMAKE_RELATIVE_QUERY_PATH).toString())); + return transform(CMAKE_QUERY_FILENAMES, [&queryDir](const QString &name) { return queryDir.absoluteFilePath(name); }); } -void FileApiParser::setParsedReplyFilePath(const QString &filePath) -{ - m_lastParsedReplyFile = filePath; -} - -void FileApiParser::replyDirectoryHasChanged(const QString &directory) const -{ - if (directory == cmakeReplyDirectory().toString()) { - QFileInfo fi = scanForCMakeReplyFile(); - if (fi.isFile() && fi.filePath() != m_lastParsedReplyFile) { - emit dirty(); - } - } -} - } // namespace Internal } // namespace CMakeProjectManager |