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