Beispiel #1
0
void ClosureExpression::initializeFromUseList(ExpressionListPtr vars) {
  m_vars = ExpressionListPtr(
    new ExpressionList(vars->getScope(), vars->getRange()));

  // 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)
  auto seenBefore = collectParamNames();

  for (int i = vars->getCount() - 1; i >= 0; i--) {
    auto 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);
    }
  }

  initializeValuesFromVars();
}
Beispiel #2
0
/**
 * Rewrites any expression query clauses in this list of clauses, taking care
 * to track variables local to the query.
 */
ExpressionListPtr CaptureExtractor::rewriteExpressionList(ExpressionListPtr l) {
  int np = 0;
  int nc = l->getCount();
  auto newList =
    std::make_shared<ExpressionList>(l->getScope(), l->getRange());
  bool noRewrites = true;
  for (int i = 0; i < nc; i++) {
    auto e = (*l)[i];
    assert(e != nullptr);
    auto kind = e->getKindOf();
    switch (kind) {
      case Expression::KindOfIntoClause: {
        // The into expression is in the scope of the into clause
        SimpleQueryClausePtr qcp(static_pointer_cast<SimpleQueryClause>(e));
        m_boundVars.push_back(qcp->getIdentifier());
        np++;
        break;
      }
      case Expression::KindOfJoinClause: {
        JoinClausePtr jcp(static_pointer_cast<JoinClause>(e));
        m_boundVars.push_back(jcp->getVar());
        np++;
        break;
      }
      default:
        break;
    }
    auto ne = rewrite(e);
    if (ne != e) noRewrites = false;
    newList->addElement(ne);
    // deal with clauses that introduce names for subsequent clauses
    switch (kind) {
      case Expression::KindOfFromClause:
      case Expression::KindOfLetClause: {
        SimpleQueryClausePtr qcp(static_pointer_cast<SimpleQueryClause>(e));
        m_boundVars.push_back(qcp->getIdentifier());
        np++;
        break;
      }
      case Expression::KindOfJoinClause: {
        JoinClausePtr jcp(static_pointer_cast<JoinClause>(e));
        auto groupId = jcp->getGroup();
        if (!groupId.empty()) {
          m_boundVars.push_back(groupId);
          np++;
        }
        break;
      }
      default:
        break;
    }
  }
  while (np-- > 0) m_boundVars.pop_back();
  if (noRewrites) return l;
  return newList;
}