From 530b9ae85a19913c2421f26c738676b0c951d99f Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 8 Apr 2022 11:35:54 +0200 Subject: [PATCH] ProjectExplorer: Copy more RunConfiguration data to RunControl The aspects are now responsible for defining what data needs to be copied and also to provide a suitable interface (kind of source-compatible to direct use) for access. The important change here is that RunControl::aspect(...) doesn't need to access RunControl::runConfiguration() in fully aspectified RunConfigurations anymore. In not-fully aspectified the runConfig access is moved to the user code to make the problem visible there. Long term, aspectification should be finished. As an additional benefit, the resolving of macros etc can now be done at the correct time. Change-Id: I690d9f8f696ce9b4efd42082ba3f81b514efcb77 Reviewed-by: Reviewed-by: Christian Kandeler --- src/libs/utils/aspects.cpp | 53 +++++++++++- src/libs/utils/aspects.h | 83 +++++++++++++++++++ src/libs/utils/environment.h | 2 + .../android/androidqmlpreviewworker.cpp | 2 +- src/plugins/android/androidrunnerworker.cpp | 18 ++-- .../debugservers/gdb/gdbserverprovider.cpp | 4 +- .../debugservers/uvsc/uvscserverprovider.cpp | 2 +- src/plugins/coreplugin/coreplugin.cpp | 1 + .../debuggerrunconfigurationaspect.cpp | 5 ++ .../debugger/debuggerrunconfigurationaspect.h | 8 ++ src/plugins/debugger/debuggerruncontrol.cpp | 16 ++-- .../mcusupport/mcusupportrunconfiguration.cpp | 2 +- .../perfprofiler/perfprofilerruncontrol.cpp | 4 +- src/plugins/projectexplorer/customparser.cpp | 1 + src/plugins/projectexplorer/customparser.h | 7 +- .../projectexplorer/environmentaspect.cpp | 1 + .../projectexplorer/environmentaspect.h | 5 ++ .../projectexplorer/runconfiguration.cpp | 15 +++- .../projectexplorer/runconfiguration.h | 10 ++- .../runconfigurationaspects.cpp | 8 ++ .../projectexplorer/runconfigurationaspects.h | 16 ++++ src/plugins/projectexplorer/runcontrol.cpp | 25 ++++-- src/plugins/projectexplorer/runcontrol.h | 8 +- src/plugins/qmlpreview/qmlpreviewplugin.cpp | 3 +- .../qmlpreview/qmlpreviewruncontrol.cpp | 4 +- src/plugins/qmlprofiler/qmlprofilertool.cpp | 5 +- .../qmlprojectmanager/qmlmainfileaspect.cpp | 7 +- .../qmlprojectmanager/qmlmainfileaspect.h | 8 +- src/plugins/qnx/slog2inforunner.cpp | 2 +- src/plugins/valgrind/valgrindengine.cpp | 2 +- .../webassemblyrunconfiguration.cpp | 2 +- .../webassemblyrunconfigurationaspects.cpp | 2 + .../webassemblyrunconfigurationaspects.h | 5 ++ 33 files changed, 282 insertions(+), 54 deletions(-) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index a4d632b7e4d..4d15450d488 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -82,6 +82,9 @@ public: int m_spanY = 1; BaseAspect::ConfigWidgetCreator m_configWidgetCreator; QList> m_subWidgets; + + BaseAspect::DataCreator m_dataCreator; + QList m_dataExtractors; }; } // Internal @@ -110,7 +113,9 @@ public: */ BaseAspect::BaseAspect() : d(new Internal::BaseAspectPrivate) -{} +{ + addDataExtractor(this, &BaseAspect::value, &Data::value); +} /*! Destructs a BaseAspect. @@ -772,6 +777,9 @@ StringAspect::StringAspect() { setDefaultValue(QString()); setSpan(2, 1); // Default: Label + something + + addDataExtractor(this, &StringAspect::value, &Data::value); + addDataExtractor(this, &StringAspect::filePath, &Data::filePath); } /*! @@ -1293,6 +1301,8 @@ BoolAspect::BoolAspect(const QString &settingsKey) setDefaultValue(false); setSettingsKey(settingsKey); setSpan(2, 1); + + addDataExtractor(this, &BoolAspect::value, &Data::value); } /*! @@ -1747,6 +1757,8 @@ IntegerAspect::IntegerAspect() { setDefaultValue(qint64(0)); setSpan(2, 1); + + addDataExtractor(this, &IntegerAspect::value, &Data::value); } /*! @@ -2378,4 +2390,43 @@ void AspectContainer::forEachAspect(const std::function &run } } +BaseAspect::Data *BaseAspect::extractData(const MacroExpander *expander) const +{ + QTC_ASSERT(d->m_dataCreator, return nullptr); + Data *data = d->m_dataCreator(); + data->m_classId = metaObject(); + data->m_id = id(); + for (const DataExtractor &extractor : d->m_dataExtractors) + extractor(data, expander); + return data; +} + +void BaseAspect::addDataExtractorHelper(const DataExtractor &extractor) const +{ + d->m_dataExtractors.append(extractor); +} + +void BaseAspect::setDataCreatorHelper(const DataCreator &creator) const +{ + d->m_dataCreator = creator; +} + +const BaseAspect::Data *AspectContainerData::aspect(Id instanceId) const +{ + for (const BaseAspect::Data *data : m_data) { + if (data->id() == instanceId) + return data; + } + return nullptr; +} + +const BaseAspect::Data *AspectContainerData::aspect(BaseAspect::Data::ClassId classId) const +{ + for (const BaseAspect::Data *data : m_data) { + if (data->classId() == classId) + return data; + } + return nullptr; +} + } // namespace Utils diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h index d1a0bdfe553..39c2992b93c 100644 --- a/src/libs/utils/aspects.h +++ b/src/libs/utils/aspects.h @@ -140,6 +140,30 @@ public: bool isDirty() const; bool hasAction() const; + class QTCREATOR_UTILS_EXPORT Data + { + public: + // The (unique) address of the "owning" aspect's meta object is used as identifier. + using ClassId = const void *; + + virtual ~Data() = default; + + Utils::Id id() const { return m_id; } + ClassId classId() const { return m_classId; } + + QVariant value; + + protected: + friend class BaseAspect; + Utils::Id m_id; + ClassId m_classId = 0; + }; + + using DataCreator = std::function; + using DataExtractor = std::function; + + Data *extractData(const MacroExpander *expander) const; + signals: void changed(); void labelLinkActivated(const QString &link); @@ -149,6 +173,29 @@ protected: void setupLabel(); void addLabeledItem(LayoutBuilder &builder, QWidget *widget); + void setDataCreatorHelper(const DataCreator &creator) const; + void addDataExtractorHelper(const DataExtractor &extractor) const; + + template + void addDataExtractor(AspectClass *aspect, + Type(AspectClass::*p)() const, + Type DataClass::*q) { + setDataCreatorHelper([] { return new DataClass; }); + addDataExtractorHelper([aspect, p, q](Data *data, const MacroExpander *) { + static_cast(data)->*q = (aspect->*p)(); + }); + } + + template + void addDataExtractor(AspectClass *aspect, + Type(AspectClass::*p)(const MacroExpander *) const, + Type DataClass::*q) { + setDataCreatorHelper([] { return new DataClass; }); + addDataExtractorHelper([aspect, p, q](Data *data, const MacroExpander *expander) { + static_cast(data)->*q = (aspect->*p)(expander); + }); + } + template Widget *createSubWidget(Args && ...args) { auto w = new Widget(args...); @@ -172,6 +219,11 @@ public: explicit BoolAspect(const QString &settingsKey = QString()); ~BoolAspect() override; + struct Data : BaseAspect::Data + { + bool value; + }; + void addToLayout(LayoutBuilder &builder) override; QAction *action() override; @@ -280,6 +332,12 @@ public: StringAspect(); ~StringAspect() override; + struct Data : BaseAspect::Data + { + QString value; + Utils::FilePath filePath; + }; + void addToLayout(LayoutBuilder &builder) override; QVariant volatileValue() const override; @@ -373,6 +431,8 @@ public: void setSpecialValueText(const QString &specialText); void setSingleStep(qint64 step); + struct Data : BaseAspect::Data { qint64 value = 0; }; + private: std::unique_ptr d; }; @@ -499,6 +559,29 @@ private: std::unique_ptr d; }; +class QTCREATOR_UTILS_EXPORT AspectContainerData +{ +public: + AspectContainerData() = default; + ~AspectContainerData() { qDeleteAll(m_data); } + + const BaseAspect::Data *aspect(Utils::Id instanceId) const; + const BaseAspect::Data *aspect(Utils::BaseAspect::Data::ClassId classId) const; + + template const typename T::Data *aspect() const + { + return static_cast(aspect(&T::staticMetaObject)); + } + + void append(BaseAspect::Data *data) { m_data.append(data); } + +private: + AspectContainerData(const AspectContainerData &) = delete; + void operator=(const AspectContainerData &) = delete; + + QList m_data; +}; + class QTCREATOR_UTILS_EXPORT AspectContainer : public QObject { Q_OBJECT diff --git a/src/libs/utils/environment.h b/src/libs/utils/environment.h index 0f150299f32..4f2e6dd087c 100644 --- a/src/libs/utils/environment.h +++ b/src/libs/utils/environment.h @@ -119,3 +119,5 @@ public: }; } // namespace Utils + +Q_DECLARE_METATYPE(Utils::Environment) diff --git a/src/plugins/android/androidqmlpreviewworker.cpp b/src/plugins/android/androidqmlpreviewworker.cpp index f8dd04bd42d..103e7b2e5c3 100644 --- a/src/plugins/android/androidqmlpreviewworker.cpp +++ b/src/plugins/android/androidqmlpreviewworker.cpp @@ -425,7 +425,7 @@ bool AndroidQmlPreviewWorker::startPreviewApp() const QDir destDir(apkInfo()->uploadDir); const QString qmlrcPath = destDir.filePath(m_uploadInfo.uploadPackage.baseName() + packageSuffix); - const QStringList envVars = m_rc->aspect()->environment().toStringList(); + const QStringList envVars = m_rc->aspect()->environment.toStringList(); const QStringList command { "am", "start", diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index 5da5d99ec27..43a03472840 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -242,8 +242,8 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa auto aspect = runControl->aspect(); Utils::Id runMode = runControl->runMode(); const bool debuggingMode = runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE; - m_useCppDebugger = debuggingMode && aspect->useCppDebugger(); - if (debuggingMode && aspect->useQmlDebugger()) + m_useCppDebugger = debuggingMode && aspect->useCppDebugger; + if (debuggingMode && aspect->useQmlDebugger) m_qmlDebugServices = QmlDebug::QmlDebuggerServices; else if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) m_qmlDebugServices = QmlDebug::QmlProfilerServices; @@ -270,7 +270,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa m_deviceSerialNumber = AndroidManager::deviceSerialNumber(target); m_apiLevel = AndroidManager::deviceApiLevel(target); - m_extraEnvVars = runControl->aspect()->environment(); + m_extraEnvVars = runControl->aspect()->environment; qCDebug(androidRunWorkerLog) << "Environment variables for the app" << m_extraEnvVars.toStringList(); @@ -279,14 +279,14 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa } if (auto aspect = runControl->aspect(Constants::ANDROID_AM_START_ARGS)) { - QTC_CHECK(aspect->value().type() == QVariant::String); - const QString startArgs = aspect->value().toString(); + QTC_CHECK(aspect->value.type() == QVariant::String); + const QString startArgs = aspect->value.toString(); m_amStartExtraArgs = ProcessArgs::splitArgs(startArgs, OsTypeOtherUnix); } if (auto aspect = runControl->aspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) { - QTC_CHECK(aspect->value().type() == QVariant::String); - const QStringList commands = aspect->value().toString().split('\n', Qt::SkipEmptyParts); + QTC_CHECK(aspect->value.type() == QVariant::String); + const QStringList commands = aspect->value.toString().split('\n', Qt::SkipEmptyParts); for (const QString &shellCmd : commands) m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd)); } @@ -295,8 +295,8 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd)); if (auto aspect = runControl->aspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) { - QTC_CHECK(aspect->value().type() == QVariant::String); - const QStringList commands = aspect->value().toString().split('\n', Qt::SkipEmptyParts); + QTC_CHECK(aspect->value.type() == QVariant::String); + const QStringList commands = aspect->value.toString().split('\n', Qt::SkipEmptyParts); for (const QString &shellCmd : commands) m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd)); } diff --git a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp index db1722043c3..3d737b90741 100644 --- a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp @@ -166,7 +166,7 @@ bool GdbServerProvider::aboutToRun(DebuggerRunTool *runTool, const auto exeAspect = runControl->aspect(); QTC_ASSERT(exeAspect, return false); - const FilePath bin = exeAspect->executable(); + const FilePath bin = exeAspect->executable; if (bin.isEmpty()) { errorMessage = BareMetalDebugSupport::tr( "Cannot debug: Local executable is not set."); @@ -184,7 +184,7 @@ bool GdbServerProvider::aboutToRun(DebuggerRunTool *runTool, inferior.extraData.insert(Debugger::Constants::kPeripheralDescriptionFile, m_peripheralDescriptionFile.toVariant()); if (const auto argAspect = runControl->aspect()) - inferior.command.setArguments(argAspect->arguments(runControl->macroExpander())); + inferior.command.setArguments(argAspect->arguments); runTool->setInferior(inferior); runTool->setSymbolFile(bin); runTool->setStartMode(AttachToRemoteServer); diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp index 4887549dab8..19c4b07ad55 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp @@ -194,7 +194,7 @@ bool UvscServerProvider::aboutToRun(DebuggerRunTool *runTool, QString &errorMess const auto exeAspect = runControl->aspect(); QTC_ASSERT(exeAspect, return false); - const FilePath bin = exeAspect->executable(); + const FilePath bin = exeAspect->executable; if (bin.isEmpty()) { errorMessage = BareMetalDebugSupport::tr("Cannot debug: Local executable is not set."); return false; diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index a6cccc3d09a..d11d0a51c24 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -95,6 +95,7 @@ CorePlugin::CorePlugin() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); m_instance = this; setupSystemEnvironment(); } diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp index 553dfafe875..4a339db3d79 100644 --- a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp +++ b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp @@ -182,6 +182,11 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target) return builder.emerge(false); }); + addDataExtractor(this, &DebuggerRunConfigurationAspect::useCppDebugger, &Data::useCppDebugger); + addDataExtractor(this, &DebuggerRunConfigurationAspect::useQmlDebugger, &Data::useQmlDebugger); + addDataExtractor(this, &DebuggerRunConfigurationAspect::useMultiProcess, &Data::useMultiProcess); + addDataExtractor(this, &DebuggerRunConfigurationAspect::overrideStartup, &Data::overrideStartup); + m_cppAspect = new DebuggerLanguageAspect; m_cppAspect->setLabel(tr("Enable C++")); m_cppAspect->setSettingsKey("RunConfiguration.UseCppDebugger"); diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.h b/src/plugins/debugger/debuggerrunconfigurationaspect.h index bd2a0a0e00e..4f390d65f60 100644 --- a/src/plugins/debugger/debuggerrunconfigurationaspect.h +++ b/src/plugins/debugger/debuggerrunconfigurationaspect.h @@ -56,6 +56,14 @@ public: int portsUsedByDebugger() const; + struct Data : BaseAspect::Data + { + bool useCppDebugger; + bool useQmlDebugger; + bool useMultiProcess; + QString overrideStartup; + }; + private: Internal::DebuggerLanguageAspect *m_cppAspect; Internal::DebuggerLanguageAspect *m_qmlAspect; diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index c0d0889b99e..86d8e1fba9b 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -868,11 +868,11 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm m_runParameters.displayName = runControl->displayName(); if (auto symbolsAspect = runControl->aspect()) - m_runParameters.symbolFile = symbolsAspect->filePath(); + m_runParameters.symbolFile = symbolsAspect->filePath; if (auto terminalAspect = runControl->aspect()) - m_runParameters.useTerminal = terminalAspect->useTerminal(); + m_runParameters.useTerminal = terminalAspect->useTerminal; if (auto runAsRootAspect = runControl->aspect()) - m_runParameters.runAsRoot = runAsRootAspect->value(); + m_runParameters.runAsRoot = runAsRootAspect->value; Kit *kit = runControl->kit(); QTC_ASSERT(kit, return); @@ -886,13 +886,13 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm m_runParameters.qtPackageSourceLocation = qtVersion->qtPackageSourcePath().toString(); if (auto aspect = runControl->aspect()) { - if (!aspect->useCppDebugger()) + if (!aspect->useCppDebugger) m_runParameters.cppEngineType = NoEngineType; - m_runParameters.isQmlDebugging = aspect->useQmlDebugger(); - m_runParameters.multiProcess = aspect->useMultiProcess(); - m_runParameters.additionalStartupCommands = aspect->overrideStartup(); + m_runParameters.isQmlDebugging = aspect->useQmlDebugger; + m_runParameters.multiProcess = aspect->useMultiProcess; + m_runParameters.additionalStartupCommands = aspect->overrideStartup; - if (aspect->useCppDebugger()) { + if (aspect->useCppDebugger) { if (DebuggerKitAspect::debugger(kit)) { const Tasks tasks = DebuggerKitAspect::validateDebugger(kit); for (const Task &t : tasks) { diff --git a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp index fbee8c56f74..7c480ebc4a5 100644 --- a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp +++ b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp @@ -92,7 +92,7 @@ public: const Target *target = runControl->target(); Runnable r; r.command = {cmakeFilePath(target), - runControl->runConfiguration()->aspect()->value(), + runControl->aspect()->value, CommandLine::Raw}; r.workingDirectory = target->activeBuildConfiguration()->buildDirectory(); r.environment = target->activeBuildConfiguration()->environment(); diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp index f638d14c903..d47af61c128 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp @@ -115,9 +115,9 @@ public: { setId("LocalPerfRecordWorker"); - auto perfAspect = static_cast(runControl->aspect(Constants::PerfSettingsId)); + auto perfAspect = runControl->aspect(); QTC_ASSERT(perfAspect, return); - PerfSettings *settings = static_cast(perfAspect->currentSettings()); + PerfSettings *settings = static_cast(perfAspect->currentSettings); QTC_ASSERT(settings, return); m_perfRecordArguments = settings->perfRecordArguments(); } diff --git a/src/plugins/projectexplorer/customparser.cpp b/src/plugins/projectexplorer/customparser.cpp index 0229a5287ce..7d19d57560c 100644 --- a/src/plugins/projectexplorer/customparser.cpp +++ b/src/plugins/projectexplorer/customparser.cpp @@ -182,6 +182,7 @@ CustomParsersAspect::CustomParsersAspect(Target *target) setId("CustomOutputParsers"); setSettingsKey("CustomOutputParsers"); setDisplayName(tr("Custom Output Parsers")); + addDataExtractor(this, &CustomParsersAspect::parsers, &Data::parsers); setConfigWidgetCreator([this] { const auto widget = new Internal::CustomParsersSelectionWidget; widget->setSelectedParsers(m_parsers); diff --git a/src/plugins/projectexplorer/customparser.h b/src/plugins/projectexplorer/customparser.h index b0df82c3f92..125ac3bd923 100644 --- a/src/plugins/projectexplorer/customparser.h +++ b/src/plugins/projectexplorer/customparser.h @@ -100,7 +100,12 @@ public: CustomParsersAspect(Target *target); void setParsers(const QList &parsers) { m_parsers = parsers; } - const QList parsers() const { return m_parsers; } + QList parsers() const { return m_parsers; } + + struct Data : BaseAspect::Data + { + QList parsers; + }; private: void fromMap(const QVariantMap &map) override; diff --git a/src/plugins/projectexplorer/environmentaspect.cpp b/src/plugins/projectexplorer/environmentaspect.cpp index d34b32170fc..f926c636f84 100644 --- a/src/plugins/projectexplorer/environmentaspect.cpp +++ b/src/plugins/projectexplorer/environmentaspect.cpp @@ -46,6 +46,7 @@ EnvironmentAspect::EnvironmentAspect() setDisplayName(tr("Environment")); setId("EnvironmentAspect"); setConfigWidgetCreator([this] { return new EnvironmentAspectWidget(this); }); + addDataExtractor(this, &EnvironmentAspect::environment, &Data::environment); } int EnvironmentAspect::baseEnvironmentBase() const diff --git a/src/plugins/projectexplorer/environmentaspect.h b/src/plugins/projectexplorer/environmentaspect.h index 79c1d622e85..8e1095738ff 100644 --- a/src/plugins/projectexplorer/environmentaspect.h +++ b/src/plugins/projectexplorer/environmentaspect.h @@ -70,6 +70,11 @@ public: bool isLocal() const { return m_isLocal; } + struct Data : BaseAspect::Data + { + Utils::Environment environment; + }; + signals: void baseEnvironmentChanged(); void userEnvironmentChangesChanged(const Utils::EnvironmentItems &diff); diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 430eadb8dae..01c68a9620e 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -93,7 +93,10 @@ void ISettingsAspect::setConfigWidgetCreator(const ConfigWidgetCreator &configWi // /////////////////////////////////////////////////////////////////////// -GlobalOrProjectAspect::GlobalOrProjectAspect() = default; +GlobalOrProjectAspect::GlobalOrProjectAspect() +{ + addDataExtractor(this, &GlobalOrProjectAspect::currentSettings, &Data::currentSettings); +} GlobalOrProjectAspect::~GlobalOrProjectAspect() { @@ -264,14 +267,20 @@ void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory) theAspectFactories.push_back(aspectFactory); } -QMap RunConfiguration::aspectData() const +QMap RunConfiguration::settingsData() const { QMap data; - for (BaseAspect *aspect : qAsConst(m_aspects)) + for (BaseAspect *aspect : m_aspects) aspect->toActiveMap(data[aspect->id()]); return data; } +void RunConfiguration::storeAspectData(AspectContainerData *storage) const +{ + for (BaseAspect *aspect : m_aspects) + storage->append(aspect->extractData(&m_expander)); +} + BuildSystem *RunConfiguration::activeBuildSystem() const { return target()->buildSystem(); diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index fe0ebb530be..a5d3a85fc2b 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -105,6 +105,11 @@ public: ISettingsAspect *globalSettings() const { return m_globalSettings; } ISettingsAspect *currentSettings() const; + struct Data : Utils::BaseAspect::Data + { + ISettingsAspect *currentSettings = nullptr; + }; + protected: friend class RunConfiguration; void fromMap(const QVariantMap &map) override; @@ -163,7 +168,8 @@ public: addAspectFactory([](Target *target) { return new T(target); }); } - QMap aspectData() const; + QMap settingsData() const; // FIXME: Merge into aspectData? + void storeAspectData(Utils::AspectContainerData *storage) const; void update(); @@ -276,3 +282,5 @@ private: }; } // namespace ProjectExplorer + +Q_DECLARE_METATYPE(ProjectExplorer::ISettingsAspect *); diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 2291a86fbda..08ae45d1775 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -65,6 +65,8 @@ TerminalAspect::TerminalAspect() setDisplayName(tr("Terminal")); setId("TerminalAspect"); setSettingsKey("RunConfiguration.UseTerminal"); + addDataExtractor(this, &TerminalAspect::useTerminal, &Data::useTerminal); + addDataExtractor(this, &TerminalAspect::isUserSet, &Data::isUserSet); calculateUseTerminal(); connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged, this, &TerminalAspect::calculateUseTerminal); @@ -320,6 +322,9 @@ ArgumentsAspect::ArgumentsAspect() setDisplayName(tr("Arguments")); setId("ArgumentsAspect"); setSettingsKey("RunConfiguration.Arguments"); + + addDataExtractor(this, &ArgumentsAspect::arguments, &Data::arguments); + m_labelText = tr("Command line arguments:"); } @@ -514,6 +519,9 @@ ExecutableAspect::ExecutableAspect() setDisplayName(tr("Executable")); setId("ExecutableAspect"); setExecutablePathStyle(HostOsInfo::hostOs()); + + addDataExtractor(this, &ExecutableAspect::executable, &Data::executable); + m_executable.setPlaceHolderText(tr("")); m_executable.setLabelText(tr("Executable:")); m_executable.setDisplayStyle(StringAspect::LabelDisplay); diff --git a/src/plugins/projectexplorer/runconfigurationaspects.h b/src/plugins/projectexplorer/runconfigurationaspects.h index 1f8a6933fb6..7426c82fa26 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.h +++ b/src/plugins/projectexplorer/runconfigurationaspects.h @@ -55,6 +55,12 @@ public: bool isUserSet() const; + struct Data : BaseAspect::Data + { + bool useTerminal; + bool isUserSet; + }; + private: void fromMap(const QVariantMap &map) override; void toMap(QVariantMap &map) const override; @@ -115,6 +121,11 @@ public: void setResetter(const std::function &resetter); void resetArguments(); + struct Data : BaseAspect::Data + { + QString arguments; + }; + private: void fromMap(const QVariantMap &map) override; void toMap(QVariantMap &map) const override; @@ -178,6 +189,11 @@ public: void setEnvironmentChange(const Utils::EnvironmentChange &change); void setDisplayStyle(Utils::StringAspect::DisplayStyle style); + struct Data : BaseAspect::Data + { + Utils::FilePath executable; + }; + protected: void fromMap(const QVariantMap &map) override; void toMap(QVariantMap &map) const override; diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp index 1ea65831037..34c4df84e01 100644 --- a/src/plugins/projectexplorer/runcontrol.cpp +++ b/src/plugins/projectexplorer/runcontrol.cpp @@ -351,6 +351,7 @@ public: Utils::Icon icon; const MacroExpander *macroExpander = nullptr; QPointer runConfiguration; // Not owned. Avoid use. + AspectContainerData aspectData; QString buildKey; QMap settingsData; Utils::Id runConfigId; @@ -390,7 +391,9 @@ void RunControl::setRunConfiguration(RunConfiguration *runConfig) d->runnable = runConfig->runnable(); d->displayName = runConfig->expandedDisplayName(); d->buildKey = runConfig->buildKey(); - d->settingsData = runConfig->aspectData(); + d->settingsData = runConfig->settingsData(); + + runConfig->storeAspectData(&d->aspectData); setTarget(runConfig->target()); @@ -857,9 +860,8 @@ void RunControlPrivate::showError(const QString &msg) void RunControl::setupFormatter(OutputFormatter *formatter) const { QList parsers = OutputFormatterFactory::createFormatters(target()); - if (const auto customParsersAspect - = (runConfiguration() ? runConfiguration()->aspect() : nullptr)) { - for (const Utils::Id id : customParsersAspect->parsers()) { + if (const auto customParsersAspect = aspect()) { + for (const Id id : qAsConst(customParsersAspect->parsers)) { if (CustomParser * const parser = CustomParser::createFromId(id)) parsers << parser; } @@ -938,12 +940,17 @@ const MacroExpander *RunControl::macroExpander() const return d->macroExpander; } -BaseAspect *RunControl::aspect(Utils::Id id) const +const BaseAspect::Data *RunControl::aspect(Id instanceId) const { - return d->runConfiguration ? d->runConfiguration->aspect(id) : nullptr; + return d->aspectData.aspect(instanceId); } -QVariantMap RunControl::settingsData(Utils::Id id) const +const BaseAspect::Data *RunControl::aspect(BaseAspect::Data::ClassId classId) const +{ + return d->aspectData.aspect(classId); +} + +QVariantMap RunControl::settingsData(Id id) const { return d->settingsData.value(id); } @@ -1181,9 +1188,9 @@ SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl) { setId("SimpleTargetRunner"); if (auto terminalAspect = runControl->aspect()) - m_useTerminal = terminalAspect->useTerminal(); + m_useTerminal = terminalAspect->useTerminal; if (auto runAsRootAspect = runControl->aspect()) - m_runAsRoot = runAsRootAspect->value(); + m_runAsRoot = runAsRootAspect->value; } void SimpleTargetRunner::start() diff --git a/src/plugins/projectexplorer/runcontrol.h b/src/plugins/projectexplorer/runcontrol.h index 7a6ca088478..d436252c467 100644 --- a/src/plugins/projectexplorer/runcontrol.h +++ b/src/plugins/projectexplorer/runcontrol.h @@ -229,9 +229,11 @@ public: Project *project() const; Kit *kit() const; const Utils::MacroExpander *macroExpander() const; - Utils::BaseAspect *aspect(Utils::Id id) const; - template T *aspect() const { - return runConfiguration() ? runConfiguration()->aspect() : nullptr; + + const Utils::BaseAspect::Data *aspect(Utils::Id instanceId) const; + const Utils::BaseAspect::Data *aspect(Utils::BaseAspect::Data::ClassId classId) const; + template const typename T::Data *aspect() const { + return dynamic_cast(aspect(&T::staticMetaObject)); } QString buildKey() const; diff --git a/src/plugins/qmlpreview/qmlpreviewplugin.cpp b/src/plugins/qmlpreview/qmlpreviewplugin.cpp index 6bd695ac72b..2f76fd54f02 100644 --- a/src/plugins/qmlpreview/qmlpreviewplugin.cpp +++ b/src/plugins/qmlpreview/qmlpreviewplugin.cpp @@ -449,7 +449,8 @@ void QmlPreviewPluginPrivate::setDirty() void QmlPreviewPluginPrivate::addPreview(ProjectExplorer::RunControl *preview) { m_runningPreviews.append(preview); - if (auto multiLanguageAspect = preview->aspect()) { + if (auto multiLanguageAspect = + preview->runConfiguration()->aspect()) { connect(multiLanguageAspect, &QmlProjectManager::QmlMultiLanguageAspect::changed, preview, &ProjectExplorer::RunControl::initiateStop); } diff --git a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp index 22c9db93cb2..23eeb0b33e0 100644 --- a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp +++ b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp @@ -134,8 +134,8 @@ LocalQmlPreviewSupport::LocalQmlPreviewSupport(ProjectExplorer::RunControl *runC const auto *qmlBuildSystem = qobject_cast(currentTarget->buildSystem()); if (const auto aspect = runControl->aspect()) { - const QString mainScript = aspect->mainScript(); - const QString currentFile = aspect->currentFile(); + const QString mainScript = aspect->mainScript; + const QString currentFile = aspect->currentFile; const QString mainScriptFromProject = qmlBuildSystem->targetFile( Utils::FilePath::fromString(mainScript)).toString(); diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 74243a574bd..030625bd64e 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -311,9 +311,8 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker) { d->m_toolBusy = true; auto runControl = runWorker->runControl(); - if (auto aspect = static_cast( - runControl->aspect(Constants::SETTINGS))) { - if (auto settings = static_cast(aspect->currentSettings())) { + if (auto aspect = runControl->aspect()) { + if (auto settings = static_cast(aspect->currentSettings)) { d->m_profilerConnections->setFlushInterval(settings->flushEnabled.value() ? settings->flushInterval.value() : 0); d->m_profilerModelManager->setAggregateTraces(settings->aggregateTraces.value()); diff --git a/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp b/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp index 602a880fad5..c16d96616a8 100644 --- a/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp +++ b/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp @@ -37,14 +37,14 @@ #include #include +#include #include #include -#include - using namespace Core; using namespace ProjectExplorer; +using namespace Utils; namespace QmlProjectManager { @@ -60,6 +60,9 @@ QmlMainFileAspect::QmlMainFileAspect(Target *target) : m_target(target) , m_scriptFile(M_CURRENT_FILE) { + addDataExtractor(this, &QmlMainFileAspect::mainScript, &Data::mainScript); + addDataExtractor(this, &QmlMainFileAspect::currentFile, &Data::currentFile); + connect(EditorManager::instance(), &EditorManager::currentEditorChanged, this, &QmlMainFileAspect::changeCurrentFile); connect(EditorManager::instance(), &EditorManager::currentDocumentStateChanged, diff --git a/src/plugins/qmlprojectmanager/qmlmainfileaspect.h b/src/plugins/qmlprojectmanager/qmlmainfileaspect.h index 7eacb128b22..ede3d8f4117 100644 --- a/src/plugins/qmlprojectmanager/qmlmainfileaspect.h +++ b/src/plugins/qmlprojectmanager/qmlmainfileaspect.h @@ -47,6 +47,7 @@ class QmlBuildSystem; class QMLPROJECTMANAGER_EXPORT QmlMainFileAspect : public Utils::BaseAspect { Q_OBJECT + public: explicit QmlMainFileAspect(ProjectExplorer::Target *target); ~QmlMainFileAspect() override; @@ -57,6 +58,12 @@ public: FileInSettings }; + struct Data : BaseAspect::Data + { + QString mainScript; + QString currentFile; + }; + void addToLayout(Utils::LayoutBuilder &builder) final; void toMap(QVariantMap &map) const final; void fromMap(const QVariantMap &map) final; @@ -74,7 +81,6 @@ public: QmlBuildSystem *qmlBuildSystem() const; public: - ProjectExplorer::Target *m_target = nullptr; QPointer m_fileListCombo; QStandardItemModel m_fileListModel; diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp index 3abb35d2b2e..6f3c1415719 100644 --- a/src/plugins/qnx/slog2inforunner.cpp +++ b/src/plugins/qnx/slog2inforunner.cpp @@ -45,7 +45,7 @@ Slog2InfoRunner::Slog2InfoRunner(RunControl *runControl) : RunWorker(runControl) { setId("Slog2InfoRunner"); - m_applicationId = runControl->aspect()->executable().fileName(); + m_applicationId = runControl->aspect()->executable.fileName(); // See QTCREATORBUG-10712 for details. // We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info. diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp index 6b34dc809dc..6f1fc91be96 100644 --- a/src/plugins/valgrind/valgrindengine.cpp +++ b/src/plugins/valgrind/valgrindengine.cpp @@ -87,7 +87,7 @@ void ValgrindToolRunner::start() m_runner.setDebuggee(runnable()); if (auto aspect = runControl()->aspect()) - m_runner.setUseTerminal(aspect->useTerminal()); + m_runner.setUseTerminal(aspect->useTerminal); connect(&m_runner, &ValgrindRunner::processOutputReceived, this, &ValgrindToolRunner::receiveProcessOutput); diff --git a/src/plugins/webassembly/webassemblyrunconfiguration.cpp b/src/plugins/webassembly/webassemblyrunconfiguration.cpp index 54f6d5cb47e..057e84ea1be 100644 --- a/src/plugins/webassembly/webassemblyrunconfiguration.cpp +++ b/src/plugins/webassembly/webassemblyrunconfiguration.cpp @@ -120,7 +120,7 @@ public: setStarter([this, runControl, portsGatherer] { Runnable r; const QString browserId = - runControl->aspect()->currentBrowser(); + runControl->aspect()->currentBrowser; r.command = emrunCommand(runControl->runConfiguration(), browserId, QString::number(portsGatherer->findEndPoint().port())); diff --git a/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp b/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp index b022c5147dc..14573001161 100644 --- a/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp +++ b/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp @@ -89,6 +89,8 @@ WebBrowserSelectionAspect::WebBrowserSelectionAspect(ProjectExplorer::Target *ta setDisplayName(tr("Web Browser")); setId("WebBrowserAspect"); setSettingsKey("RunConfiguration.WebBrowser"); + + addDataExtractor(this, &WebBrowserSelectionAspect::currentBrowser, &Data::currentBrowser); } void WebBrowserSelectionAspect::addToLayout(LayoutBuilder &builder) diff --git a/src/plugins/webassembly/webassemblyrunconfigurationaspects.h b/src/plugins/webassembly/webassemblyrunconfigurationaspects.h index b1360a79faf..312ed40adf2 100644 --- a/src/plugins/webassembly/webassemblyrunconfigurationaspects.h +++ b/src/plugins/webassembly/webassemblyrunconfigurationaspects.h @@ -49,6 +49,11 @@ public: QString currentBrowser() const; + struct Data : BaseAspect::Data + { + QString currentBrowser; + }; + private: QComboBox *m_webBrowserComboBox = nullptr; QString m_currentBrowser;