void StatementList::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { FunctionScopePtr func = getFunctionScope(); for (unsigned int i = 0; i < m_stmts.size(); i++) { StatementPtr stmt = m_stmts[i]; stmt->outputCPP(cg, ar); if (stmt->is(Statement::KindOfMethodStatement)) { MethodStatementPtr methodStmt = dynamic_pointer_cast<MethodStatement>(stmt); std::string methodName = methodStmt->getName(); if (methodName == "offsetget") { ClassScopePtr cls = getClassScope(); std::string arrayAccess("arrayaccess"); if (cls->derivesFrom(ar, arrayAccess, false, false)) { FunctionScopePtr funcScope = methodStmt->getFunctionScope(); std::string name = funcScope->getName(); funcScope->setName("__offsetget_lval"); methodStmt->setName("__offsetget_lval"); methodStmt->outputCPP(cg, ar); funcScope->setName(name); methodStmt->setName("offsetget"); } } } } }
void StatementList::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { FunctionScopePtr func = getFunctionScope(); bool inPseudoMain = func && func->inPseudoMain(); std::vector<bool> isDeclaration; if (inPseudoMain) { // We need these declarations to go first, because PHP allows top level // function and class declarations to appear after usage. for (unsigned int i = 0; i < m_stmts.size(); i++) { StatementPtr stmt = m_stmts[i]; bool isDecl = false; if (stmt->is(Statement::KindOfFunctionStatement)) { isDecl = true; } else if (stmt->is(Statement::KindOfClassStatement) || stmt->is(Statement::KindOfInterfaceStatement)) { ClassScopePtr cls = (dynamic_pointer_cast<InterfaceStatement>(stmt))->getClassScope(); isDecl = cls->isBaseClass() || !cls->isVolatile(); } if (isDecl) stmt->outputCPP(cg,ar); isDeclaration.push_back(isDecl); } } for (unsigned int i = 0; i < m_stmts.size(); i++) { StatementPtr stmt = m_stmts[i]; if (stmt->is(Statement::KindOfClassStatement)) { if (!inPseudoMain || !isDeclaration[i]) stmt->outputCPP(cg, ar); } else if (!(stmt->is(Statement::KindOfFunctionStatement) || stmt->is(Statement::KindOfInterfaceStatement)) || (!inPseudoMain || !isDeclaration[i])) { stmt->outputCPP(cg, ar); if (stmt->is(Statement::KindOfMethodStatement)) { MethodStatementPtr methodStmt = dynamic_pointer_cast<MethodStatement>(stmt); std::string methodName = methodStmt->getName(); if (methodName == "offsetget") { ClassScopePtr cls = getClassScope(); std::string arrayAccess("arrayaccess"); if (cls->derivesFrom(ar, arrayAccess, false, false)) { FunctionScopePtr funcScope = methodStmt->getFunctionScope(); std::string name = funcScope->getName(); funcScope->setName("__offsetget_lval"); methodStmt->setName("__offsetget_lval"); methodStmt->outputCPP(cg, ar); funcScope->setName(name); methodStmt->setName("offsetget"); } } } } } }
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); }
MethodStatementPtr ClassScope::importTraitMethod(const TraitMethod& traitMethod, AnalysisResultPtr ar, string methName, const std::map<string, MethodStatementPtr>& importedTraitMethods) { MethodStatementPtr meth = traitMethod.m_method; string origMethName = traitMethod.m_originalName; ModifierExpressionPtr modifiers = traitMethod.m_modifiers; MethodStatementPtr cloneMeth = dynamic_pointer_cast<MethodStatement>( dynamic_pointer_cast<ClassStatement>(m_stmt)->addClone(meth)); cloneMeth->setName(methName); cloneMeth->setOriginalName(origMethName); // Note: keep previous modifiers if none specified when importing the trait if (modifiers && modifiers->getCount()) { cloneMeth->setModifiers(modifiers); } FunctionScopePtr funcScope = meth->getFunctionScope(); // Trait method typehints, self and parent, need to be converted ClassScopePtr cScope = dynamic_pointer_cast<ClassScope>(shared_from_this()); cloneMeth->fixupSelfAndParentTypehints( cScope ); FunctionScopePtr cloneFuncScope (new HPHP::FunctionScope(funcScope, ar, methName, origMethName, cloneMeth, cloneMeth->getModifiers(), cScope->isUserClass())); cloneMeth->resetScope(cloneFuncScope, true); cloneFuncScope->setOuterScope(shared_from_this()); informClosuresAboutScopeClone(cloneMeth, cloneFuncScope, ar); cloneMeth->addTraitMethodToScope(ar, dynamic_pointer_cast<ClassScope>(shared_from_this())); // Preserve original filename (as this varies per-function and not per-unit // in the case of methods imported from flattened traits) cloneMeth->setOriginalFilename(meth->getFileScope()->getName()); return cloneMeth; }