Exemplo n.º 1
0
void fromScriptValueEntityReference(const QScriptValue &obj, EntityReference &s)
{
    if (obj.isString())
        s.ref = obj.toString();
    else
    {
        if (!obj.property("ref").isValid())
            LogError("Can't convert QScriptValue to EntityReference! QScriptValue does not contain ref attribute!");
        else
        {
            QScriptValue ref = obj.property("ref");
            if (ref.isNull())
                s.ref = ""; // Empty the reference
            else if (ref.isString())
                s.ref = ref.toString();
            else if (ref.isQObject())
            {
                // If the object is an Entity, call EntityReference::Set() with it
                Entity* entity = dynamic_cast<Entity*>(ref.toQObject());
                s.Set(entity);
            }
            else if (ref.isNumber() || ref.isVariant())
                s.ref = QString::number(ref.toInt32());
            else
                LogError("Can't convert QScriptValue to EntityReference! Ref attribute is not null, string, a number, or an entity");
        }
    }
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    MagicCore SomeMagicCoreClass;

    QScriptEngine scriptEngine;

    QScriptValue scriptMagicCore = scriptEngine.newQObject (&SomeMagicCoreClass);
    Q_ASSERT (scriptMagicCore.isQObject());

    scriptEngine.globalObject().setProperty("Core", scriptMagicCore);

    ReadScriptsFromPath(QDir("./scripts/objects/"), scriptEngine);
    ReadScriptsFromPath(QDir("./scripts/levels/"), scriptEngine);

    char szLine[256];
    strcpy(szLine, "");

    std::cout << std::endl << "Entering scripting console: " << std::endl;

    while (strcmp(szLine, "exit") != 0)
    {
        // evaluate script line and store return value
        QScriptValue retVal = scriptEngine.evaluate(szLine);

        if (retVal.isUndefined() == false)
            std::cout << "ScriptEngine returns: " << retVal.toString().toStdString() << std::endl;

        // read line
        strcpy(szLine, "");
        std::cin.getline(szLine, 256);
    }


   /* QScriptValue object = scriptEngine.globalObject().property("testObject");
    Q_ASSERT(object.isValid());

    QScriptValue SlotMethod = object.property("ExampleSlot1");
    Q_ASSERT(SlotMethod.isFunction());

    bool bOk = qScriptConnect(&SomeMagicCoreClass, SIGNAL(TestSignal()), object, SlotMethod);
    Q_ASSERT(bOk);


    QScriptValue object2 = scriptEngine.globalObject().property("testObject2");
    Q_ASSERT(object2.isValid());

    QScriptValue SlotMethod2 = object2.property("ExampleSlot2");
    Q_ASSERT(SlotMethod2.isFunction());

    bool bOk2 = qScriptConnect(&SomeMagicCoreClass, SIGNAL(TestSignal()), object2, SlotMethod2);
    Q_ASSERT(bOk2);

    SomeMagicCoreClass.TriggerSignal();*/

    return 0;
    /*a.exit(0);

    return a.exec();*/
}
Exemplo n.º 3
0
static JSAgentWatchData fromScriptValue(const QString &expression,
                                        const QScriptValue &value)
{
    static const QString arrayStr = QCoreApplication::translate
            ("Debugger::JSAgentWatchData", "[Array of length %1]");
    static const QString undefinedStr = QCoreApplication::translate
            ("Debugger::JSAgentWatchData", "<undefined>");

    JSAgentWatchData data;
    data.exp = expression.toUtf8();
    data.name = data.exp;
    data.hasChildren = false;
    data.value = value.toString().toUtf8();
    data.objectId = value.objectId();
    if (value.isArray()) {
        data.type = "Array";
        data.value = arrayStr.arg(value.property(QLatin1String("length")).toString()).toUtf8();
        data.hasChildren = true;
    } else if (value.isBool()) {
        data.type = "Bool";
        // data.value = value.toBool() ? "true" : "false";
    } else if (value.isDate()) {
        data.type = "Date";
        data.value = value.toDateTime().toString().toUtf8();
    } else if (value.isError()) {
        data.type = "Error";
    } else if (value.isFunction()) {
        data.type = "Function";
    } else if (value.isUndefined()) {
        data.type = undefinedStr.toUtf8();
    } else if (value.isNumber()) {
        data.type = "Number";
    } else if (value.isRegExp()) {
        data.type = "RegExp";
    } else if (value.isString()) {
        data.type = "String";
    } else if (value.isVariant()) {
        data.type = "Variant";
    } else if (value.isQObject()) {
        const QObject *obj = value.toQObject();
        data.type = "Object";
        data.value += '[';
        data.value += obj->metaObject()->className();
        data.value += ']';
        data.hasChildren = true;
    } else if (value.isObject()) {
        data.type = "Object";
        data.hasChildren = true;
        data.value = "[Object]";
    } else if (value.isNull()) {
        data.type = "<null>";
    } else {
        data.type = "<unknown>";
    }
    return data;
}
Exemplo n.º 4
0
//    Q_DECLARE_METATYPE(QGraphicsLayoutItem*)
QGraphicsLayoutItem *extractLayoutItem(QScriptContext *ctx, int index = 0, bool noExistingLayout = false)
{
    QScriptValue v = ctx->argument(index);
    if (ctx->argumentCount() == 0 || v.isQObject()) {
        QObject *object = v.toQObject();
        QGraphicsWidget *w = qobject_cast<QGraphicsWidget *>(object);
        if (!w) {
            AppletInterface *interface = qobject_cast<AppletInterface*>(object);
            if (!interface) {
                interface =  qobject_cast<AppletInterface*>(ctx->engine()->globalObject().property("plasmoid").toQObject());
            }

            if (interface) {
                w = interface->applet();
            }
        }

        if (noExistingLayout && w->layout()) {
            return 0;
        }

        return w;
    }

    QVariant variant = v.toVariant();
    QGraphicsLayoutItem *item = variant.value<QGraphicsLayoutItem *>();
    //this is horribly ugly code, but when a QLinearLayout* is stuffed into a QVariant,
    //QVariant does not know that it is a QGraphicsLayoutItem. repeat for all subclasses
    //of same
    if (!item) {
        item = variant.value<QGraphicsLayout *>();

        if (!item) {
            item = variant.value<QGraphicsLinearLayout *>();

            if (!item) {
                item = variant.value<QGraphicsGridLayout *>();

                if (!item) {
                    item = variant.value<QGraphicsAnchorLayout *>();
                }
            }
        }
    }

    QGraphicsWidget *w = dynamic_cast<QGraphicsWidget *>(item);
    if (noExistingLayout && w && w->layout()) {
        return 0;
    }

    return item;
}
Exemplo n.º 5
0
            bool init() {
                if( m_script->action()->hadError() )
                    m_script->action()->clearError();

                delete m_engine;
                m_engine = new QScriptEngine();

                // load the Qross QScriptExtensionPlugin plugin that provides
                // us a bridge between Qross and QtScript. See here plugin.h
                m_engine->importExtension("qross");
                if( m_engine->hasUncaughtException() ) {
                    handleException();
                    delete m_engine;
                    m_engine = 0;
                    return false;
                }

                // the Qross QScriptExtensionPlugin exports the "Qross" property.
                QScriptValue global = m_engine->globalObject();
                m_qross = global.property("Qross");
                Q_ASSERT( m_qross.isQObject() );
                Q_ASSERT( ! m_engine->hasUncaughtException() );

                // Attach our Qross::Action instance to be able to access it in
                // scripts. Just like at the Kjs-backend we publish our own
                // action as "self".
                m_self = m_engine->newQObject( m_script->action() );
                global.setProperty("self", m_self, QScriptValue::ReadOnly|QScriptValue::Undeletable);

                { // publish the global objects.
                    QHash< QString, QObject* > objects = Manager::self().objects();
                    QHash< QString, QObject* >::Iterator it(objects.begin()), end(objects.end());
                    for(; it != end; ++it)
                        global.setProperty(it.key(), m_engine->newQObject( it.value() ) );
                }

                { // publish the local objects.
                    QHash< QString, QObject* > objects = m_script->action()->objects();
                    QHash< QString, QObject* >::Iterator it(objects.begin()), end(objects.end());
                    for(; it != end; ++it) {
                        copyEnumsToProperties( it.value() );
                        global.setProperty(it.key(), m_engine->newQObject( it.value() ) );
                    }
                }

                return ! m_engine->hasUncaughtException();
            }
QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e)
{
    QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e);

    if (type == qMetaTypeId<QScriptValue>()) {
        return QScriptDeclarativeClass::Value(engine, *qscriptValuePtr);
    } else if (type == QMetaType::Int) {
        return QScriptDeclarativeClass::Value(engine, int(intValue));
    } else if (type == QMetaType::UInt) {
        return QScriptDeclarativeClass::Value(engine, uint(intValue));
    } else if (type == QMetaType::Bool) {
        return QScriptDeclarativeClass::Value(engine, boolValue);
    } else if (type == QMetaType::Double) {
        return QScriptDeclarativeClass::Value(engine, doubleValue);
    } else if (type == QMetaType::Float) {
        return QScriptDeclarativeClass::Value(engine, floatValue);
    } else if (type == QMetaType::QString) {
        return QScriptDeclarativeClass::Value(engine, *qstringPtr);
    } else if (type == QMetaType::QObjectStar) {
        if (qobjectPtr)
            QDeclarativeData::get(qobjectPtr, true)->setImplicitDestructible();
        QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
        return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(qobjectPtr));
    } else if (type == qMetaTypeId<QList<QObject *> >()) {
        QList<QObject *> &list = *qlistPtr;
        QScriptValue rv = engine->newArray(list.count());
        QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
        for (int ii = 0; ii < list.count(); ++ii) {
            QObject *object = list.at(ii);
            QDeclarativeData::get(object, true)->setImplicitDestructible();
            rv.setProperty(ii, priv->objectClass->newQObject(object));
        }
        return QScriptDeclarativeClass::Value(engine, rv);
    } else if (type == -1 || type == qMetaTypeId<QVariant>()) {
        QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e);
        QScriptValue rv = ep->scriptValueFromVariant(*qvariantPtr);
        if (rv.isQObject()) {
            QObject *object = rv.toQObject();
            if (object)
                QDeclarativeData::get(object, true)->setImplicitDestructible();
        }
        return QScriptDeclarativeClass::Value(engine, rv);
    } else {
        return QScriptDeclarativeClass::Value();
    }
}
Exemplo n.º 7
0
void JavascriptInstance::GetObjectInformation(const QScriptValue &object, QSet<qint64> &ids, uint &valueCount, uint &objectCount, uint &nullCount, uint &numberCount, 
    uint &boolCount, uint &stringCount, uint &arrayCount, uint &funcCount, uint &qobjCount, uint &qobjMethodCount)
{
    if (!ids.contains(object.objectId()))       
        ids << object.objectId();
    
    QScriptValueIterator iter(object);
    while(iter.hasNext()) 
    {
        iter.next();
        QScriptValue v = iter.value();

        if (ids.contains(v.objectId()))
            continue;
        ids << v.objectId();
        
        valueCount++;
        if (v.isNull())
            nullCount++;

        if (v.isNumber())
            numberCount++;
        else if (v.isBool())
            boolCount++;
        else if (v.isString())
            stringCount++;
        else if (v.isArray())
            arrayCount++;
        else if (v.isFunction())
            funcCount++;
        else if (v.isQObject())
            qobjCount++;
        
        if (v.isObject())
            objectCount++;

        if (v.isQMetaObject())
            qobjMethodCount += v.toQMetaObject()->methodCount();
        
        // Recurse
        if ((v.isObject() || v.isArray()) && !v.isFunction() && !v.isString() && !v.isNumber() && !v.isBool() && !v.isQObject() && !v.isQMetaObject())
            GetObjectInformation(v, ids, valueCount, objectCount, nullCount, numberCount, boolCount, stringCount, arrayCount, funcCount, qobjCount, qobjMethodCount);
    }
}
Exemplo n.º 8
0
            void connectFunctions(ChildrenInterface* children) {
                Q_ASSERT( m_engine );
                Q_ASSERT( ! m_engine->hasUncaughtException() );
                QString eval;
                QScriptValue global = m_engine->globalObject();
                QHashIterator< QString, ChildrenInterface::Options > it( children->objectOptions() );
                while(it.hasNext()) {
                    it.next();
                    if( it.value() & ChildrenInterface::AutoConnectSignals ) {
                        QObject* sender = children->object(it.key());
                        if( ! sender )
                            continue;
                        QScriptValue obj = m_engine->globalObject().property(it.key());
                        if( ! obj.isQObject() )
                            continue;
                        const QMetaObject* mo = sender->metaObject();
                        const int count = mo->methodCount();
                        for(int i = 0; i < count; ++i) {
                            QMetaMethod mm = mo->method(i);
#if QT_VERSION < 0x050000
                            const QString signature = mm.signature();
#else
                            const QString signature = mm.methodSignature();
#endif
                            const QString name = signature.left(signature.indexOf('('));
                            if( mm.methodType() == QMetaMethod::Signal ) {
                                QScriptValue func = global.property(name);
                                if( ! func.isFunction() ) {
                                    //qrossdebug( QString("EcmaScript::connectFunctions No function to connect with %1.%2").arg(it.key()).arg(name) );
                                    continue;
                                }
                                qrossdebug( QString("EcmaScript::connectFunctions Connecting with %1.%2").arg(it.key()).arg(name) );
                                eval += QString("try { %1.%2.connect(%3); } catch(e) { print(e); }\n").arg(it.key()).arg(name).arg(name);
                            }
                        }
                    }
                }
                Q_ASSERT( ! m_engine->hasUncaughtException() );
                if( ! eval.isNull() ) {
                    m_engine->evaluate(eval);
                    Q_ASSERT( ! m_engine->hasUncaughtException() );
                }
            }
