void TraitRequireStatement::onParseRecur(AnalysisResultConstPtr ar, ClassScopePtr scope) { if (!scope->isTrait()) { parseTimeFatal(Compiler::InvalidTraitStatement, "Only traits can require in class scope"); } ar->parseOnDemandByClass(toLower(m_required)); scope->addTraitRequirement(m_required, m_extends); }
void UseTraitStatement::onParseRecur(AnalysisResultConstPtr ar, ClassScopePtr scope) { if (scope->isInterface()) { parseTimeFatal(Compiler::InvalidTraitStatement, "Interfaces cannot use traits"); } vector<string> usedTraits; getUsedTraitNames(usedTraits); for (auto &t : usedTraits) { ar->parseOnDemandByClass(Util::toLower(t)); } scope->addUsedTraits(usedTraits); }
void ClassRequireStatement::onParseRecur(AnalysisResultConstPtr ar, FileScopeRawPtr fs, ClassScopePtr scope) { if (!scope->isTrait() && !scope->isInterface()) { parseTimeFatal(fs, Compiler::InvalidTraitStatement, "Only traits and interfaces may use 'require' in class scope"); } if (scope->isInterface() && !m_extends) { parseTimeFatal( fs, Compiler::InvalidTraitStatement, "'require implements' may not be used in interface scope" "; instead, use interface inheritance"); } ar->parseOnDemandByClass(toLower(m_required)); scope->addClassRequirement(m_required, m_extends); }
void InterfaceStatement::onParse(AnalysisResultConstPtr ar, FileScopePtr scope) { vector<string> bases; if (m_base) m_base->getStrings(bases); for (auto &b : bases) { ar->parseOnDemandByClass(b); } StatementPtr stmt = dynamic_pointer_cast<Statement>(shared_from_this()); vector<UserAttributePtr> attrs; if (m_attrList) { for (int i = 0; i < m_attrList->getCount(); ++i) { UserAttributePtr a = dynamic_pointer_cast<UserAttribute>((*m_attrList)[i]); attrs.push_back(a); } } auto classScope = std::make_shared<ClassScope>( scope, ClassScope::KindOf::Interface, m_originalName, "", bases, m_docComment, stmt, attrs); setBlockScope(classScope); scope->addClass(ar, classScope); classScope->setPersistent(false); if (m_stmt) { for (int i = 0; i < m_stmt->getCount(); i++) { IParseHandlerPtr ph = dynamic_pointer_cast<IParseHandler>((*m_stmt)[i]); ph->onParseRecur(ar, scope, classScope); } checkArgumentsToPromote(scope, ExpressionListPtr(), T_INTERFACE); } }
void InterfaceStatement::onParse(AnalysisResultConstPtr ar, FileScopePtr scope) { vector<string> bases; if (m_base) m_base->getOriginalStrings(bases); for (auto &b : bases) { ar->parseOnDemandByClass(Util::toLower(b)); } StatementPtr stmt = dynamic_pointer_cast<Statement>(shared_from_this()); vector<UserAttributePtr> attrs; if (m_attrList) { for (int i = 0; i < m_attrList->getCount(); ++i) { UserAttributePtr a = dynamic_pointer_cast<UserAttribute>((*m_attrList)[i]); attrs.push_back(a); } } ClassScopePtr classScope (new ClassScope(ClassScope::KindOfInterface, m_name, "", bases, m_docComment, stmt, attrs)); setBlockScope(classScope); scope->addClass(ar, classScope); if (Option::PersistenceHook) { classScope->setPersistent(Option::PersistenceHook(classScope, scope)); } if (m_stmt) { for (int i = 0; i < m_stmt->getCount(); i++) { IParseHandlerPtr ph = dynamic_pointer_cast<IParseHandler>((*m_stmt)[i]); ph->onParseRecur(ar, classScope); } checkArgumentsToPromote(ExpressionListPtr(), T_INTERFACE); } }
void StaticClassName::onParse(AnalysisResultConstPtr ar, FileScopePtr scope) { if (!m_self && !m_parent && !m_static && !m_className.empty()) { ar->parseOnDemandByClass(m_className); } }
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); for (auto &b : bases) { ar->parseOnDemandByClass(Util::toLower(b)); } vector<UserAttributePtr> attrs; if (m_attrList) { for (int i = 0; i < m_attrList->getCount(); ++i) { UserAttributePtr a = dynamic_pointer_cast<UserAttribute>((*m_attrList)[i]); attrs.push_back(a); } } StatementPtr stmt = dynamic_pointer_cast<Statement>(shared_from_this()); ClassScopePtr classScope(new ClassScope(kindOf, m_originalName, m_originalParent, bases, m_docComment, stmt, attrs)); setBlockScope(classScope); if (!fs->addClass(ar, classScope)) { m_ignored = true; return; } if (Option::PersistenceHook) { classScope->setPersistent(Option::PersistenceHook(classScope, fs)); } if (m_stmt) { MethodStatementPtr constructor; // 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") { constructor = meth; break; } } for (int i = 0; i < m_stmt->getCount(); i++) { if (!constructor) { MethodStatementPtr meth = dynamic_pointer_cast<MethodStatement>((*m_stmt)[i]); if (meth && meth->getName() == classScope->getName() && !classScope->isTrait()) { // class-name constructor constructor = meth; classScope->setAttribute(ClassScope::ClassNameConstructor); } } IParseHandlerPtr ph = dynamic_pointer_cast<IParseHandler>((*m_stmt)[i]); ph->onParseRecur(ar, classScope); } if (constructor && constructor->getModifiers()->isStatic()) { constructor->parseTimeFatal(Compiler::InvalidAttribute, "Constructor %s::%s() cannot be static", classScope->getOriginalName().c_str(), constructor->getOriginalName().c_str()); } } }
void ClassStatement::onParse(AnalysisResultConstPtr ar, FileScopePtr fs) { ClassScope::KindOf kindOf = ClassScope::KindOf::ObjectClass; switch (m_type) { case T_CLASS: kindOf = ClassScope::KindOf::ObjectClass; break; case T_ABSTRACT: kindOf = ClassScope::KindOf::AbstractClass; break; case T_STATIC: // Slight hack: see comments in hphp.y kindOf = ClassScope::KindOf::UtilClass; break; case T_FINAL: kindOf = ClassScope::KindOf::FinalClass; break; case T_TRAIT: kindOf = ClassScope::KindOf::Trait; break; case T_ENUM: kindOf = ClassScope::KindOf::Enum; break; default: assert(false); } std::vector<std::string> bases; if (!m_originalParent.empty()) { bases.push_back(m_originalParent); } if (m_base) m_base->getStrings(bases); for (auto &b : bases) { ar->parseOnDemandByClass(b); } std::vector<UserAttributePtr> attrs; if (m_attrList) { for (int i = 0; i < m_attrList->getCount(); ++i) { UserAttributePtr a = dynamic_pointer_cast<UserAttribute>((*m_attrList)[i]); attrs.push_back(a); } } StatementPtr stmt = dynamic_pointer_cast<Statement>(shared_from_this()); auto classScope = std::make_shared<ClassScope>( fs, kindOf, m_originalName, m_originalParent, bases, m_docComment, stmt, attrs); setBlockScope(classScope); if (!fs->addClass(ar, classScope)) { m_ignored = true; return; } classScope->setPersistent(false); if (m_stmt) { MethodStatementPtr constructor = nullptr; MethodStatementPtr destructor = nullptr; MethodStatementPtr clone = nullptr; // 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) { if (meth->isNamed("__construct")) { constructor = meth; continue; } if (meth->isNamed("__destruct")) { destructor = meth; continue; } if (meth->isNamed("__clone")) { clone = meth; continue; } } if (constructor && destructor && clone) { break; } } for (int i = 0; i < m_stmt->getCount(); i++) { if (!constructor) { MethodStatementPtr meth = dynamic_pointer_cast<MethodStatement>((*m_stmt)[i]); if (meth && meth->isNamed(classScope->getOriginalName()) && !classScope->isTrait()) { // class-name constructor constructor = meth; classScope->setAttribute(ClassScope::ClassNameConstructor); } } IParseHandlerPtr ph = dynamic_pointer_cast<IParseHandler>((*m_stmt)[i]); ph->onParseRecur(ar, fs, classScope); } if (constructor && constructor->getModifiers()->isStatic()) { constructor->parseTimeFatal(fs, Compiler::InvalidAttribute, "Constructor %s::%s() cannot be static", classScope->getOriginalName().c_str(), constructor->getOriginalName().c_str()); } if (destructor && destructor->getModifiers()->isStatic()) { destructor->parseTimeFatal(fs, Compiler::InvalidAttribute, "Destructor %s::%s() cannot be static", classScope->getOriginalName().c_str(), destructor->getOriginalName().c_str()); } if (clone && clone->getModifiers()->isStatic()) { clone->parseTimeFatal(fs, Compiler::InvalidAttribute, "Clone method %s::%s() cannot be static", classScope->getOriginalName().c_str(), clone->getOriginalName().c_str()); } } }