// This method removes trait abstract methods that are either: // 1) implemented by other traits // 2) duplicate void ClassScope::removeSpareTraitAbstractMethods(AnalysisResultPtr ar) { assert(Option::WholeProgram); for (MethodToTraitListMap::iterator iter = m_importMethToTraitMap.begin(); iter != m_importMethToTraitMap.end(); iter++) { TraitMethodList& tMethList = iter->second; bool hasNonAbstractMeth = false; unsigned countAbstractMeths = 0; for (TraitMethodList::const_iterator traitMethIter = tMethList.begin(); traitMethIter != tMethList.end(); traitMethIter++) { ModifierExpressionPtr modifiers = traitMethIter->m_modifiers ? traitMethIter->m_modifiers : traitMethIter->m_method->getModifiers(); if (!(modifiers->isAbstract())) { hasNonAbstractMeth = true; } else { countAbstractMeths++; } } if (hasNonAbstractMeth || countAbstractMeths > 1) { // Erase spare abstract declarations bool firstAbstractMeth = true; for (TraitMethodList::iterator nextTraitIter = tMethList.begin(); nextTraitIter != tMethList.end(); ) { TraitMethodList::iterator traitIter = nextTraitIter++; ModifierExpressionPtr modifiers = traitIter->m_modifiers ? traitIter->m_modifiers : traitIter->m_method->getModifiers(); if (modifiers->isAbstract()) { if (hasNonAbstractMeth || !firstAbstractMeth) { tMethList.erase(traitIter); } firstAbstractMeth = false; } } } } }
FunctionScope::FunctionScope(AnalysisResultPtr ar, bool method, const std::string &name, StatementPtr stmt, bool reference, int minParam, int maxParam, ModifierExpressionPtr modifiers, int attribute, const std::string &docComment, FileScopePtr file, bool inPseudoMain /* = false */) : BlockScope(name, docComment, stmt, BlockScope::FunctionScope), m_method(method), m_file(file), m_minParam(0), m_maxParam(0), m_attribute(attribute), m_refReturn(reference), m_modifiers(modifiers), m_virtual(false), m_overriding(false), m_redeclaring(-1), m_volatile(false), m_ignored(false), m_pseudoMain(inPseudoMain), m_magicMethod(false), m_system(false), m_inlineable(false), m_sep(false), m_containsThis(false), m_staticMethodAutoFixed(false), m_callTempCountMax(0), m_callTempCountCurrent(0) { bool canInline = true; if (inPseudoMain) { canInline = false; m_variables->forceVariants(ar); setReturnType(ar, Type::Variant); } setParamCounts(ar, minParam, maxParam); if (m_refReturn) { m_returnType = Type::Variant; } // FileScope's flags are from parser, but VariableTable has more flags // coming from type inference phase. So we are tranferring these two // flags just for better modularization between FileScope and VariableTable. if (m_attribute & FileScope::ContainsDynamicVariable) { m_variables->setAttribute(VariableTable::ContainsDynamicVariable); } if (m_attribute & FileScope::ContainsLDynamicVariable) { m_variables->setAttribute(VariableTable::ContainsLDynamicVariable); } if (m_attribute & FileScope::ContainsExtract) { m_variables->setAttribute(VariableTable::ContainsExtract); } if (m_attribute & FileScope::ContainsCompact) { m_variables->setAttribute(VariableTable::ContainsCompact); } if (m_attribute & FileScope::ContainsUnset) { m_variables->setAttribute(VariableTable::ContainsUnset); } if (m_attribute & FileScope::ContainsGetDefinedVars) { m_variables->setAttribute(VariableTable::ContainsGetDefinedVars); } if (m_stmt && Option::AllVolatile) { m_volatile = true; } m_dynamic = Option::IsDynamicFunction(method, m_name) || Option::EnableEval == Option::FullEval; if (modifiers) { m_virtual = modifiers->isAbstract(); } if (m_stmt) { MethodStatementPtr stmt = dynamic_pointer_cast<MethodStatement>(m_stmt); StatementListPtr stmts = stmt->getStmts(); if (stmts) { if (stmts->getRecursiveCount() > Option::InlineFunctionThreshold) canInline = false; for (int i = 0; i < stmts->getCount(); i++) { StatementPtr stmt = (*stmts)[i]; stmt->setFileLevel(); if (stmt->is(Statement::KindOfExpStatement)) { ExpStatementPtr expStmt = dynamic_pointer_cast<ExpStatement>(stmt); ExpressionPtr exp = expStmt->getExpression(); exp->setTopLevel(); } } } } else { canInline = false; } m_inlineable = canInline; }