aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/language
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@theqtcompany.com>2015-01-27 17:47:47 +0100
committerJoerg Bornemann <joerg.bornemann@theqtcompany.com>2015-01-27 17:20:25 +0000
commitd4010ce842360d0fa5ba67f8dcb3267aae49092c (patch)
tree58eb91e39477a5214da20524868c8160159c8a3e /src/lib/corelib/language
parent18ef8a2d82fd898be83bf2bc9a6f946d879ac14e (diff)
fix caching for properties transitively dependent on product
Let there be property A using the product identifier on the right hand side. Let there be property B using A on the rhs. B must also be considered as dependent on product. Change-Id: I237ce7103e0707f6a1bc99bc0195ec714da04116 Task-number: QBS-729 Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
Diffstat (limited to 'src/lib/corelib/language')
-rw-r--r--src/lib/corelib/language/evaluatorscriptclass.cpp41
-rw-r--r--src/lib/corelib/language/evaluatorscriptclass.h2
-rw-r--r--src/lib/corelib/language/testdata/modules/dummy/dummy.qbs1
-rw-r--r--src/lib/corelib/language/tst_language.cpp4
-rw-r--r--src/lib/corelib/language/value.h1
5 files changed, 46 insertions, 3 deletions
diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp
index 4ca5e30be..800678628 100644
--- a/src/lib/corelib/language/evaluatorscriptclass.cpp
+++ b/src/lib/corelib/language/evaluatorscriptclass.cpp
@@ -50,6 +50,29 @@
namespace qbs {
namespace Internal {
+template <class T>
+class ScopedPopper
+{
+ QStack<T> *m_stack;
+ bool m_mustPop;
+public:
+ ScopedPopper(QStack<T> *s)
+ : m_stack(s), m_mustPop(false)
+ {
+ }
+
+ ~ScopedPopper()
+ {
+ if (m_mustPop)
+ m_stack->pop();
+ }
+
+ void mustPop()
+ {
+ m_mustPop = true;
+ }
+};
+
class SVConverter : ValueHandler
{
EvaluatorScriptClass *const scriptClass;
@@ -58,6 +81,7 @@ class SVConverter : ValueHandler
const QScriptValue *object;
const ValuePtr &valuePtr;
const Item * const itemOfProperty;
+ QStack<JSSourceValue *> * const sourceValueStack;
char pushedScopesCount;
public:
@@ -66,13 +90,14 @@ public:
QScriptValue *result;
SVConverter(EvaluatorScriptClass *esc, const QScriptValue *obj, const ValuePtr &v,
- const Item *_itemOfProperty)
+ const Item *_itemOfProperty, QStack<JSSourceValue *> *sourceValueStack)
: scriptClass(esc)
, engine(static_cast<ScriptEngine *>(esc->engine()))
, scriptContext(esc->engine()->currentContext())
, object(obj)
, valuePtr(v)
, itemOfProperty(_itemOfProperty)
+ , sourceValueStack(sourceValueStack)
, pushedScopesCount(0)
{
}
@@ -122,6 +147,15 @@ private:
void handle(JSSourceValue *value)
{
+ ScopedPopper<JSSourceValue *> popper(sourceValueStack);
+ if (value->sourceUsesProduct()) {
+ foreach (JSSourceValue *a, *sourceValueStack)
+ a->setSourceUsesProductFlag();
+ } else {
+ sourceValueStack->push(value);
+ popper.mustPop();
+ }
+
const Item *conditionScopeItem = 0;
QScriptValue conditionScope;
QScriptValue conditionFileScope;
@@ -196,7 +230,8 @@ private:
if (value->sourceUsesBase()) {
QScriptValue baseValue;
if (value->baseValue()) {
- SVConverter converter(scriptClass, object, value->baseValue(), itemOfProperty);
+ SVConverter converter(scriptClass, object, value->baseValue(), itemOfProperty,
+ sourceValueStack);
converter.propertyName = propertyName;
converter.data = data;
converter.result = &baseValue;
@@ -405,7 +440,7 @@ QScriptValue EvaluatorScriptClass::property(const QScriptValue &object, const QS
}
}
- SVConverter converter(this, &object, value, itemOfProperty);
+ SVConverter converter(this, &object, value, itemOfProperty, &m_sourceValueStack);
converter.propertyName = &name;
converter.data = data;
converter.result = &result;
diff --git a/src/lib/corelib/language/evaluatorscriptclass.h b/src/lib/corelib/language/evaluatorscriptclass.h
index 7e414e47d..46d3a3b42 100644
--- a/src/lib/corelib/language/evaluatorscriptclass.h
+++ b/src/lib/corelib/language/evaluatorscriptclass.h
@@ -36,6 +36,7 @@
#include <logging/logger.h>
#include <QScriptClass>
+#include <QStack>
QT_BEGIN_NAMESPACE
class QScriptContext;
@@ -93,6 +94,7 @@ private:
QScriptValue m_getEnvBuiltin;
QScriptValue m_getHostOSBuiltin;
QScriptValue m_canonicalArchitectureBuiltin;
+ QStack<JSSourceValue *> m_sourceValueStack;
};
} // namespace Internal
diff --git a/src/lib/corelib/language/testdata/modules/dummy/dummy.qbs b/src/lib/corelib/language/testdata/modules/dummy/dummy.qbs
index 6f96f9a99..67bd3bd0d 100644
--- a/src/lib/corelib/language/testdata/modules/dummy/dummy.qbs
+++ b/src/lib/corelib/language/testdata/modules/dummy/dummy.qbs
@@ -7,5 +7,6 @@ DummyBase {
property stringList cxxFlags
property string someString
property string productName: product.name
+ property string upperCaseProductName: productName.toUpperCase()
property string zort: "zort in dummy"
}
diff --git a/src/lib/corelib/language/tst_language.cpp b/src/lib/corelib/language/tst_language.cpp
index 44a2389a7..d50592e03 100644
--- a/src/lib/corelib/language/tst_language.cpp
+++ b/src/lib/corelib/language/tst_language.cpp
@@ -456,12 +456,16 @@ void TestLanguage::exports()
QCOMPARE(propertyValue.toStringList(), QStringList() << "ABC");
QCOMPARE(PropertyFinder().propertyValue(product->moduleProperties->value(), "dummy",
"productName").toString(), QString("myapp2"));
+ QCOMPARE(PropertyFinder().propertyValue(product->moduleProperties->value(), "dummy",
+ "upperCaseProductName").toString(), QString("MYAPP2"));
// Check whether we're returning incorrect cached values.
product = products.value("myapp3");
QVERIFY(product);
QCOMPARE(PropertyFinder().propertyValue(product->moduleProperties->value(), "dummy",
"productName").toString(), QString("myapp3"));
+ QCOMPARE(PropertyFinder().propertyValue(product->moduleProperties->value(), "dummy",
+ "upperCaseProductName").toString(), QString("MYAPP3"));
}
catch (const ErrorInfo &e) {
exceptionCaught = true;
diff --git a/src/lib/corelib/language/value.h b/src/lib/corelib/language/value.h
index ea3cd497e..3891a2804 100644
--- a/src/lib/corelib/language/value.h
+++ b/src/lib/corelib/language/value.h
@@ -109,6 +109,7 @@ public:
bool sourceUsesBase() const { return m_flags.testFlag(SourceUsesBase); }
bool sourceUsesOuter() const { return m_flags.testFlag(SourceUsesOuter); }
+ void setSourceUsesProductFlag() { m_flags |= SourceUsesProduct; }
bool sourceUsesProduct() const { return m_flags.testFlag(SourceUsesProduct); }
bool hasFunctionForm() const { return m_flags.testFlag(HasFunctionForm); }
void setHasFunctionForm(bool b);