diff options
author | Robin Burchell <robin.burchell@crimson.no> | 2017-01-18 16:26:43 +0100 |
---|---|---|
committer | Robin Burchell <robin.burchell@crimson.no> | 2017-03-15 22:11:31 +0000 |
commit | 34ff6c40c1a03f51bc259e57cffb02ad69c7663b (patch) | |
tree | acae6098eb50fd44506c404aa2bfc6c40f9ca203 /src/qml/qml/qqmltypewrapper.cpp | |
parent | 212ccd59627deb8c06227dbf0f3f3329006c326e (diff) |
qml: Override the new Object::instanceOf hook to allow QML type checking
[ChangeLog][QtQml] The instanceof keyword in JavaScript has been
extended to work on QML types and instances. This means that you are now
able to use it to verify that a var is indeed the type you expect (e.g.
someVar instanceof Rectangle).
Note that one of the added tests revealed a slight shortcoming in the
QML type system (QTBUG-58477). For now, we should keep consistency and
work to address the problem universally in the future.
Change-Id: I7d9bf9b64cfd037908de1ae51b01065eacb95abe
Task-number: QTBUG-24799
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/qml/qqmltypewrapper.cpp')
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 49103ed653..7b98096a7f 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -342,4 +342,44 @@ bool QmlTypeWrapper::isEqualTo(Managed *a, Managed *b) return false; } +ReturnedValue QmlTypeWrapper::instanceOf(const Object *typeObject, const Value &var) +{ + Q_ASSERT(typeObject->as<QV4::QmlTypeWrapper>()); + const QV4::QmlTypeWrapper *typeWrapper = static_cast<const QV4::QmlTypeWrapper *>(typeObject); + QV4::ExecutionEngine *engine = typeObject->internalClass()->engine; + QQmlEnginePrivate *qenginepriv = QQmlEnginePrivate::get(engine->qmlEngine()); + + // can only compare a QObject* against a QML type + const QObjectWrapper *wrapper = var.as<QObjectWrapper>(); + if (!wrapper) + return engine->throwTypeError(); + + // in case the wrapper outlived the QObject* + const QObject *wrapperObject = wrapper->object(); + if (!wrapperObject) + return engine->throwTypeError(); + + const int myTypeId = typeWrapper->d()->type->typeId(); + QQmlMetaObject myQmlType; + if (myTypeId == 0) { + // we're a composite type; a composite type cannot be equal to a + // non-composite object instance (Rectangle{} is never an instance of + // CustomRectangle) + QQmlData *theirDData = QQmlData::get(wrapperObject, /*create=*/false); + Q_ASSERT(theirDData); // must exist, otherwise how do we have a QObjectWrapper for it?! + if (!theirDData->compilationUnit) + return Encode(false); + + QQmlTypeData *td = qenginepriv->typeLoader.getType(typeWrapper->d()->type->sourceUrl()); + CompiledData::CompilationUnit *cu = td->compilationUnit(); + myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId); + } else { + myQmlType = qenginepriv->metaObjectForType(myTypeId); + } + + const QMetaObject *theirType = wrapperObject->metaObject(); + + return QV4::Encode(QQmlMetaObject::canConvert(theirType, myQmlType)); +} + QT_END_NAMESPACE |