void QSFuncExprNode::check( QSCheckData *c ) { // ### Check attributes and refactor code with QSFuncDeclNode QSClass * cl = c->currentScope(); QSFunctionScopeClass * fscope = new QSFunctionScopeClass( c->env()->objectClass() ); fscope->setEnclosingClass( cl ); body->setScopeDefinition( fscope ); fscope->setFunctionBodyNode(body); c->enterFunction( fscope ); if( param ) param->check( c ); body->check( c ); c->leaveFunction(); // Calculate the number of arguments int count = 0; QSParameterNode * node = param; while( node ) { count++; node = node->nextParam(); } fscope->setNumArguments( count ); }
QSObject QSFuncRefClass::construct( const QSList &args ) const { // ### QString p = QString::fromLatin1(""); QString body; int argsSize = args.size(); if (argsSize == 0) { body = ""; } else if (argsSize == 1) { body = args[0].toString(); } else { p = args[0].toString(); for (int k = 1; k < argsSize - 1; k++) p += QString::fromLatin1(",") + args[k].toString(); body = args[argsSize-1].toString(); } QSLexer::lexer()->setCode( body, -1 ); if ( qsyyparse() ) { /* TODO: free nodes */ return env()->throwError( SyntaxError, QString::fromLatin1("Syntax error in function body") ); } QSFunctionScopeClass *scope = new QSFunctionScopeClass( env()->objectClass() ); QSFunctionBodyNode * bodyNode = QSProgramNode::last(); bodyNode->setScopeDefinition( scope ); scope->setFunctionBodyNode(bodyNode); QSMember mem( bodyNode ); // parse parameter list. throw syntax error on illegal identifiers int len = p.length(); const QChar *c = p.unicode(); int i = 0, params = 0; QString param; while (i < len) { while (*c == ' ' && i < len) c++, i++; if ( QSLexer::isIdentLetter( c->unicode() ) ) { // else error param = QString(c, 1); c++, i++; while (i < len && ( QSLexer::isIdentLetter( c->unicode() ) || QSLexer::isDecimalDigit( c->unicode() ) ) ) { param += QString(c, 1); c++, i++; } while (i < len && *c == ' ') c++, i++; if (i == len) { int index = scope->addVariableMember( param, AttributeNone ); Q_ASSERT( params==index ); params++; break; } else if (*c == ',') { int index = scope->addVariableMember( param, AttributeNone ); Q_ASSERT( params==index ); params++; c++, i++; continue; } // else error } return env()->throwError( SyntaxError, QString::fromLatin1("Syntax error in parameter list") ); } scope->setNumArguments( params ); return createReference( env()->currentScope(), mem ); }
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 ); }