aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@theqtcompany.com>2015-02-09 14:36:03 +0100
committerJoerg Bornemann <joerg.bornemann@theqtcompany.com>2015-02-10 10:57:56 +0000
commit6cd2ec6266f29d08ed337357049faea7a93c1b7c (patch)
tree72432584e6ef7d8798303de9449abf348e75071b
parentaec6c77bb8ce33b6535106c78eeb9cd755398953 (diff)
fix scalar property lookup some more
Let there be a product P that depends on module A. Module A depends on module B.A sets B.foo to 1. Default value of B.foo is 0. The value of product.moduleProperty("B", "foo") is 1. Now add the direct dependency B to P. P does not overwrite the default value of B.foo. The overwritten value of B.foo from A takes precedence. This semantics change is needed to make sure that adding/removing modules to a product does not change property values in surprising ways. Task-number: QBS-736 Change-Id: I73152a24649bc670a9075e82998ef2b0d8709a84 Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
-rw-r--r--src/lib/corelib/language/projectresolver.cpp19
-rw-r--r--src/lib/corelib/tools/propertyfinder.cpp46
-rw-r--r--src/lib/corelib/tools/propertyfinder.h3
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp1
4 files changed, 59 insertions, 10 deletions
diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp
index 0bf8b5ed3..3117edd80 100644
--- a/src/lib/corelib/language/projectresolver.cpp
+++ b/src/lib/corelib/language/projectresolver.cpp
@@ -1079,6 +1079,21 @@ QVariantMap ProjectResolver::evaluateModuleValues(Item *item, bool lookupPrototy
return result;
}
+static QStringList ownPropertiesSet(Item *item)
+{
+ QStringList names;
+ do {
+ names += item->properties().keys();
+ item = item->prototype();
+ } while (item && item->isModuleInstance());
+
+ std::sort(names.begin(), names.end());
+ QStringList::iterator lastIt = std::unique(names.begin(), names.end());
+ if (lastIt != names.end())
+ names.erase(lastIt);
+ return names;
+}
+
void ProjectResolver::evaluateModuleValues(Item *item, QVariantMap *modulesMap,
bool lookupPrototype) const
{
@@ -1097,7 +1112,9 @@ void ProjectResolver::evaluateModuleValues(Item *item, QVariantMap *modulesMap,
evaluateModuleValues(module.item, &depmods, lookupPrototype);
QVariantMap dep = evaluateProperties(module.item, lookupPrototype);
dep.insert(QLatin1String("modules"), depmods);
- modulesMap->insert(ModuleLoader::fullModuleName(module.name), dep);
+ const QString fullName = ModuleLoader::fullModuleName(module.name);
+ modulesMap->insert(fullName, dep);
+ modulesMap->insert(QLatin1Char('@') + fullName, ownPropertiesSet(module.item));
}
}
diff --git a/src/lib/corelib/tools/propertyfinder.cpp b/src/lib/corelib/tools/propertyfinder.cpp
index b1f89592e..3941228b0 100644
--- a/src/lib/corelib/tools/propertyfinder.cpp
+++ b/src/lib/corelib/tools/propertyfinder.cpp
@@ -31,6 +31,8 @@
#include "qbsassert.h"
+#include <QQueue>
+
namespace qbs {
namespace Internal {
@@ -40,7 +42,7 @@ QVariantList PropertyFinder::propertyValues(const QVariantMap &properties,
m_moduleName = moduleName;
m_key = key;
m_values.clear();
- findModuleValues(properties, true);
+ findModuleValues(properties);
if (mergeType == DoMergeLists)
mergeLists(&m_values);
return m_values;
@@ -52,13 +54,13 @@ QVariant PropertyFinder::propertyValue(const QVariantMap &properties, const QStr
m_moduleName = moduleName;
m_key = key;
m_values.clear();
- findModuleValues(properties, false);
+ findScalarModuleValue(properties);
QBS_ASSERT(m_values.count() <= 1, return QVariant());
return m_values.isEmpty() ? QVariant() : m_values.first();
}
-void PropertyFinder::findModuleValues(const QVariantMap &properties, bool searchRecursively)
+void PropertyFinder::findModuleValues(const QVariantMap &properties)
{
QVariantMap moduleProperties = properties.value(QLatin1String("modules")).toMap();
@@ -71,13 +73,43 @@ void PropertyFinder::findModuleValues(const QVariantMap &properties, bool search
moduleProperties.erase(modIt);
}
- if (!m_values.isEmpty() && !searchRecursively)
- return;
-
// These are the non-matching modules.
for (QVariantMap::ConstIterator it = moduleProperties.constBegin();
it != moduleProperties.constEnd(); ++it) {
- findModuleValues(it->toMap(), searchRecursively);
+ findModuleValues(it->toMap());
+ }
+}
+
+void PropertyFinder::findScalarModuleValue(const QVariantMap &properties)
+{
+ QQueue<QVariantMap> q;
+ q.enqueue(properties.value(QLatin1String("modules")).toMap());
+
+ while (!q.isEmpty()) {
+ QVariantMap moduleProperties = q.takeFirst();
+ const QVariantMap::Iterator modIt = moduleProperties.find(m_moduleName);
+ if (modIt != moduleProperties.end()) {
+ const QVariantMap moduleMap = modIt->toMap();
+ const QVariant property = moduleMap.value(m_key);
+ const QStringList ownPropertiesSet
+ = moduleProperties.value(QLatin1Char('@') + m_moduleName).toStringList();
+ if (std::binary_search(ownPropertiesSet.constBegin(), ownPropertiesSet.constEnd(),
+ m_key)) {
+ // this is the one!
+ m_values.clear();
+ addToList(property);
+ return;
+ }
+ addToList(property);
+ moduleProperties.erase(modIt);
+ }
+
+ // These are the non-matching modules.
+ for (QVariantMap::ConstIterator it = moduleProperties.constBegin();
+ it != moduleProperties.constEnd(); ++it) {
+ if (!it.key().startsWith(QLatin1Char('@')))
+ q.enqueue(it->toMap().value(QLatin1String("modules")).toMap());
+ }
}
}
diff --git a/src/lib/corelib/tools/propertyfinder.h b/src/lib/corelib/tools/propertyfinder.h
index 9c559b464..66322952a 100644
--- a/src/lib/corelib/tools/propertyfinder.h
+++ b/src/lib/corelib/tools/propertyfinder.h
@@ -48,7 +48,8 @@ public:
const QString &key);
private:
- void findModuleValues(const QVariantMap &properties, bool searchRecursively);
+ void findModuleValues(const QVariantMap &properties);
+ void findScalarModuleValue(const QVariantMap &properties);
void addToList(const QVariant &value);
static void mergeLists(QVariantList *values);
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 753558ffb..d1e3353ab 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -1923,7 +1923,6 @@ void TestBlackbox::nestedProperties()
{
QDir::setCurrent(testDataDir + "/nested-properties");
QCOMPARE(runQbs(), 0);
- QEXPECT_FAIL(0, "QBS-736", Abort);
QVERIFY2(m_qbsStdout.contains("value in higherlevel"), m_qbsStdout.constData());
}