in thrift/compiler/generate/t_hack_generator.cc [3697:3777]
void t_hack_generator::generate_php_struct_constructor_field_assignment(
std::ofstream& out,
const t_field& field,
const t_struct* tstruct,
ThriftStructType type,
const std::string& name,
bool is_default_assignment) {
const t_type* t = field.type()->get_true_type();
const auto true_type = type_to_typehint(t, false, false, false, false);
std::string dval = "";
bool is_exception = tstruct->is_exception();
if (field.default_value() != nullptr &&
!(t->is_struct() || t->is_xception())) {
dval = render_const_value(t, field.default_value());
} else if (
tstruct->is_exception() &&
(field.name() == "code" || field.name() == "line")) {
if (t->is_any_int()) {
dval = "0";
} else {
// just use the lowest value
const t_enum* tenum = static_cast<const t_enum*>(t);
dval =
hack_name(tenum) + "::" + (*tenum->get_enum_values().begin())->name();
}
} else if (
is_exception && (field.name() == "message" || field.name() == "file")) {
dval = "''";
} else if (tstruct->is_union() || nullable_everything_) {
dval = "null";
} else {
dval = render_default_value(t);
}
if (dval != "null") {
if (const auto* adapter = find_hack_adapter(field.get_type())) {
dval = *adapter + "::fromThrift(" + dval + ")";
}
}
// result structs only contain fields: success and e.
// success is whatever type the method returns, but must be nullable
// regardless, since if there is an exception we expect it to be null
// TODO(ckwalsh) Extract this logic into a helper function
bool nullable = type == ThriftStructType::RESULT ||
(!(is_exception && is_base_exception_property(&field)) &&
(dval == "null" ||
(field.get_req() == t_field::e_req::optional &&
field.default_value() == nullptr)));
const std::string& field_name = field.name();
bool need_enum_code_fixme = is_exception && field_name == "code" &&
t->is_enum() && !enum_transparenttype_;
if (is_default_assignment) {
if (const auto* field_wrapper = find_hack_wrapper(field)) {
out << indent() << "$this->" << field_name << " = " << *field_wrapper
<< "::fromThrift_DO_NOT_USE_THRIFT_INTERNAL<" << (nullable ? "?" : "")
<< true_type << ", " << hack_name(name, tstruct->program(), true)
<< ">(" << (nullable ? "null" : dval) << ", " << field.get_key()
<< ", $this);\n";
} else if (!nullable) {
out << indent() << "$this->" << field_name << " = " << dval << ";\n";
}
} else {
if (tstruct->is_union()) {
// Capture value from constructor and update _type field
out << indent() << "if ($" << field_name << " !== null) {\n";
}
if (need_enum_code_fixme) {
out << indent() << " /* HH_FIXME[4110] nontransparent Enum */\n";
}
out << indent() << (tstruct->is_union() ? " " : "") << "$this->"
<< field_name << " = $" << field_name
<< (!nullable ? " ?? " + dval : "") << ";\n";
if (tstruct->is_union()) {
out << indent()
<< " $this->_type = " << union_field_to_enum(tstruct, &field, name)
<< ";\n"
<< indent() << "}\n";
}
}
}