MacroExpander: Generalize registration of project variables

We provide global macros for ActiveProject and CurrentDocument:Project,
but these were completely separate, and the CurrentDocument:Project one
comparatively incomplete. Unifiy them.

Change-Id: I2622012f2c760e9f5b328766eca9d64c0bf9c5b1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Eike Ziller
2023-01-04 15:30:43 +01:00
parent 23fa784e9c
commit b7731b58a8
3 changed files with 142 additions and 114 deletions

View File

@@ -8,12 +8,14 @@
#include "buildsystem.h"
#include "deployconfiguration.h"
#include "editorconfiguration.h"
#include "environmentaspect.h"
#include "kit.h"
#include "kitinformation.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "projectnodes.h"
#include "runconfiguration.h"
#include "runconfigurationaspects.h"
#include "session.h"
#include "target.h"
#include "taskhub.h"
@@ -1087,6 +1089,129 @@ void Project::runGenerator(Utils::Id id)
}
}
void Project::addVariablesToMacroExpander(const QByteArray &prefix,
const QString &descriptor,
MacroExpander *expander,
const std::function<Project *()> &projectGetter)
{
const auto targetGetter = [projectGetter]() -> Target * {
if (const Project *const project = projectGetter())
return project->activeTarget();
return nullptr;
};
const auto bcGetter = [targetGetter]() -> BuildConfiguration * {
if (const Target *const target = targetGetter())
return target->activeBuildConfiguration();
return nullptr;
};
const auto rcGetter = [targetGetter]() -> RunConfiguration * {
if (const Target *const target = targetGetter())
return target->activeRunConfiguration();
return nullptr;
};
const QByteArray fullPrefix = (prefix.endsWith(':') ? prefix : prefix + ':');
const QByteArray prefixWithoutColon = fullPrefix.chopped(1);
expander->registerVariable(fullPrefix + "Name",
//: %1 is something like "Active project"
tr("%1: Name.").arg(descriptor),
[projectGetter]() -> QString {
if (const Project *const project = projectGetter())
return project->displayName();
return {};
});
expander->registerFileVariables(prefixWithoutColon,
//: %1 is something like "Active project"
tr("%1: Full path to main file.").arg(descriptor),
[projectGetter]() -> FilePath {
if (const Project *const project = projectGetter())
return project->projectFilePath();
return {};
});
expander->registerVariable(fullPrefix + "Kit:Name",
//: %1 is something like "Active project"
tr("%1: The name the active kit.").arg(descriptor),
[targetGetter]() -> QString {
if (const Target *const target = targetGetter())
return target->kit()->displayName();
return {};
});
expander->registerVariable(fullPrefix + "BuildConfig:Name",
//: %1 is something like "Active project"
tr("%1: Name of the active build configuration.").arg(descriptor),
[bcGetter]() -> QString {
if (const BuildConfiguration *const bc = bcGetter())
return bc->displayName();
return {};
});
expander->registerVariable(fullPrefix + "BuildConfig:Type",
//: %1 is something like "Active project"
tr("%1: Type of the active build configuration.").arg(descriptor),
[bcGetter]() -> QString {
const BuildConfiguration *const bc = bcGetter();
const BuildConfiguration::BuildType type
= bc ? bc->buildType() : BuildConfiguration::Unknown;
return BuildConfiguration::buildTypeName(type);
});
expander
->registerVariable(fullPrefix + "BuildConfig:Path",
//: %1 is something like "Active project"
tr("%1: Full build path of active build configuration.").arg(descriptor),
[bcGetter]() -> QString {
if (const BuildConfiguration *const bc = bcGetter())
return bc->buildDirectory().toUserOutput();
return {};
});
expander->registerPrefix(fullPrefix + "BuildConfig:Env",
//: %1 is something like "Active project"
tr("%1: Variables in the active build environment.").arg(descriptor),
[bcGetter](const QString &var) {
if (BuildConfiguration *const bc = bcGetter())
return bc->environment().expandedValueForKey(var);
return QString();
});
expander->registerVariable(fullPrefix + "RunConfig:Name",
//: %1 is something like "Active project"
tr("%1: Name of the active run configuration.").arg(descriptor),
[rcGetter]() -> QString {
if (const RunConfiguration *const rc = rcGetter())
return rc->displayName();
return QString();
});
expander->registerFileVariables(fullPrefix + "RunConfig:Executable",
//: %1 is something like "Active project"
tr("%1: Executable of the active run configuration.")
.arg(descriptor),
[rcGetter]() -> FilePath {
if (const RunConfiguration *const rc = rcGetter())
return rc->commandLine().executable();
return {};
});
expander->registerPrefix(fullPrefix + "RunConfig:Env",
//: %1 is something like "Active project"
tr("%1: Variables in the environment of the active run configuration.")
.arg(descriptor),
[rcGetter](const QString &var) {
if (const RunConfiguration *const rc = rcGetter()) {
if (const auto envAspect = rc->aspect<EnvironmentAspect>())
return envAspect->environment().expandedValueForKey(var);
}
return QString();
});
expander->registerVariable(fullPrefix + "RunConfig:WorkingDir",
//: %1 is something like "Active project"
tr("%1: Working directory of the active run configuration.")
.arg(descriptor),
[rcGetter] {
if (const RunConfiguration *const rc = rcGetter()) {
if (const auto wdAspect
= rc->aspect<WorkingDirectoryAspect>())
return wdAspect->workingDirectory().toString();
}
return QString();
});
}
#if defined(WITH_TESTS)
static FilePath constructTestPath(const QString &basePath)

