aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/qmljs/qmljsinterpreter.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <[email protected]>2010-01-26 14:50:52 +0100
committerErik Verbruggen <[email protected]>2010-01-26 15:20:18 +0100
commitcf35a0249b91e9d52391a374ef08f52bdf2f92c0 (patch)
tree1aa40858e161638fb9ce81d28040550d7085f75f /src/libs/qmljs/qmljsinterpreter.cpp
parent5d272795cfdcd0711ba413e13f68a9b2bce2cb48 (diff)
Implemented the binding phase for QML.
Done-with: Christian Kamm
Diffstat (limited to 'src/libs/qmljs/qmljsinterpreter.cpp')
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp293
1 files changed, 149 insertions, 144 deletions
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 4d664ee8cc9..1389d4d01d7 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -43,8 +43,6 @@
using namespace QmlJS::Interpreter;
-namespace {
-
#ifndef NO_DECLARATIVE_BACKEND
class QmlAttachedKeys: public ObjectValue
@@ -166,93 +164,102 @@ public:
}
};
-class QmlObjectValue: public ObjectValue
-{
-public:
- QmlObjectValue(const QMetaObject *metaObject, Engine *engine)
- : ObjectValue(engine), _metaObject(metaObject)
- {
- }
+QmlObjectValue::QmlObjectValue(const QMetaObject *metaObject, const QString &qmlTypeName, int majorVersion, int minorVersion, Engine *engine)
+ : ObjectValue(engine), _metaObject(metaObject), _qmlTypeName(qmlTypeName), _majorVersion(majorVersion), _minorVersion(minorVersion)
+{}
- virtual ~QmlObjectValue() {}
+QmlObjectValue::~QmlObjectValue() {}
- virtual const Value *lookupMember(const QString &name) const
- {
- for (int index = 0; index < _metaObject->propertyCount(); ++index) {
- QMetaProperty prop = _metaObject->property(index);
+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);
- }
+ if (name == QString::fromUtf8(prop.name()))
+ return propertyValue(prop);
+ }
- for (int index = 0; index < _metaObject->methodCount(); ++index) {
- QMetaMethod method = _metaObject->method(index);
+ for (int index = 0; index < _metaObject->methodCount(); ++index) {
+ QMetaMethod method = _metaObject->method(index);
- const QString signature = QString::fromUtf8(method.signature());
+ const QString signature = QString::fromUtf8(method.signature());
- const int indexOfParen = signature.indexOf(QLatin1Char('('));
- if (indexOfParen == -1)
- continue; // skip it, invalid signature.
+ const int indexOfParen = signature.indexOf(QLatin1Char('('));
+ if (indexOfParen == -1)
+ continue; // skip it, invalid signature.
- const QString methodName = signature.left(indexOfParen);
+ const QString methodName = signature.left(indexOfParen);
- if (methodName != name) {
- continue;
+ if (methodName != name) {
+ continue;
- } else if (method.methodType() == QMetaMethod::Slot && method.access() == QMetaMethod::Public) {
- return new MetaFunction(method, engine());
+ } else if (method.methodType() == QMetaMethod::Slot && method.access() == QMetaMethod::Public) {
+ return new MetaFunction(method, engine());
- } else if (method.methodType() == QMetaMethod::Signal && method.access() != QMetaMethod::Private) {
- return new MetaFunction(method, engine());
- }
+ } else if (method.methodType() == QMetaMethod::Signal && method.access() != QMetaMethod::Private) {
+ return new MetaFunction(method, engine());
}
-
- return ObjectValue::lookupMember(name);
}
- virtual void processMembers(MemberProcessor *processor) const
- {
- for (int index = 0; index < _metaObject->propertyCount(); ++index) {
- QMetaProperty prop = _metaObject->property(index);
+ return ObjectValue::lookupMember(name);
+}
- processor->processProperty(prop.name(), propertyValue(prop));
- }
+void QmlObjectValue::processMembers(MemberProcessor *processor) const
+{
+ for (int index = 0; index < _metaObject->propertyCount(); ++index) {
+ QMetaProperty prop = _metaObject->property(index);
- for (int index = 0; index < _metaObject->methodCount(); ++index) {
- QMetaMethod method = _metaObject->method(index);
+ processor->processProperty(prop.name(), propertyValue(prop));
+ }
- const QString signature = QString::fromUtf8(method.signature());
+ for (int index = 0; index < _metaObject->methodCount(); ++index) {
+ QMetaMethod method = _metaObject->method(index);
- const int indexOfParen = signature.indexOf(QLatin1Char('('));
- if (indexOfParen == -1)
- continue; // skip it, invalid signature.
+ const QString signature = QString::fromUtf8(method.signature());
- const QString methodName = signature.left(indexOfParen);
+ const int indexOfParen = signature.indexOf(QLatin1Char('('));
+ if (indexOfParen == -1)
+ continue; // skip it, invalid signature.
- if (method.methodType() == QMetaMethod::Slot && method.access() == QMetaMethod::Public) {
- processor->processSlot(methodName, engine()->undefinedValue());
+ const QString methodName = signature.left(indexOfParen);
- } else if (method.methodType() == QMetaMethod::Signal && method.access() != QMetaMethod::Private) {
- // process the signal
- processor->processSignal(methodName, engine()->undefinedValue());
+ if (method.methodType() == QMetaMethod::Slot && method.access() == QMetaMethod::Public) {
+ processor->processSlot(methodName, engine()->undefinedValue());
- QString slotName;
- slotName += QLatin1String("on");
- slotName += methodName.at(0).toUpper();
- slotName += methodName.midRef(1);
+ } else if (method.methodType() == QMetaMethod::Signal && method.access() != QMetaMethod::Private) {
+ // process the signal
+ processor->processSignal(methodName, engine()->undefinedValue());
- // process the generated slot
- processor->processGeneratedSlot(slotName, engine()->undefinedValue());
- }
- }
+ QString slotName;
+ slotName += QLatin1String("on");
+ slotName += methodName.at(0).toUpper();
+ slotName += methodName.midRef(1);
- ObjectValue::processMembers(processor);
+ // process the generated slot
+ processor->processGeneratedSlot(slotName, engine()->undefinedValue());
+ }
}
- const Value *propertyValue(const QMetaProperty &prop) const {
- const Value *value = engine()->undefinedValue();
+ ObjectValue::processMembers(processor);
+}
+
+const Value *QmlObjectValue::propertyValue(const QMetaProperty &prop) const
+{
+ if (QmlMetaType::isObject(prop.userType())) {
+ QmlType *qmlPropertyType = QmlMetaType::qmlType(QmlMetaType::metaObjectForType(prop.userType()));
- if (QmlMetaType::isObject(prop.userType())) {
+ if (qmlPropertyType && !qmlPropertyType->qmlTypeName().isEmpty()) {
+ QString typeName = qmlPropertyType->qmlTypeName();
+ int slashIdx = typeName.lastIndexOf(QLatin1Char('/'));
+ QString package;
+ if (slashIdx != -1) {
+ package = typeName.left(slashIdx);
+ typeName = typeName.mid(slashIdx + 1);
+ }
+
+ if (const ObjectValue *objectValue = engine()->newQmlObject(typeName, package, qmlPropertyType->majorVersion(), qmlPropertyType->minorVersion()))
+ return objectValue;
+ } else {
QString typeName = QString::fromUtf8(prop.typeName());
if (typeName.endsWith(QLatin1Char('*')))
@@ -260,78 +267,78 @@ public:
typeName.replace(QLatin1Char('.'), QLatin1Char('/'));
- if (const ObjectValue *objectValue = engine()->newQmlObject(typeName))
+ if (const ObjectValue *objectValue = engine()->newQmlObject(typeName, "", -1, -1)) // ### we should extend this to lookup the property types in the QmlType object, instead of the QMetaProperty.
return objectValue;
}
-
- switch (prop.type()) {
- case QMetaType::QByteArray:
- case QMetaType::QString:
- case QMetaType::QUrl:
- value = engine()->stringValue();
- break;
-
- case QMetaType::Bool:
- value = engine()->booleanValue();
- break;
-
- case QMetaType::Int:
- case QMetaType::Float:
- case QMetaType::Double:
- value = engine()->numberValue();
- break;
-
- case QMetaType::QFont: {
- // ### cache
- ObjectValue *object = engine()->newObject(/*prototype =*/ 0);
- object->setProperty("family", engine()->stringValue());
- object->setProperty("weight", engine()->undefinedValue()); // ### make me an object
- object->setProperty("copitalization", engine()->undefinedValue()); // ### make me an object
- object->setProperty("bold", engine()->booleanValue());
- object->setProperty("italic", engine()->booleanValue());
- object->setProperty("underline", engine()->booleanValue());
- object->setProperty("overline", engine()->booleanValue());
- object->setProperty("strikeout", engine()->booleanValue());
- object->setProperty("pointSize", engine()->numberValue());
- object->setProperty("pixelSize", engine()->numberValue());
- object->setProperty("letterSpacing", engine()->numberValue());
- object->setProperty("wordSpacing", engine()->numberValue());
- value = object;
- } break;
-
- case QMetaType::QPoint:
- case QMetaType::QPointF: {
- // ### cache
- ObjectValue *object = engine()->newObject(/*prototype =*/ 0);
- object->setProperty("x", engine()->numberValue());
- object->setProperty("y", engine()->numberValue());
- value = object;
- } break;
-
- case QMetaType::QRect:
- case QMetaType::QRectF: {
- // ### cache
- ObjectValue *object = engine()->newObject(/*prototype =*/ 0);
- object->setProperty("x", engine()->numberValue());
- object->setProperty("y", engine()->numberValue());
- object->setProperty("width", engine()->numberValue());
- object->setProperty("height", engine()->numberValue());
- value = object;
- } break;
-
- default:
- break;
- } // end of switch
-
- return value;
}
-private:
- const QMetaObject *_metaObject;
-};
-
+ const Value *value = engine()->undefinedValue();
+
+ switch (prop.type()) {
+ case QMetaType::QByteArray:
+ case QMetaType::QString:
+ case QMetaType::QUrl:
+ value = engine()->stringValue();
+ break;
+
+ case QMetaType::Bool:
+ value = engine()->booleanValue();
+ break;
+
+ case QMetaType::Int:
+ case QMetaType::Float:
+ case QMetaType::Double:
+ value = engine()->numberValue();
+ break;
+
+ case QMetaType::QFont: {
+ // ### cache
+ ObjectValue *object = engine()->newObject(/*prototype =*/ 0);
+ object->setProperty("family", engine()->stringValue());
+ object->setProperty("weight", engine()->undefinedValue()); // ### make me an object
+ object->setProperty("copitalization", engine()->undefinedValue()); // ### make me an object
+ object->setProperty("bold", engine()->booleanValue());
+ object->setProperty("italic", engine()->booleanValue());
+ object->setProperty("underline", engine()->booleanValue());
+ object->setProperty("overline", engine()->booleanValue());
+ object->setProperty("strikeout", engine()->booleanValue());
+ object->setProperty("pointSize", engine()->numberValue());
+ object->setProperty("pixelSize", engine()->numberValue());
+ object->setProperty("letterSpacing", engine()->numberValue());
+ object->setProperty("wordSpacing", engine()->numberValue());
+ value = object;
+ } break;
+
+ case QMetaType::QPoint:
+ case QMetaType::QPointF: {
+ // ### cache
+ ObjectValue *object = engine()->newObject(/*prototype =*/ 0);
+ object->setProperty("x", engine()->numberValue());
+ object->setProperty("y", engine()->numberValue());
+ value = object;
+ } break;
+
+ case QMetaType::QRect:
+ case QMetaType::QRectF: {
+ // ### cache
+ ObjectValue *object = engine()->newObject(/*prototype =*/ 0);
+ object->setProperty("x", engine()->numberValue());
+ object->setProperty("y", engine()->numberValue());
+ object->setProperty("width", engine()->numberValue());
+ object->setProperty("height", engine()->numberValue());
+ value = object;
+ } break;
+
+ default:
+ break;
+ } // end of switch
+
+ return value;
+}
#endif
+namespace {
+
////////////////////////////////////////////////////////////////////////////////
// constructors
////////////////////////////////////////////////////////////////////////////////
@@ -1300,8 +1307,9 @@ Engine::Engine()
_convertToString(this),
_convertToObject(this)
{
-
initializePrototypes();
+
+ _metaTypeSystem.reload(this);
}
Engine::~Engine()
@@ -1780,19 +1788,19 @@ const Value *Engine::defaultValueForBuiltinType(const QString &typeName) const
return undefinedValue();
}
-ObjectValue *Engine::newQmlObject(const QString &name)
-{
#ifndef NO_DECLARATIVE_BACKEND
+QmlObjectValue *Engine::newQmlObject(const QString &name, const QString &prefix, int majorVersion, int minorVersion)
+{
if (name == QLatin1String("QmlGraphicsAnchors")) {
- QmlObjectValue *object = new QmlObjectValue(&QmlGraphicsAnchors::staticMetaObject, this);
+ QmlObjectValue *object = new QmlObjectValue(&QmlGraphicsAnchors::staticMetaObject, QLatin1String("Anchors"), -1, -1, this);
_objects.append(object);
return object;
} else if (name == QLatin1String("QmlGraphicsPen")) {
- QmlObjectValue *object = new QmlObjectValue(&QmlGraphicsPen::staticMetaObject, this);
+ QmlObjectValue *object = new QmlObjectValue(&QmlGraphicsPen::staticMetaObject, QLatin1String("Pen"), -1, -1, this);
_objects.append(object);
return object;
} else if (name == QLatin1String("QmlGraphicsScaleGrid")) {
- ObjectValue *object = newObject(/*prototype =*/ 0);
+ QmlObjectValue *object = new QmlObjectValue(&QObject::staticMetaObject, QLatin1String("ScaleGrid"), -1, -1, this);
object->setProperty("left", numberValue());
object->setProperty("top", numberValue());
object->setProperty("right", numberValue());
@@ -1801,20 +1809,17 @@ ObjectValue *Engine::newQmlObject(const QString &name)
}
// ### TODO: add support for QML packages
- QString componentName;
- componentName += QLatin1String("Qt/");
- componentName += name;
- componentName.replace(QLatin1Char('.'), QLatin1Char('/'));
+ const QString componentName = prefix + QLatin1Char('/') + name;
- if (QmlType *qmlType = QmlMetaType::qmlType(componentName.toUtf8(), 4, 6)) {
- QmlObjectValue *object = new QmlObjectValue(qmlType->metaObject(), this);
+ if (QmlType *qmlType = QmlMetaType::qmlType(componentName.toUtf8(), majorVersion, minorVersion)) {
+ const QString typeName = qmlType->qmlTypeName();
+ const QString strippedTypeName = typeName.mid(typeName.lastIndexOf('/') + 1);
+ QmlObjectValue *object = new QmlObjectValue(qmlType->metaObject(), strippedTypeName, majorVersion, minorVersion, this);
_objects.append(object);
return object;
}
return 0;
-#else
- return newObject(/*prototype = */ 0);
-#endif
}
+#endif