Example #1
0
void QSEngine::registerType(QSClass *c)
{
  QSClass *glob = env()->globalClass();
  glob->addStaticVariableMember(c->identifier(),
                                env()->typeClass()->createType(c),
                                AttributeExecutable);
}
Example #2
0
QSObject QSObject::getQualified(const QString &name) const
{
  QSObject obj = *this;
  QString s = name;

  // break up dotted notation ns like P1.P2.P3
  while (!s.isEmpty()) {
    int pos = s.find('.');
    if (pos < 0)
      pos = s.length();
    // don't overwrite any existing objects, reuse them
    QString cname = s.left(pos);
    QSObject tmpobj = obj.get(cname);

    // Search the class hieriarchy for member if undefined
    if (!tmpobj.isDefined()) {
      QSClass *base = obj.objectType()->base();
      while (base && !tmpobj.isDefined()) {
        tmpobj = base->get(&obj, cname);
        base = base->base();
      }
      if (!tmpobj.isDefined())
        return env()->createUndefined();
    }
    obj = tmpobj;
    s = s.mid(pos + 1);
  }
  return obj;
}
Example #3
0
void QSParameterNode::check( QSCheckData * c ) {
    Q_ASSERT( c->inFunction() );

    QSClass * cl = c->currentScope();

    if (id == QString::fromLatin1("arguments")) {
        c->addError(this, QString::fromLatin1("Parameter 'arguments' is a predefined value in function '%1'. Use different parameter name.")
                    .arg(cl->identifier()));
        return;
    }

    QSMember m;
    if( cl->member( 0, id, &m ) ) {
	c->addError( this, QString::fromLatin1( "Parameter '%1' already declared in function '%2'" )
		     .arg( id )
		     .arg( cl->identifier() ) );
	return;
    }

    cl->addVariableMember( id, AttributeNone );

    if( next )
	next->check( c );

    // create a member from id
    // add member to current scope
    // next.check();
}
Example #4
0
void QSCatchNode::checkStatement( QSCheckData *c )
{
    checkIfGlobalAllowed( c );
    QSClass *cl = c->currentScope();
    index = cl->addVariableMember( ident, AttributeNone );
    block->check( c );
}
Example #5
0
QSClass *QSEnv::classByIdentifier(const QString &n)
{
    QPtrListIterator<QSClass> it(classList);
    QSClass *cl;
    while ((cl = it()) != 0) {
        if (cl->identifier() == n)
            return cl;
    }
    return 0;
}
QStringList QuickInterpreter::classes() const
{
    QPtrList<QSClass> clsLst = env()->classes();
    QStringList lst;
    for ( QSClass *cls = clsLst.first(); cls; cls = clsLst.next() ) {
	if ( cls->asClass() )
	    lst << cls->asClass()->identifier();
    }
    return lst;
}
Example #7
0
void QSCheckData::registerType( QSClass *t )
{
    Q_ASSERT( !t->asClass() );
    QSClass * scope = currentScope();
    // ### Uncertain as to use identifier or name here?
    QSMember member;
    Q_ASSERT( !scope->member( 0, t->identifier(), &member ) );
    scope->addStaticVariableMember( t->identifier(),
				    env()->typeClass()->createType(t),
				    AttributeExecutable );
}
Example #8
0
void QSProgramNode::check( QSCheckData *c )
{
    if ( source )
	source->check( c );
    QSClass *cl = c->currentScope();
    if( cl->numVariables() < c->varBlockCount() ) {
	cl->setNumVariables( c->varBlockCount() );
    }
    ( (QSInstanceData*) c->env()->currentScope().shVal() )->
	ensureSize( c->currentScope()->numVariables(),
		    c->env()->createUndefined() );
}
Example #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.
    }
}
Example #10
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 );
    }
}
Example #11
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);
    }

}
Example #12
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 );
}
Example #13
0
void QSEnv::clear()
{
    shutDown = TRUE;

    Q_ASSERT(scopeChain);   // protection against consecutive calls
    delete scopeChain;
    scopeChain = 0;

    // lose class references
    thVal.invalidate();
    exVal.invalidate();
    retVal.invalidate();

    QPtrListIterator<QSClass> it(classList);
    QSClass *cur;
    while ((cur = it()))
        cur->finalize();

    // invalidate & delete QSShared that might still hang
    // around due to cyclic references
    QSShared *sh = sharedList;
    while ((sh = sh->next))
        sh->invalidate();

#if QS_DEBUG_MEM == 1
    // flag check for in ~QSObject()
    qs_finalDeletion = TRUE;
#endif
    sh = sharedList->next;
    while (sh) {
        QSShared *next = sh->next;
        delete sh;
        sh = next;
    }
    delete sharedList;
#if QS_DEBUG_MEM == 1
    qs_finalDeletion = FALSE;
#endif

    it = QPtrListIterator<QSClass>(classList);
    while ((cur = it()))
        cur->clear();

    classList.clear();

    objClass = 0;
    undefClass = 0;
    nilClass = 0;
    boolClass = 0;
    numClass = 0;
    strClass = 0;
    charClass = 0;
    typClass = 0;
    datClass = 0;
    matClass = 0;
    regClass = 0;
    arrClass = 0;
    errClass = 0;
    globClass = 0;
    argsClass = 0;
    dynClass = 0;
    refClass = 0;
    dbgClass = 0;
    sysClass = 0;
    shutDown = FALSE;
}