summaryrefslogtreecommitdiffstats
path: root/library
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2007-07-05 18:03:44 (GMT)
committerdgp <dgp@users.sourceforge.net>2007-07-05 18:03:44 (GMT)
commitb72d91bd10dfec0ff66a2bdc8d79d9b7de67dc98 (patch)
tree33aa64cb31ab43146bf30d021269ec1f1aa8b1c7 /library
parent699e0abdd1f9687bdda33420a941f8217d88c18c (diff)
downloadtcl-b72d91bd10dfec0ff66a2bdc8d79d9b7de67dc98.zip
tcl-b72d91bd10dfec0ff66a2bdc8d79d9b7de67dc98.tar.gz
tcl-b72d91bd10dfec0ff66a2bdc8d79d9b7de67dc98.tar.bz2
* library/init.tcl (unknown): Corrected inconsistent error message
in interactive [unknown] when empty command is invoked. [Bug 1743676]
Diffstat (limited to 'library')
-rw-r--r--library/init.tcl23
1 files changed, 11 insertions, 12 deletions
diff --git a/library/init.tcl b/library/init.tcl
index 8105642..be02fa1 100644
--- a/library/init.tcl
+++ b/library/init.tcl
@@ -3,7 +3,7 @@
# Default system startup file for Tcl-based applications. Defines
# "unknown" procedure and auto-load facilities.
#
-# RCS: @(#) $Id: init.tcl,v 1.55.2.6 2005/07/22 21:59:40 dgp Exp $
+# RCS: @(#) $Id: init.tcl,v 1.55.2.7 2007/07/05 18:03:45 dgp Exp $
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
@@ -312,19 +312,18 @@ proc unknown args {
"error in unknown while checking if \"$name\" is\
a unique command abbreviation:\n$msg"
}
- # Handle empty $name separately due to strangeness in [string first]
- if {$name eq ""} {
- if {[llength $candidates] != 1} {
- return -code error "empty command name \"\""
- }
- return [uplevel 1 [lreplace $args 0 0 [lindex $candidates 0]]]
- }
# Filter out bogus matches when $name contained
# a glob-special char [Bug 946952]
- set cmds [list]
- foreach x $candidates {
- if {[string first $name $x] == 0} {
- lappend cmds $x
+ if {$name eq ""} {
+ # Handle empty $name separately due to strangeness
+ # in [string first] (See RFE 1243354)
+ set cmds $candidates
+ } else {
+ set cmds [list]
+ foreach x $candidates {
+ if {[string first $name $x] == 0} {
+ lappend cmds $x
+ }
}
}
if {[llength $cmds] == 1} {
ptEngine, this, new ObjectData(object, type)); } else if (!ddata->scriptValue) { ddata->scriptValue = new QScriptValue(newObject(scriptEngine, this, new ObjectData(object, type))); return *ddata->scriptValue; } else if (ddata->scriptValue->engine() == QDeclarativeEnginePrivate::getScriptEngine(engine)) { return *ddata->scriptValue; } else { return newObject(scriptEngine, this, new ObjectData(object, type)); } } QObject *QDeclarativeObjectScriptClass::toQObject(const QScriptValue &value) const { return value.toQObject(); } int QDeclarativeObjectScriptClass::objectType(const QScriptValue &value) const { if (scriptClass(value) != this) return QVariant::Invalid; Object *o = object(value); return ((ObjectData*)(o))->type; } QScriptClass::QueryFlags QDeclarativeObjectScriptClass::queryProperty(Object *object, const Identifier &name, QScriptClass::QueryFlags flags) { return queryProperty(toQObject(object), name, flags, 0); } QScriptClass::QueryFlags QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, QScriptClass::QueryFlags flags, QDeclarativeContextData *evalContext, QueryHints hints) { Q_UNUSED(flags); lastData = 0; lastTNData = 0; if (name == m_destroyId.identifier || name == m_toStringId.identifier) return QScriptClass::HandlesReadAccess; if (!obj) return 0; QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine); lastData = QDeclarativePropertyCache::property(engine, obj, name, local); if (lastData) return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess; if (!(hints & SkipAttachedProperties)) { if (!evalContext && context()) { // Global object, QScriptContext activation object, QDeclarativeContext object QScriptValue scopeNode = scopeChainValue(context(), -3); if (scopeNode.isValid()) { Q_ASSERT(scriptClass(scopeNode) == enginePrivate->contextClass); evalContext = enginePrivate->contextClass->contextFromValue(scopeNode); } } if (evalContext && evalContext->imports) { QDeclarativeTypeNameCache::Data *data = evalContext->imports->data(name); if (data) { lastTNData = data; return QScriptClass::HandlesReadAccess; } } } if (!(hints & ImplicitObject)) { local.coreIndex = -1; lastData = &local; return QScriptClass::HandlesWriteAccess; } return 0; } QDeclarativeObjectScriptClass::Value QDeclarativeObjectScriptClass::property(Object *object, const Identifier &name) { return property(toQObject(object), name); } QDeclarativeObjectScriptClass::Value QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) { QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (name == m_destroyId.identifier) return Value(scriptEngine, m_destroy); else if (name == m_toStringId.identifier) return Value(scriptEngine, m_toString); if (lastData && !lastData->isValid()) return Value(); Q_ASSERT(obj); QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); if (lastTNData) { if (lastTNData->type) return Value(scriptEngine, enginePriv->typeNameClass->newObject(obj, lastTNData->type)); else return Value(scriptEngine, enginePriv->typeNameClass->newObject(obj, lastTNData->typeNamespace)); } else if (lastData->flags & QDeclarativePropertyCache::Data::IsFunction) { if (lastData->flags & QDeclarativePropertyCache::Data::IsVMEFunction) { return Value(scriptEngine, ((QDeclarativeVMEMetaObject *)(obj->metaObject()))->vmeMethod(lastData->coreIndex)); } else { // Uncomment to use QtScript method call logic // QScriptValue sobj = scriptEngine->newQObject(obj); // return Value(scriptEngine, sobj.property(toString(name))); return Value(scriptEngine, methods.newMethod(obj, lastData)); } } else { if (enginePriv->captureProperties && !(lastData->flags & QDeclarativePropertyCache::Data::IsConstant)) { enginePriv->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(obj, lastData->coreIndex, lastData->notifyIndex); } if (QDeclarativeValueTypeFactory::isValueType((uint)lastData->propType)) { QDeclarativeValueType *valueType = enginePriv->valueTypes[lastData->propType]; if (valueType) return Value(scriptEngine, enginePriv->valueTypeClass->newObject(obj, lastData->coreIndex, valueType)); } if (lastData->flags & QDeclarativePropertyCache::Data::IsQList) { return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, lastData->propType)); } else if (lastData->flags & QDeclarativePropertyCache::Data::IsQObjectDerived) { QObject *rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, newQObject(rv, lastData->propType)); } else if (lastData->flags & QDeclarativePropertyCache::Data::IsQScriptValue) { QScriptValue rv = scriptEngine->nullValue(); void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::QReal) { qreal rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::Int || lastData->flags & QDeclarativePropertyCache::Data::IsEnumType) { int rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::Bool) { bool rv = false; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::QString) { QString rv; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::UInt) { uint rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::Float) { float rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::Double) { double rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else { QVariant var = obj->metaObject()->property(lastData->coreIndex).read(obj); return Value(scriptEngine, enginePriv->scriptValueFromVariant(var)); } } } void QDeclarativeObjectScriptClass::setProperty(Object *object, const Identifier &name, const QScriptValue &value) { return setProperty(toQObject(object), name, value, context()); } void QDeclarativeObjectScriptClass::setProperty(QObject *obj, const Identifier &name, const QScriptValue &value, QScriptContext *context, QDeclarativeContextData *evalContext) { Q_UNUSED(name); Q_ASSERT(obj); Q_ASSERT(lastData); Q_ASSERT(context); if (!lastData->isValid()) { QString error = QLatin1String("Cannot assign to non-existent property \"") + toString(name) + QLatin1Char('\"'); context->throwError(error); return; } if (!(lastData->flags & QDeclarativePropertyCache::Data::IsWritable) && !(lastData->flags & QDeclarativePropertyCache::Data::IsQList)) { QString error = QLatin1String("Cannot assign to read-only property \"") + toString(name) + QLatin1Char('\"'); context->throwError(error); return; } QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); if (!evalContext) { // Global object, QScriptContext activation object, QDeclarativeContext object QScriptValue scopeNode = scopeChainValue(context, -3); if (scopeNode.isValid()) { Q_ASSERT(scriptClass(scopeNode) == enginePriv->contextClass); evalContext = enginePriv->contextClass->contextFromValue(scopeNode); } } QDeclarativeAbstractBinding *delBinding = QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, 0); if (delBinding) delBinding->destroy(); if (value.isNull() && lastData->flags & QDeclarativePropertyCache::Data::IsQObjectDerived) { QObject *o = 0; int status = -1; int flags = 0; void *argv[] = { &o, 0, &status, &flags }; QMetaObject::metacall(obj, QMetaObject::WriteProperty, lastData->coreIndex, argv); } else if (value.isUndefined() && lastData->flags & QDeclarativePropertyCache::Data::IsResettable) { void *a[] = { 0 }; QMetaObject::metacall(obj, QMetaObject::ResetProperty, lastData->coreIndex, a); } else if (value.isUndefined() && lastData->propType == qMetaTypeId<QVariant>()) { QDeclarativePropertyPrivate::write(obj, *lastData, QVariant(), evalContext); } else if (value.isUndefined()) { QString error = QLatin1String("Cannot assign [undefined] to ") + QLatin1String(QMetaType::typeName(lastData->propType)); context->throwError(error); } else if (!value.isRegExp() && value.isFunction()) { QString error = QLatin1String("Cannot assign a function to a property."); context->throwError(error); } else { QVariant v; if (lastData->flags & QDeclarativePropertyCache::Data::IsQList) v = enginePriv->scriptValueToVariant(value, qMetaTypeId<QList<QObject *> >()); else v = enginePriv->scriptValueToVariant(value, lastData->propType); if (!QDeclarativePropertyPrivate::write(obj, *lastData, v, evalContext)) { const char *valueType = 0; if (v.userType() == QVariant::Invalid) valueType = "null"; else valueType = QMetaType::typeName(v.userType()); QString error = QLatin1String("Cannot assign ") + QLatin1String(valueType) + QLatin1String(" to ") + QLatin1String(QMetaType::typeName(lastData->propType)); context->throwError(error); } } } bool QDeclarativeObjectScriptClass::isQObject() const { return true; } QObject *QDeclarativeObjectScriptClass::toQObject(Object *object, bool *ok) { if (ok) *ok = true; ObjectData *data = (ObjectData*)object; return data->object.data(); } QScriptValue QDeclarativeObjectScriptClass::tostring(QScriptContext *context, QScriptEngine *) { QObject* obj = context->thisObject().toQObject(); QString ret; if(obj){ QString objectName = obj->objectName(); ret += QString::fromUtf8(obj->metaObject()->className()); ret += QLatin1String("(0x"); ret += QString::number((intptr_t)obj,16); if (!objectName.isEmpty()) { ret += QLatin1String(", \""); ret += objectName; ret += QLatin1Char('\"'); } ret += QLatin1Char(')'); }else{ ret += QLatin1String("null"); } return QScriptValue(ret); } QScriptValue QDeclarativeObjectScriptClass::destroy(QScriptContext *context, QScriptEngine *engine) { QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine); QScriptValue that = context->thisObject(); if (scriptClass(that) != p->objectClass) return engine->undefinedValue(); ObjectData *data = (ObjectData *)p->objectClass->object(that); if (!data->object) return engine->undefinedValue(); QDeclarativeData *ddata = QDeclarativeData::get(data->object, false); if (!ddata || ddata->indestructible) return engine->currentContext()->throwError(QLatin1String("Invalid attempt to destroy() an indestructible object")); QObject *obj = data->object; int delay = 0; if (context->argumentCount() > 0) delay = context->argument(0).toInt32(); if (delay > 0) QTimer::singleShot(delay, obj, SLOT(deleteLater())); else obj->deleteLater(); return engine->undefinedValue(); } QStringList QDeclarativeObjectScriptClass::propertyNames(Object *object) { QObject *obj = toQObject(object); if (!obj) return QStringList(); QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine); QDeclarativePropertyCache *cache = 0; QDeclarativeData *ddata = QDeclarativeData::get(obj); if (ddata) cache = ddata->propertyCache; if (!cache) { cache = enginePrivate->cache(obj); if (cache) { if (ddata) { cache->addref(); ddata->propertyCache = cache; } } else { // Not cachable - fall back to QMetaObject (eg. dynamic meta object) // XXX QDeclarativeOpenMetaObject has a cache, so this is suboptimal. // XXX This is a workaround for QTBUG-9420. const QMetaObject *mo = obj->metaObject(); QStringList r; int pc = mo->propertyCount(); int po = mo->propertyOffset(); for (int i=po; i<pc; ++i) r += QString::fromUtf8(mo->property(i).name()); return r; } } return cache->propertyNames(); } bool QDeclarativeObjectScriptClass::compare(Object *o1, Object *o2) { ObjectData *d1 = (ObjectData *)o1; ObjectData *d2 = (ObjectData *)o2; return d1 == d2 || d1->object == d2->object; } struct MethodData : public QScriptDeclarativeClass::Object { MethodData(QObject *o, const QDeclarativePropertyCache::Data &d) : object(o), data(d) {} QDeclarativeGuard<QObject> object; QDeclarativePropertyCache::Data data; }; QDeclarativeObjectMethodScriptClass::QDeclarativeObjectMethodScriptClass(QDeclarativeEngine *bindEngine) : QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine) { qRegisterMetaType<QList<QObject *> >("QList<QObject *>"); setSupportsCall(true); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); m_connect = scriptEngine->newFunction(connect); m_connectId = createPersistentIdentifier(QLatin1String("connect")); m_disconnect = scriptEngine->newFunction(disconnect); m_disconnectId = createPersistentIdentifier(QLatin1String("disconnect")); } QDeclarativeObjectMethodScriptClass::~QDeclarativeObjectMethodScriptClass() { } QScriptValue QDeclarativeObjectMethodScriptClass::newMethod(QObject *object, const QDeclarativePropertyCache::Data *method) { QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); return newObject(scriptEngine, this, new MethodData(object, *method)); } QScriptValue QDeclarativeObjectMethodScriptClass::connect(QScriptContext *context, QScriptEngine *engine) { QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine); QScriptValue that = context->thisObject(); if (&p->objectClass->methods != scriptClass(that)) return engine->undefinedValue(); MethodData *data = (MethodData *)object(that); if (!data->object || context->argumentCount() == 0) return engine->undefinedValue(); QByteArray signal("2"); signal.append(data->object->metaObject()->method(data->data.coreIndex).signature()); if (context->argumentCount() == 1) { qScriptConnect(data->object, signal.constData(), QScriptValue(), context->argument(0)); } else { qScriptConnect(data->object, signal.constData(), context->argument(0), context->argument(1)); } return engine->undefinedValue(); } QScriptValue QDeclarativeObjectMethodScriptClass::disconnect(QScriptContext *context, QScriptEngine *engine) { QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine); QScriptValue that = context->thisObject(); if (&p->objectClass->methods != scriptClass(that)) return engine->undefinedValue(); MethodData *data = (MethodData *)object(that); if (!data->object || context->argumentCount() == 0) return engine->undefinedValue(); QByteArray signal("2"); signal.append(data->object->metaObject()->method(data->data.coreIndex).signature()); if (context->argumentCount() == 1) { qScriptDisconnect(data->object, signal.constData(), QScriptValue(), context->argument(0)); } else { qScriptDisconnect(data->object, signal.constData(), context->argument(0), context->argument(1)); } return engine->undefinedValue(); } QScriptClass::QueryFlags QDeclarativeObjectMethodScriptClass::queryProperty(Object *, const Identifier &name, QScriptClass::QueryFlags flags) { Q_UNUSED(flags); if (name == m_connectId.identifier || name == m_disconnectId.identifier) return QScriptClass::HandlesReadAccess; else return 0; } QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass::property(Object *, const Identifier &name) { QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (name == m_connectId.identifier) return Value(scriptEngine, m_connect); else if (name == m_disconnectId.identifier) return Value(scriptEngine, m_disconnect); else return Value(); } namespace { struct MetaCallArgument { inline MetaCallArgument(); inline ~MetaCallArgument(); inline void *dataPtr(); inline void initAsType(int type, QDeclarativeEngine *); void fromScriptValue(int type, QDeclarativeEngine *, const QScriptValue &); inline QScriptDeclarativeClass::Value toValue(QDeclarativeEngine *); private: MetaCallArgument(const MetaCallArgument &); inline void cleanup(); char data[4 * sizeof(void *)]; int type; bool isObjectType; }; } MetaCallArgument::MetaCallArgument() : type(QVariant::Invalid), isObjectType(false) { } MetaCallArgument::~MetaCallArgument() { cleanup(); } void MetaCallArgument::cleanup() { if (type == QMetaType::QString) { ((QString *)&data)->~QString(); } else if (type == -1 || type == qMetaTypeId<QVariant>()) { ((QVariant *)&data)->~QVariant(); } else if (type == qMetaTypeId<QScriptValue>()) { ((QScriptValue *)&data)->~QScriptValue(); } else if (type == qMetaTypeId<QList<QObject *> >()) { ((QList<QObject *> *)&data)->~QList<QObject *>(); } } void *MetaCallArgument::dataPtr() { if (type == -1) return ((QVariant *)data)->data(); else return (void *)&data; } void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) { if (type != 0) { cleanup(); type = 0; } if (callType == 0) return; QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (callType == qMetaTypeId<QScriptValue>()) { new (&data) QScriptValue(engine->undefinedValue()); type = callType; } else if (callType == QMetaType::Int || callType == QMetaType::UInt || callType == QMetaType::Bool || callType == QMetaType::Double || callType == QMetaType::Float) { type = callType; } else if (callType == QMetaType::QObjectStar) { *((QObject **)&data) = 0; type = callType; } else if (callType == QMetaType::QString) { new (&data) QString(); type = callType; } else if (callType == qMetaTypeId<QVariant>()) { type = callType; new (&data) QVariant(); } else if (callType == qMetaTypeId<QList<QObject *> >()) { type = callType; new (&data) QList<QObject *>(); } else { type = -1; new (&data) QVariant(callType, (void *)0); } } void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, const QScriptValue &value) { if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId<QScriptValue>()) { new (&data) QScriptValue(value); type = qMetaTypeId<QScriptValue>(); } else if (callType == QMetaType::Int) { *((int *)&data) = int(value.toInt32()); type = callType; } else if (callType == QMetaType::UInt) { *((uint *)&data) = uint(value.toUInt32()); type = callType; } else if (callType == QMetaType::Bool) { *((bool *)&data) = value.toBool(); type = callType; } else if (callType == QMetaType::Double) { *((double *)&data) = double(value.toNumber()); type = callType; } else if (callType == QMetaType::Float) { *((float *)&data) = float(value.toNumber()); type = callType; } else if (callType == QMetaType::QString) { if (value.isNull() || value.isUndefined()) new (&data) QString(); else new (&data) QString(value.toString()); type = callType; } else if (callType == QMetaType::QObjectStar) { *((QObject **)&data) = value.toQObject(); type = callType; } else if (callType == qMetaTypeId<QVariant>()) { new (&data) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value)); type = callType; } else if (callType == qMetaTypeId<QList<QObject*> >()) { QList<QObject *> *list = new (&data) QList<QObject *>(); if (value.isArray()) { int length = value.property(QLatin1String("length")).toInt32(); for (int ii = 0; ii < length; ++ii) { QScriptValue arrayItem = value.property(ii); QObject *d = arrayItem.toQObject(); list->append(d); } } else if (QObject *d = value.toQObject()) { list->append(d); } type = callType; } else { new (&data) QVariant(); type = -1; QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine); QVariant v = priv->scriptValueToVariant(value); if (v.userType() == callType) { *((QVariant *)&data) = v; } else if (v.canConvert((QVariant::Type)callType)) { *((QVariant *)&data) = v; ((QVariant *)&data)->convert((QVariant::Type)callType); } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) { QObject *obj = priv->toQObject(v); if (obj) { const QMetaObject *objMo = obj->metaObject(); while (objMo && objMo != mo) objMo = objMo->superClass(); if (!objMo) obj = 0; } *((QVariant *)&data) = QVariant(callType, &obj); } else { *((QVariant *)&data) = QVariant(callType, (void *)0); } } } QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) { QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (type == qMetaTypeId<QScriptValue>()) { return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)&data)); } else if (type == QMetaType::Int) { return QScriptDeclarativeClass::Value(engine, *((int *)&data)); } else if (type == QMetaType::UInt) { return QScriptDeclarativeClass::Value(engine, *((uint *)&data)); } else if (type == QMetaType::Bool) { return QScriptDeclarativeClass::Value(engine, *((bool *)&data)); } else if (type == QMetaType::Double) { return QScriptDeclarativeClass::Value(engine, *((double *)&data)); } else if (type == QMetaType::Float) { return QScriptDeclarativeClass::Value(engine, *((float *)&data)); } else if (type == QMetaType::QString) { return QScriptDeclarativeClass::Value(engine, *((QString *)&data)); } else if (type == QMetaType::QObjectStar) { QObject *object = *((QObject **)&data); if (object) QDeclarativeData::get(object, true)->setImplicitDestructible(); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object)); } else if (type == qMetaTypeId<QList<QObject *> >()) { QList<QObject *> &list = *(QList<QObject *>*)&data; 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>()) { return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)&data))); } else { return QScriptDeclarativeClass::Value(); } } int QDeclarativeObjectMethodScriptClass::enumType(const QMetaObject *meta, const QString &strname) { QByteArray str = strname.toUtf8(); QByteArray scope; QByteArray name; int scopeIdx = str.lastIndexOf("::"); if (scopeIdx != -1) { scope = str.left(scopeIdx); name = str.mid(scopeIdx + 2); } else { name = str; } for (int i = meta->enumeratorCount() - 1; i >= 0; --i) { QMetaEnum m = meta->enumerator(i); if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope))) return QVariant::Int; } return QVariant::Invalid; } QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass::call(Object *o, QScriptContext *ctxt) { MethodData *method = static_cast<MethodData *>(o); if (method->data.flags & QDeclarativePropertyCache::Data::HasArguments) { QMetaMethod m = method->object->metaObject()->method(method->data.coreIndex); QList<QByteArray> argTypeNames = m.parameterTypes(); QVarLengthArray<int, 9> argTypes(argTypeNames.count()); // ### Cache for (int ii = 0; ii < argTypeNames.count(); ++ii) { argTypes[ii] = QMetaType::type(argTypeNames.at(ii)); if (argTypes[ii] == QVariant::Invalid) argTypes[ii] = enumType(method->object->metaObject(), QString::fromLatin1(argTypeNames.at(ii))); if (argTypes[ii] == QVariant::Invalid) return Value(ctxt, ctxt->throwError(QString::fromLatin1("Unknown method parameter type: %1").arg(QLatin1String(argTypeNames.at(ii))))); } if (argTypes.count() > ctxt->argumentCount()) return Value(ctxt, ctxt->throwError(QLatin1String("Insufficient arguments"))); QVarLengthArray<MetaCallArgument, 9> args(argTypes.count() + 1); args[0].initAsType(method->data.propType, engine); for (int ii = 0; ii < argTypes.count(); ++ii) args[ii + 1].fromScriptValue(argTypes[ii], engine, ctxt->argument(ii)); QVarLengthArray<void *, 9> argData(args.count()); for (int ii = 0; ii < args.count(); ++ii) argData[ii] = args[ii].dataPtr(); QMetaObject::metacall(method->object, QMetaObject::InvokeMetaMethod, method->data.coreIndex, argData.data()); return args[0].toValue(engine); } else if (method->data.propType != 0) { MetaCallArgument arg; arg.initAsType(method->data.propType, engine); void *args[] = { arg.dataPtr() }; QMetaObject::metacall(method->object, QMetaObject::InvokeMetaMethod, method->data.coreIndex, args); return arg.toValue(engine); } else { void *args[] = { 0 }; QMetaObject::metacall(method->object, QMetaObject::InvokeMetaMethod, method->data.coreIndex, args); return Value(); } return Value(); } QT_END_NAMESPACE