Exemplo n.º 1
0
static fbstring genDocComment(const PhpFunc& func,
                              const fbstring& classname) {
  fbstring ret(genDocCommentPreamble(func.getPhpName(), func.getDesc(),
                                     func.flags(), classname));

  for (auto &param : func.params()) {
    ret += "@" + param.name() + " " + param.getPhpType() + " ";
    if (param.isRef()) {
      ret += "(output) ";
    }
    ret += param.getDesc() + "\n";
  }

  if (func.numParams() > 0) {
    ret += "\n";
  }

  auto rko = func.returnKindOf();
  if ((rko != KindOfNull) && (rko != KindOfInvalid)) {
    ret += "@return " + func.returnPhpType() + " ";
    if (func.isReturnRef()) {
      ret += "(output) ";
    }
    ret += func.returnDesc() + "\n";
  }

  return formatDocComment(ret);
}
Exemplo n.º 2
0
static void writeFunction(std::ostream& out, const PhpFunc& func) {
  auto flags = (func.flags() & FUNC_FLAG_MASK) | IsSystem | IsNothing;

  if (flags & RefVariableArguments) {
    flags |= VariableArguments;
  }
  if (flags & MixedVariableArguments) {
    flags |= RefVariableArguments | VariableArguments;
  }
  if (!func.isMethod() || !(flags & VISIBILITY_MASK)) {
    flags |= IsPublic;
  }
  if (func.isReturnRef()) {
    flags |= IsReference;
  }

  out << "  " << castLong(flags, true)
      << ", \"" << escapeCpp(func.getPhpName()) << "\", " << "\"\", "
      << castLong(0) << ", "
      << castLong(0) << ",\n";

  out << "  \""
      << escapeCpp(genDocComment(func, func.className()))
      << "\",\n";

  DataType rko = func.returnKindOf();
  if (rko == KindOfAny) {
    // ClassInfo::MethodInfo expects this for Any/Variant
    // TODO: Fix that broken assumption
    rko = KindOfInvalid;
  }
  out << "  " << castLong(rko, true) << ",\n";
  for (auto &p : func.params()) {
    long attr = IsNothing;
    DataType ko = p.kindOf();
    if (p.isRef()) {
      // We don't declare param type as KindOfRef
      // as then the caller will try to cast it as such
      attr |= IsReference;
      ko = KindOfAny;
    }
    if (ko == KindOfAny) {
      // TODO: See above
      ko = KindOfInvalid;
    }
    out << "  "
        << castLong(attr, true) << ", "
        << "\"" << escapeCpp(p.name()) << "\", \"\", "
        << castLong(ko, true) << ",\n";
    auto ser = p.getDefaultSerialized();
    auto val = p.getDefaultPhp();
    out << "    "
        << "\"" << escapeCpp(ser) << "\", " << castLong(ser.size()) << ", "
        << "\"" << escapeCpp(val) << "\", " << castLong(val.size()) << ", "
        << "NULL,\n";
  }
  out << "  NULL,\n"
      << "  NULL,\n"
      << "  NULL,\n";
}
Exemplo n.º 3
0
PhpFunc PhpFunc::fromDynamic(const folly::dynamic& d,
                             const fbstring& className) {
  // Better at least have a name
  auto name = d["name"].asString();
  auto args = d.find("args");
  auto flags = d.find("flags");
  auto ret = d.find("return");
  if (args == d.items().end() || !args->second.isArray()) {
    throw std::logic_error(
      folly::format("'{0}' must have an array field 'args'", name).str()
    );
  }
  if (flags == d.items().end() || !flags->second.isArray()) {
    throw std::logic_error(
      folly::format("'{0}' must have an array field 'flags'", name).str()
    );
  }
  if (ret == d.items().end() || !ret->second.isObject() ||
      ret->second.find("type") == ret->second.items().end()) {
    throw std::logic_error(
      folly::format("'{0}' must have an array field 'return', which must have "
                    "a string field 'type'", name).str()
    );
  }

  auto areVarargs = [](const fbstring& str) {
    return (str == "VariableArguments" ||
            str == "RefVariableArguments" ||
            str == "MixedVariableArguments");
  };

  fbvector<PhpParam> params;
  try {
    params = std::move(folly::convertTo<fbvector<PhpParam>>(args->second));
  } catch (const std::exception& exc) {
    throw std::logic_error(
      folly::format("'{0}' has an arg with either 'name' or 'type' field "
                    "missing", name).str()
    );
  }
  if (name == "__get" ||
      name == "__set" ||
      name == "__isset" ||
      name == "__unset" ||
      name == "__call") {
    for (auto& param : params) {
      param.cppType = "HPHP::Variant";
    }
  }

  auto refIt = d.find("ref");
  bool ref = (refIt != d.items().end() && refIt->second.asString() == "true");

  PhpFunc retval;
  retval.name = name;
  retval.className = className;
  retval.returnCppType = typeString(ret->second["type"], true);
  retval.returnByRef = ref;
  retval.params = params;
  retval.isVarargs = anyFlags(areVarargs, flags->second);
  retval.isStatic = false;

  if (!className.empty()) {
    auto areStatic = [](const fbstring& str) {
      return str == "IsStatic";
    };

    retval.isStatic = anyFlags(areStatic, flags->second);
  }
  retval.initComputedProps();
  return retval;
}