ClosureExpression::ClosureExpression (EXPRESSION_CONSTRUCTOR_PARAMETERS, FunctionStatementPtr func, ExpressionListPtr vars) : Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(ClosureExpression)), m_func(func) { if (vars) { m_vars = ExpressionListPtr (new ExpressionList(vars->getScope(), vars->getLocation())); // push the vars in reverse order, not retaining duplicates std::set<string> seenBefore; // Because PHP is insane you can have a use variable with the same // name as a param name. // In that case, params win (which is different than zend but much easier) ExpressionListPtr bodyParams = m_func->getParams(); if (bodyParams) { int nParams = bodyParams->getCount(); for (int i = 0; i < nParams; i++) { ParameterExpressionPtr par( static_pointer_cast<ParameterExpression>((*bodyParams)[i])); seenBefore.insert(par->getName()); } } for (int i = vars->getCount() - 1; i >= 0; i--) { ParameterExpressionPtr param( dynamic_pointer_cast<ParameterExpression>((*vars)[i])); assert(param); if (seenBefore.find(param->getName().c_str()) == seenBefore.end()) { seenBefore.insert(param->getName().c_str()); m_vars->insertElement(param); } } if (m_vars) { m_values = ExpressionListPtr (new ExpressionList(m_vars->getScope(), m_vars->getLocation())); for (int i = 0; i < m_vars->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_vars)[i]); const string &name = param->getName(); SimpleVariablePtr var(new SimpleVariable(param->getScope(), param->getLocation(), name)); if (param->isRef()) { var->setContext(RefValue); } m_values->addElement(var); } assert(m_vars->getCount() == m_values->getCount()); } } }
ClosureExpression::ClosureExpression (EXPRESSION_CONSTRUCTOR_PARAMETERS, FunctionStatementPtr func, ExpressionListPtr vars) : Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(ClosureExpression)), m_func(func) { if (vars) { m_vars = ExpressionListPtr (new ExpressionList(vars->getScope(), vars->getLocation())); // push the vars in reverse order, not retaining duplicates std::set<string> seenBefore; for (int i = vars->getCount() - 1; i >= 0; i--) { ParameterExpressionPtr param( dynamic_pointer_cast<ParameterExpression>((*vars)[i])); assert(param); if (param->getName() == "this") { // "this" is automatically included. // Once we get rid of all the callsites, make this an error continue; } if (seenBefore.find(param->getName().c_str()) == seenBefore.end()) { seenBefore.insert(param->getName().c_str()); m_vars->insertElement(param); } } if (m_vars) { m_values = ExpressionListPtr (new ExpressionList(m_vars->getScope(), m_vars->getLocation())); for (int i = 0; i < m_vars->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_vars)[i]); const string &name = param->getName(); SimpleVariablePtr var(new SimpleVariable(param->getScope(), param->getLocation(), name)); if (param->isRef()) { var->setContext(RefValue); } m_values->addElement(var); } assert(m_vars->getCount() == m_values->getCount()); } } }
ClosureExpression::ClosureExpression (EXPRESSION_CONSTRUCTOR_PARAMETERS, FunctionStatementPtr func, ExpressionListPtr vars) : Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES), m_func(func) { if (vars) { m_vars = ExpressionListPtr (new ExpressionList(vars->getScope(), vars->getLocation(), KindOfExpressionList)); // push the vars in reverse order, not retaining duplicates set<string> seenBefore; for (int i = vars->getCount() - 1; i >= 0; i--) { ParameterExpressionPtr param( dynamic_pointer_cast<ParameterExpression>((*vars)[i])); ASSERT(param); if (seenBefore.find(param->getName().c_str()) == seenBefore.end()) { seenBefore.insert(param->getName().c_str()); m_vars->insertElement(param); } } if (m_vars) { m_values = ExpressionListPtr (new ExpressionList(m_vars->getScope(), m_vars->getLocation(), KindOfExpressionList)); for (int i = 0; i < m_vars->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_vars)[i]); string name = param->getName(); SimpleVariablePtr var(new SimpleVariable(param->getScope(), param->getLocation(), KindOfSimpleVariable, name)); if (param->isRef()) { var->setContext(RefValue); } m_values->addElement(var); } } } }