void qsa_slot_callback(QObject *_this, int callId, int paramCount, const QMetaType::Type *types, const QByteArray *typeNames, void *argumentList[]) { // printf("qsa_slot_callback, id=%d\n", callId); QuickInterpreter *ip = static_cast<QuickInterpreter *>(_this); QSAConnection connection = ip->scriptSlot(callId); Q_ASSERT(connection.sender); Q_ASSERT(connection.signal.length()); Q_ASSERT(connection.function_ref.isValid()); QSEnv *env = ip->env(); QSList arguments; for (int i=1; i<paramCount; ++i) { QSATypeInfo info; info.name = typeNames[i]; info.id = types[i]; QSObject val = convert_qt2qsa(env, argumentList[i], info, _this); Q_ASSERT(val.isValid()); arguments.append(val); } QSObject func_base = QSFuncRefClass::refBase(connection.function_ref); QString func_name = QSFuncRefClass::refMember(connection.function_ref).name(); ip->call(func_base, func_name, arguments); }
bool QSObject::strictEquals(const QSObject &other) const { Q_ASSERT(isValid()); Q_ASSERT(other.isValid()); QSEqualsResult eq = clss->isStrictEqual(*this, other); if (eq == EqualsUndefined) eq = other.clss->isStrictEqual(other, *this); return eq == EqualsIsEqual; }
void QSEnv::printScopeChain(const ScopeChain *chain) { QStringList lst; ScopeChain::const_iterator it = chain->begin(); while (it != chain->end()) { QSObject obj = *it; QString tmp = !obj.isValid() ? QString::fromLatin1("#") : obj.objectType()->identifier(); lst.append(tmp); it++; } printf("Current scope is:: %s\n", lst.join(QString::fromLatin1(", ")).latin1()); }
bool QSEngineImp::call( QSObject *scope, const QString &func, const QSList &args ) { init(); QSObject t; if ( !scope || !scope->isValid() ) { t = env()->globalObject(); scope = &t; } QSObject v = scope->getQualified(func); Q_ASSERT(v.isValid()); if ( !v.isDefined() ) { if (func != QString::fromLatin1("main")) { errType = ReferenceError; errMsgs.append( QString::fromLatin1("Unknown function: ") + func ); errLines.append( 0 ); } return false; } if ( !v.isFunction() ) { errType = TypeError; errMsgs.append( func + QString::fromLatin1(" is not a function. Call failed.") ); errLines.append( 0 ); return false; } QSObject res = v.invoke( QSMember(), args ); if ( env()->isExceptionMode() ) { QSObject err = env()->exception(); errType = 99; /* TODO */ errLines.append(QSErrorClass::errorLine(&err)); errMsgs.append(QSErrorClass::errorName(&err) + QString::fromLatin1(". ") + QSErrorClass::errorMessage(&err)); #ifdef QSDEBUGGER if (dbg) dbg->setSourceId(QSErrorClass::errorSourceId(&err)); #endif env()->clearException(); return false; } else { errType = 0; errLines.clear(); errMsgs.clear(); // return value retVal = res; return true; } }
void QSList::remove( const QSObject &obj ) { if ( !obj.isValid() ) return; #if 0 // ### ListNode *n = hook->next; while ( n != hook ) { if ( n->member.imp() == obj.imp() ) { erase( n ); return; } n = n->next; } #endif }
void QuickInterpreter::timerEvent(QTimerEvent *e) { int id = e->timerId(); QSObject function = m_timers[id]; Q_ASSERT(function.isValid()); Q_ASSERT(function.isFunction()); QSList arguments; arguments.append(env()->createNumber(id)); QSObject func_base = QSFuncRefClass::refBase(function); QString func_name = QSFuncRefClass::refMember(function).name(); call(func_base, func_name, arguments); }
QSArgument QuickInterpreter::convertToArgument( const QSObject &o ) { if( !o.isValid() ) return QSArgument(); const QSClass *cl = o.objectType(); if( cl->name() == QString::fromLatin1("QObject") ) { QSWrapperShared *shared = (QSWrapperShared*) o.shVal(); if (shared->objects.isEmpty()) return QSArgument(); return QSArgument( shared->objects[0] ); } else if( cl == ptrClass ) { Q_ASSERT( ptrClass->pointer( &o ) ); return QSArgument( ptrClass->pointer( &o ) ); } else { return QSArgument( o.toVariant( QVariant::Invalid ) ); } }
static bool hasMember(QSEnv *env, const QString &function, QSMember::Type type) { QSObject o = env->globalObject(); QSMember member; QStringList names = function.split(QString::fromLatin1(".")); int nameCount = names.count(); for (QStringList::ConstIterator it = names.begin(); it != names.end(); ++it, --nameCount) { if (nameCount==1) { if (o.objectType() == env->typeClass()) return QSTypeClass::classValue(&o)->member(0, *it, &member) && member.type() == type; else if (o.objectType()->member(&o, *it, &member)) return o.objectType()->member(0, *it, &member) && member.type() == type; } else { o = o.get(*it); if (!o.isValid()) return false; } } return false; }
QVariant QuickInterpreter::convertToArgument(const QSObject &o) { if(!o.isValid()) return QVariant(); const QSClass *cl = o.objectType(); if(cl->name() == QString::fromLatin1("QObject")) { QSWrapperShared *shared = (QSWrapperShared*) o.shVal(); if (shared->objects.isEmpty()) return QVariant(); QVariant v(QMetaType::QObjectStar, static_cast<QObject *>(0)); qVariantSetValue<QObject *>(v, shared->objects[0]); return v; } else if(cl == ptrClass) { Q_ASSERT(ptrClass->pointer(&o)); QVariant v(QMetaType::VoidStar, static_cast<void *>(0)); qVariantSetValue<void *>(v, ptrClass->pointer(&o)); return v; } else { return QVariant(o.toVariant(QVariant::Invalid)); } }
QString Debugger::varInfo(const QString &ident) const { if (!eng) return QString(); int dot = ident.find('.'); if (dot < 0) dot = ident.length(); QString sub = ident.mid(0, dot); QSObject obj; // resolve base if (sub == QString::fromLatin1("||Global||")) { obj = env()->globalObject(); } else if (sub == QString::fromLatin1("||Activation||")) { obj = env()->currentScope(); } else if (sub == QString::fromLatin1("this")) { obj = env()->thisValue(); } else { obj = env()->resolveValue(ident); if (!obj.isValid()) return QString(); } // look up each part of a.b.c. while (dot < (int)ident.length()) { int olddot = dot; dot = ident.find('.', olddot + 1); if (dot < 0) dot = ident.length(); sub = ident.mid(olddot + 1, dot - olddot - 1); obj = obj.get(sub); if (!obj.isDefined()) break; } return sub + QString::fromLatin1("=") + obj.debugString(); }
void QSAEditor::completeQMetaObject( const QMetaObject *meta, const QString &, QVector<CompletionEntry> &res, int flags, QSObject &obj ) { QMap<QString, bool> propMap; bool includeSuperClass = (flags & IncludeSuperClass) == IncludeSuperClass; // properties const QMetaObject *m = meta; int num = m->propertyCount(); for ( int j = 0; j < num; ++j ) { const QMetaProperty mp = m->property( j ); if ( propMap.find( QString::fromLatin1(mp.name()) ) != propMap.end() ) continue; CompletionEntry c; propMap[QLatin1String(mp.name())] = false; c.type = QLatin1String("property"); c.text = mp.name(); c.prefix = QString(); c.postfix2 = mp.typeName(); QuickInterpreter::cleanType( c.postfix2 ); if ( !c.postfix2.isEmpty() ) c.postfix2.prepend( QLatin1String(" : ") ); res.append( c ); } if ( includeSuperClass && obj.isValid() && !obj.isUndefined() ) { QStringList vars = interpreter()->variablesOf( obj, true ); QStringList::iterator it; for ( it = vars.begin(); it != vars.end(); ++it ) { CompletionEntry c; c.type = QLatin1String("variable"); c.text = *it; c.prefix = QString(); c.postfix2 = QString(); res << c; } } // functions QList<Property> lst; QList<Property>::Iterator pit; getSlots( meta, lst, includeSuperClass, false, false ); for ( pit = lst.begin(); pit != lst.end(); ++pit ) { CompletionEntry c; c.type = QLatin1String("function"); c.text = (*pit).name; c.postfix = QLatin1String("()"); c.postfix2 = (*pit).type; if ( !c.postfix2.isEmpty() ) c.postfix2.prepend( QString::fromLatin1(" : ") ); res << c; } if ( includeSuperClass && obj.isValid() && !obj.isUndefined() ) { QStringList funcs = interpreter()->functionsOf( obj, true, true, true ); QStringList::Iterator it; for ( it = funcs.begin(); it != funcs.end(); ++it ) { CompletionEntry c; c.type = QLatin1String("function"); c.text = *it; c.prefix = QString(); c.postfix2 = QString(); res << c; } } // enum values m = meta; for (int k=0; k<m->enumeratorCount(); ++k) { QMetaEnum me = m->enumerator(k); for (int l=0; l<me.keyCount(); ++l) { CompletionEntry c; c.type = QLatin1String("enum"); c.text = QLatin1String(me.key(l)); c.prefix = QString(); c.postfix2 = QLatin1String(me.name()); if (!c.postfix2.isEmpty()) c.postfix2.prepend( QString::fromLatin1(" : ") ); res << c; } } if ( includeSuperClass && obj.isValid() && !obj.isUndefined() ) { QStringList classes = interpreter()->classesOf( obj ); QStringList::Iterator it; for ( it = classes.begin(); it != classes.end(); ++it ) { CompletionEntry c; c.type = QLatin1String("class"); c.text = *it; c.prefix = QString(); c.postfix2 = QString(); res << c; } } }
void QSAEditor::doObjectCompletion() { QTextCursor cursor = textCursor(); cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor); QString objectName = cursor.selectedText(); if (objectName.endsWith(QLatin1Char('-'))) objectName.chop(1); objectName = objectName.simplified(); QString object = resolveFullyQualifiedValue(objectName, parseAssignments(functionCode())); bool assumedStatic = false; QSCompletionObject o; if(objectName == object) { QSObject stobj = env()->globalObject().get(object); if(stobj.isValid() && stobj.objectType()->valueType() == TypeClass) { #if defined ( QSA_COMPLETION_DEBUG ) printf(" -> assuming static\n"); #endif o = stobj; assumedStatic = true; } } if(o.type == QSCompletionObject::TNull) { o = queryObject(object); } #if defined ( QSA_COMPLETION_DEBUG ) printf(" -> type is: %d\n", o.type); #endif o.resolve(); if (o.isNull()) return; QVector<CompletionEntry> res; QSObject nullObject; switch (o.type) { case QSCompletionObject::TQSObject: #if defined ( QSA_COMPLETION_DEBUG ) printf(" -> objectType is: %s\n", o.qsobj.objectType()->name().latin1()); #endif if(o.qsobj.objectType()->name() == QString::fromLatin1("FactoryObject")){ QSObject sinst = ( (QSFactoryObjectProxy*) o.qsobj.objectType() )->staticInstance(); if(!sinst.isValid()) return; QSWrapperShared *shared = (QSWrapperShared*) sinst.shVal(); completeQObject( shared->objects, object, res ); break; } completeQSObject(o.qsobj, res, !assumedStatic); break; case QSCompletionObject::TQMetaObject: completeQMetaObject(o.meta, object, res, IncludeSuperClass, nullObject); break; case QSCompletionObject::TQObject: completeQObject(o.qobj, object, res); break; case QSCompletionObject::TNull: break; } if (!res.isEmpty()) { QFrame *f = new QFrame(0, Qt::Popup); f->setAttribute(Qt::WA_DeleteOnClose); QWidget *box = new CompletionBox(this, res); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(box); layout->setMargin(0); f->setLayout(layout); f->move(mapToGlobal(cursorRect().bottomLeft())); f->show(); box->setFocus(); } }
// eval() static QSObject qsEval( QSEnv *env ) { QSObject x = env->arg( 0 ); if ( !x.isString() ) { return x; } else { QSEngineImp *eimp = env->engine()->imp(); QString s = x.toString(); QSNode *progNode = 0; { // begin mutext locker QMutexLocker locker(qsa_lexer_mutex()); QSLexer::lexer()->setCode( s, #ifdef QSDEBUGGER eimp->sourceId() #else 0 #endif ); int yp = qsyyparse(); progNode = QSProgramNode::last(); if ( yp || QSLexer::lexer()->lexerState() == QSLexer::Bad ) { if (!progNode && progNode->deref()) delete progNode; return env->throwError( SyntaxError ); } } // end mutext locker QSCheckData data( env ); QSObject scopeTop = env->currentScope(); postfixAdd( scopeTop.objectType(), &data ); QSEvalScopeClass *cl = new QSEvalScopeClass( env->objectClass() ); data.enterEval( cl ); progNode->check( &data ); if ( data.hasError() ) { if (!progNode->deref()) delete progNode; return env->throwError( EvalError, data.errorMessages().first(), data.errorLines().first() ); } QSList empty; env->pushScope( cl->construct( empty ) ); // ### delete tmp scope class QSObject res = ((QSProgramNode*)progNode)->execute( env ); if (!progNode->deref()) delete progNode; env->popScope(); if ( env->isReturnValueMode() ) return res; else if ( env->isNormalMode() ) { if ( res.isValid() ) return res; else return env->createUndefined(); } else return res; } }
void QSFuncDeclNode::check( QSCheckData *c ) { // qDebug( "Function noticed: " + c->globalName(ident) ); if ( attrs ) attrs->check( c ); else c->setLastAttributes( AttributeNone ); int as = c->lastAttributes(); QSClass * cl = c->currentScope(); Q_ASSERT( cl ); if ( (as&AttributeStatic) && cl->name() != QString::fromLatin1("Class") ) { c->addError( this, QSErrAttrStaticContext, QString::fromLatin1( "Function '%1' cannot be declared static " "outside a class" ).arg( ident ) ); return; } // A bit of magic fail early when trying to overwrite a context. if (c->inGlobal()) { QSObject object = c->env()->globalObject().get(ident); if (object.isValid()) { if (object.objectType()->name() == QString::fromLatin1("QObject")) { c->addError(this, QString("Cannot declare function '%1', already a global object " "present with same name").arg(ident)); return; } } } QSMember m; m.setPrivate( as&AttributePrivate ); if ( cl->member( 0, ident, &m ) ) { QSMember mem( body, as ); cl->replaceMember( ident, &mem ); } else { cl->addFunctionMember( ident, body, as ); } int tmpVarBlockCount = c->varBlockCount(); c->setVarBlockCount( 0 ); QSFunctionScopeClass * fscope = new QSFunctionScopeClass( c->env()->objectClass(), this ); fscope->setEnclosingClass( cl ); body->setScopeDefinition( fscope ); fscope->setFunctionBodyNode(body); c->enterFunction( fscope ); if( param ) param->check( c ); body->check( c ); c->leaveFunction(); if( c->varBlockCount()>fscope->numVariables() ) fscope->setNumVariables( c->varBlockCount() ); c->setVarBlockCount( tmpVarBlockCount ); // Calculate the number of arguments int count = 0; QSParameterNode * node = param; while( node ) { count++; node = node->nextParam(); } fscope->setNumArguments( count ); // unset attributes c->setLastAttributes( AttributeNone ); }
bool QSEngine::evaluate(const QSObject &thisV, const QString &code, int linezero) { return rep->evaluate(code, thisV.isValid() ? &thisV : 0, linezero); }