diff options
author | Joerg Bornemann <joerg.bornemann@theqtcompany.com> | 2015-01-27 17:47:47 +0100 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@theqtcompany.com> | 2015-01-27 17:20:25 +0000 |
commit | d4010ce842360d0fa5ba67f8dcb3267aae49092c (patch) | |
tree | 58eb91e39477a5214da20524868c8160159c8a3e /src/lib/corelib/language | |
parent | 18ef8a2d82fd898be83bf2bc9a6f946d879ac14e (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.cpp | 41 | ||||
-rw-r--r-- | src/lib/corelib/language/evaluatorscriptclass.h | 2 | ||||
-rw-r--r-- | src/lib/corelib/language/testdata/modules/dummy/dummy.qbs | 1 | ||||
-rw-r--r-- | src/lib/corelib/language/tst_language.cpp | 4 | ||||
-rw-r--r-- | src/lib/corelib/language/value.h | 1 |
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); |