Esempio n. 1
0
void QSRegExpClass::write(QSObject *objPtr, const QSMember &mem,
			  const QSObject &val ) const
{
    if (mem.type() != QSMember::Custom) {
	QSWritableClass::write(objPtr, mem, val);
	return;
    }

    Q_ASSERT(objPtr->objectType() == objPtr->objectType()->env()->regexpClass());

    switch (mem.index()) {
    case Source:
	((QSRegExpShared*)objPtr->shVal())->source = val.toString();
	break;
    case Global:
	((QSRegExpShared*)objPtr->shVal())->global = val.toBoolean();
	break;
    case IgnoreCase:
	{
	    bool ic = val.toBoolean();
	    ((QSRegExpShared*)objPtr->shVal())->ignoreCase = ic;
	    ((QSRegExpShared*)objPtr->shVal())->reg.setCaseSensitive(!ic);
	}
	break;
    default:
	QSWritableClass::write(objPtr, mem, val);
    }
}
Esempio n. 2
0
QSObject QSRegExpClass::fetchValue( const QSObject *objPtr,
				    const QSMember &mem ) const
{
    if ( mem.type() != QSMember::Custom )
	return QSWritableClass::fetchValue( objPtr, mem );

    QRegExp *re = regExp( objPtr );
    switch ( mem.index() ) {
    case Valid:
	return createBoolean( re->isValid() );
    case Empty:
	return createBoolean( re->isEmpty() );
    case MLength:
	return createNumber( re->matchedLength() );
    case Source:
	return createString( source(objPtr) );
    case Global:
	return createBoolean( isGlobal(objPtr) );
    case IgnoreCase:
	return createBoolean( isIgnoreCase(objPtr) );
    case CTexts: {
 	QSArray array( env() );
 	QStringList ct = re->capturedTexts();
 	QStringList::ConstIterator it = ct.begin();
 	int i = 0;
 	for ( ; it != ct.end(); ++it, ++i )
 	    array.put( QString::number( i ), createString( *it ) );
	array.put( QString::fromLatin1("length"), createNumber( i ) );
 	return array;
    }
    default:
	return createUndefined();
    }
}
Esempio n. 3
0
/*!
  Adds the Qt Script function \a qtscriptFunction (fully qualified)
  as a transient signal handler for the C++ signal \a signal of the
  object \a sender.

  Example:
  \code
  interpreter->addTransientSignalHandler( myButton, SIGNAL( clicked() ), "classA.obj.calculate" );
  \endcode

  \sa removeTransientSignalHandler()
*/
void QSInterpreter::addTransientSignalHandler(QObject *sender,
                                              const char *signal,
                                              const char *qtscriptFunction)
{
  QuickInterpreter *ip = interpreter();
  QString func = QString::fromLatin1(qtscriptFunction);
  func.left(func.find('('));
  QSObject senderObj = ip->wrap(sender);

  QSObject obj = ip->object(func);
  if (!obj.isFunction()) {
    qDebug("QSInterpreter::addTransientSignalHandler(): '%s' not a function",
           qtscriptFunction);
    return;
  }

  QSObject base = QSFuncRefClass::refBase(obj);
  QSMember member = QSFuncRefClass::refMember(obj);
  QSWrapperShared *sh = ip->wrapperClass()->shared(&senderObj);
  if (!sh->setEventHandler(ip, QString::fromLatin1(signal + 1), 0, member.name(), base)) {
#if defined( QT_CHECK_STATE )
    qWarning("QSInterpreter::addTransientSignalHandler(), "
             "failed to add signal handler: '%s' to '%s'", signal + 1, qtscriptFunction);
#endif
  }
}
Esempio n. 4
0
// ECMA 8.6.2.5
bool QSObject::deleteProperty(const QString &p)
{
  QSMember mem;
  if (!objectType()->member(this, p, &mem) ||
      mem.type() == QSMember::Identifier)
    return TRUE;
  return objectType()->deleteProperty(this, mem);
}
Esempio n. 5
0
void QSRectClass::write(QSObject *o, const QSMember &mem,
                        const QSObject &val) const
{
  if (mem.type() == QSMember::Custom) {
    int i = val.toInteger();
    switch (mem.idx) {
      case 0:
      case 1:
        rect(o)->setX(i);
        break;
      case 2:
      case 3:
        rect(o)->setY(i);
        break;
      case 4:
        rect(o)->setWidth(i);
        break;
      case 5:
        rect(o)->setHeight(i);
        break;
      case 6:
        rect(o)->setRight(i);
        break;
      case 7:
        rect(o)->setBottom(i);
        break;
      case 8:
        break;
      default:
        qFatal("QSRectClass::write: unhandled case");
    }
  } else {
    QSClass::write(o, mem, val);
  }
}
Esempio n. 6
0
QSObject QSRectClass::fetchValue(const QSObject *o,
                                 const QSMember &mem) const
{
  if (mem.type() == QSMember::Custom) {
    switch (mem.idx) {
      case 0:
      case 1:
        return createNumber(rect(o)->x());
      case 2:
      case 3:
        return createNumber(rect(o)->y());
      case 4:
        return createNumber(rect(o)->width());
      case 5:
        return createNumber(rect(o)->height());
      case 6:
        return createNumber(rect(o)->right());
      case 7:
        return createNumber(rect(o)->bottom());
      case 8:
        return pointClass()->construct(rect(o)->center());
      default:
        qFatal("QSRectClass::fetchValue: unhandled case");
        return createUndefined();
    }
  }
  return QSClass::fetchValue(o, mem);
}
Esempio n. 7
0
/*!
  Tries to resolve a member named \a name. If it is found \a mem is
  initialized with the result and the class defining this member is
  returned. In case of a failed search, 0 is returned and the content
  of \a mem is undefined.
*/
const QSClass *QSObject::resolveMember(const QString &name,
                                       QSMember *mem,
                                       const QSClass *owner,
                                       int *offset) const
{
  Q_ASSERT(offset);
  Q_ASSERT(mem);
  Q_ASSERT(!name.isEmpty());
  if (!owner)
    owner = objectType();
  QPtrList<QSClass> enclosing;
  QSMember stackedMember;
  while (owner) {
    if (owner->member(*offset == 0 ? this : 0, name, mem)) {
      return owner;
    } else if (mem->type() == QSMember::Identifier && !stackedMember.isDefined()) {
      stackedMember = *mem;
    }
    if (owner->enclosingClass())
      enclosing.append(owner->enclosingClass());
    owner = owner->base();
  }

  const QSClass *eClass = enclosing.first();
  while (eClass) {
    const QSClass *enc =
      resolveMember(name, mem, eClass, &(++(*offset)));
    if (enc) {
      if (mem->type() == QSMember::Identifier)
        if (!stackedMember.isDefined())
          stackedMember = *mem;
        else
          return enc;
    } else {
      --(*offset);
    }
    eClass = enclosing.next();
  }

  if (stackedMember.isDefined()) {
    *mem = stackedMember;
    return stackedMember.owner();

  }

  return 0;
}
Esempio n. 8
0
QSObject QSEnv::resolveValue(const QString &ident) const
{
    Q_ASSERT(!ident.isEmpty());
    ScopeChain::const_iterator it = scopeChain->begin();
    QSMember mem;
    int offset;
    while (it != scopeChain->end() && (*it).isValid()) {
        offset = 0;
        const QSClass *cl = (*it).resolveMember(ident, &mem, (*it).objectType(), &offset);
        if (cl && mem.type() != QSMember::Identifier) {
            while (offset--)
                it++;
            return cl->fetchValue(&(*it), mem);
        }
        it++;
    }

    return QSObject();
}
Esempio n. 9
0
void QSVarBindingNode::check( QSCheckData *c )
{
    var->check( c );
    if ( assign )
	assign->check( c );

    if (!c->directLookupEnabled()) {
        c->addError( this, QString::fromLatin1( "QSA does not support declaring variables inside "
                                                "a 'with' block" ));

        return;
    }

    int attrs = c->lastAttributes();
    QSClass * cl = c->currentScope();
    QSMember m;
    if ( cl->member( 0, var->identifier(), &m ) ) {
	if( cl->asClass() ) {
	    c->addError( this, QString::fromLatin1( "Variable '%1' has already been "
					"declared in class '%2'" )
			 .arg( var->identifier() )
			 .arg( cl->identifier() ) );
	    return;
	}
	m = QSMember( QSMember::Variable, 0, attrs );
	cl->replaceMember( var->identifier(), &m );
	idx = m.index();
    } else {
	idx = cl->addVariableMember( var->identifier(), attrs );
    }

    // store pointer to init node if this is a class member
    QSClassClass *clcl = cl->asClass();
    if ( clcl ) {
	if( attrs & AttributeStatic )
	    clcl->addStaticInitializer( assign );
	else
	    clcl->addMemberInitializer( assign );
	idx = -1; // Disable the variable binding node.
    }
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
QSObject QSStringClass::fetchValue( const QSObject *objPtr,
				    const QSMember &mem ) const
{
    if ( mem.type() == QSMember::Custom )
	if ( mem.idx == 0 ) {
	    return createNumber( objPtr->sVal().length() );
	} else {
	    qFatal( "QSStringClass::fetchValue: unhandled member" );
	    return createUndefined();
	}
    else
	return QSClass::fetchValue( objPtr, mem );
}
Esempio n. 12
0
void QSResolveNode::check( QSCheckData *c )
{
    if ( !c->directLookupEnabled() )
	return;
    QSClass * cl = c->currentScope();
    QSClass *cont = cl;
    int uplvl = 0;
    int blocks = 0;
    QSMember member;
    while ( cont ) {
	QSMember mem;
	if ( cont->member( 0, ident, &mem ) ) {
	    if ( mem.type()==QSMember::Variable && !mem.isStatic() ) {
		member = mem;
		break;
	    }
	}
	uplvl++;
	cont = cont->enclosingClass();
    }
    if( member.isDefined() ) {

	/* If the containing class has an undefined base, the indexes will be moved
	   when the we call QSAbstractBaseClass::replace() and the lookup info
	   will be crap. Therefore, we don't create it. */
	QSClass *tmp = cont->base();
	while (tmp) {
	    if (tmp->name() == QString::fromLatin1("AbstractBase"))
		return;
	    tmp = tmp->base();
	}

	// Due to special handling of block scopes in the global object...
	if( cont==c->env()->globalClass() )
 	    uplvl+=blocks;
   	info = new QSLookupInfo( uplvl, member );
    }
}
Esempio n. 13
0
QSObject QSPixmapClass::fetchValue( const QSObject *obj,
				    const QSMember &mem ) const
{
    if ( mem.type() == QSMember::Custom ) {
	switch ( mem.index() ) {
	case Width:
	    return createNumber( pixmap( obj )->width() );
	case Height:
	    return createNumber( pixmap( obj )->height() );
	case Rect:
	    return rectClass()->construct( pixmap( obj )->rect() );
	case Size:
	    return sizeClass()->construct( pixmap( obj )->size() );
	case Depth:
	    return createNumber( pixmap( obj )->depth() );
	default:
	    qWarning( "QSPixmapClass::fetchValue: unhandled case" );
	    return createUndefined();
	}
    } else {
	return QSClass::fetchValue( obj, mem );
    }
}
Esempio n. 14
0
static QSObject qsDisconnect( QSEnv *env )
{
    QS_CONNECT_INIT( disconnect );

    // find receiver and slot
    QObject *receiver = 0;
    int member_index = -1;
    const char *slotName = sl.ascii();
    if ( recIfaces ) {
	for ( int i = (int)recIfaces->count()-1; i >= 0; --i ) {
	    receiver = recIfaces->at( i );
	    member_index = receiver->metaObject()->findSlot( slotName, TRUE );
	    if ( member_index > 0 && signal_index > 0 ) {
		// regular signal/slot connection
		QObject::disconnectInternal( sender, signal_index, receiver,
					     QSLOT_CODE, member_index );
		return env->createUndefined();
	    }
	}
    }

    if ( signal_index == -1 ) {
	QString msg = QString::fromLatin1("Can't find signal named ") + sig;
	return env->throwError( SyntaxError, msg );
    }

    if ( recIfaces ) {
	sendObj->removeEventHandler( sig, recIfaces->at( 0 ), sl.left( sl.find( '(' ) ) );
    } else {
	QSObject base = QSFuncRefClass::refBase( arg2 );
	QSMember member = QSFuncRefClass::refMember( arg2 );
	sendObj->removeEventHandler( sig, 0, member.name(), base );
    }

    return env->createUndefined();
}
Esempio n. 15
0
QSObject QSPointClass::fetchValue(const QSObject *obj,
                                  const QSMember &mem) const
{
  if (mem.type() == QSMember::Custom) {
    switch (mem.idx) {
      case 0:
        return createNumber(point(obj)->x());
      case 1:
        return createNumber(point(obj)->y());
      default:
        qFatal("QSPointClass::fetchValue: unhandled case");
        return createUndefined();
    }
  }
  return QSClass::fetchValue(obj, mem);
}
Esempio n. 16
0
QSObject QSSizeClass::fetchValue(const QSObject *objPtr,
                                 const QSMember &mem) const
{
  if (mem.type() == QSMember::Custom) {
    switch (mem.idx) {
      case 0:
        return createNumber(size(objPtr)->width());
      case 1:
        return createNumber(size(objPtr)->height());
      default:
        qFatal("QSSizeClass::fetchValue, unhandled case");
        return createUndefined();
    }
  }
  return QSClass::fetchValue(objPtr, mem);
}
Esempio n. 17
0
void QSPointClass::write(QSObject *objPtr, const QSMember &mem,
                         const QSObject &val) const
{
  if (mem.type() == QSMember::Custom) {
    switch (mem.idx) {
      case 0:
        point(objPtr)->setX(val.toInteger());
        break;
      case 1:
        point(objPtr)->setY(val.toInteger());
        break;
      default:
        qDebug("QSPointClass::write() Unhandled case");
    }
  } else {
    QSClass::write(objPtr, mem, val);
  }
}
Esempio n. 18
0
void QSSizeClass::write(QSObject *objPtr, const QSMember &mem,
                        const QSObject &val) const
{
  if (mem.type() == QSMember::Custom) {
    switch (mem.idx) {
      case 0:
        size(objPtr)->setWidth(val.toInteger());
        break;
      case 1:
        size(objPtr)->setHeight(val.toInteger());
        break;
      default:
        qFatal("QSSizeClass::write, unhandled case");
        break;
    }
  } else {
    QSClass::write(objPtr, mem, val);
  }
}
Esempio n. 19
0
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 );
}
Esempio n. 20
0
void QSClassDefNode::check( QSCheckData *c )
{
//     qDebug( "Class noticed: " + c->globalName( ident ) );

    // forward declaration ?
    if ( !body ) {
	c->addWarning( this, QString::fromLatin1("Forward declarations not supported, yet") );
	return;
    }

    if ( attrs )
	attrs->check( c );
    else
	c->setLastAttributes( AttributeNone );
    int as = c->lastAttributes();

    // base class
    QSClass *b = c->env()->objectClass();
    if ( type ) {
	type->check( c );
	if ( c->hasError() )
	    return;
	Q_ASSERT( c->lastType() );
	b = c->lastType();
	// try to cast
	if ( b->isFinal() ) {
	    c->addError( this, QSErrClassBaseFinal,
			 QString::fromLatin1("Base class has been declared final") );
	    return;
	}
    }

    // create new class description
    QSClass *scope = c->currentScope();
    if ( scope->name()==QString::fromLatin1("Class") ) {
	if ( !(as&AttributeStatic) ) {
	    c->addError( this, QSErrNestedClass,
			 QString::fromLatin1( "Nested class '%1' in class '%2' must be "
				  "declared static" )
			 .arg( ident ).arg( scope->identifier() ) );
	    return;
	}
    } else if ( as&AttributeStatic ) {
        c->addError( this, QSErrAttributeConflict,
		     QString::fromLatin1( "Static class '%1' cannot be declared outside "
			      "a class" ).arg( ident ) );
	return;
    } else if ( scope->name()==QString::fromLatin1("FunctionScope") ) {
	c->addError( this, QSErrNestedClass,
		     QString::fromLatin1( "Class '%1' cannot be declared inside function '%2'" )
		     .arg( ident ).arg( scope->identifier() ) );
	return;
    }

    QSClass *absBase = c->env()->classByIdentifier(ident);
    bool usesAbstractBase = absBase && absBase->name() == QString::fromLatin1("AbstractBase");

    QSClassClass *cl = new QSClassClass( b, as, ident );
    ref(); // Compensate for setClassDefNode below. Dereffed in QSClassClass destructor.
    cl->setClassDefNode( this );
    cl->setEnclosingClass( scope );

    QSMember member;
    QSObject tobj = c->env()->typeClass()->createType(cl);
    if( scope->member( 0, cl->identifier(), &member ) ) {
	scope->replaceMember( cl->identifier(), &member, tobj );
    } else {
	scope->addStaticVariableMember( cl->identifier(), tobj,
					AttributeExecutable );
    }

    c->enterClass( cl );
    body->check( c );
    c->leaveClass();

    // if there is a function with the same name it becomes the constructor
    QSMember ctor;
    if ( cl->member( 0, ident, &ctor ) ) {
	if ( ctor.isExecutable() ) {
	    cl->setHasDefaultConstructor( true );
	} else {
	    qWarning( "Constructor is no function" ); // pedantic
	}
    }

    cl->setClassBodyNode( body );
    QSFunctionScopeClass *fs = new QSFunctionScopeClass( c->env()->objectClass() );
    fs->setEnclosingClass( cl );
    body->setScopeDefinition( fs );
    fs->setFunctionBodyNode(body);

    // will be used in execute()
    this->cldef = cl;

    // If the classname exists in env and is a previously undefined type, we have to
    // replace it with this one.
    if (usesAbstractBase) {
	((QSAbstractBaseClass*)absBase)->replace(cl);
    }

}