void Parser::onMethod(Token &out, Token &modifiers, Token &ret, Token &ref, Token &name, Token ¶ms, Token &stmt, bool reloc /* = true */) { ClassStatementPtr cs = peekClass(); MethodStatementPtr ms = peekFunc()->unsafe_cast<MethodStatement>(); ASSERT(ms); popFunc(); if (reloc) { ms->setLoc(popFuncLocation().get()); } ms->resetLoc(this); bool hasCallToGetArgs = m_hasCallToGetArgs.back(); m_hasCallToGetArgs.pop_back(); if (ms->hasYield()) { string closureName = getClosureName(); ms->setName(closureName); ms->setPublic(); Token new_params; prepare_generator(this, stmt, new_params, ms->getYieldCount()); StatementListStatementPtr stmts = stmt->getStmtList(); if (stmts) stmts->resetLoc(this); ms->init(this, ref.num(), new_params->params(), stmts, hasCallToGetArgs); String clsname = cs->name(); create_generator(this, out, params, name, closureName, clsname.data(), &modifiers); } else { StatementListStatementPtr stmts = stmt->getStmtList(); if (stmts) stmts->resetLoc(this); ms->init(this, ref.num(), params->params(), stmts, hasCallToGetArgs); } cs->addMethod(ms); }
void Parser::saveParseTree(Token &tree) { StatementListStatementPtr s = tree->getStmtList(); // Reorder so that classes and funcs are first. if (s) { std::vector<StatementPtr> scopes; std::vector<StatementPtr> rest; const std::vector<StatementPtr> &svec = s->stmts(); for (std::vector<StatementPtr>::const_iterator it = svec.begin(); it != svec.end(); ++it) { ClassStatementPtr cs = (*it)->cast<ClassStatement>(); if (cs || (*it)->cast<FunctionStatement>()) { scopes.push_back(*it); if (cs) { rest.push_back(cs->getMarker()); } } else { rest.push_back(*it); } } rest.insert(rest.begin(), scopes.begin(), scopes.end()); m_tree = StatementPtr(new StatementListStatement(this, rest)); } else { m_tree = tree->stmt(); } if (!m_tree) { m_tree = NEW_STMT0(StatementList); } }
void Parser::onMethod(Token &out, Token &modifiers, Token &ref, Token &name, Token ¶ms, Token &stmt) { ClassStatementPtr cs = peekClass(); MethodStatementPtr ms = peekFunc()->unsafe_cast<MethodStatement>(); ASSERT(ms); popFunc(); StatementListStatementPtr stmts = stmt->getStmtList(); ms->resetLoc(this); if (stmts) stmts->resetLoc(this); ms->init(this, ref.num(), params->params(), stmts, m_hasCallToGetArgs); cs->addMethod(ms); }
void Parser::saveParseTree(Token &tree) { StatementListStatementPtr s = tree->getStmtList(); // Reorder so that classes and funcs are first. if (s) { std::vector<StatementPtr> scopes; std::vector<StatementPtr> rest; const std::vector<StatementPtr> &svec = s->stmts(); for (std::vector<StatementPtr>::const_iterator it = svec.begin(); it != svec.end(); ++it) { ClassStatementPtr cs = (*it)->unsafe_cast<ClassStatement>(); if (cs || (*it)->unsafe_cast<FunctionStatement>()) { scopes.push_back(*it); } else { rest.push_back(*it); } if (cs) { rest.push_back(cs->getMarker()); } } rest.insert(rest.begin(), scopes.begin(), scopes.end()); m_tree = StatementPtr(new StatementListStatement(this, rest)); // Classes that have a parent declared after them must be evaluated at // the marker position. I don't know why. hphp_const_char_map<bool> seen; for (int i = svec.size() - 1; i >= 0; --i) { ClassStatementPtr cs = svec[i]->unsafe_cast<ClassStatement>(); if (cs) { seen[cs->name().c_str()] = true; if (!cs->parent().empty()) { if (seen.find(cs->parent().c_str()) != seen.end()) { cs->delayDeclaration(); } } } } } else { m_tree = tree->stmt(); } if (!m_tree) { m_tree = NEW_STMT0(StatementList); } }