| 1 | /****************************************************************************
|
|---|
| 2 | **
|
|---|
| 3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|---|
| 4 | ** Contact: Qt Software Information (qt-info@nokia.com)
|
|---|
| 5 | **
|
|---|
| 6 | ** This file is part of the QtScript module of the Qt Toolkit.
|
|---|
| 7 | **
|
|---|
| 8 | ** $QT_BEGIN_LICENSE:LGPL$
|
|---|
| 9 | ** Commercial Usage
|
|---|
| 10 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
|---|
| 11 | ** accordance with the Qt Commercial License Agreement provided with the
|
|---|
| 12 | ** Software or, alternatively, in accordance with the terms contained in
|
|---|
| 13 | ** a written agreement between you and Nokia.
|
|---|
| 14 | **
|
|---|
| 15 | ** GNU Lesser General Public License Usage
|
|---|
| 16 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
|---|
| 17 | ** General Public License version 2.1 as published by the Free Software
|
|---|
| 18 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
|---|
| 19 | ** packaging of this file. Please review the following information to
|
|---|
| 20 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
|---|
| 21 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|---|
| 22 | **
|
|---|
| 23 | ** In addition, as a special exception, Nokia gives you certain
|
|---|
| 24 | ** additional rights. These rights are described in the Nokia Qt LGPL
|
|---|
| 25 | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
|---|
| 26 | ** package.
|
|---|
| 27 | **
|
|---|
| 28 | ** GNU General Public License Usage
|
|---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU
|
|---|
| 30 | ** General Public License version 3.0 as published by the Free Software
|
|---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
|---|
| 32 | ** packaging of this file. Please review the following information to
|
|---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
|---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
|---|
| 35 | **
|
|---|
| 36 | ** If you are unsure which license is appropriate for your use, please
|
|---|
| 37 | ** contact the sales department at qt-sales@nokia.com.
|
|---|
| 38 | ** $QT_END_LICENSE$
|
|---|
| 39 | **
|
|---|
| 40 | ****************************************************************************/
|
|---|
| 41 |
|
|---|
| 42 | #include "qscriptecmafunction_p.h"
|
|---|
| 43 |
|
|---|
| 44 | #ifndef QT_NO_SCRIPT
|
|---|
| 45 |
|
|---|
| 46 | #include "qscriptengine_p.h"
|
|---|
| 47 | #include "qscriptvalueimpl_p.h"
|
|---|
| 48 | #include "qscriptcontext_p.h"
|
|---|
| 49 | #include "qscriptmember_p.h"
|
|---|
| 50 | #include "qscriptobject_p.h"
|
|---|
| 51 |
|
|---|
| 52 | #include <QtCore/QtDebug>
|
|---|
| 53 |
|
|---|
| 54 | #ifndef QT_NO_QOBJECT
|
|---|
| 55 | # include "qscriptextqobject_p.h"
|
|---|
| 56 | # include <QtCore/QMetaMethod>
|
|---|
| 57 | #endif
|
|---|
| 58 |
|
|---|
| 59 | QT_BEGIN_NAMESPACE
|
|---|
| 60 |
|
|---|
| 61 | namespace QScript { namespace Ecma {
|
|---|
| 62 |
|
|---|
| 63 | class FunctionClassData: public QScriptClassData
|
|---|
| 64 | {
|
|---|
| 65 | QScriptClassInfo *m_classInfo;
|
|---|
| 66 |
|
|---|
| 67 | public:
|
|---|
| 68 | FunctionClassData(QScriptClassInfo *classInfo);
|
|---|
| 69 | virtual ~FunctionClassData();
|
|---|
| 70 |
|
|---|
| 71 | inline QScriptClassInfo *classInfo() const
|
|---|
| 72 | { return m_classInfo; }
|
|---|
| 73 |
|
|---|
| 74 | virtual bool resolve(const QScriptValueImpl &object,
|
|---|
| 75 | QScriptNameIdImpl *nameId,
|
|---|
| 76 | QScript::Member *member, QScriptValueImpl *base,
|
|---|
| 77 | QScript::AccessMode access);
|
|---|
| 78 | virtual bool get(const QScriptValueImpl &obj, const Member &m,
|
|---|
| 79 | QScriptValueImpl *out_value);
|
|---|
| 80 | virtual bool put(QScriptValueImpl *object, const QScript::Member &member,
|
|---|
| 81 | const QScriptValueImpl &value);
|
|---|
| 82 | virtual void mark(const QScriptValueImpl &object, int generation);
|
|---|
| 83 | };
|
|---|
| 84 |
|
|---|
| 85 | FunctionClassData::FunctionClassData(QScriptClassInfo *classInfo)
|
|---|
| 86 | : m_classInfo(classInfo)
|
|---|
| 87 | {
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | FunctionClassData::~FunctionClassData()
|
|---|
| 91 | {
|
|---|
| 92 | }
|
|---|
| 93 |
|
|---|
| 94 | bool FunctionClassData::resolve(const QScriptValueImpl &object,
|
|---|
| 95 | QScriptNameIdImpl *nameId,
|
|---|
| 96 | QScript::Member *member, QScriptValueImpl *base,
|
|---|
| 97 | QScript::AccessMode /*access*/)
|
|---|
| 98 | {
|
|---|
| 99 | if (object.classInfo() != classInfo())
|
|---|
| 100 | return false;
|
|---|
| 101 |
|
|---|
| 102 | QScriptEnginePrivate *eng = object.engine();
|
|---|
| 103 |
|
|---|
| 104 | if ((nameId == eng->idTable()->id_length)
|
|---|
| 105 | || (nameId == eng->idTable()->id_arguments)) {
|
|---|
| 106 | member->native(nameId, /*id=*/ 0,
|
|---|
| 107 | QScriptValue::Undeletable
|
|---|
| 108 | | QScriptValue::ReadOnly
|
|---|
| 109 | | QScriptValue::SkipInEnumeration);
|
|---|
| 110 | *base = object;
|
|---|
| 111 | return true;
|
|---|
| 112 | }
|
|---|
| 113 |
|
|---|
| 114 | return false;
|
|---|
| 115 | }
|
|---|
| 116 |
|
|---|
| 117 | bool FunctionClassData::get(const QScriptValueImpl &object, const Member &member,
|
|---|
| 118 | QScriptValueImpl *result)
|
|---|
| 119 | {
|
|---|
| 120 | if (object.classInfo() != classInfo())
|
|---|
| 121 | return false;
|
|---|
| 122 |
|
|---|
| 123 | QScriptEnginePrivate *eng = object.engine();
|
|---|
| 124 | if (! member.isNativeProperty())
|
|---|
| 125 | return false;
|
|---|
| 126 |
|
|---|
| 127 | if (member.nameId() == eng->idTable()->id_length) {
|
|---|
| 128 | *result = QScriptValueImpl(object.toFunction()->length);
|
|---|
| 129 | return true;
|
|---|
| 130 | } else if (member.nameId() == eng->idTable()->id_arguments) {
|
|---|
| 131 | *result = eng->nullValue();
|
|---|
| 132 | return true;
|
|---|
| 133 | }
|
|---|
| 134 |
|
|---|
| 135 | return false;
|
|---|
| 136 | }
|
|---|
| 137 |
|
|---|
| 138 | bool FunctionClassData::put(QScriptValueImpl *, const QScript::Member &,
|
|---|
| 139 | const QScriptValueImpl &)
|
|---|
| 140 | {
|
|---|
| 141 | return false;
|
|---|
| 142 | }
|
|---|
| 143 |
|
|---|
| 144 | void FunctionClassData::mark(const QScriptValueImpl &object, int generation)
|
|---|
| 145 | {
|
|---|
| 146 | if (object.classInfo() != classInfo())
|
|---|
| 147 | return;
|
|---|
| 148 | QScriptFunction *fun = object.toFunction();
|
|---|
| 149 | QScriptEnginePrivate *eng = object.engine();
|
|---|
| 150 | fun->mark(eng, generation);
|
|---|
| 151 | }
|
|---|
| 152 |
|
|---|
| 153 | Function::Function(QScriptEnginePrivate *eng, QScriptClassInfo *classInfo):
|
|---|
| 154 | Core(eng, classInfo)
|
|---|
| 155 | {
|
|---|
| 156 | publicPrototype = eng->createFunction(method_void, 0, classInfo); // public prototype
|
|---|
| 157 | }
|
|---|
| 158 |
|
|---|
| 159 | Function::~Function()
|
|---|
| 160 | {
|
|---|
| 161 | }
|
|---|
| 162 |
|
|---|
| 163 | void Function::initialize()
|
|---|
| 164 | {
|
|---|
| 165 | QScriptEnginePrivate *eng = engine();
|
|---|
| 166 | eng->newConstructor(&ctor, this, publicPrototype);
|
|---|
| 167 |
|
|---|
| 168 | addPrototypeFunction(QLatin1String("toString"), method_toString, 1);
|
|---|
| 169 | addPrototypeFunction(QLatin1String("apply"), method_apply, 2);
|
|---|
| 170 | addPrototypeFunction(QLatin1String("call"), method_call, 1);
|
|---|
| 171 | addPrototypeFunction(QLatin1String("connect"), method_connect, 1);
|
|---|
| 172 | addPrototypeFunction(QLatin1String("disconnect"), method_disconnect, 1);
|
|---|
| 173 |
|
|---|
| 174 | classInfo()->setData(new FunctionClassData(classInfo()));
|
|---|
| 175 | }
|
|---|
| 176 |
|
|---|
| 177 | void Function::execute(QScriptContextPrivate *context)
|
|---|
| 178 | {
|
|---|
| 179 | #ifndef Q_SCRIPT_NO_EVENT_NOTIFY
|
|---|
| 180 | engine()->notifyFunctionEntry(context);
|
|---|
| 181 | #endif
|
|---|
| 182 | int lineNumber = context->currentLine;
|
|---|
| 183 | QString contents = buildFunction(context);
|
|---|
| 184 | engine()->evaluate(context, contents, lineNumber);
|
|---|
| 185 | #ifndef Q_SCRIPT_NO_EVENT_NOTIFY
|
|---|
| 186 | engine()->notifyFunctionExit(context);
|
|---|
| 187 | #endif
|
|---|
| 188 | }
|
|---|
| 189 |
|
|---|
| 190 | QString Function::buildFunction(QScriptContextPrivate *context)
|
|---|
| 191 | {
|
|---|
| 192 | int argc = context->argumentCount();
|
|---|
| 193 |
|
|---|
| 194 | QString code;
|
|---|
| 195 | code += QLatin1String("function(");
|
|---|
| 196 |
|
|---|
| 197 | // the formals
|
|---|
| 198 | for (int i = 0; i < argc - 1; ++i) {
|
|---|
| 199 | if (i != 0)
|
|---|
| 200 | code += QLatin1String(",");
|
|---|
| 201 |
|
|---|
| 202 | code += context->argument(i).toString();
|
|---|
| 203 | }
|
|---|
| 204 |
|
|---|
| 205 | code += QLatin1String("){");
|
|---|
| 206 |
|
|---|
| 207 | // the function body
|
|---|
| 208 | if (argc != 0)
|
|---|
| 209 | code += context->argument(argc - 1).toString();
|
|---|
| 210 |
|
|---|
| 211 | code += QLatin1String("\n}");
|
|---|
| 212 |
|
|---|
| 213 | return code;
|
|---|
| 214 | }
|
|---|
| 215 |
|
|---|
| 216 | void Function::newFunction(QScriptValueImpl *result, QScriptFunction *foo)
|
|---|
| 217 | {
|
|---|
| 218 | engine()->newFunction(result, foo);
|
|---|
| 219 | }
|
|---|
| 220 |
|
|---|
| 221 | QScriptValueImpl Function::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
|
|---|
| 222 | {
|
|---|
| 223 | QScriptValueImpl self = context->thisObject();
|
|---|
| 224 | if (QScriptFunction *foo = self.toFunction()) {
|
|---|
| 225 | QString code = foo->toString(context);
|
|---|
| 226 | return QScriptValueImpl(eng, code);
|
|---|
| 227 | }
|
|---|
| 228 |
|
|---|
| 229 | return throwThisObjectTypeError(
|
|---|
| 230 | context, QLatin1String("Function.prototype.toString"));
|
|---|
| 231 | }
|
|---|
| 232 |
|
|---|
| 233 | QScriptValueImpl Function::method_call(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
|
|---|
| 234 | {
|
|---|
| 235 | if (! context->thisObject().isFunction()) {
|
|---|
| 236 | return throwThisObjectTypeError(
|
|---|
| 237 | context, QLatin1String("Function.prototype.call"));
|
|---|
| 238 | }
|
|---|
| 239 |
|
|---|
| 240 | QScriptValueImpl thisObject = eng->toObject(context->argument(0));
|
|---|
| 241 | if (! (thisObject.isValid () && thisObject.isObject()))
|
|---|
| 242 | thisObject = eng->globalObject();
|
|---|
| 243 |
|
|---|
| 244 | QScriptValueImplList args;
|
|---|
| 245 | for (int i = 1; i < context->argumentCount(); ++i)
|
|---|
| 246 | args << context->argument(i);
|
|---|
| 247 |
|
|---|
| 248 | return context->thisObject().call(thisObject, args);
|
|---|
| 249 | }
|
|---|
| 250 |
|
|---|
| 251 | QScriptValueImpl Function::method_apply(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
|
|---|
| 252 | {
|
|---|
| 253 | if (! context->thisObject().isFunction()) {
|
|---|
| 254 | return throwThisObjectTypeError(
|
|---|
| 255 | context, QLatin1String("Function.prototype.apply"));
|
|---|
| 256 | }
|
|---|
| 257 |
|
|---|
| 258 | QScriptValueImpl thisObject = eng->toObject(context->argument(0));
|
|---|
| 259 | if (! (thisObject.isValid () && thisObject.isObject()))
|
|---|
| 260 | thisObject = eng->globalObject();
|
|---|
| 261 |
|
|---|
| 262 | QScriptValueImplList args;
|
|---|
| 263 | QScriptValueImpl undefined = eng->undefinedValue();
|
|---|
| 264 |
|
|---|
| 265 | QScriptValueImpl arg = context->argument(1);
|
|---|
| 266 |
|
|---|
| 267 | if (Ecma::Array::Instance *arr = eng->arrayConstructor->get(arg)) {
|
|---|
| 268 | QScript::Array actuals = arr->value;
|
|---|
| 269 |
|
|---|
| 270 | for (quint32 i = 0; i < actuals.count(); ++i) {
|
|---|
| 271 | QScriptValueImpl a = actuals.at(i);
|
|---|
| 272 | if (! a.isValid())
|
|---|
| 273 | args << undefined;
|
|---|
| 274 | else
|
|---|
| 275 | args << a;
|
|---|
| 276 | }
|
|---|
| 277 | } else if (arg.classInfo() == eng->m_class_arguments) {
|
|---|
| 278 | QScript::ArgumentsObjectData *arguments;
|
|---|
| 279 | arguments = static_cast<QScript::ArgumentsObjectData*> (arg.objectData());
|
|---|
| 280 | QScriptObject *activation = arguments->activation.objectValue();
|
|---|
| 281 | for (uint i = 0; i < arguments->length; ++i)
|
|---|
| 282 | args << activation->m_values[i];
|
|---|
| 283 | } else if (!(arg.isUndefined() || arg.isNull())) {
|
|---|
| 284 | return context->throwError(QScriptContext::TypeError,
|
|---|
| 285 | QLatin1String("Function.prototype.apply: second argument is not an array"));
|
|---|
| 286 | }
|
|---|
| 287 |
|
|---|
| 288 | return context->thisObject().call(thisObject, args);
|
|---|
| 289 | }
|
|---|
| 290 |
|
|---|
| 291 | QScriptValueImpl Function::method_void(QScriptContextPrivate *, QScriptEnginePrivate *eng, QScriptClassInfo *)
|
|---|
| 292 | {
|
|---|
| 293 | return eng->undefinedValue();
|
|---|
| 294 | }
|
|---|
| 295 |
|
|---|
| 296 | QScriptValueImpl Function::method_disconnect(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
|
|---|
| 297 | {
|
|---|
| 298 | #ifndef QT_NO_QOBJECT
|
|---|
| 299 | if (context->argumentCount() == 0) {
|
|---|
| 300 | return context->throwError(
|
|---|
| 301 | QLatin1String("Function.prototype.disconnect: no arguments given"));
|
|---|
| 302 | }
|
|---|
| 303 |
|
|---|
| 304 | QScriptValueImpl self = context->thisObject();
|
|---|
| 305 | QScriptFunction *fun = self.toFunction();
|
|---|
| 306 | if ((fun == 0) || (fun->type() != QScriptFunction::Qt)) {
|
|---|
| 307 | return context->throwError(
|
|---|
| 308 | QScriptContext::TypeError,
|
|---|
| 309 | QLatin1String("Function.prototype.disconnect: this object is not a signal"));
|
|---|
| 310 | }
|
|---|
| 311 |
|
|---|
| 312 | QtFunction *qtSignal = static_cast<QtFunction*>(fun);
|
|---|
| 313 |
|
|---|
| 314 | const QMetaObject *meta = qtSignal->metaObject();
|
|---|
| 315 | if (!meta) {
|
|---|
| 316 | return context->throwError(
|
|---|
| 317 | QScriptContext::TypeError,
|
|---|
| 318 | QString::fromLatin1("Function.prototype.disconnect: cannot disconnect from deleted QObject"));
|
|---|
| 319 | }
|
|---|
| 320 |
|
|---|
| 321 | QMetaMethod sig = meta->method(qtSignal->initialIndex());
|
|---|
| 322 | if (sig.methodType() != QMetaMethod::Signal) {
|
|---|
| 323 | return context->throwError(QScriptContext::TypeError,
|
|---|
| 324 | QString::fromLatin1("Function.prototype.disconnect: %0::%1 is not a signal")
|
|---|
| 325 | .arg(QLatin1String(qtSignal->metaObject()->className()))
|
|---|
| 326 | .arg(QLatin1String(sig.signature())));
|
|---|
| 327 | }
|
|---|
| 328 |
|
|---|
| 329 | QScriptValueImpl receiver;
|
|---|
| 330 | QScriptValueImpl slot;
|
|---|
| 331 | QScriptValueImpl arg0 = context->argument(0);
|
|---|
| 332 | if (context->argumentCount() < 2) {
|
|---|
| 333 | receiver = QScriptValueImpl();
|
|---|
| 334 | slot = arg0;
|
|---|
| 335 | } else {
|
|---|
| 336 | receiver = arg0;
|
|---|
| 337 | QScriptValueImpl arg1 = context->argument(1);
|
|---|
| 338 | if (arg1.isFunction())
|
|---|
| 339 | slot = arg1;
|
|---|
| 340 | else
|
|---|
| 341 | slot = receiver.property(arg1.toString(), QScriptValue::ResolvePrototype);
|
|---|
| 342 | }
|
|---|
| 343 |
|
|---|
| 344 | if (!slot.isFunction()) {
|
|---|
| 345 | return context->throwError(
|
|---|
| 346 | QScriptContext::TypeError,
|
|---|
| 347 | QLatin1String("Function.prototype.disconnect: target is not a function"));
|
|---|
| 348 | }
|
|---|
| 349 |
|
|---|
| 350 | bool ok = eng->scriptDisconnect(self, receiver, slot);
|
|---|
| 351 | if (!ok) {
|
|---|
| 352 | return context->throwError(
|
|---|
| 353 | QString::fromLatin1("Function.prototype.disconnect: failed to disconnect from %0::%1")
|
|---|
| 354 | .arg(QLatin1String(qtSignal->metaObject()->className()))
|
|---|
| 355 | .arg(QLatin1String(sig.signature())));
|
|---|
| 356 | }
|
|---|
| 357 | return eng->undefinedValue();
|
|---|
| 358 | #else
|
|---|
| 359 | Q_UNUSED(eng);
|
|---|
| 360 | return context->throwError(QScriptContext::TypeError,
|
|---|
| 361 | QLatin1String("Function.prototype.disconnect"));
|
|---|
| 362 | #endif // QT_NO_QOBJECT
|
|---|
| 363 | }
|
|---|
| 364 |
|
|---|
| 365 | QScriptValueImpl Function::method_connect(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo)
|
|---|
| 366 | {
|
|---|
| 367 | Q_UNUSED(classInfo);
|
|---|
| 368 |
|
|---|
| 369 | #ifndef QT_NO_QOBJECT
|
|---|
| 370 | if (context->argumentCount() == 0) {
|
|---|
| 371 | return context->throwError(
|
|---|
| 372 | QLatin1String("Function.prototype.connect: no arguments given"));
|
|---|
| 373 | }
|
|---|
| 374 |
|
|---|
| 375 | QScriptValueImpl self = context->thisObject();
|
|---|
| 376 | QScriptFunction *fun = self.toFunction();
|
|---|
| 377 | if ((fun == 0) || (fun->type() != QScriptFunction::Qt)) {
|
|---|
| 378 | return context->throwError(
|
|---|
| 379 | QScriptContext::TypeError,
|
|---|
| 380 | QLatin1String("Function.prototype.connect: this object is not a signal"));
|
|---|
| 381 | }
|
|---|
| 382 |
|
|---|
| 383 | QtFunction *qtSignal = static_cast<QtFunction*>(fun);
|
|---|
| 384 |
|
|---|
| 385 | const QMetaObject *meta = qtSignal->metaObject();
|
|---|
| 386 | if (!meta) {
|
|---|
| 387 | return context->throwError(
|
|---|
| 388 | QScriptContext::TypeError,
|
|---|
| 389 | QString::fromLatin1("Function.prototype.connect: cannot connect to deleted QObject"));
|
|---|
| 390 | }
|
|---|
| 391 |
|
|---|
| 392 | QMetaMethod sig = meta->method(qtSignal->initialIndex());
|
|---|
| 393 | if (sig.methodType() != QMetaMethod::Signal) {
|
|---|
| 394 | return context->throwError(QScriptContext::TypeError,
|
|---|
| 395 | QString::fromLatin1("Function.prototype.connect: %0::%1 is not a signal")
|
|---|
| 396 | .arg(QLatin1String(qtSignal->metaObject()->className()))
|
|---|
| 397 | .arg(QLatin1String(sig.signature())));
|
|---|
| 398 | }
|
|---|
| 399 |
|
|---|
| 400 | {
|
|---|
| 401 | QList<int> overloads = qtSignal->overloadedIndexes();
|
|---|
| 402 | if (!overloads.isEmpty()) {
|
|---|
| 403 | overloads.append(qtSignal->initialIndex());
|
|---|
| 404 | QByteArray signature = sig.signature();
|
|---|
| 405 | QString message = QString::fromLatin1("Function.prototype.connect: ambiguous connect to %0::%1(); candidates are\n")
|
|---|
| 406 | .arg(QLatin1String(qtSignal->metaObject()->className()))
|
|---|
| 407 | .arg(QLatin1String(signature.left(signature.indexOf('('))));
|
|---|
| 408 | for (int i = 0; i < overloads.size(); ++i) {
|
|---|
| 409 | QMetaMethod mtd = meta->method(overloads.at(i));
|
|---|
| 410 | message.append(QString::fromLatin1(" %0\n").arg(QString::fromLatin1(mtd.signature())));
|
|---|
| 411 | }
|
|---|
| 412 | message.append(QString::fromLatin1("Use e.g. object['%0'].connect() to connect to a particular overload")
|
|---|
| 413 | .arg(QLatin1String(signature)));
|
|---|
| 414 | return context->throwError(message);
|
|---|
| 415 | }
|
|---|
| 416 | }
|
|---|
| 417 |
|
|---|
| 418 | QScriptValueImpl receiver;
|
|---|
| 419 | QScriptValueImpl slot;
|
|---|
| 420 | QScriptValueImpl arg0 = context->argument(0);
|
|---|
| 421 | if (context->argumentCount() < 2) {
|
|---|
| 422 | receiver = QScriptValueImpl();
|
|---|
| 423 | slot = arg0;
|
|---|
| 424 | } else {
|
|---|
| 425 | receiver = arg0;
|
|---|
| 426 | QScriptValueImpl arg1 = context->argument(1);
|
|---|
| 427 | if (arg1.isFunction())
|
|---|
| 428 | slot = arg1;
|
|---|
| 429 | else
|
|---|
| 430 | slot = receiver.property(arg1.toString(), QScriptValue::ResolvePrototype);
|
|---|
| 431 | }
|
|---|
| 432 |
|
|---|
| 433 | if (!slot.isFunction()) {
|
|---|
| 434 | return context->throwError(
|
|---|
| 435 | QScriptContext::TypeError,
|
|---|
| 436 | QLatin1String("Function.prototype.connect: target is not a function"));
|
|---|
| 437 | }
|
|---|
| 438 |
|
|---|
| 439 | bool ok = eng->scriptConnect(self, receiver, slot);
|
|---|
| 440 | if (!ok) {
|
|---|
| 441 | return context->throwError(
|
|---|
| 442 | QString::fromLatin1("Function.prototype.connect: failed to connect to %0::%1")
|
|---|
| 443 | .arg(QLatin1String(qtSignal->metaObject()->className()))
|
|---|
| 444 | .arg(QLatin1String(sig.signature())));
|
|---|
| 445 | }
|
|---|
| 446 | return eng->undefinedValue();
|
|---|
| 447 | #else
|
|---|
| 448 | Q_UNUSED(eng);
|
|---|
| 449 | Q_UNUSED(classInfo);
|
|---|
| 450 | return context->throwError(QScriptContext::TypeError,
|
|---|
| 451 | QLatin1String("Function.prototype.connect"));
|
|---|
| 452 | #endif // QT_NO_QOBJECT
|
|---|
| 453 | }
|
|---|
| 454 |
|
|---|
| 455 | } } // namespace QScript::Ecma
|
|---|
| 456 |
|
|---|
| 457 | QT_END_NAMESPACE
|
|---|
| 458 |
|
|---|
| 459 | #endif // QT_NO_SCRIPT
|
|---|