summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp6
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp4
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h3
-rw-r--r--src/plugins/cpptools/cppprojectupdater.cpp91
-rw-r--r--src/plugins/cpptools/cppprojectupdater.h9
-rw-r--r--src/plugins/projectexplorer/extracompiler.cpp18
-rw-r--r--src/plugins/projectexplorer/extracompiler.h8
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.cpp4
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.cpp3
9 files changed, 124 insertions, 22 deletions
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index 2ec4e68e6c..71fac0757c 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -630,8 +630,7 @@ void CMakeBuildSystem::updateProjectData()
{
qDeleteAll(m_extraCompilers);
m_extraCompilers = findExtraCompilers();
- CppTools::GeneratedCodeModelSupport::update(m_extraCompilers);
- qCDebug(cmakeBuildSystemLog) << "Extra compilers updated.";
+ qCDebug(cmakeBuildSystemLog) << "Extra compilers created.";
}
QtSupport::CppKitInfo kitInfo(kit());
@@ -658,7 +657,8 @@ void CMakeBuildSystem::updateProjectData()
}
}
- m_cppCodeModelUpdater->update({p, kitInfo, cmakeBuildConfiguration()->environment(), rpps});
+ m_cppCodeModelUpdater->update({p, kitInfo, cmakeBuildConfiguration()->environment(), rpps},
+ m_extraCompilers);
}
{
const bool mergedHeaderPathsAndQmlImportPaths = kit()->value(
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index f92248b222..2366b5d4da 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -1145,7 +1145,8 @@ void CppModelManager::updateCppEditorDocuments(bool projectsUpdated) const
}
}
-QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectInfo)
+QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectInfo,
+ const QSet<QString> &additionalFiles)
{
if (!newProjectInfo.isValid())
return QFuture<void>();
@@ -1236,6 +1237,7 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
// resolved includes that we could rely on.
updateCppEditorDocuments(/*projectsUpdated = */ true);
+ filesToReindex.unite(additionalFiles);
// Trigger reindexing
const QFuture<void> indexingFuture = updateSourceFiles(filesToReindex,
ForcedProgressNotification);
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index 402f37bee6..81e8ec3710 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -116,7 +116,8 @@ public:
QList<ProjectInfo> projectInfos() const;
ProjectInfo projectInfo(ProjectExplorer::Project *project) const;
- QFuture<void> updateProjectInfo(const ProjectInfo &newProjectInfo);
+ QFuture<void> updateProjectInfo(const ProjectInfo &newProjectInfo,
+ const QSet<QString> &additionalFiles = {});
/// \return The project part with the given project file
ProjectPart::Ptr projectPartForId(const QString &projectPartId) const override;
diff --git a/src/plugins/cpptools/cppprojectupdater.cpp b/src/plugins/cpptools/cppprojectupdater.cpp
index 794fd7abe7..f34628af51 100644
--- a/src/plugins/cpptools/cppprojectupdater.cpp
+++ b/src/plugins/cpptools/cppprojectupdater.cpp
@@ -27,14 +27,21 @@
#include "cppmodelmanager.h"
#include "cppprojectinfogenerator.h"
+#include "generatedcodemodelsupport.h"
+
+#include <coreplugin/progressmanager/progressmanager.h>
#include <projectexplorer/toolchainmanager.h>
+#include <utils/algorithm.h>
+#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
#include <QFutureInterface>
+using namespace ProjectExplorer;
+
namespace CppTools {
CppProjectUpdater::CppProjectUpdater()
@@ -46,11 +53,25 @@ CppProjectUpdater::CppProjectUpdater()
m_futureSynchronizer.setCancelOnWait(true);
}
-void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo)
+CppProjectUpdater::~CppProjectUpdater()
+{
+ cancel();
+}
+
+void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo)
+{
+ update(projectUpdateInfo, {});
+}
+
+void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo,
+ const QList<ProjectExplorer::ExtraCompiler *> &extraCompilers)
{
// Stop previous update.
cancel();
+ m_extraCompilers = Utils::transform(extraCompilers, [](ExtraCompiler *compiler) {
+ return QPointer<ExtraCompiler>(compiler);
+ });
m_projectUpdateInfo = projectUpdateInfo;
// Ensure that we do not operate on a deleted toolchain.
@@ -68,15 +89,52 @@ void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &project
});
m_generateFutureWatcher.setFuture(generateFuture);
m_futureSynchronizer.addFuture(generateFuture);
+
+ // extra compilers
+ for (QPointer<ExtraCompiler> compiler : qAsConst(m_extraCompilers)) {
+ if (compiler->isDirty()) {
+ auto watcher = new QFutureWatcher<void>;
+ // queued connection to delay after the extra compiler updated its result contents,
+ // which is also done in the main thread when compiler->run() finished
+ connect(watcher, &QFutureWatcherBase::finished,
+ this, [this, watcher] {
+ m_projectUpdateFutureInterface->setProgressValue(
+ m_projectUpdateFutureInterface->progressValue() + 1);
+ m_extraCompilersFutureWatchers.remove(watcher);
+ watcher->deleteLater();
+ if (!watcher->isCanceled())
+ checkForExtraCompilersFinished();
+ },
+ Qt::QueuedConnection);
+ m_extraCompilersFutureWatchers += watcher;
+ watcher->setFuture(QFuture<void>(compiler->run()));
+ m_futureSynchronizer.addFuture(watcher->future());
+ }
+ }
+
+ m_projectUpdateFutureInterface.reset(new QFutureInterface<void>);
+ m_projectUpdateFutureInterface->setProgressRange(0, m_extraCompilersFutureWatchers.size()
+ + 1 /*generateFuture*/);
+ m_projectUpdateFutureInterface->setProgressValue(0);
+ m_projectUpdateFutureInterface->reportStarted();
+ Core::ProgressManager::addTask(m_projectUpdateFutureInterface->future(),
+ tr("Preparing C++ Code Model"),
+ "CppProjectUpdater");
}
void CppProjectUpdater::cancel()
{
+ if (m_projectUpdateFutureInterface && m_projectUpdateFutureInterface->isRunning())
+ m_projectUpdateFutureInterface->reportFinished();
m_generateFutureWatcher.setFuture({});
+ m_isProjectInfoGenerated = false;
+ qDeleteAll(m_extraCompilersFutureWatchers);
+ m_extraCompilersFutureWatchers.clear();
+ m_extraCompilers.clear();
m_futureSynchronizer.cancelAllFutures();
}
-void CppProjectUpdater::onToolChainRemoved(ProjectExplorer::ToolChain *t)
+void CppProjectUpdater::onToolChainRemoved(ToolChain *t)
{
QTC_ASSERT(t, return);
if (t == m_projectUpdateInfo.cToolChain || t == m_projectUpdateInfo.cxxToolChain)
@@ -93,8 +151,33 @@ void CppProjectUpdater::onProjectInfoGenerated()
if (m_generateFutureWatcher.isCanceled() || m_generateFutureWatcher.future().resultCount() < 1)
return;
- auto updateFuture = CppModelManager::instance()->updateProjectInfo(
- m_generateFutureWatcher.result());
+ m_projectUpdateFutureInterface->setProgressValue(m_projectUpdateFutureInterface->progressValue()
+ + 1);
+ m_isProjectInfoGenerated = true;
+ checkForExtraCompilersFinished();
+}
+
+void CppProjectUpdater::checkForExtraCompilersFinished()
+{
+ if (!m_extraCompilersFutureWatchers.isEmpty() || !m_isProjectInfoGenerated)
+ return; // still need to wait
+
+ m_projectUpdateFutureInterface->reportFinished();
+ m_projectUpdateFutureInterface.reset();
+
+ QList<ExtraCompiler *> extraCompilers;
+ QSet<QString> compilerFiles;
+ for (const QPointer<ExtraCompiler> &compiler : qAsConst(m_extraCompilers)) {
+ if (compiler) {
+ extraCompilers += compiler.data();
+ compilerFiles += Utils::transform<QSet>(compiler->targets(), &Utils::FilePath::toString);
+ }
+ }
+ GeneratedCodeModelSupport::update(extraCompilers);
+ m_extraCompilers.clear();
+
+ auto updateFuture = CppModelManager::instance()
+ ->updateProjectInfo(m_generateFutureWatcher.result(), compilerFiles);
m_futureSynchronizer.addFuture(updateFuture);
}
diff --git a/src/plugins/cpptools/cppprojectupdater.h b/src/plugins/cpptools/cppprojectupdater.h
index 6b994871ef..c356ab63d1 100644
--- a/src/plugins/cpptools/cppprojectupdater.h
+++ b/src/plugins/cpptools/cppprojectupdater.h
@@ -29,6 +29,7 @@
#include "cpptools_global.h"
#include "projectinfo.h"
+#include <projectexplorer/extracompiler.h>
#include <utils/futuresynchronizer.h>
#include <QFutureWatcher>
@@ -54,18 +55,26 @@ class CPPTOOLS_EXPORT CppProjectUpdater final : public QObject, public CppProjec
public:
CppProjectUpdater();
+ ~CppProjectUpdater() override;
void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) override;
+ void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo,
+ const QList<ProjectExplorer::ExtraCompiler *> &extraCompilers);
void cancel() override;
private:
void onToolChainRemoved(ProjectExplorer::ToolChain *);
void onProjectInfoGenerated();
+ void checkForExtraCompilersFinished();
private:
ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo;
+ QList<QPointer<ProjectExplorer::ExtraCompiler>> m_extraCompilers;
QFutureWatcher<ProjectInfo> m_generateFutureWatcher;
+ bool m_isProjectInfoGenerated = false;
+ QSet<QFutureWatcher<void> *> m_extraCompilersFutureWatchers;
+ std::unique_ptr<QFutureInterface<void>> m_projectUpdateFutureInterface;
Utils::FutureSynchronizer m_futureSynchronizer;
};
diff --git a/src/plugins/projectexplorer/extracompiler.cpp b/src/plugins/projectexplorer/extracompiler.cpp
index 6dd653774e..893997de3f 100644
--- a/src/plugins/projectexplorer/extracompiler.cpp
+++ b/src/plugins/projectexplorer/extracompiler.cpp
@@ -123,11 +123,6 @@ ExtraCompiler::ExtraCompiler(const Project *project, const Utils::FilePath &sour
if (file.open(QFile::ReadOnly | QFile::Text))
setContent(target, file.readAll());
}
-
- if (d->dirty) {
- d->dirty = false;
- QTimer::singleShot(0, this, [this]() { run(d->source); }); // delay till available.
- }
}
ExtraCompiler::~ExtraCompiler() = default;
@@ -173,6 +168,11 @@ QThreadPool *ExtraCompiler::extraCompilerThreadPool()
return s_extraCompilerThreadPool();
}
+bool ExtraCompiler::isDirty() const
+{
+ return d->dirty;
+}
+
void ExtraCompiler::onTargetsBuilt(Project *project)
{
if (project != d->project || BuildManager::isBuilding(project))
@@ -346,15 +346,16 @@ void ProcessExtraCompiler::run(const QByteArray &sourceContents)
runImpl(contents);
}
-void ProcessExtraCompiler::run(const Utils::FilePath &fileName)
+QFuture<FileNameToContentsHash> ProcessExtraCompiler::run()
{
+ const Utils::FilePath fileName = source();
ContentProvider contents = [fileName]() {
QFile file(fileName.toString());
if (!file.open(QFile::ReadOnly | QFile::Text))
return QByteArray();
return file.readAll();
};
- runImpl(contents);
+ return runImpl(contents);
}
Utils::FilePath ProcessExtraCompiler::workingDirectory() const
@@ -379,7 +380,7 @@ Tasks ProcessExtraCompiler::parseIssues(const QByteArray &stdErr)
return {};
}
-void ProcessExtraCompiler::runImpl(const ContentProvider &provider)
+QFuture<FileNameToContentsHash> ProcessExtraCompiler::runImpl(const ContentProvider &provider)
{
if (m_watcher)
delete m_watcher;
@@ -392,6 +393,7 @@ void ProcessExtraCompiler::runImpl(const ContentProvider &provider)
&ProcessExtraCompiler::runInThread, this,
command(), workingDirectory(), arguments(), provider,
buildEnvironment()));
+ return m_watcher->future();
}
void ProcessExtraCompiler::runInThread(
diff --git a/src/plugins/projectexplorer/extracompiler.h b/src/plugins/projectexplorer/extracompiler.h
index 5c0854a3b4..e38a5900a0 100644
--- a/src/plugins/projectexplorer/extracompiler.h
+++ b/src/plugins/projectexplorer/extracompiler.h
@@ -80,6 +80,9 @@ public:
static QThreadPool *extraCompilerThreadPool();
+ virtual QFuture<FileNameToContentsHash> run() = 0;
+ bool isDirty() const;
+
signals:
void contentsChanged(const Utils::FilePath &file);
@@ -94,7 +97,6 @@ private:
void setDirty();
// This method may not block!
virtual void run(const QByteArray &sourceContent) = 0;
- virtual void run(const Utils::FilePath &file) = 0;
const std::unique_ptr<ExtraCompilerPrivate> d;
};
@@ -115,7 +117,7 @@ protected:
// * prepareToRun returns true
// * The process is not yet running
void run(const QByteArray &sourceContents) override;
- void run(const Utils::FilePath &fileName) override;
+ QFuture<FileNameToContentsHash> run() override;
// Information about the process to run:
virtual Utils::FilePath workingDirectory() const;
@@ -133,7 +135,7 @@ protected:
private:
using ContentProvider = std::function<QByteArray()>;
- void runImpl(const ContentProvider &sourceContents);
+ QFuture<FileNameToContentsHash> runImpl(const ContentProvider &sourceContents);
void runInThread(QFutureInterface<FileNameToContentsHash> &futureInterface,
const Utils::FilePath &cmd, const Utils::FilePath &workDir,
const QStringList &args, const ContentProvider &provider,
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index dcf5552468..1de06cedaf 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -193,6 +193,10 @@ QbsBuildSystem::QbsBuildSystem(QbsBuildConfiguration *bc)
}
}
CppTools::GeneratedCodeModelSupport::update(m_extraCompilers);
+ for (ExtraCompiler *compiler : m_extraCompilers) {
+ if (compiler->isDirty())
+ compiler->run();
+ }
m_sourcesForGeneratedFiles.clear();
});
connect(m_session, &QbsSession::errorOccurred, this, [](QbsSession::Error e) {
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index a1ff1f21f1..acb1c14e1f 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -399,8 +399,7 @@ void QmakeBuildSystem::updateCppCodeModel()
rpps.append(rpp);
}
- CppTools::GeneratedCodeModelSupport::update(generators);
- m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), rpps});
+ m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), rpps}, generators);
}
void QmakeBuildSystem::updateQmlJSCodeModel()