aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/language/language.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/corelib/language/language.cpp')
-rw-r--r--src/lib/corelib/language/language.cpp190
1 files changed, 104 insertions, 86 deletions
diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp
index 3db41b8c8..b3f4b2a64 100644
--- a/src/lib/corelib/language/language.cpp
+++ b/src/lib/corelib/language/language.cpp
@@ -51,6 +51,8 @@
#include <buildgraph/rulegraph.h> // TODO: Move to language?
#include <buildgraph/transformer.h>
#include <jsextensions/jsextensions.h>
+#include <language/value.h>
+#include <loader/loaderutils.h>
#include <logging/categories.h>
#include <logging/translator.h>
#include <tools/buildgraphlocker.h>
@@ -60,6 +62,7 @@
#include <tools/qbsassert.h>
#include <tools/qttools.h>
#include <tools/scripttools.h>
+#include <tools/setupprojectparameters.h>
#include <tools/stlutils.h>
#include <tools/stringconstants.h>
@@ -68,8 +71,6 @@
#include <QtCore/qdiriterator.h>
#include <QtCore/qmap.h>
-#include <QtScript/qscriptvalue.h>
-
#include <algorithm>
#include <memory>
#include <mutex>
@@ -117,6 +118,12 @@ bool Probe::needsReconfigure(const FileTime &referenceTime) const
return Internal::any_of(m_importedFilesUsed, criterion);
}
+void Probe::restoreValues()
+{
+ for (auto it = m_properties.begin(), end = m_properties.end(); it != end; ++it) {
+ m_values[it.key()] = VariantValue::createStored(it.value());
+ }
+}
/*!
* \class SourceArtifact
@@ -137,41 +144,16 @@ bool Probe::needsReconfigure(const FileTime &referenceTime) const
/*!
* \variable ResolvedGroup::files
* \brief The files listed in the group item's "files" binding.
- * Note that these do not include expanded wildcards.
*/
/*!
* \variable ResolvedGroup::wildcards
- * \brief Represents the wildcard elements in this group's "files" binding.
+ * \brief Represents the wildcard patterns in this group's "files" binding.
* If no wildcards are specified there, this variable is null.
* \sa SourceWildCards
*/
/*!
- * \brief Returns all files specified in the group item as source artifacts.
- * This includes the expanded list of wildcards.
- */
-std::vector<SourceArtifactPtr> ResolvedGroup::allFiles() const
-{
- std::vector<SourceArtifactPtr> lst = files;
- if (wildcards)
- lst << wildcards->files;
- return lst;
-}
-
-void ResolvedGroup::load(PersistentPool &pool)
-{
- serializationOp<PersistentPool::Load>(pool);
- if (wildcards)
- wildcards->group = this;
-}
-
-void ResolvedGroup::store(PersistentPool &pool)
-{
- serializationOp<PersistentPool::Store>(pool);
-}
-
-/*!
* \class RuleArtifact
* \brief The \c RuleArtifact class represents an Artifact item encountered in the context
* of a Rule item.
@@ -313,7 +295,7 @@ void ResolvedProduct::accept(BuildGraphVisitor *visitor) const
{
if (!buildData)
return;
- for (BuildGraphNode * const node : qAsConst(buildData->rootNodes()))
+ for (BuildGraphNode * const node : std::as_const(buildData->rootNodes()))
node->accept(visitor);
}
@@ -325,7 +307,7 @@ std::vector<SourceArtifactPtr> ResolvedProduct::allFiles() const
{
std::vector<SourceArtifactPtr> lst;
for (const auto &group : groups)
- lst << group->allFiles();
+ lst << group->files;
return lst;
}
@@ -338,7 +320,7 @@ std::vector<SourceArtifactPtr> ResolvedProduct::allEnabledFiles() const
std::vector<SourceArtifactPtr> lst;
for (const auto &group : groups) {
if (group->enabled)
- lst << group->allFiles();
+ lst << group->files;
}
return lst;
}
@@ -347,7 +329,7 @@ FileTags ResolvedProduct::fileTagsForFileName(const QString &fileName) const
{
FileTags result;
std::unique_ptr<int> priority;
- for (const FileTaggerConstPtr &tagger : qAsConst(fileTaggers)) {
+ for (const FileTaggerConstPtr &tagger : std::as_const(fileTaggers)) {
for (const QRegularExpression &pattern : tagger->patterns()) {
if (pattern.match(fileName).hasMatch()) {
if (priority) {
@@ -374,6 +356,8 @@ void ResolvedProduct::load(PersistentPool &pool)
rule->product = this;
for (const ResolvedModulePtr &module : modules)
module->product = this;
+ for (const auto &group: groups)
+ group->restoreWildcards(buildDirectory());
}
void ResolvedProduct::store(PersistentPool &pool)
@@ -425,18 +409,9 @@ QString ResolvedProduct::uniqueName() const
return uniqueName(name, multiplexConfigurationId);
}
-QString ResolvedProduct::fullDisplayName(const QString &name,
- const QString &multiplexConfigurationId)
-{
- QString result = name;
- if (!multiplexConfigurationId.isEmpty())
- result.append(QLatin1Char(' ')).append(multiplexIdToString(multiplexConfigurationId));
- return result;
-}
-
QString ResolvedProduct::fullDisplayName() const
{
- return fullDisplayName(name, multiplexConfigurationId);
+ return fullProductDisplayName(name, multiplexConfigurationId);
}
QString ResolvedProduct::profile() const
@@ -512,6 +487,19 @@ QString ResolvedProduct::cachedExecutablePath(const QString &origFilePath) const
return m_executablePathCache.value(origFilePath);
}
+void ResolvedGroup::restoreWildcards(const QString &buildDir)
+{
+ if (wildcards) {
+ wildcards->buildDir = buildDir;
+ wildcards->prefix = prefix;
+ wildcards->baseDir = FileInfo::path(location.filePath());
+ for (const auto &sourceArtifact : files) {
+ if (sourceArtifact->fromWildcard)
+ wildcards->expandedFiles += sourceArtifact->absoluteFilePath;
+ }
+ }
+}
+
ResolvedProject::ResolvedProject() : enabled(true), m_topLevelProject(nullptr)
{
@@ -523,7 +511,7 @@ void ResolvedProject::accept(BuildGraphVisitor *visitor) const
{
for (const ResolvedProductPtr &product : products)
product->accept(visitor);
- for (const ResolvedProjectPtr &subProject : qAsConst(subProjects))
+ for (const ResolvedProjectPtr &subProject : std::as_const(subProjects))
subProject->accept(visitor);
}
@@ -550,7 +538,7 @@ std::vector<ResolvedProjectPtr> ResolvedProject::allSubProjects() const
std::vector<ResolvedProductPtr> ResolvedProject::allProducts() const
{
std::vector<ResolvedProductPtr> productList = products;
- for (const auto &subProject : qAsConst(subProjects))
+ for (const auto &subProject : std::as_const(subProjects))
productList << subProject->allProducts();
return productList;
}
@@ -562,11 +550,11 @@ void ResolvedProject::load(PersistentPool &pool)
[](const ResolvedProductPtr &p) {
if (!p->buildData)
return;
- for (BuildGraphNode * const node : qAsConst(p->buildData->allNodes())) {
+ for (BuildGraphNode * const node : std::as_const(p->buildData->allNodes())) {
node->product = p;
// restore parent links
- for (BuildGraphNode * const child : qAsConst(node->children))
+ for (BuildGraphNode * const child : std::as_const(node->children))
child->parents.insert(node);
}
});
@@ -592,7 +580,7 @@ TopLevelProject::~TopLevelProject()
QString TopLevelProject::deriveId(const QVariantMap &config)
{
const QVariantMap qbsProperties = config.value(StringConstants::qbsModule()).toMap();
- const QString configurationName = qbsProperties.value(
+ QString configurationName = qbsProperties.value(
StringConstants::configurationNameProperty()).toString();
return configurationName;
}
@@ -619,6 +607,16 @@ void TopLevelProject::makeModuleProvidersNonTransient()
m.transientOutput = false;
}
+QVariantMap TopLevelProject::fullProfileConfigsTree() const
+{
+ QVariantMap tree;
+ for (auto it = profileConfigs.cbegin(); it != profileConfigs.cend(); ++it) {
+ tree.insert(it.key(), SetupProjectParameters::finalBuildConfigurationTree(
+ it.value().toMap(), overriddenValues));
+ }
+ return tree;
+}
+
QString TopLevelProject::buildGraphFilePath() const
{
return ProjectBuildData::deriveBuildGraphFilePath(buildDirectory, id());
@@ -665,7 +663,7 @@ void TopLevelProject::store(PersistentPool &pool)
void TopLevelProject::cleanupModuleProviderOutput()
{
QString error;
- for (const ModuleProviderInfo &m : qAsConst(moduleProviderInfo.providers)) {
+ for (const ModuleProviderInfo &m : std::as_const(moduleProviderInfo.providers)) {
if (m.transientOutput) {
if (!removeDirectoryWithContents(m.outputDirPath(buildDirectory), &error))
qCWarning(lcBuildGraph) << "Error removing module provider output:" << error;
@@ -709,25 +707,22 @@ void TopLevelProject::cleanupModuleProviderOutput()
* \brief The \c SourceArtifacts resulting from the expanded list of matching files.
*/
-Set<QString> SourceWildCards::expandPatterns(const GroupConstPtr &group,
- const QString &baseDir, const QString &buildDir)
+void SourceWildCards::expandPatterns()
{
- Set<QString> files = expandPatterns(group, patterns, baseDir, buildDir);
- files -= expandPatterns(group, excludePatterns, baseDir, buildDir);
- return files;
+ dirTimeStamps.clear();
+ expandedFiles = expandPatterns(patterns) - expandPatterns(excludePatterns);
}
-Set<QString> SourceWildCards::expandPatterns(const GroupConstPtr &group,
- const QStringList &patterns, const QString &baseDir, const QString &buildDir)
+Set<QString> SourceWildCards::expandPatterns(const QStringList &patterns)
{
Set<QString> files;
- QString expandedPrefix = group->prefix;
+ QString expandedPrefix = prefix;
if (expandedPrefix.startsWith(StringConstants::tildeSlash()))
expandedPrefix.replace(0, 1, QDir::homePath());
for (QString pattern : patterns) {
pattern.prepend(expandedPrefix);
pattern.replace(QLatin1Char('\\'), QLatin1Char('/'));
- QStringList parts = pattern.split(QLatin1Char('/'), QBS_SKIP_EMPTY_PARTS);
+ QStringList parts = pattern.split(QLatin1Char('/'), Qt::SkipEmptyParts);
if (FileInfo::isAbsolute(pattern)) {
QString rootDir;
if (HostOsInfo::isWindowsHost() && pattern.at(0) != QLatin1Char('/')) {
@@ -737,18 +732,17 @@ Set<QString> SourceWildCards::expandPatterns(const GroupConstPtr &group,
} else {
rootDir = QLatin1Char('/');
}
- expandPatterns(files, group, parts, rootDir, buildDir);
+ expandPatterns(files, parts, rootDir);
} else {
- expandPatterns(files, group, parts, baseDir, buildDir);
+ expandPatterns(files, parts, baseDir);
}
}
return files;
}
-void SourceWildCards::expandPatterns(Set<QString> &result, const GroupConstPtr &group,
- const QStringList &parts,
- const QString &baseDir, const QString &buildDir)
+void SourceWildCards::expandPatterns(Set<QString> &result, const QStringList &parts,
+ const QString &baseDir)
{
// People might build directly in the project source directory. This is okay, since
// we keep the build data in a "container" directory. However, we must make sure we don't
@@ -756,8 +750,6 @@ void SourceWildCards::expandPatterns(Set<QString> &result, const GroupConstPtr &
if (baseDir.startsWith(buildDir))
return;
- dirTimeStamps.emplace_back(baseDir, FileInfo(baseDir).lastModified());
-
QStringList changed_parts = parts;
bool recursive = false;
QString part = changed_parts.takeFirst();
@@ -784,8 +776,12 @@ void SourceWildCards::expandPatterns(Set<QString> &result, const GroupConstPtr &
: QDir::Files | QDir::System
| QDir::Dirs; // This one is needed to get symbolic links to directories
- if (isDir && !FileInfo::isPattern(filePattern))
+ if (FileInfo::isPattern(filePattern)) {
+ if (!recursive)
+ dirTimeStamps.emplace_back(baseDir, FileInfo(baseDir).lastModified());
+ } else if (isDir) {
itFilters |= QDir::Hidden;
+ }
if (filePattern != StringConstants::dotDot() && filePattern != StringConstants::dot())
itFilters |= QDir::NoDotAndDotDot;
@@ -797,16 +793,28 @@ void SourceWildCards::expandPatterns(Set<QString> &result, const GroupConstPtr &
continue; // See above.
if (!isDir && it.fileInfo().isDir() && !it.fileInfo().isSymLink())
continue;
- if (isDir) {
- expandPatterns(result, group, changed_parts, filePath, buildDir);
- } else {
- if (parentDir != baseDir)
- dirTimeStamps.emplace_back(parentDir, FileInfo(baseDir).lastModified());
+ if (isDir)
+ expandPatterns(result, changed_parts, filePath);
+ else
result += QDir::cleanPath(filePath);
- }
}
}
+bool SourceWildCards::hasChangedSinceExpansion() const
+{
+ const bool reExpansionRequired =
+ Internal::any_of(dirTimeStamps,
+ [](const std::pair<QString, FileTime> &pair) {
+ return FileInfo(pair.first).lastModified() > pair.second;
+ });
+ if (reExpansionRequired)
+ return true;
+
+ auto wc = *this;
+ wc.expandPatterns();
+ return this->expandedFiles != wc.expandedFiles;
+}
+
template<typename L>
QMap<QString, typename L::value_type> listToMap(const L &list)
{
@@ -915,11 +923,6 @@ bool artifactPropertyListsAreEqual(const std::vector<ArtifactPropertiesPtr> &l1,
return listsAreEqual(l1, l2);
}
-QString multiplexIdToString(const QString &id)
-{
- return QString::fromUtf8(QByteArray::fromBase64(id.toUtf8()));
-}
-
bool operator==(const PrivateScriptFunction &a, const PrivateScriptFunction &b)
{
return equals(a.m_sharedData.get(), b.m_sharedData.get());
@@ -935,7 +938,7 @@ bool operator==(const ExportedProperty &p1, const ExportedProperty &p2)
bool operator==(const ExportedModuleDependency &d1, const ExportedModuleDependency &d2)
{
- return d1.name == d2.name && d1.moduleProperties == d2.moduleProperties;
+ return d1.name == d2.name && qVariantMapsEqual(d1.moduleProperties, d2.moduleProperties);
}
bool equals(const std::vector<ExportedItemPtr> &l1, const std::vector<ExportedItemPtr> &l2)
@@ -962,20 +965,35 @@ bool operator==(const ExportedModule &m1, const ExportedModule &m2)
for (auto it1 = m1.cbegin(), it2 = m2.cbegin(); it1 != m1.cend(); ++it1, ++it2) {
if (it1.key()->name != it2.key()->name)
return false;
- if (it1.value() != it2.value())
+ if (!qVariantMapsEqual(it1.value(), it2.value()))
return false;
}
return true;
};
- return m1.propertyValues == m2.propertyValues
- && m1.modulePropertyValues == m2.modulePropertyValues
- && equals(m1.children, m2.children)
- && m1.m_properties == m2.m_properties
- && m1.importStatements == m2.importStatements
- && m1.productDependencies.size() == m2.productDependencies.size()
- && m1.productDependencies == m2.productDependencies
- && depMapsEqual(m1.dependencyParameters, m2.dependencyParameters);
+ return qVariantMapsEqual(m1.propertyValues, m2.propertyValues)
+ && qVariantMapsEqual(m1.modulePropertyValues, m2.modulePropertyValues)
+ && equals(m1.children, m2.children) && m1.m_properties == m2.m_properties
+ && m1.importStatements == m2.importStatements
+ && m1.productDependencies.size() == m2.productDependencies.size()
+ && m1.productDependencies == m2.productDependencies
+ && depMapsEqual(m1.dependencyParameters, m2.dependencyParameters);
+}
+
+JSValue PrivateScriptFunction::getFunction(ScriptEngine *engine, const QString &errorMessage) const
+{
+ if (JS_IsUndefined(scriptFunction)) {
+ ScopedJsValue val(engine->context(),
+ engine->evaluate(JsValueOwner::Caller, sourceCode(),
+ location().filePath(), location().line()));
+ if (Q_UNLIKELY(!JS_IsFunction(engine->context(), val)))
+ throw ErrorInfo(errorMessage, location());
+ scriptFunction = val.release();
+ engine->addExternallyCachedValue(&scriptFunction);
+ } else {
+ QBS_CHECK(JS_IsFunction(engine->context(), scriptFunction));
+ }
+ return scriptFunction;
}
} // namespace Internal