Commit 0f6551c4 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Introduced ASTObjectValue.

parent 0cf48cb4
......@@ -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;
}
......
......@@ -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))
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment