void ClassConstant::onParseRecur(AnalysisResultConstPtr ar, ClassScopePtr scope) { ConstantTablePtr constants = scope->getConstants(); if (scope->isTrait()) { parseTimeFatal(Compiler::InvalidTraitStatement, "Traits cannot have constants"); } for (int i = 0; i < m_exp->getCount(); i++) { AssignmentExpressionPtr assignment = dynamic_pointer_cast<AssignmentExpression>((*m_exp)[i]); ExpressionPtr var = assignment->getVariable(); const std::string &name = dynamic_pointer_cast<ConstantExpression>(var)->getName(); if (constants->isPresent(name)) { assignment->parseTimeFatal(Compiler::DeclaredConstantTwice, "Cannot redeclare %s::%s", scope->getOriginalName().c_str(), name.c_str()); } else { assignment->onParseRecur(ar, scope); } } }
void ClassConstant::onParseRecur(AnalysisResultConstPtr ar, ClassScopePtr scope) { ConstantTablePtr constants = scope->getConstants(); if (scope->isTrait()) { parseTimeFatal(Compiler::InvalidTraitStatement, "Traits cannot have constants"); } if (isAbstract()) { for (int i = 0; i < m_exp->getCount(); i++) { ConstantExpressionPtr exp = dynamic_pointer_cast<ConstantExpression>((*m_exp)[i]); const std::string &name = exp->getName(); if (constants->isPresent(name)) { exp->parseTimeFatal(Compiler::DeclaredConstantTwice, "Cannot redeclare %s::%s", scope->getOriginalName().c_str(), name.c_str()); } // HACK: break attempts to write global constants here; // see ConstantExpression::preOptimize exp->setContext(Expression::LValue); // Unlike with assignment expression below, nothing needs to be added // to the scope's constant table } } else { for (int i = 0; i < m_exp->getCount(); i++) { AssignmentExpressionPtr assignment = dynamic_pointer_cast<AssignmentExpression>((*m_exp)[i]); ExpressionPtr var = assignment->getVariable(); const std::string &name = dynamic_pointer_cast<ConstantExpression>(var)->getName(); if (constants->isPresent(name)) { assignment->parseTimeFatal(Compiler::DeclaredConstantTwice, "Cannot redeclare %s::%s", scope->getOriginalName().c_str(), name.c_str()); } else { if (isTypeconst()) { // We do not want type constants to be available at run time. // To ensure this we do not want them to be added to the constants // table. The constants table is used to inline values for expressions // See ClassConstantExpression::preOptimize. // AssignmentExpression::onParseRecur essentially adds constants to // the constant table so we skip it. continue; } assignment->onParseRecur(ar, scope); } } } }