View File

@@ -167,6 +167,11 @@ public:
const QList<QPair<Utils::Id, QString>> allGenerators() const;
void runGenerator(Utils::Id id);
static void addVariablesToMacroExpander(const QByteArray &prefix,
const QString &descriptor,
Utils::MacroExpander *expander,
const std::function<Project *()> &projectGetter);
signals:
void projectFileIsDirty(const Utils::FilePath &path);

View File

@@ -1945,34 +1945,13 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd->updateWelcomePage();
MacroExpander *expander = Utils::globalMacroExpander();
expander->registerFileVariables("CurrentDocument:Project",
tr("Main file of the project the current document belongs to."),
[]() -> FilePath {
FilePath projectFilePath;
if (Project *project = ProjectTree::currentProject())
projectFilePath = project->projectFilePath();
return projectFilePath;
}, false);
expander->registerVariable("CurrentDocument:Project:Name",
tr("The name of the project the current document belongs to."),
[]() -> QString {
Project *project = ProjectTree::currentProject();
return project ? project->displayName() : QString();
});
const char currentBuildEnvVar[] = "CurrentDocument:Project:BuildConfig:Env";
expander->registerPrefix(currentBuildEnvVar,
BuildConfiguration::tr(
"Variables in the active build environment "
"of the project containing the currently open document."),
[](const QString &var) {
if (BuildConfiguration *bc = currentBuildConfiguration())
return bc->environment().expandedValueForKey(var);
return QString();
});
// Global variables for the project that the current document belongs to.
Project::addVariablesToMacroExpander("CurrentDocument:Project:",
"Project of current document",
expander,
&ProjectTree::currentProject);
EnvironmentProvider::addProvider(
{currentBuildEnvVar, tr("Current Build Environment"), [] {
{"CurrentDocument:Project:BuildConfig:Env", tr("Current Build Environment"), [] {
if (BuildConfiguration *bc = currentBuildConfiguration())
return bc->environment();
return Environment::systemEnvironment();
@@ -1990,105 +1969,24 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
}});
// Global variables for the active project.
expander->registerVariable("ActiveProject:Name", tr("The name of the active project."),
[]() -> QString {
if (const Project * const project = SessionManager::startupProject())
return project->displayName();
return {};
});
expander->registerFileVariables("ActiveProject", tr("Active project's main file."),
[]() -> FilePath {
if (const Project * const project = SessionManager::startupProject())
return project->projectFilePath();
return {};
});
expander->registerVariable("ActiveProject:Kit:Name",
"The name of the active project's active kit.", // TODO: tr()
[]() -> QString {
if (const Target * const target = activeTarget())
return target->kit()->displayName();
return {};
});
expander->registerVariable("ActiveProject:BuildConfig:Name",
"The name of the active project's active build configuration.", // TODO: tr()
[]() -> QString {
if (const BuildConfiguration * const bc = activeBuildConfiguration())
return bc->displayName();
return {};
});
expander->registerVariable("ActiveProject:BuildConfig:Type",
tr("The type of the active project's active build configuration."),
[]() -> QString {
const BuildConfiguration * const bc = activeBuildConfiguration();
const BuildConfiguration::BuildType type = bc
? bc->buildType() : BuildConfiguration::Unknown;
return BuildConfiguration::buildTypeName(type);
});
expander->registerVariable("ActiveProject:BuildConfig:Path",
tr("Full build path of the active project's active build configuration."),
[]() -> QString {
if (const BuildConfiguration * const bc = activeBuildConfiguration())
return bc->buildDirectory().toUserOutput();
return {};
});
const char activeBuildEnvVar[] = "ActiveProject:BuildConfig:Env";
Project::addVariablesToMacroExpander("ActiveProject:",
"Active project",
expander,
&SessionManager::startupProject);
EnvironmentProvider::addProvider(
{activeBuildEnvVar, tr("Active build environment of the active project."), [] {
{"ActiveProject:BuildConfig:Env", tr("Active build environment of the active project."), [] {
if (const BuildConfiguration * const bc = activeBuildConfiguration())
return bc->environment();
return Environment::systemEnvironment();
}});
expander->registerPrefix(activeBuildEnvVar,
BuildConfiguration::tr("Variables in the active build environment "
"of the active project."),
[](const QString &var) {
if (BuildConfiguration * const bc = activeBuildConfiguration())
return bc->environment().expandedValueForKey(var);
return QString();
});
expander->registerVariable("ActiveProject:RunConfig:Name",
tr("Name of the active project's active run configuration."),
[]() -> QString {
if (const RunConfiguration * const rc = activeRunConfiguration())
return rc->displayName();
return QString();
});
expander->registerFileVariables("ActiveProject:RunConfig:Executable",
tr("The executable of the active project's active run configuration."),
[]() -> FilePath {
if (const RunConfiguration * const rc = activeRunConfiguration())
return rc->commandLine().executable();
return {};
});
const char activeRunEnvVar[] = "ActiveProject:RunConfig:Env";
EnvironmentProvider::addProvider(
{activeRunEnvVar, tr("Active run environment of the active project."), [] {
{"ActiveProject:RunConfig:Env", tr("Active run environment of the active project."), [] {
if (const RunConfiguration *const rc = activeRunConfiguration()) {
if (auto envAspect = rc->aspect<EnvironmentAspect>())
return envAspect->environment();
}
return Environment::systemEnvironment();
}});
expander->registerPrefix(
activeRunEnvVar,
tr("Variables in the environment of the active project's active run configuration."),
[](const QString &var) {
if (const RunConfiguration * const rc = activeRunConfiguration()) {
if (const auto envAspect = rc->aspect<EnvironmentAspect>())
return envAspect->environment().expandedValueForKey(var);
}
return QString();
});
expander->registerVariable("ActiveProject:RunConfig:WorkingDir",
tr("The working directory of the active project's active run configuration."),
[] {
if (const RunConfiguration * const rc = activeRunConfiguration()) {
if (const auto wdAspect = rc->aspect<WorkingDirectoryAspect>())
return wdAspect->workingDirectory().toString();
}
return QString();
});
const auto fileHandler = [] {
return SessionManager::sessionNameToFileName(SessionManager::activeSession());