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); } }