aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorRoberto Raggi <[email protected]>2010-02-01 13:54:44 +0100
committerRoberto Raggi <[email protected]>2010-02-01 13:54:59 +0100
commit0f6551c43f12512ecd57242bead784f67d2a3fab (patch)
tree58a584f85f45d9243152ee5e67be38adb9c64a67 /src/libs
parent0cf48cb45d3816f231f5f7dd24225e77ef1603d7 (diff)
Introduced ASTObjectValue.
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/qmljs/qmljsbind.cpp34
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp139
-rw-r--r--src/libs/qmljs/qmljsinterpreter.h4
3 files changed, 131 insertions, 46 deletions
diff --git a/src/libs/qmljs/qmljsbind.cpp b/src/libs/qmljs/qmljsbind.cpp
index 94889f637fd..a5d61af7969 100644
--- a/src/libs/qmljs/qmljsbind.cpp
+++ b/src/libs/qmljs/qmljsbind.cpp
@@ -39,6 +39,36 @@ using namespace QmlJS::Interpreter;
namespace {
+class ASTObjectValue: public ObjectValue
+{
+ UiQualifiedId *_typeName;
+ UiObjectInitializer *_initializer;
+
+public:
+ ASTObjectValue(UiQualifiedId *typeName, UiObjectInitializer *initializer, Interpreter::Engine *engine)
+ : ObjectValue(engine), _typeName(typeName), _initializer(initializer)
+ {
+ }
+
+ virtual void processMembers(MemberProcessor *processor) const
+ {
+ if (_initializer) {
+ for (UiObjectMemberList *it = _initializer->members; it; it = it->next) {
+ UiObjectMember *member = it->member;
+ if (UiPublicMember *def = cast<UiPublicMember *>(member)) {
+ if (def->name && def->memberType) {
+ const QString propName = def->name->asString();
+ const QString propType = def->memberType->asString();
+
+ processor->processProperty(propName, engine()->defaultValueForBuiltinType(propType));
+ }
+ }
+ }
+ }
+ ObjectValue::processMembers(processor);
+ }
+};
+
class ASTFunctionValue: public FunctionValue
{
FunctionDeclaration *_ast;
@@ -175,7 +205,7 @@ ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitia
// Script blocks all contribute to the same scope
parentObjectValue = switchObjectValue(_functionEnvironment);
} else { // normal component instance
- ObjectValue *objectValue = _interp->newObject(/*prototype =*/0);
+ ASTObjectValue *objectValue = new ASTObjectValue(qualifiedTypeNameId, initializer, _interp);
parentObjectValue = switchObjectValue(objectValue);
if (parentObjectValue)
objectValue->setProperty("parent", parentObjectValue);
@@ -257,12 +287,14 @@ bool Bind::visit(UiImport *ast)
bool Bind::visit(UiPublicMember *ast)
{
+#if 0
if (_currentObjectValue && ast->name && ast->memberType) {
const QString propName = ast->name->asString();
const QString propType = ast->memberType->asString();
_currentObjectValue->setProperty(propName, _interp->defaultValueForBuiltinType(propType));
}
+#endif
return false;
}
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 4b101bc5cb1..9767de7c08c 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -43,8 +43,64 @@
using namespace QmlJS::Interpreter;
+namespace {
+
+class LookupMember: public MemberProcessor
+{
+ QString _name;
+ const Value *_value;
+
+ bool process(const QString &name, const Value *value)
+ {
+ if (_value)
+ return false;
+
+ if (name == _name) {
+ _value = value;
+ return false;
+ }
+
+ return true;
+ }
+
+public:
+ LookupMember(const QString &name)
+ : _name(name), _value(0) {}
+
+ const Value *value() const { return _value; }
+
+ virtual bool processProperty(const QString &name, const Value *value)
+ {
+ return process(name, value);
+ }
+
+ virtual bool processEnumerator(const QString &name, const Value *value)
+ {
+ return process(name, value);
+ }
+
+ virtual bool processSignal(const QString &name, const Value *value)
+ {
+ return process(name, value);
+ }
+
+ virtual bool processSlot(const QString &name, const Value *value)
+ {
+ return process(name, value);
+ }
+
+ virtual bool processGeneratedSlot(const QString &name, const Value *value)
+ {
+ return process(name, value);
+ }
+};
+
+} // end of anonymous namespace
+
#ifndef NO_DECLARATIVE_BACKEND
+namespace {
+
class MetaFunction: public FunctionValue
{
QMetaMethod _method;
@@ -89,6 +145,8 @@ public:
}
};
+} // end of anonymous namespace
+
QmlObjectValue::QmlObjectValue(const QMetaObject *metaObject, const QString &qmlTypeName,
int majorVersion, int minorVersion, Engine *engine)
: ObjectValue(engine),
@@ -104,46 +162,29 @@ QmlObjectValue::~QmlObjectValue() {}
const Value *QmlObjectValue::lookupMember(const QString &name) const
{
- for (int index = 0; index < _metaObject->propertyCount(); ++index) {
- QMetaProperty prop = _metaObject->property(index);
-
- if (name == QString::fromUtf8(prop.name()))
- return propertyValue(prop);
- }
-
- for (int index = 0; index < _metaObject->methodCount(); ++index) {
- QMetaMethod method = _metaObject->method(index);
-
- const QString signature = QString::fromUtf8(method.signature());
-
- const int indexOfParen = signature.indexOf(QLatin1Char('('));
- if (indexOfParen == -1)
- continue; // skip it, invalid signature.
-
- const QString methodName = signature.left(indexOfParen);
+ return ObjectValue::lookupMember(name);
+}
- if (methodName != name) {
- continue;
+const Value *QmlObjectValue::findOrCreateSignature(int index, const QMetaMethod &method, QString *methodName) const
+{
+ const QString signature = QString::fromUtf8(method.signature());
- } else if (method.methodType() == QMetaMethod::Slot && method.access() == QMetaMethod::Public) {
- return new MetaFunction(method, engine());
+ const int indexOfParen = signature.indexOf(QLatin1Char('('));
+ if (indexOfParen == -1)
+ return engine()->undefinedValue(); // skip it, invalid signature.
- } else if (method.methodType() == QMetaMethod::Signal && method.access() != QMetaMethod::Private) {
- return new MetaFunction(method, engine());
- }
+ *methodName = signature.left(indexOfParen);
+ const Value *value = _metaSignature.value(index);
+ if (! value) {
+ value = new MetaFunction(method, engine());
+ _metaSignature.insert(index, value);
}
-
- return ObjectValue::lookupMember(name);
+ return value;
}
void QmlObjectValue::processMembers(MemberProcessor *processor) const
{
- for (int index = 0; index < _metaObject->propertyCount(); ++index) {
- QMetaProperty prop = _metaObject->property(index);
-
- processor->processProperty(prop.name(), propertyValue(prop));
- }
-
+ // process the meta enums
for (int index = _metaObject->enumeratorOffset(); index < _metaObject->propertyCount(); ++index) {
QMetaEnum e = _metaObject->enumerator(index);
@@ -152,23 +193,25 @@ void QmlObjectValue::processMembers(MemberProcessor *processor) const
}
}
- for (int index = 0; index < _metaObject->methodCount(); ++index) {
- QMetaMethod method = _metaObject->method(index);
-
- const QString signature = QString::fromUtf8(method.signature());
+ // process the meta properties
+ for (int index = 0; index < _metaObject->propertyCount(); ++index) {
+ QMetaProperty prop = _metaObject->property(index);
- const int indexOfParen = signature.indexOf(QLatin1Char('('));
- if (indexOfParen == -1)
- continue; // skip it, invalid signature.
+ processor->processProperty(prop.name(), propertyValue(prop));
+ }
- const QString methodName = signature.left(indexOfParen);
+ // process the meta methods
+ for (int index = 0; index < _metaObject->methodCount(); ++index) {
+ QMetaMethod method = _metaObject->method(index);
+ QString methodName;
+ const Value *signature = findOrCreateSignature(index, method, &methodName);
if (method.methodType() == QMetaMethod::Slot && method.access() == QMetaMethod::Public) {
- processor->processSlot(methodName, engine()->undefinedValue());
+ processor->processSlot(methodName, signature);
} else if (method.methodType() == QMetaMethod::Signal && method.access() != QMetaMethod::Private) {
// process the signal
- processor->processSignal(methodName, engine()->undefinedValue());
+ processor->processSignal(methodName, signature);
QString slotName;
slotName += QLatin1String("on");
@@ -176,7 +219,7 @@ void QmlObjectValue::processMembers(MemberProcessor *processor) const
slotName += methodName.midRef(1);
// process the generated slot
- processor->processGeneratedSlot(slotName, engine()->undefinedValue());
+ processor->processGeneratedSlot(slotName, signature);
}
}
@@ -599,8 +642,8 @@ const Value *Environment::lookup(const QString &name) const
return 0;
}
-const Value *Environment::lookupMember(const QString &name) const {
- Q_UNUSED(name);
+const Value *Environment::lookupMember(const QString &) const
+{
return 0;
}
@@ -806,6 +849,12 @@ const Value *ObjectValue::lookupMember(const QString &name) const
{
if (const Value *m = _members.value(name))
return m;
+ else {
+ LookupMember slowLookup(name);
+ processMembers(&slowLookup);
+ if (slowLookup.value())
+ return slowLookup.value();
+ }
if (_prototype) {
if (const Value *m = _prototype->lookup(name))
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 54251a87ff3..ba4b7606560 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -273,11 +273,15 @@ public:
int minorVersion() const
{ return _minorVersion; }
+protected:
+ const Value *findOrCreateSignature(int index, const QMetaMethod &method, QString *methodName) const;
+
private:
const QMetaObject *_metaObject;
QString _qmlTypeName;
int _majorVersion;
int _minorVersion;
+ mutable QHash<int, const Value *> _metaSignature;
};
#endif // !NO_DECLARATIVE_BACKEND