diff --git a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp index e08f4453b0e22a88182e645ba4c8ae28ed0c521e..cbd0d85dbf5593feb6e93ad2ded1aa1682211e77 100644 --- a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp @@ -94,14 +94,13 @@ QString getInitialDetails(const QmlEventType &event) return details; } -QmlProfilerDataModel::QmlProfilerDataModel(Utils::FileInProjectFinder *fileFinder, - QmlProfilerModelManager *parent) : +QmlProfilerDataModel::QmlProfilerDataModel(QmlProfilerModelManager *parent) : QObject(parent), d_ptr(new QmlProfilerDataModelPrivate) { Q_D(QmlProfilerDataModel); Q_ASSERT(parent); + d->detailsRewriter = new QmlProfilerDetailsRewriter(this); d->modelManager = parent; - d->detailsRewriter = new QmlProfilerDetailsRewriter(fileFinder, this); d->modelId = d->modelManager->registerModelProxy(); connect(d->detailsRewriter, &QmlProfilerDetailsRewriter::rewriteDetailsString, this, &QmlProfilerDataModel::detailsChanged); @@ -146,6 +145,19 @@ void QmlProfilerDataModel::addEventType(const QmlEventType &type) d->rewriteType(typeIndex); } +void QmlProfilerDataModel::populateFileFinder( + const ProjectExplorer::RunConfiguration *runConfiguration) +{ + Q_D(QmlProfilerDataModel); + d->detailsRewriter->populateFileFinder(runConfiguration); +} + +QString QmlProfilerDataModel::findLocalFile(const QString &remoteFile) +{ + Q_D(QmlProfilerDataModel); + return d->detailsRewriter->getLocalFile(remoteFile); +} + void QmlProfilerDataModel::addEvent(const QmlEvent &event) { Q_D(QmlProfilerDataModel); diff --git a/src/plugins/qmlprofiler/qmlprofilerdatamodel.h b/src/plugins/qmlprofiler/qmlprofilerdatamodel.h index a9123f1ee8e44d002fd470abfde9591567d6cd0b..9f86d74b773fcabcbb9cddaad967ae50bd5ba1b5 100644 --- a/src/plugins/qmlprofiler/qmlprofilerdatamodel.h +++ b/src/plugins/qmlprofiler/qmlprofilerdatamodel.h @@ -32,6 +32,7 @@ #include "qmlevent.h" #include <utils/fileinprojectfinder.h> +#include <projectexplorer/runconfiguration.h> namespace QmlProfiler { @@ -39,8 +40,7 @@ class QMLPROFILER_EXPORT QmlProfilerDataModel : public QObject { Q_OBJECT public: - explicit QmlProfilerDataModel(Utils::FileInProjectFinder *fileFinder, - QmlProfilerModelManager *parent); + explicit QmlProfilerDataModel(QmlProfilerModelManager *parent); ~QmlProfilerDataModel(); const QmlEventType &eventType(int typeId) const; @@ -48,6 +48,9 @@ public: void addEventTypes(const QVector<QmlEventType> &types); void addEventType(const QmlEventType &type); + void populateFileFinder(const ProjectExplorer::RunConfiguration *runConfiguration = nullptr); + QString findLocalFile(const QString &remoteFile); + void clear(); bool isEmpty() const; void addEvent(const QmlEvent &event); diff --git a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp index 49c66b2b8501472326a76ad910cd0ac08c79b80f..a5199491f61767958e5fff17d0f99e9611c4b5b3 100644 --- a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp @@ -25,6 +25,12 @@ #include "qmlprofilerdetailsrewriter.h" +#include <projectexplorer/kit.h> +#include <projectexplorer/kitinformation.h> +#include <projectexplorer/project.h> +#include <projectexplorer/session.h> +#include <projectexplorer/target.h> +#include <projectexplorer/runconfiguration.h> #include <qmljs/parser/qmljsast_p.h> #include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljstools/qmljsmodelmanager.h> @@ -85,37 +91,42 @@ protected: } }; -QmlProfilerDetailsRewriter::QmlProfilerDetailsRewriter(Utils::FileInProjectFinder *fileFinder, - QObject *parent) - : QObject(parent), m_projectFinder(fileFinder) +QmlProfilerDetailsRewriter::QmlProfilerDetailsRewriter(QObject *parent) + : QObject(parent) { } void QmlProfilerDetailsRewriter::requestDetailsForLocation(int typeId, const QmlEventLocation &location) { - QString localFile; - const QString locationFile = location.filename(); - if (!m_filesCache.contains(locationFile)) { - localFile = m_projectFinder->findFile(locationFile); - m_filesCache[locationFile] = localFile; - } else { - localFile = m_filesCache[locationFile]; - } - QFileInfo fileInfo(localFile); - if (!fileInfo.exists() || !fileInfo.isReadable()) - return; - if (!QmlJS::ModelManagerInterface::guessLanguageOfFile(localFile).isQmlLikeLanguage()) + const QString localFile = getLocalFile(location.filename()); + if (localFile.isEmpty()) return; - localFile = fileInfo.canonicalFilePath(); - if (m_pendingEvents.isEmpty()) connectQmlModel(); m_pendingEvents.insert(localFile, {location, typeId}); } +QString QmlProfilerDetailsRewriter::getLocalFile(const QString &remoteFile) +{ + QString localFile; + if (!m_filesCache.contains(remoteFile)) { + localFile = m_projectFinder.findFile(remoteFile); + m_filesCache[remoteFile] = localFile; + } else { + localFile = m_filesCache[remoteFile]; + } + QFileInfo fileInfo(localFile); + if (!fileInfo.exists() || !fileInfo.isReadable()) + return QString(); + if (!QmlJS::ModelManagerInterface::guessLanguageOfFile(localFile).isQmlLikeOrJsLanguage()) + return QString(); + + return fileInfo.canonicalFilePath(); +} + void QmlProfilerDetailsRewriter::reloadDocuments() { if (!m_pendingEvents.isEmpty()) { @@ -196,5 +207,57 @@ void QmlProfilerDetailsRewriter::documentReady(QmlJS::Document::Ptr doc) } } +void QmlProfilerDetailsRewriter::populateFileFinder( + const ProjectExplorer::RunConfiguration *runConfiguration) +{ + // Prefer the given runConfiguration's target if available + const ProjectExplorer::Target *target = runConfiguration ? runConfiguration->target() : nullptr; + + // If runConfiguration given, then use the project associated with that ... + const ProjectExplorer::Project *startupProject = target ? target->project() : nullptr; + + // ... else try the session manager's global startup project ... + if (!startupProject) + startupProject = ProjectExplorer::SessionManager::startupProject(); + + // ... and if that is null, use the first project available. + const QList<ProjectExplorer::Project *> projects = ProjectExplorer::SessionManager::projects(); + if (!startupProject && !projects.isEmpty()) + startupProject = projects.first(); + + QString projectDirectory; + QStringList sourceFiles; + + // Sort files from startupProject to the front of the list ... + if (startupProject) { + projectDirectory = startupProject->projectDirectory().toString(); + sourceFiles.append(startupProject->files(ProjectExplorer::Project::SourceFiles)); + } + + // ... then add all the other projects' files. + for (const ProjectExplorer::Project *project : projects) { + if (project != startupProject) + sourceFiles.append(project->files(ProjectExplorer::Project::SourceFiles)); + } + + // If no runConfiguration was given, but we've found a startupProject, then try to deduct a + // target from that. + if (!target && startupProject) + target = startupProject->activeTarget(); + + // ... and find the sysroot if we have any target at all. + QString activeSysroot; + if (target) { + const ProjectExplorer::Kit *kit = target->kit(); + if (kit && ProjectExplorer::SysRootKitInformation::hasSysRoot(kit)) + activeSysroot = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString(); + } + + // Finally, do populate m_projectFinder + m_projectFinder.setProjectDirectory(projectDirectory); + m_projectFinder.setProjectFiles(sourceFiles); + m_projectFinder.setSysroot(activeSysroot); +} + } // namespace Internal } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.h b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.h index f4717c90fb50e3788e61a485a037786fcca34b54..d5dcf6e773cbbf9ab04e5671e10ba7b1efe4eac2 100644 --- a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.h +++ b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.h @@ -27,6 +27,7 @@ #include "qmleventlocation.h" +#include <projectexplorer/runconfiguration.h> #include <qmljs/qmljsdocument.h> #include <utils/fileinprojectfinder.h> @@ -39,13 +40,14 @@ class QmlProfilerDetailsRewriter : public QObject { Q_OBJECT public: - explicit QmlProfilerDetailsRewriter(Utils::FileInProjectFinder *fileFinder, - QObject *parent = nullptr); + explicit QmlProfilerDetailsRewriter(QObject *parent = nullptr); void clearRequests(); void requestDetailsForLocation(int typeId, const QmlEventLocation &location); + QString getLocalFile(const QString &remoteFile); void reloadDocuments(); void documentReady(QmlJS::Document::Ptr doc); + void populateFileFinder(const ProjectExplorer::RunConfiguration *runConfiguration); struct PendingEvent { QmlEventLocation location; @@ -58,7 +60,7 @@ signals: private: QMultiHash<QString, PendingEvent> m_pendingEvents; - Utils::FileInProjectFinder *m_projectFinder; + Utils::FileInProjectFinder m_projectFinder; QHash<QString, QString> m_filesCache; void rewriteDetailsForLocation(const QString &source, QmlJS::Document::Ptr doc, int typeId, diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index ccb05f674976342188ffcd403553e47f0a63b4b8..bee5f3deb2f04bbebf0283a642ac91b5e5df76c3 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -158,7 +158,7 @@ public: }; -QmlProfilerModelManager::QmlProfilerModelManager(Utils::FileInProjectFinder *finder, QObject *parent) : +QmlProfilerModelManager::QmlProfilerModelManager(QObject *parent) : QObject(parent), d(new QmlProfilerModelManagerPrivate) { d->numRegisteredModels = 0; @@ -168,7 +168,7 @@ QmlProfilerModelManager::QmlProfilerModelManager(Utils::FileInProjectFinder *fin d->visibleFeatures = 0; d->recordedFeatures = 0; d->aggregateTraces = false; - d->model = new QmlProfilerDataModel(finder, this); + d->model = new QmlProfilerDataModel(this); d->state = Empty; d->traceTime = new QmlProfilerTraceTime(this); d->notesModel = new QmlProfilerNotesModel(this); diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h index bd05ab97f9937e76cd9c9ed2ec77b38b9bec18ee..7ed64ef187df6bcc17e945dbee42c47a7183b847 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h @@ -90,7 +90,7 @@ public: typedef std::function<void(const QmlEvent &, const QmlEventType &)> EventLoader; typedef std::function<void()> Finalizer; - explicit QmlProfilerModelManager(Utils::FileInProjectFinder *finder, QObject *parent = 0); + explicit QmlProfilerModelManager(QObject *parent = 0); ~QmlProfilerModelManager(); State state() const; diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index c5ad6a7cfca99458d54a384bf58ee651cd6ed47a..ec9d8ed5932b0ae71ea1d3f00c50e1cb5ac40198 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -100,7 +100,6 @@ public: QmlProfilerModelManager *m_profilerModelManager = 0; QmlProfilerViewManager *m_viewContainer = 0; - Utils::FileInProjectFinder m_projectFinder; QToolButton *m_recordButton = 0; QMenu *m_recordFeaturesMenu = 0; @@ -147,7 +146,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent) connect(d->m_profilerConnections, &QmlProfilerClientManager::connectionClosed, this, &QmlProfilerTool::clientsDisconnected); - d->m_profilerModelManager = new QmlProfilerModelManager(&d->m_projectFinder, this); + d->m_profilerModelManager = new QmlProfilerModelManager(this); connect(d->m_profilerModelManager, &QmlProfilerModelManager::stateChanged, this, &QmlProfilerTool::profilerDataModelStateChanged); connect(d->m_profilerModelManager, &QmlProfilerModelManager::error, @@ -242,7 +241,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent) // When the widgets are requested we assume that the session data // is available, then we can populate the file finder - populateFileFinder(); + d->m_profilerModelManager->qmlModel()->populateFileFinder(); auto runControlCreator = [this](RunConfiguration *runConfiguration, Core::Id) { return createRunControl(runConfiguration); @@ -309,15 +308,6 @@ void QmlProfilerTool::updateRunActions() } } -static QString sysroot(RunConfiguration *runConfig) -{ - QTC_ASSERT(runConfig, return QString()); - Kit *k = runConfig->target()->kit(); - if (k && SysRootKitInformation::hasSysRoot(k)) - return SysRootKitInformation::sysRoot(runConfig->target()->kit()).toString(); - return QString(); -} - AnalyzerRunControl *QmlProfilerTool::createRunControl(RunConfiguration *runConfiguration) { d->m_toolBusy = true; @@ -368,10 +358,7 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunControl *runControl) RunConfiguration *runConfiguration = runControl->runConfiguration(); if (runConfiguration) { - QString projectDirectory; - Project *project = runConfiguration->target()->project(); - projectDirectory = project->projectDirectory().toString(); - populateFileFinder(projectDirectory, sysroot(runConfiguration)); + d->m_profilerModelManager->qmlModel()->populateFileFinder(runConfiguration); } if (connection.analyzerSocket.isEmpty()) { @@ -413,35 +400,6 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunControl *runControl) }); } -void QmlProfilerTool::populateFileFinder(QString projectDirectory, QString activeSysroot) -{ - // Initialize filefinder with some sensible default - QStringList sourceFiles; - QList<Project *> projects = SessionManager::projects(); - if (Project *startupProject = SessionManager::startupProject()) { - // startup project first - projects.removeOne(startupProject); - projects.insert(0, startupProject); - } - foreach (Project *project, projects) - sourceFiles << project->files(Project::SourceFiles); - - if (!projects.isEmpty()) { - if (projectDirectory.isEmpty()) - projectDirectory = projects.first()->projectDirectory().toString(); - - if (activeSysroot.isEmpty()) { - if (Target *target = projects.first()->activeTarget()) - if (RunConfiguration *rc = target->activeRunConfiguration()) - activeSysroot = sysroot(rc); - } - } - - d->m_projectFinder.setProjectDirectory(projectDirectory); - d->m_projectFinder.setProjectFiles(sourceFiles); - d->m_projectFinder.setSysroot(activeSysroot); -} - void QmlProfilerTool::recordingButtonChanged(bool recording) { // clientRecording is our intention for new sessions. That may differ from the state of the @@ -492,7 +450,7 @@ void QmlProfilerTool::gotoSourceLocation(const QString &fileUrl, int lineNumber, if (lineNumber < 0 || fileUrl.isEmpty()) return; - const QString projectFileName = d->m_projectFinder.findFile(fileUrl); + const QString projectFileName = d->m_profilerModelManager->qmlModel()->findLocalFile(fileUrl); QFileInfo fileInfo(projectFileName); if (!fileInfo.exists() || !fileInfo.isReadable()) @@ -693,7 +651,7 @@ void QmlProfilerTool::showLoadDialog() Debugger::enableMainWindow(false); connect(d->m_profilerModelManager, &QmlProfilerModelManager::recordedFeaturesChanged, this, &QmlProfilerTool::setRecordedFeatures); - populateFileFinder(); + d->m_profilerModelManager->qmlModel()->populateFileFinder(); d->m_profilerModelManager->load(filename); } } diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h index 3651c759e86972f143c75b2316ddd4d674246cdc..ec263ade2f23fe2c1775b20cde4d28391d8d4062 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.h +++ b/src/plugins/qmlprofiler/qmlprofilertool.h @@ -95,7 +95,6 @@ private slots: private: void updateRunActions(); void clearDisplay(); - void populateFileFinder(QString projectDirectory = QString(), QString activeSysroot = QString()); template<ProfileFeature feature> void updateFeatures(quint64 features); bool checkForUnsavedNotes(); diff --git a/src/plugins/qmlprofiler/tests/flamegraphmodel_test.cpp b/src/plugins/qmlprofiler/tests/flamegraphmodel_test.cpp index 129388cfbedc096b46660547dda5eb870e38827f..6afe091b93085e686ddbc49497d0d156eb6f9439 100644 --- a/src/plugins/qmlprofiler/tests/flamegraphmodel_test.cpp +++ b/src/plugins/qmlprofiler/tests/flamegraphmodel_test.cpp @@ -33,7 +33,7 @@ namespace QmlProfiler { namespace Internal { FlameGraphModelTest::FlameGraphModelTest(QObject *parent) : - QObject(parent), manager(&finder), model(&manager) + QObject(parent), model(&manager) { } diff --git a/src/plugins/qmlprofiler/tests/flamegraphmodel_test.h b/src/plugins/qmlprofiler/tests/flamegraphmodel_test.h index 6d9793e16fd3d274c1e0098f00352e8f534d737b..1099ee62007a30181f7eafbcac5190427db349c0 100644 --- a/src/plugins/qmlprofiler/tests/flamegraphmodel_test.h +++ b/src/plugins/qmlprofiler/tests/flamegraphmodel_test.h @@ -49,7 +49,6 @@ private slots: void cleanupTestCase(); private: - Utils::FileInProjectFinder finder; QmlProfilerModelManager manager; FlameGraphModel model; int rangeModelId = -1; diff --git a/src/plugins/qmlprofiler/tests/flamegraphview_test.cpp b/src/plugins/qmlprofiler/tests/flamegraphview_test.cpp index 6dbca7b98e0487af4514a074e81f458c67685cea..799f3c3ac15c937ea5a7860939f0791100ccc950 100644 --- a/src/plugins/qmlprofiler/tests/flamegraphview_test.cpp +++ b/src/plugins/qmlprofiler/tests/flamegraphview_test.cpp @@ -34,8 +34,7 @@ namespace QmlProfiler { namespace Internal { -FlameGraphViewTest::FlameGraphViewTest(QObject *parent) : QObject(parent), manager(&finder), - view(&manager) +FlameGraphViewTest::FlameGraphViewTest(QObject *parent) : QObject(parent), view(&manager) { } diff --git a/src/plugins/qmlprofiler/tests/flamegraphview_test.h b/src/plugins/qmlprofiler/tests/flamegraphview_test.h index e16050bdbf2a8e4a287de2faebc0f0e743dc085f..c99a2177d2ba7001d015395efc576c99a78c5d34 100644 --- a/src/plugins/qmlprofiler/tests/flamegraphview_test.h +++ b/src/plugins/qmlprofiler/tests/flamegraphview_test.h @@ -45,7 +45,6 @@ private slots: void cleanupTestCase(); private: - Utils::FileInProjectFinder finder; QmlProfilerModelManager manager; FlameGraphView view; };