static void parse_string_arg(ExpressionPtr exp, string &var, string &lit) {
  if (exp->is(Expression::KindOfUnaryOpExpression)) {
    UnaryOpExpressionPtr u(static_pointer_cast<UnaryOpExpression>(exp));
    if (u->getOp() == '(') {
      parse_string_arg(u->getExpression(), var, lit);
      return;
    }
  } else if (exp->is(Expression::KindOfBinaryOpExpression)) {
    BinaryOpExpressionPtr b(static_pointer_cast<BinaryOpExpression>(exp));
    if (b->getOp() == '.') {
      string v, l;
      parse_string_arg(b->getExp2(), v, l);
      if (v.empty()) {
        parse_string_arg(b->getExp1(), var, lit);
        lit += l;
        return;
      }
    }
  }
  if (exp->isLiteralString()) {
    var = "";
    lit = exp->getLiteralString();
    return;
  }
  var = exp->getText();
  lit = "";
  return;
}
Exemplo n.º 2
0
string DependencyGraph::parseInclude(const string &source,
                                     ExpressionPtr parentExp,
                                     bool documentRoot /* = false */) {
  string included = parentExp->getText();
  string parent = getIncludeFilePath(source, included, documentRoot);
  return Util::canonicalize(parent);
}
Exemplo n.º 3
0
void FunctionScope::setParamCounts(AnalysisResultPtr ar, int minParam,
                                   int maxParam) {
  m_minParam = minParam;
  m_maxParam = maxParam;
  ASSERT(m_minParam >= 0 && m_maxParam >= m_minParam);
  if (m_maxParam > 0) {
    m_paramNames.resize(m_maxParam);
    m_paramTypes.resize(m_maxParam);
    m_paramTypeSpecs.resize(m_maxParam);
    m_paramDefaults.resize(m_maxParam);
    m_paramDefaultTexts.resize(m_maxParam);
    m_refs.resize(m_maxParam);

    if (m_stmt) {
      MethodStatementPtr stmt = dynamic_pointer_cast<MethodStatement>(m_stmt);
      ExpressionListPtr params = stmt->getParams();

      for (int i = 0; i < m_maxParam; i++) {
        if (stmt->isRef(i)) m_refs[i] = true;

        ParameterExpressionPtr param =
          dynamic_pointer_cast<ParameterExpression>((*params)[i]);
        m_paramNames[i] = param->getName();
        m_paramTypeSpecs[i] = param->getTypeSpec(ar);
        ExpressionPtr exp = param->defaultValue();
        if (exp) {
          m_paramDefaults[i] = exp->getText(false, false, ar);
        }
      }
    }
  }
}
Exemplo n.º 4
0
bool Option::GetArrayElements(ExpressionPtr value, ExpressionListPtr &out) {
  UnaryOpExpressionPtr v = dynamic_pointer_cast<UnaryOpExpression>(value);
  if (!v || v->getOp() != T_ARRAY) {
    Logger::Error("Line %d: invalid array: %s", value->getLocation()->line1,
                  value->getText().c_str());
    return false;
  }

  ExpressionPtr exp = v->getExpression();
  out = dynamic_pointer_cast<ExpressionList>(exp);
  if (!out) {
    Logger::Error("Line %d: invalid array: %s", value->getLocation()->line1,
                  value->getText().c_str());
    return false;
  }

  return true;
}
Exemplo n.º 5
0
bool Option::Load(string &option, ExpressionPtr value) {
  ScalarExpressionPtr v = dynamic_pointer_cast<ScalarExpression>(value);
  if (!v || !v->isLiteralString()) {
    Logger::Error("Line %d: invalid string: %s", value->getLocation()->line1,
                  value->getText().c_str());
    return false;
  }
  option = v->getLiteralString();
  return true;
}
Exemplo n.º 6
0
bool Option::Load(bool &option, ExpressionPtr value) {
  ConstantExpressionPtr v = dynamic_pointer_cast<ConstantExpression>(value);
  if (!v || !v->isBoolean()) {
    Logger::Error("Line %d: invalid boolean: %s", value->getLocation()->line1,
                  value->getText().c_str());
    return false;
  }
  option = v->getBooleanValue();
  return true;
}
Exemplo n.º 7
0
bool Option::Load(map<string, int> &option, ExpressionPtr value) {
  ExpressionListPtr elements;
  if (!GetArrayElements(value, elements)) return false;

  for (int i = 0; i < elements->getCount(); i++) {
    ExpressionPtr e = (*elements)[i];
    ArrayPairExpressionPtr pair = dynamic_pointer_cast<ArrayPairExpression>(e);

    bool negative = false;
    ScalarExpressionPtr n, v;
    if (pair) n = dynamic_pointer_cast<ScalarExpression>(pair->getName());
    if (pair) {
      if (pair->getValue()->is(Expression::KindOfUnaryOpExpression)) {
        UnaryOpExpressionPtr una =
          dynamic_pointer_cast<UnaryOpExpression>(pair->getValue());
        if (una->getOp() != '+' && una->getOp() != '-') {
          Logger::Error("Line %d: invalid integer: %s",
                        una->getLocation()->line1, una->getText().c_str());
          return false;
        }

        v = dynamic_pointer_cast<ScalarExpression>(una->getExpression());
        if (una->getOp() == '-') {
          negative = true;
        }
      } else {
        v = dynamic_pointer_cast<ScalarExpression>(pair->getValue());
      }
    }

    if (!pair || !n || !v || !n->isLiteralString() || !v->isLiteralInteger()) {
      Logger::Error("Line %d: invalid element: %s", e->getLocation()->line1,
                    e->getText().c_str());
      return false;
    }

    if (negative) {
      option[n->getLiteralString()] = - v->getLiteralInteger();
    } else {
      option[n->getLiteralString()] = v->getLiteralInteger();
    }
  }

  return true;
}
Exemplo n.º 8
0
static inline
std::string ExtractInitializer(AnalysisResultPtr ar, ExpressionPtr e) {
  switch (e->getKindOf()) {
  case Expression::KindOfParameterExpression:
    {
      auto p = static_pointer_cast<ParameterExpression>(e);
      if (!p->defaultValue()) return "";
      return p->defaultValue()->getText(ar);
    }
  default:
    // TODO(stephentu): this doesn't allow us to tell the difference between
    // something like:
    //   class X { public $x;        } versus
    //   class X { public $x = null; }
    // we'll just end up treating both cases like the latter
    return e->getText(ar);
  }
  return "";
}
Exemplo n.º 9
0
bool DependencyGraph::checkInclude(ConstructPtr childExp,
                                   ExpressionPtr parentExp,
                                   CodeErrorPtr codeError,
                                   bool documentRoot,
                                   string &child,
                                   string &parent) {
  child = childExp->getLocation()->file;
  parent = parseInclude(child, parentExp, documentRoot);
  if ((parent.empty() || parent == child) &&
      Option::AllowedBadPHPIncludes.find(parentExp->getText()) ==
      Option::AllowedBadPHPIncludes.end()) {
    if (codeError) {
      codeError->record(CodeError::BadPHPIncludeFile, childExp);
    }
    return false;
  }
  if (parent.empty()) return false;
  return true;
}
Exemplo n.º 10
0
void FunctionScope::setParamSpecs(AnalysisResultPtr ar) {
  if (m_maxParam > 0 && m_stmt) {
    MethodStatementPtr stmt = dynamic_pointer_cast<MethodStatement>(m_stmt);
    ExpressionListPtr params = stmt->getParams();

    for (int i = 0; i < m_maxParam; i++) {
      ParameterExpressionPtr param =
        dynamic_pointer_cast<ParameterExpression>((*params)[i]);
      TypePtr specType = param->getTypeSpec(ar, false);
      if (specType &&
          !specType->is(Type::KindOfSome) &&
          !specType->is(Type::KindOfVariant)) {
        m_paramTypeSpecs[i] = specType;
      }
      ExpressionPtr exp = param->defaultValue();
      if (exp) {
        m_paramDefaults[i] = exp->getText(false, false, ar);
      }
    }
  }
}
Exemplo n.º 11
0
bool Option::Load(vector<string> &option, ExpressionPtr value) {
  ExpressionListPtr elements;
  if (!GetArrayElements(value, elements)) return false;

  for (int i = 0; i < elements->getCount(); i++) {
    ExpressionPtr e = (*elements)[i];
    ArrayPairExpressionPtr pair = dynamic_pointer_cast<ArrayPairExpression>(e);

    ScalarExpressionPtr v;
    if (pair) v = dynamic_pointer_cast<ScalarExpression>(pair->getValue());

    if (!pair || !v || !v->isLiteralString()) {
      Logger::Error("Line %d: invalid element: %s", e->getLocation()->line1,
                    e->getText().c_str());
      return false;
    }
    option.push_back(v->getLiteralString());
  }

  return true;
}
Exemplo n.º 12
0
static bool isEquivRedecl(const std::string &name,
                          ExpressionPtr exp,
                          ModifierExpressionPtr modif,
                          Symbol * symbol) {
  assert(exp);
  assert(modif);
  assert(symbol);
  if (symbol->getName()     != name                 ||
      symbol->isProtected() != modif->isProtected() ||
      symbol->isPrivate()   != modif->isPrivate()   ||
      symbol->isPublic()    != modif->isPublic()    ||
      symbol->isStatic()    != modif->isStatic())
    return false;

  auto symDeclExp =
    dynamic_pointer_cast<Expression>(symbol->getDeclaration());
  if (!exp) return !symDeclExp;
  Variant v1, v2;
  auto s1 = exp->getScalarValue(v1);
  auto s2 = symDeclExp->getScalarValue(v2);
  if (s1 != s2) return false;
  if (s1) return same(v1, v2);
  return exp->getText() == symDeclExp->getText();
}
Exemplo n.º 13
0
bool StatementList::mergeConcatAssign() {
  if (Option::LocalCopyProp) {
    return false;
  } else {
    // check for vector string concat assignment such as
    //   $space = " ";
    //   $a .= "hello";
    //   $a .= $space;
    //   $a .= "world!";
    // turn into (for constant folding and concat sequence)
    //   $a .= " " . "hello " . $space . "world!";
    unsigned int i = 0;
    bool merged = false;
    do {
      std::string lhsName;
      int length = 0;
      for (; i < m_stmts.size(); i++) {
        StatementPtr stmt = m_stmts[i];
        if (!stmt->is(Statement::KindOfExpStatement)) break;
        ExpStatementPtr expStmt = dynamic_pointer_cast<ExpStatement>(stmt);
        ExpressionPtr exp = expStmt->getExpression();

        // check the first assignment
        if (exp->is(Expression::KindOfAssignmentExpression)) {
          AssignmentExpressionPtr assignment_exp =
            dynamic_pointer_cast<AssignmentExpression>(exp);
          ExpressionPtr variable = assignment_exp->getVariable();
          ExpressionPtr value = assignment_exp->getValue();
          std::string variableName = variable->getText();
          if (variableName.find("->") != std::string::npos) break;
          if (value->hasEffect()) break;
          // cannot turn $a .= $b; a .= $a into $a .= $b . $a;
          if (value->getText().find(variableName) != std::string::npos) break;
          if (lhsName.empty()) {
            lhsName = variable->getText();
            length++;
            continue;
          } else {
            break;
          }
        } else if (!exp->is(Expression::KindOfBinaryOpExpression)) {
          break;
        }
        BinaryOpExpressionPtr binaryOpExp =
          dynamic_pointer_cast<BinaryOpExpression>(exp);
        if (binaryOpExp->getOp() != T_CONCAT_EQUAL) break;
        ExpressionPtr exp1 = binaryOpExp->getExp1();
        std::string exp1Text = exp1->getText();
        if (exp1Text.find("->") != std::string::npos) break;
        ExpressionPtr exp2 = binaryOpExp->getExp2();
        if (exp2->hasEffect()) break;
        if (exp2->getText().find(exp1Text) != std::string::npos) break;
        if (lhsName.empty()) {
          lhsName = exp1Text;
          length++;
        } else if (lhsName == exp1Text) {
          length++;
        } else {
          break;
        }
      }
      if (length > 1) {
        // replace m_stmts[j] to m_stmts[i - 1] with a new statement
        unsigned j = i - length;
        ExpStatementPtr expStmt;
        ExpressionPtr exp;
        BinaryOpExpressionPtr binaryOpExp;
        ExpressionPtr var;
        ExpressionPtr exp1;
        ExpressionPtr exp2;
        bool isAssignment = false;
        expStmt = dynamic_pointer_cast<ExpStatement>(m_stmts[j++]);
        exp = expStmt->getExpression();
        if (exp->is(Expression::KindOfAssignmentExpression)) {
          isAssignment = true;
          AssignmentExpressionPtr assignment_exp =
            dynamic_pointer_cast<AssignmentExpression>(exp);
          var = assignment_exp->getVariable();
          exp1 = assignment_exp->getValue();
        } else {
          binaryOpExp = dynamic_pointer_cast<BinaryOpExpression>(exp);
          var = binaryOpExp->getExp1();
          exp1 = binaryOpExp->getExp2();
        }

        for (; j < i; j++) {
          expStmt = dynamic_pointer_cast<ExpStatement>(m_stmts[j]);
          exp = expStmt->getExpression();
          binaryOpExp = dynamic_pointer_cast<BinaryOpExpression>(exp);
          exp2 = binaryOpExp->getExp2();
          exp1 = BinaryOpExpressionPtr
            (new BinaryOpExpression(getScope(), getLocation(),
                                    Expression::KindOfBinaryOpExpression,
                                    exp1, exp2, '.'));
        }
        if (isAssignment) {
          exp = AssignmentExpressionPtr
            (new AssignmentExpression(exp->getScope(), exp->getLocation(),
                                      Expression::KindOfAssignmentExpression,
                                      var, exp1,
                                      false));
        } else {
          exp = BinaryOpExpressionPtr
            (new BinaryOpExpression(getScope(), getLocation(),
                                    Expression::KindOfBinaryOpExpression,
                                    var, exp1, T_CONCAT_EQUAL));
        }
        expStmt = ExpStatementPtr
          (new ExpStatement(getScope(), getLocation(),
                            Statement::KindOfExpStatement, exp));

        m_stmts[i - length] = expStmt;
        for (j = i - (length - 1); i > j; i--) removeElement(j);
        merged = true;
      } else if (length == 0) {
        i++;
      }
    } while (i < m_stmts.size());
    return merged;
  }
}
Exemplo n.º 14
0
void FunctionScope::outputCPPClassMap(CodeGenerator &cg, AnalysisResultPtr ar) {
  int attribute = ClassInfo::IsNothing;
  if (!isUserFunction()) attribute |= ClassInfo::IsSystem;
  if (isRedeclaring()) attribute |= ClassInfo::IsRedeclared;
  if (isVolatile()) attribute |= ClassInfo::IsVolatile;
  if (isRefReturn()) attribute |= ClassInfo::IsReference;

  if (isProtected()) {
    attribute |= ClassInfo::IsProtected;
  } else if (isPrivate()) {
    attribute |= ClassInfo::IsPrivate;
  } else {
    attribute |= ClassInfo::IsPublic;
  }
  if (isAbstract()) attribute |= ClassInfo::IsAbstract;
  if (isStatic()) {
    attribute |= ClassInfo::IsStatic;
  }
  if (isFinal()) attribute |= ClassInfo::IsFinal;

  if (isVariableArgument()) {
    attribute |= ClassInfo::VariableArguments;
  }
  if (isReferenceVariableArgument()) {
    attribute |= ClassInfo::RefVariableArguments;
  }
  if (isMixedVariableArgument()) {
    attribute |= ClassInfo::MixedVariableArguments;
  }

  attribute |= m_attributeClassInfo;
  if (!m_docComment.empty() && Option::GenerateDocComments) {
    attribute |= ClassInfo::HasDocComment;
  } else {
    attribute &= ~ClassInfo::HasDocComment;
  }

  // Use the original cased name, for reflection to work correctly.
  cg_printf("(const char *)0x%04X, \"%s\", \"%s\", (const char *)%d, "
            "(const char *)%d, NULL, NULL,\n", attribute,
            getOriginalName().c_str(),
            m_stmt ? m_stmt->getLocation()->file : "",
            m_stmt ? m_stmt->getLocation()->line0 : 0,
            m_stmt ? m_stmt->getLocation()->line1 : 0);

  if (!m_docComment.empty() && Option::GenerateDocComments) {
    char *dc = string_cplus_escape(m_docComment.c_str(), m_docComment.size());
    cg_printf("\"%s\",\n", dc);
    free(dc);
  }

  Variant defArg;
  for (int i = 0; i < m_maxParam; i++) {
    int attr = ClassInfo::IsNothing;
    if (i >= m_minParam) attr |= ClassInfo::IsOptional;
    if (isRefParam(i)) attr |= ClassInfo::IsReference;

    const std::string &tname = m_paramTypeSpecs[i] ?
      m_paramTypeSpecs[i]->getPHPName() : "";
    cg_printf("(const char *)0x%04X, \"%s\", \"%s\", ",
              attr, m_paramNames[i].c_str(),
              Util::toLower(tname).c_str());

    if (i >= m_minParam) {
      MethodStatementPtr m =
        dynamic_pointer_cast<MethodStatement>(getStmt());
      if (m) {
        ExpressionListPtr params = m->getParams();
        assert(i < params->getCount());
        ParameterExpressionPtr param =
          dynamic_pointer_cast<ParameterExpression>((*params)[i]);
        assert(param);
        ExpressionPtr def = param->defaultValue();
        string sdef = def->getText();
        char *esdef = string_cplus_escape(sdef.data(), sdef.size());
        if (!def->isScalar() || !def->getScalarValue(defArg)) {
          /**
           * Special value runtime/ext/ext_reflection.cpp can check and throw.
           * If we want to avoid seeing this so to make getDefaultValue()
           * work better for reflections, we will have to implement
           * getScalarValue() to greater extent under compiler/expressions.
           */
          cg_printf("\"\x01\", \"%s\",\n", esdef);
        } else {
          String str = f_serialize(defArg);
          char *s = string_cplus_escape(str.data(), str.size());
          cg_printf("\"%s\", \"%s\",\n", s, esdef);
          free(s);
        }
        free(esdef);
      } else {
        char *def = string_cplus_escape(m_paramDefaults[i].data(),
                                        m_paramDefaults[i].size());
        char *defText = string_cplus_escape(m_paramDefaultTexts[i].data(),
                                            m_paramDefaultTexts[i].size());
        cg_printf("\"%s\", \"%s\",\n", def, defText);
        free(def);
        free(defText);
      }
    } else {
      cg_printf("\"\", \"\",\n");
    }
  }
  cg_printf("NULL,\n");

  m_variables->outputCPPStaticVariables(cg, ar);
}