aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@digia.com>2014-06-12 15:37:35 +0200
committerChristian Kandeler <christian.kandeler@digia.com>2014-06-16 13:49:52 +0200
commita5c93306557cfd69f6e6d7181eb4c7d884af4d41 (patch)
treebbc5f048b072c26864816678bb479afb142f04eb
parent2152a18c38520b1e9c54baa236faddda35a937ef (diff)
fix scope chain of conditions of Properties items
Conditions of Properties items that were used to set non-module properties were evaluated in the wrong scope. Task-number: QBS-613 Change-Id: Ia28070c4352bcca4c153f3cdfb3b66586ea5f3e5 Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
-rw-r--r--src/lib/corelib/language/evaluatorscriptclass.cpp32
-rw-r--r--src/lib/corelib/language/testdata/propertiesblocks.qbs4
-rw-r--r--src/lib/corelib/language/tst_language.cpp73
3 files changed, 88 insertions, 21 deletions
diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp
index a5f03b81c..8fcd785eb 100644
--- a/src/lib/corelib/language/evaluatorscriptclass.cpp
+++ b/src/lib/corelib/language/evaluatorscriptclass.cpp
@@ -128,9 +128,35 @@ private:
const JSSourceValue::Alternative *alternative = 0;
alternative = &value->alternatives().at(i);
if (!conditionScopeItem) {
- conditionScopeItem = data->item->scope();
- if (!conditionScopeItem)
- conditionScopeItem = data->item;
+ // We have to differentiate between module instances and normal items here.
+ //
+ // The module instance case:
+ // Product {
+ // property bool something: true
+ // Properties {
+ // condition: something
+ // cpp.defines: ["ABC"]
+ // }
+ // }
+ //
+ // data->item points to cpp and the condition's scope chain must contain cpp's
+ // scope, which is the item where cpp is instantiated. The scope chain must not
+ // contain data->item itself.
+ //
+ // The normal item case:
+ // Product {
+ // property bool something: true
+ // property string value: "ABC"
+ // Properties {
+ // condition: something
+ // value: "DEF"
+ // }
+ // }
+ //
+ // data->item points to the product and the condition's scope chain must contain
+ // the product item.
+ conditionScopeItem = data->item->isModuleInstance()
+ ? data->item->scope() : data->item;
conditionScope = data->evaluator->scriptValue(conditionScopeItem);
QBS_ASSERT(conditionScope.isObject(), return);
conditionFileScope = data->evaluator->fileScope(conditionScopeItem->file());
diff --git a/src/lib/corelib/language/testdata/propertiesblocks.qbs b/src/lib/corelib/language/testdata/propertiesblocks.qbs
index d61f0dd86..2480e9e7b 100644
--- a/src/lib/corelib/language/testdata/propertiesblocks.qbs
+++ b/src/lib/corelib/language/testdata/propertiesblocks.qbs
@@ -86,19 +86,23 @@ Project {
Product {
name: "condition_refers_to_product_property"
property string narf: true
+ property string someString: "SOMETHING"
Depends { name: "dummy" }
Properties {
condition: narf
dummy.defines: ["OVERWRITTEN"]
+ someString: "OVERWRITTEN"
}
}
property string zort: true
Product {
name: "condition_refers_to_project_property"
+ property string someString: "SOMETHING"
Depends { name: "dummy" }
Properties {
condition: project.zort
dummy.defines: ["OVERWRITTEN"]
+ someString: "OVERWRITTEN"
}
}
ProductBase {
diff --git a/src/lib/corelib/language/tst_language.cpp b/src/lib/corelib/language/tst_language.cpp
index ff19b8afe..eb77a2df1 100644
--- a/src/lib/corelib/language/tst_language.cpp
+++ b/src/lib/corelib/language/tst_language.cpp
@@ -1127,45 +1127,77 @@ void TestLanguage::propertiesBlocks_data()
{
QTest::addColumn<QString>("propertyName");
QTest::addColumn<QStringList>("expectedValues");
+ QTest::addColumn<QString>("expectedStringValue");
- QTest::newRow("init") << QString() << QStringList();
- QTest::newRow("property_overwrite") << QString("dummy.defines") << QStringList("OVERWRITTEN");
- QTest::newRow("property_overwrite_no_outer") << QString("dummy.defines") << QStringList("OVERWRITTEN");
- QTest::newRow("property_append_to_outer") << QString("dummy.defines") << (QStringList() << QString("ONE") << QString("TWO"));
+ QTest::newRow("init") << QString() << QStringList() << QString();
+ QTest::newRow("property_overwrite")
+ << QString("dummy.defines")
+ << QStringList("OVERWRITTEN")
+ << QString();
+ QTest::newRow("property_overwrite_no_outer")
+ << QString("dummy.defines")
+ << QStringList("OVERWRITTEN")
+ << QString();
+ QTest::newRow("property_append_to_outer")
+ << QString("dummy.defines")
+ << (QStringList() << QString("ONE") << QString("TWO"))
+ << QString();
+
+ QTest::newRow("multiple_exclusive_properties")
+ << QString("dummy.defines")
+ << QStringList("OVERWRITTEN")
+ << QString();
+ QTest::newRow("multiple_exclusive_properties_no_outer")
+ << QString("dummy.defines")
+ << QStringList("OVERWRITTEN")
+ << QString();
+ QTest::newRow("multiple_exclusive_properties_append_to_outer")
+ << QString("dummy.defines")
+ << (QStringList() << QString("ONE") << QString("TWO"))
+ << QString();
- QTest::newRow("multiple_exclusive_properties") << QString("dummy.defines") << QStringList("OVERWRITTEN");
- QTest::newRow("multiple_exclusive_properties_no_outer") << QString("dummy.defines") << QStringList("OVERWRITTEN");
- QTest::newRow("multiple_exclusive_properties_append_to_outer") << QString("dummy.defines") << (QStringList() << QString("ONE") << QString("TWO"));
QTest::newRow("condition_refers_to_product_property")
- << QString("dummy.defines") << QStringList("OVERWRITTEN");
+ << QString("dummy.defines")
+ << QStringList("OVERWRITTEN")
+ << QString("OVERWRITTEN");
QTest::newRow("condition_refers_to_project_property")
- << QString("dummy.defines") << QStringList("OVERWRITTEN");
+ << QString("dummy.defines")
+ << QStringList("OVERWRITTEN")
+ << QString("OVERWRITTEN");
QTest::newRow("ambiguous_properties")
<< QString("dummy.defines")
- << (QStringList() << QString("ONE") << QString("TWO"));
+ << (QStringList() << QString("ONE") << QString("TWO"))
+ << QString();
QTest::newRow("inheritance_overwrite_in_subitem")
<< QString("dummy.defines")
- << (QStringList() << QString("OVERWRITTEN_IN_SUBITEM"));
+ << (QStringList() << QString("OVERWRITTEN_IN_SUBITEM"))
+ << QString();
QTest::newRow("inheritance_retain_base1")
<< QString("dummy.defines")
- << (QStringList() << QString("BASE") << QString("SUB"));
+ << (QStringList() << QString("BASE") << QString("SUB"))
+ << QString();
QTest::newRow("inheritance_retain_base2")
<< QString("dummy.defines")
- << (QStringList() << QString("BASE") << QString("SUB"));
+ << (QStringList() << QString("BASE") << QString("SUB"))
+ << QString();
QTest::newRow("inheritance_retain_base3")
<< QString("dummy.defines")
- << (QStringList() << QString("BASE") << QString("SUB"));
+ << (QStringList() << QString("BASE") << QString("SUB"))
+ << QString();
QTest::newRow("inheritance_condition_in_subitem1")
<< QString("dummy.defines")
- << (QStringList() << QString("SOMETHING") << QString("SUB"));
+ << (QStringList() << QString("SOMETHING") << QString("SUB"))
+ << QString();
QTest::newRow("inheritance_condition_in_subitem2")
<< QString("dummy.defines")
- << (QStringList() << QString("SOMETHING"));
+ << (QStringList() << QString("SOMETHING"))
+ << QString();
QTest::newRow("condition_references_id")
<< QString("dummy.defines")
- << (QStringList() << QString("OVERWRITTEN"));
- QTest::newRow("cleanup") << QString() << QStringList();
+ << (QStringList() << QString("OVERWRITTEN"))
+ << QString();
+ QTest::newRow("cleanup") << QString() << QStringList() << QString();
}
void TestLanguage::propertiesBlocks()
@@ -1173,6 +1205,7 @@ void TestLanguage::propertiesBlocks()
HANDLE_INIT_CLEANUP_DATATAGS("propertiesblocks.qbs");
QFETCH(QString, propertyName);
QFETCH(QStringList, expectedValues);
+ QFETCH(QString, expectedStringValue);
QVERIFY(project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
const QString productName = QString::fromLocal8Bit(QTest::currentDataTag());
@@ -1181,6 +1214,10 @@ void TestLanguage::propertiesBlocks()
QCOMPARE(product->name, productName);
QVariant v = productPropertyValue(product, propertyName);
QCOMPARE(v.toStringList(), expectedValues);
+ if (!expectedStringValue.isEmpty()) {
+ v = productPropertyValue(product, "someString");
+ QCOMPARE(v.toString(), expectedStringValue);
+ }
}
void TestLanguage::fileTags_data()