void ClassScope::applyTraitRules(TMIData& tmid) { ClassStatementPtr classStmt = dynamic_pointer_cast<ClassStatement>(getStmt()); assert(classStmt); StatementListPtr stmts = classStmt->getStmts(); if (!stmts) return; for (int s = 0; s < stmts->getCount(); s++) { StatementPtr stmt = (*stmts)[s]; UseTraitStatementPtr useStmt = dynamic_pointer_cast<UseTraitStatement>(stmt); if (!useStmt) continue; StatementListPtr rules = useStmt->getStmts(); for (int r = 0; r < rules->getCount(); r++) { StatementPtr rule = (*rules)[r]; TraitPrecStatementPtr precStmt = dynamic_pointer_cast<TraitPrecStatement>(rule); if (precStmt) { tmid.applyPrecRule(precStmt); } else { TraitAliasStatementPtr aliasStmt = dynamic_pointer_cast<TraitAliasStatement>(rule); assert(aliasStmt); tmid.applyAliasRule(aliasStmt, this); } } } }
void ClassScope::applyTraitRules(AnalysisResultPtr ar) { assert(Option::WholeProgram); ClassStatementPtr classStmt = dynamic_pointer_cast<ClassStatement>(getStmt()); assert(classStmt); StatementListPtr stmts = classStmt->getStmts(); if (!stmts) return; for (int s = 0; s < stmts->getCount(); s++) { StatementPtr stmt = (*stmts)[s]; UseTraitStatementPtr useStmt = dynamic_pointer_cast<UseTraitStatement>(stmt); if (!useStmt) continue; StatementListPtr rules = useStmt->getStmts(); for (int r = 0; r < rules->getCount(); r++) { StatementPtr rule = (*rules)[r]; TraitPrecStatementPtr precStmt = dynamic_pointer_cast<TraitPrecStatement>(rule); if (precStmt) { applyTraitPrecRule(precStmt); } else { TraitAliasStatementPtr aliasStmt = dynamic_pointer_cast<TraitAliasStatement>(rule); assert(aliasStmt); applyTraitAliasRule(ar, aliasStmt); } } } }
MethodStatementPtr ClassScope::findTraitMethod(AnalysisResultPtr ar, ClassScopePtr trait, const string &methodName, std::set<ClassScopePtr> &visitedTraits) { if (visitedTraits.find(trait) != visitedTraits.end()) { return MethodStatementPtr(); } visitedTraits.insert(trait); ClassStatementPtr tStmt = dynamic_pointer_cast<ClassStatement>(trait->getStmt()); StatementListPtr tStmts = tStmt->getStmts(); // Look in the current trait for (int s = 0; s < tStmts->getCount(); s++) { MethodStatementPtr meth = dynamic_pointer_cast<MethodStatement>((*tStmts)[s]); if (meth) { // Handle methods if (meth->getName() == methodName) { return meth; } } } // Look into children traits for (int s = 0; s < tStmts->getCount(); s++) { UseTraitStatementPtr useTraitStmt = dynamic_pointer_cast<UseTraitStatement>((*tStmts)[s]); if (useTraitStmt) { vector<string> usedTraits; useTraitStmt->getUsedTraitNames(usedTraits); for (unsigned i = 0; i < usedTraits.size(); i++) { MethodStatementPtr foundMethod = findTraitMethod(ar, ar->findClass(usedTraits[i]), methodName, visitedTraits); if (foundMethod) return foundMethod; } } } return MethodStatementPtr(); // not found }
void ClassStatement::onParse(AnalysisResultConstPtr ar, FileScopePtr fs) { ClassScope::KindOf kindOf = ClassScope::KindOfObjectClass; switch (m_type) { case T_CLASS: kindOf = ClassScope::KindOfObjectClass; break; case T_ABSTRACT: kindOf = ClassScope::KindOfAbstractClass; break; case T_FINAL: kindOf = ClassScope::KindOfFinalClass; break; case T_TRAIT: kindOf = ClassScope::KindOfTrait; break; default: ASSERT(false); } vector<string> bases; if (!m_originalParent.empty()) { bases.push_back(m_originalParent); } if (m_base) m_base->getOriginalStrings(bases); StatementPtr stmt = dynamic_pointer_cast<Statement>(shared_from_this()); ClassScopePtr classScope(new ClassScope(kindOf, m_originalName, m_originalParent, bases, m_docComment, stmt)); setBlockScope(classScope); if (!fs->addClass(ar, classScope)) { m_ignored = true; return; } if (m_stmt) { bool seenConstruct = false; // flatten continuation StatementList into MethodStatements for (int i = 0; i < m_stmt->getCount(); i++) { StatementListPtr stmts = dynamic_pointer_cast<StatementList>((*m_stmt)[i]); if (stmts) { m_stmt->removeElement(i); for (int j = 0; j < stmts->getCount(); j++) { m_stmt->insertElement((*stmts)[j], i + j); } } } for (int i = 0; i < m_stmt->getCount(); i++) { MethodStatementPtr meth = dynamic_pointer_cast<MethodStatement>((*m_stmt)[i]); if (meth && meth->getName() == "__construct") { seenConstruct = true; break; } } for (int i = 0; i < m_stmt->getCount(); i++) { if (!seenConstruct) { MethodStatementPtr meth = dynamic_pointer_cast<MethodStatement>((*m_stmt)[i]); if (meth && classScope && meth->getName() == classScope->getName() && !meth->getModifiers()->isStatic() && !classScope->isTrait()) { // class-name constructor classScope->setAttribute(ClassScope::ClassNameConstructor); } } IParseHandlerPtr ph = dynamic_pointer_cast<IParseHandler>((*m_stmt)[i]); ph->onParseRecur(ar, classScope); } for (int i = 0; i < m_stmt->getCount(); i++) { UseTraitStatementPtr useTrait = dynamic_pointer_cast<UseTraitStatement>((*m_stmt)[i]); if (useTrait) { vector<string> usedTraits; useTrait->getUsedTraitNames(usedTraits); classScope->addUsedTraits(usedTraits); } } } }