Exemplo n.º 9
0
bool operator==(const QScriptValue& first, const QScriptValue& second) {
    if (first.isUndefined()) {
        return second.isUndefined();
        
    } else if (first.isNull()) {
        return second.isNull();
    
    } else if (first.isBool()) {
        return second.isBool() && first.toBool() == second.toBool();
    
    } else if (first.isNumber()) {
        return second.isNumber() && first.toNumber() == second.toNumber();
    
    } else if (first.isString()) {
        return second.isString() && first.toString() == second.toString();
    
    } else if (first.isVariant()) {
        return second.isVariant() && first.toVariant() == second.toVariant();
        
    } else if (first.isQObject()) {
        return second.isQObject() && first.toQObject() == second.toQObject();
    
    } else if (first.isQMetaObject()) {
        return second.isQMetaObject() && first.toQMetaObject() == second.toQMetaObject();
        
    } else if (first.isDate()) {
        return second.isDate() && first.toDateTime() == second.toDateTime();
    
    } else if (first.isRegExp()) {
        return second.isRegExp() && first.toRegExp() == second.toRegExp();
    
    } else if (first.isArray()) {
        if (!second.isArray()) {
            return false;
        }
        int length = first.property(ScriptCache::getInstance()->getLengthString()).toInt32();
        if (second.property(ScriptCache::getInstance()->getLengthString()).toInt32() != length) {
            return false;
        }
        for (int i = 0; i < length; i++) {
            if (first.property(i) != second.property(i)) {
                return false;
            }
        }
        return true;
        
    } else if (first.isObject()) {
        if (!second.isObject()) {
            return false;
        }
        int propertyCount = 0;
        for (QScriptValueIterator it(first); it.hasNext(); ) {
            it.next();
            if (second.property(it.scriptName()) != it.value()) {
                return false;
            }
            propertyCount++;
        }
        // make sure the second has exactly as many properties as the first
        for (QScriptValueIterator it(second); it.hasNext(); ) {
            it.next();
            if (--propertyCount < 0) {
                return false;
            }
        }
        return true;
        
    } else {
        // if none of the above tests apply, first must be invalid
        return !second.isValid();
    }
}
Exemplo n.º 10
0
/*!
    Returns the match score for converting \a actual to be of type \a conversionType.  A 
    zero score means "perfect match" whereas a higher score is worse.

    The conversion table is copied out of the QtScript callQtMethod() function.
*/
int QDeclarativeObjectMethodScriptClass::matchScore(const QScriptValue &actual, int conversionType, 
                                                    const QByteArray &conversionTypeName)
{
    if (actual.isNumber()) {
        switch (conversionType) {
        case QMetaType::Double:
            return 0;
        case QMetaType::Float:
            return 1;
        case QMetaType::LongLong:
        case QMetaType::ULongLong:
            return 2;
        case QMetaType::Long:
        case QMetaType::ULong:
            return 3;
        case QMetaType::Int:
        case QMetaType::UInt:
            return 4;
        case QMetaType::Short:
        case QMetaType::UShort:
            return 5;
            break;
        case QMetaType::Char:
        case QMetaType::UChar:
            return 6;
        default:
            return 10;
        }
    } else if (actual.isString()) {
        switch (conversionType) {
        case QMetaType::QString:
            return 0;
        default:
            return 10;
        }
    } else if (actual.isBoolean()) {
        switch (conversionType) {
        case QMetaType::Bool:
            return 0;
        default:
            return 10;
        }
    } else if (actual.isDate()) {
        switch (conversionType) {
        case QMetaType::QDateTime:
            return 0;
        case QMetaType::QDate:
            return 1;
        case QMetaType::QTime:
            return 2;
        default:
            return 10;
        }
    } else if (actual.isRegExp()) {
        switch (conversionType) {
        case QMetaType::QRegExp:
            return 0;
        default:
            return 10;
        }
    } else if (actual.isVariant()) {
        if (conversionType == qMetaTypeId<QVariant>())
            return 0;
        else if (actual.toVariant().userType() == conversionType)
            return 0;
        else
            return 10;
    } else if (actual.isArray()) {
        switch (conversionType) {
        case QMetaType::QStringList:
        case QMetaType::QVariantList:
            return 5;
        default:
            return 10;
        }
    } else if (actual.isQObject()) {
        switch (conversionType) {
        case QMetaType::QObjectStar:
            return 0;
        default:
            return 10;
        }
    } else if (actual.isNull()) {
        switch (conversionType) {
        case QMetaType::VoidStar:
        case QMetaType::QObjectStar:
            return 0;
        default:
            if (!conversionTypeName.endsWith('*'))
                return 10;
            else
                return 0;
        }
    } else {
        return 10;
    }
}
Exemplo n.º 11
0
void tst_QScriptClass::extension()
{
    QScriptEngine eng;
    {
        TestClass cls(&eng);
        cls.setCallableMode(TestClass::NotCallable);
        QVERIFY(!cls.supportsExtension(QScriptClass::Callable));
        QVERIFY(!cls.supportsExtension(QScriptClass::HasInstance));
        QScriptValue obj = eng.newObject(&cls);
        QVERIFY(!obj.call().isValid());
        QCOMPARE((int)cls.lastExtensionType(), -1);
        QVERIFY(!obj.instanceOf(obj));
        QCOMPARE((int)cls.lastExtensionType(), -1);
    }
    // Callable
    {
        TestClass cls(&eng);
        cls.setCallableMode(TestClass::CallableReturnsSum);
        QVERIFY(cls.supportsExtension(QScriptClass::Callable));

        QScriptValue obj = eng.newObject(&cls);
        eng.globalObject().setProperty("obj", obj);
        obj.setProperty("one", QScriptValue(&eng, 1));
        obj.setProperty("two", QScriptValue(&eng, 2));
        obj.setProperty("three", QScriptValue(&eng, 3));
        // From C++
        cls.clearReceivedArgs();
        {
            QScriptValueList args;
            args << QScriptValue(&eng, 4) << QScriptValue(&eng, 5);
            QScriptValue ret = obj.call(obj, args);
            QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
            QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
            QVERIFY(ret.isNumber());
            QCOMPARE(ret.toNumber(), qsreal(15));
        }
        // From JS
        cls.clearReceivedArgs();
        {
            QScriptValue ret = eng.evaluate("obj(4, 5)");
            QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
            QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
            QVERIFY(ret.isNumber());
            QCOMPARE(ret.toNumber(), qsreal(15));
        }

        cls.setCallableMode(TestClass::CallableReturnsArgument);
        // From C++
        cls.clearReceivedArgs();
        {
            QScriptValue ret = obj.call(obj, QScriptValueList() << 123);
            QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
            QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
            QVERIFY(ret.isNumber());
            QCOMPARE(ret.toInt32(), 123);
        }
        cls.clearReceivedArgs();
        {
            QScriptValue ret = obj.call(obj, QScriptValueList() << true);
            QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
            QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
            QVERIFY(ret.isBoolean());
            QCOMPARE(ret.toBoolean(), true);
        }
        {
            QScriptValue ret = obj.call(obj, QScriptValueList() << QString::fromLatin1("ciao"));
            QVERIFY(ret.isString());
            QCOMPARE(ret.toString(), QString::fromLatin1("ciao"));
        }
        {
            QScriptValue objobj = eng.newObject();
            QScriptValue ret = obj.call(obj, QScriptValueList() << objobj);
            QVERIFY(ret.isObject());
            QVERIFY(ret.strictlyEquals(objobj));
        }
        {
            QScriptValue ret = obj.call(obj, QScriptValueList() << QScriptValue());
            QVERIFY(ret.isUndefined());
        }
        // From JS
        cls.clearReceivedArgs();
        {
            QScriptValue ret = eng.evaluate("obj(123)");
            QVERIFY(ret.isNumber());
            QCOMPARE(ret.toInt32(), 123);
        }

        cls.setCallableMode(TestClass::CallableReturnsInvalidVariant);
        {
            QScriptValue ret = obj.call(obj);
            QVERIFY(ret.isUndefined());
        }

        cls.setCallableMode(TestClass::CallableReturnsThisObject);
        // From C++
        {
            QScriptValue ret = obj.call(obj);
            QVERIFY(ret.isObject());
            QVERIFY(ret.strictlyEquals(obj));
        }
        // From JS
        {
            QScriptValue ret = eng.evaluate("obj()");
            QVERIFY(ret.isObject());
            QVERIFY(ret.strictlyEquals(eng.globalObject()));
        }

        cls.setCallableMode(TestClass::CallableReturnsCallee);
        // From C++
        {
            QScriptValue ret = obj.call();
            QVERIFY(ret.isObject());
            QVERIFY(ret.strictlyEquals(obj));
        }
        // From JS
        {
            QScriptValue ret = eng.evaluate("obj()");
            QVERIFY(ret.isObject());
            QVERIFY(ret.strictlyEquals(obj));
        }

        cls.setCallableMode(TestClass::CallableReturnsArgumentsObject);
        // From C++
        {
            QScriptValue ret = obj.call(obj, QScriptValueList() << 123);
            QVERIFY(ret.isObject());
            QVERIFY(ret.property("length").isNumber());
            QCOMPARE(ret.property("length").toInt32(), 1);
            QVERIFY(ret.property(0).isNumber());
            QCOMPARE(ret.property(0).toInt32(), 123);
        }
        // From JS
        {
            QScriptValue ret = eng.evaluate("obj(123)");
            QVERIFY(ret.isObject());
            QVERIFY(ret.property("length").isNumber());
            QCOMPARE(ret.property("length").toInt32(), 1);
            QVERIFY(ret.property(0).isNumber());
            QCOMPARE(ret.property(0).toInt32(), 123);
        }

        // construct()
        // From C++
        cls.clearReceivedArgs();
        cls.setCallableMode(TestClass::CallableReturnsGlobalObject);
        {
            QScriptValue ret = obj.construct();
            QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
            QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
            QVERIFY(ret.isObject());
            QVERIFY(ret.strictlyEquals(eng.globalObject()));
        }
        // From JS
        cls.clearReceivedArgs();
        {
            QScriptValue ret = eng.evaluate("new obj()");
            QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
            QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
            QVERIFY(ret.isObject());
            QVERIFY(ret.strictlyEquals(eng.globalObject()));
        }
        // From C++
        cls.clearReceivedArgs();
        cls.setCallableMode(TestClass::CallableInitializesThisObject);
        {
            QScriptValue ret = obj.construct();
            QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
            QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
            QVERIFY(ret.isQObject());
            QCOMPARE(ret.toQObject(), (QObject*)&eng);
        }
        // From JS
        cls.clearReceivedArgs();
        {
            QScriptValue ret = eng.evaluate("new obj()");
            QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
            QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
            QVERIFY(ret.isQObject());
            QCOMPARE(ret.toQObject(), (QObject*)&eng);
        }
    }
    // HasInstance
    {
        TestClass cls(&eng);
        cls.setHasInstance(true);
        QVERIFY(cls.supportsExtension(QScriptClass::HasInstance));

        QScriptValue obj = eng.newObject(&cls);
        obj.setProperty("foo", QScriptValue(&eng, 123));
        QScriptValue plain = eng.newObject();
        QVERIFY(!plain.instanceOf(obj));

        eng.globalObject().setProperty("HasInstanceTester", obj);
        eng.globalObject().setProperty("hasInstanceValue", plain);
        cls.clearReceivedArgs();
        {
            QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester");
            QCOMPARE(cls.lastExtensionType(), QScriptClass::HasInstance);
            QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptValueList>());
            QScriptValueList lst = qvariant_cast<QScriptValueList>(cls.lastExtensionArgument());
            QCOMPARE(lst.size(), 2);
            QVERIFY(lst.at(0).strictlyEquals(obj));
            QVERIFY(lst.at(1).strictlyEquals(plain));
            QVERIFY(ret.isBoolean());
            QVERIFY(!ret.toBoolean());
        }

        plain.setProperty("foo", QScriptValue(&eng, 456));
        QVERIFY(!plain.instanceOf(obj));
        {
            QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester");
            QVERIFY(ret.isBoolean());
            QVERIFY(!ret.toBoolean());
        }

        plain.setProperty("foo", obj.property("foo"));
        QVERIFY(plain.instanceOf(obj));
        {
            QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester");
            QVERIFY(ret.isBoolean());
            QVERIFY(ret.toBoolean());
        }
    }
}
void tst_QScriptValueGenerated::isQObject_test(const char*, const QScriptValue& value)
{
    QFETCH(bool, expected);
    QCOMPARE(value.isQObject(), expected);
    QCOMPARE(value.isQObject(), expected);
}