summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@digia.com>2013-04-09 11:47:19 +0200
committerChristian Kandeler <christian.kandeler@digia.com>2013-04-10 12:30:23 +0200
commit66068863ca647c5216b0fb7ee8ce933ef6aea077 (patch)
tree26be59e5c747c4dcabecc5aec4c4de79227bb82b
parent35710e2ebe7e3f0a2ada05bedb0868ed2edda14f (diff)
downloadqbs-66068863ca647c5216b0fb7ee8ce933ef6aea077.tar.gz
fix scope of own properties of module instances
Own properties of module instances must not have the instance itself in the scope. This fixes the following case: Product { name: "foo" Depends { name: "cpp" } cpp.defines: [name.toUpperCase()] // expected result: ["FOO"] } Task-number: QBS-252 Change-Id: Iac3d7153918132d01aec980a19502e9817f5e31d Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
-rw-r--r--src/lib/language/evaluatorscriptclass.cpp19
-rw-r--r--src/lib/language/evaluatorscriptclass.h3
-rw-r--r--src/lib/language/item.cpp1
-rw-r--r--src/lib/language/item.h13
-rw-r--r--src/lib/language/moduleloader.cpp1
-rw-r--r--src/lib/language/tst_language.cpp1
6 files changed, 31 insertions, 7 deletions
diff --git a/src/lib/language/evaluatorscriptclass.cpp b/src/lib/language/evaluatorscriptclass.cpp
index 8404e5384..95c3df1da 100644
--- a/src/lib/language/evaluatorscriptclass.cpp
+++ b/src/lib/language/evaluatorscriptclass.cpp
@@ -50,6 +50,7 @@ class SVConverter : ValueHandler
QScriptContext *const scriptContext;
const QScriptValue *object;
const ValuePtr &valuePtr;
+ const bool inPrototype;
char pushedScopesCount;
public:
@@ -57,12 +58,14 @@ public:
const EvaluationData *data;
QScriptValue *result;
- SVConverter(EvaluatorScriptClass *esc, const QScriptValue *obj, const ValuePtr &v)
+ SVConverter(EvaluatorScriptClass *esc, const QScriptValue *obj, const ValuePtr &v,
+ bool _inPrototype)
: scriptClass(esc)
, engine(esc->engine())
, scriptContext(esc->engine()->currentContext())
, object(obj)
, valuePtr(v)
+ , inPrototype(_inPrototype)
, pushedScopesCount(0)
{
}
@@ -157,7 +160,7 @@ private:
if (value->sourceUsesBase()) {
QScriptValue baseValue;
if (value->baseValue()) {
- SVConverter converter(scriptClass, object, value->baseValue());
+ SVConverter converter(scriptClass, object, value->baseValue(), inPrototype);
converter.propertyName = propertyName;
converter.data = data;
converter.result = &baseValue;
@@ -171,11 +174,13 @@ private:
pushScope(data->evaluator->fileScope(value->file()));
pushItemScopes(data->item);
- scriptContext->pushScope(*object);
+ if (inPrototype || !data->item->isModuleInstance()) {
+ // Own properties of module instances must not have the instance itself in the scope.
+ pushScope(*object);
+ }
pushScope(extraScope);
*result = engine->evaluate(value->sourceCode());
popScopes();
- scriptContext->popScope();
}
void handle(ItemValue *value)
@@ -255,6 +260,8 @@ QScriptClass::QueryFlags EvaluatorScriptClass::queryItemProperty(const Evaluatio
m_queryResult.value = item->properties().value(name);
if (!m_queryResult.value.isNull()) {
m_queryResult.data = data;
+ if (data->item != item)
+ m_queryResult.inPrototype = true;
return HandlesReadAccess;
}
}
@@ -297,7 +304,9 @@ QScriptValue EvaluatorScriptClass::property(const QScriptValue &object, const QS
uint id)
{
const EvaluationData *data = m_queryResult.data;
+ const bool inPrototype = m_queryResult.inPrototype;
m_queryResult.data = 0;
+ m_queryResult.inPrototype = false;
QBS_ASSERT(data, return QScriptValue());
const QueryPropertyType qpt = static_cast<QueryPropertyType>(id);
@@ -321,7 +330,7 @@ QScriptValue EvaluatorScriptClass::property(const QScriptValue &object, const QS
return result;
}
- SVConverter converter(this, &object, value);
+ SVConverter converter(this, &object, value, inPrototype);
converter.propertyName = &name;
converter.data = data;
converter.result = &result;
diff --git a/src/lib/language/evaluatorscriptclass.h b/src/lib/language/evaluatorscriptclass.h
index cfbabefa3..60da663d7 100644
--- a/src/lib/language/evaluatorscriptclass.h
+++ b/src/lib/language/evaluatorscriptclass.h
@@ -70,7 +70,7 @@ private:
struct QueryResult
{
QueryResult()
- : data(0)
+ : data(0), inPrototype(false)
{}
bool isNull() const
@@ -79,6 +79,7 @@ private:
}
const EvaluationData *data;
+ bool inPrototype;
ValuePtr value;
};
QueryResult m_queryResult;
diff --git a/src/lib/language/item.cpp b/src/lib/language/item.cpp
index 1adc0a5c8..b0ec37db2 100644
--- a/src/lib/language/item.cpp
+++ b/src/lib/language/item.cpp
@@ -36,6 +36,7 @@ namespace Internal {
Item::Item()
: m_propertyObserver(0)
+ , m_moduleInstance(false)
{
}
diff --git a/src/lib/language/item.h b/src/lib/language/item.h
index cb1fcbe4e..233e5b1b7 100644
--- a/src/lib/language/item.h
+++ b/src/lib/language/item.h
@@ -72,6 +72,7 @@ public:
const CodeLocation &location() const;
const ItemPtr &prototype() const;
ItemPtr scope() const;
+ bool isModuleInstance() const;
WeakPointer<Item> outerItem() const;
WeakPointer<Item> parent() const;
const FileContextPtr file() const;
@@ -93,6 +94,7 @@ public:
void setPrototype(const ItemPtr &prototype);
void setFile(const FileContextPtr &file);
void setScope(const ItemPtr &item);
+ void setModuleInstanceFlag(bool b);
void setOuterItem(const ItemPtr &item);
void setChildren(const QList<ItemPtr> &children);
void setParent(const ItemPtr &item);
@@ -105,6 +107,7 @@ private:
CodeLocation m_location;
ItemPtr m_prototype;
ItemPtr m_scope;
+ bool m_moduleInstance;
WeakPointer<Item> m_outerItem;
WeakPointer<Item> m_parent;
QList<ItemPtr> m_children;
@@ -140,6 +143,11 @@ inline ItemPtr Item::scope() const
return m_scope;
}
+inline bool Item::isModuleInstance() const
+{
+ return m_moduleInstance;
+}
+
inline WeakPointer<Item> Item::outerItem() const
{
return m_outerItem;
@@ -202,6 +210,11 @@ inline void Item::setScope(const ItemPtr &item)
m_scope = item;
}
+inline void Item::setModuleInstanceFlag(bool b)
+{
+ m_moduleInstance = b;
+}
+
inline void Item::setOuterItem(const ItemPtr &item)
{
m_outerItem = item;
diff --git a/src/lib/language/moduleloader.cpp b/src/lib/language/moduleloader.cpp
index dc6655031..06a9fa59b 100644
--- a/src/lib/language/moduleloader.cpp
+++ b/src/lib/language/moduleloader.cpp
@@ -547,6 +547,7 @@ void ModuleLoader::instantiateModule(ProductContext *productContext, const ItemP
copyProperty(QLatin1String("project"), productContext->project->scope, moduleScope);
copyProperty(QLatin1String("product"), productContext->scope, moduleScope);
moduleInstance->setScope(moduleScope);
+ moduleInstance->setModuleInstanceFlag(true);
QHash<ItemPtr, ItemPtr> prototypeInstanceMap;
prototypeInstanceMap[modulePrototype] = moduleInstance;
diff --git a/src/lib/language/tst_language.cpp b/src/lib/language/tst_language.cpp
index 4f34683bb..df7adb986 100644
--- a/src/lib/language/tst_language.cpp
+++ b/src/lib/language/tst_language.cpp
@@ -637,7 +637,6 @@ void TestLanguage::moduleScope()
QCOMPARE(ipf.intValue("d"), 2); // genuine, dependent on genuine value
QCOMPARE(ipf.intValue("e"), 1); // genuine
QCOMPARE(ipf.intValue("f"), 2); // overridden
- QEXPECT_FAIL("", "QBS-252", Abort);
QCOMPARE(ipf.intValue("g"), 156); // overridden, dependent on product properties
QCOMPARE(ipf.intValue("h"), 158); // overridden, base dependent on product properties
}