Exemplo n.º 1
0
void AnalysisResult::analyzeProgram(ConstructPtr c) const {
  if (!c) return;
  for (auto i = 0, n = c->getKidCount(); i < n; ++i) {
    analyzeProgram(c->getNthKid(i));
  }
  c->analyzeProgram(AnalysisResultConstRawPtr{this});
}
Exemplo n.º 2
0
void ClassScope::informClosuresAboutScopeClone(
    ConstructPtr root,
    FunctionScopePtr outerScope,
    AnalysisResultPtr ar) {

  if (!root) {
    return;
  }

  for (int i = 0; i < root->getKidCount(); i++) {
    ConstructPtr cons = root->getNthKid(i);
    ClosureExpressionPtr closure =
      dynamic_pointer_cast<ClosureExpression>(cons);

    if (!closure) {
      informClosuresAboutScopeClone(cons, outerScope, ar);
      continue;
    }

    FunctionStatementPtr func = closure->getClosureFunction();
    HPHP::FunctionScopePtr funcScope = func->getFunctionScope();
    assert(funcScope->isClosure());
    funcScope->addClonedTraitOuterScope(outerScope);
    // Don't need to recurse
  }
}
Exemplo n.º 3
0
  void walk_ast(ConstructPtr node) {
    if (!node) return;

    if (dynamic_pointer_cast<MethodStatement>(node)) {
      // Don't descend into nested non-closure functions, or functions
      // in the psuedo-main.
      return;
    }

    if (auto ce = dynamic_pointer_cast<ClosureExpression>(node)) {
      visit_closure(ce);
      return;
    }

    for (int i = 0; i < node->getKidCount(); ++i) {
      walk_ast(node->getNthKid(i));
    }
  }
bool ClosureExpression::hasStaticLocalsImpl(ConstructPtr root) {
  if (!root) {
    return false;
  }
  if (root->getFunctionScope() != m_func->getFunctionScope()) {
    // new scope, new statics
    return false;
  }

  for (int i = 0; i < root->getKidCount(); i++) {
    ConstructPtr cons = root->getNthKid(i);
    if (StatementPtr s = dynamic_pointer_cast<Statement>(cons)) {
      if (s->is(Statement::KindOfStaticStatement)) {
        return true;
      }
    }
    if (hasStaticLocalsImpl(cons)) {
      return true;
    }
  }
  return false;
}
Exemplo n.º 5
0
  // Returns: whether or not $this is implicitly used in this part of the AST,
  // e.g. via a call using parent::.
  bool walk_ast(ConstructPtr node) {
    if (!node) return false;

    if (dynamic_pointer_cast<MethodStatement>(node)) {
      // Don't descend into nested non-closure functions, or functions
      // in the pseudo-main.
      return false;
    }

    if (auto ce = dynamic_pointer_cast<ClosureExpression>(node)) {
      return visit_closure(ce);
    }

    auto ret = false;
    if (auto fc = dynamic_pointer_cast<FunctionCall>(node)) {
      if (fc->isParent()) ret = true;
    }

    for (int i = 0; i < node->getKidCount(); ++i) {
      if (walk_ast(node->getNthKid(i))) ret = true;
    }

    return ret;
  }
Exemplo n.º 6
0
void AliasManager::collectAliasInfoRecur(ConstructPtr cs) {
  if (!cs) {
    return;
  }

  if (StatementPtr s = dpc(Statement, cs)) {
    switch (s->getKindOf()) {
      case Statement::KindOfFunctionStatement:
      case Statement::KindOfMethodStatement:
      case Statement::KindOfClassStatement:
      case Statement::KindOfInterfaceStatement:
        return;
      default:
        break;
    }
  }

  int nkid = cs->getKidCount();

  for (int i = 0; i < nkid; i++) {
    ConstructPtr kid = cs->getNthKid(i);
    if (kid) {
      collectAliasInfoRecur(kid);
    }
  }

  if (ExpressionPtr e = dpc(Expression, cs)) {
    int context = e->getContext();
    switch (e->getKindOf()) {
    case Expression::KindOfAssignmentExpression:
      {
        AssignmentExpressionPtr ae = spc(AssignmentExpression, e);
        ExpressionPtr var = ae->getVariable();
        ExpressionPtr val = ae->getValue();
        if (var->is(Expression::KindOfSimpleVariable)) {
          const std::string &name = spc(SimpleVariable, var)->getName();
          AliasInfo &ai = m_aliasInfo[name];
          if (val->getContext() & Expression::RefValue) {
            ai.setIsRefTo();
            m_variables->addUsed(name);
          } else {
            Expression::checkUsed(m_arp, var, val);
          }
        }
      }
      break;
    case Expression::KindOfListAssignment:
      {
        ListAssignmentPtr la = spc(ListAssignment, e);
        ExpressionListPtr vars = la->getVariables();
        for (int i = vars->getCount(); i--; ) {
          ExpressionPtr v = (*vars)[i];
          if (v && v->is(Expression::KindOfSimpleVariable)) {
            SimpleVariablePtr sv = spc(SimpleVariable, v);
            m_variables->addUsed(sv->getName());
          }
        }
      }
      break;
    case Expression::KindOfSimpleVariable:
      {
        const std::string &name = spc(SimpleVariable, e)->getName();
        if (context & Expression::RefValue) {
          AliasInfo &ai = m_aliasInfo[name];
          ai.addRefLevel(0);
        }
        if (!(context & (Expression::AssignmentLHS |
                         Expression::UnsetContext))) {
          m_variables->addUsed(name);
        }
      }
      break;
    case Expression::KindOfDynamicVariable:
      if (context & Expression::RefValue) {
        m_wildRefs = true;
      }
      break;
    case Expression::KindOfArrayElementExpression:
      {
        int n = 1;
        while (n < 10 &&
               e->is(Expression::KindOfArrayElementExpression)) {
          e = spc(ArrayElementExpression, e)->getVariable();
        }
        if (e->is(Expression::KindOfSimpleVariable)) {
          const std::string &name = spc(SimpleVariable, e)->getName();
          if (context & Expression::RefValue) {
            AliasInfo &ai = m_aliasInfo[name];
            ai.addRefLevel(n);
          }
          m_variables->addUsed(name); // need this for UnsetContext
        }
      }
      break;
    case Expression::KindOfObjectPropertyExpression:
      {
        e = spc(ObjectPropertyExpression, e)->getObject();
        if (e->is(Expression::KindOfSimpleVariable)) {
          const std::string &name = spc(SimpleVariable, e)->getName();
          if (context & Expression::RefValue) {
            AliasInfo &ai = m_aliasInfo[name];
            ai.addRefLevel(1);
          }
          m_variables->addUsed(name); // need this for UnsetContext
        }
      }
      break;
    default:
      break;
    }
  } else {
    StatementPtr s = spc(Statement, cs);
    switch (s->getKindOf()) {
    case Statement::KindOfCatchStatement:
      {
        const std::string &name = spc(CatchStatement, s)->getVariable();
        m_variables->addUsed(name);
        break;
      }
    default:
      break;
    }
  }
}