mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-18 06:54:26 +00:00
Fix 64-bit numeric enum values in typescript (#7135)
* Fix 64-bit default numeric enum values in typescript If you had a default value that wasn't a valid enum value (e.g., a zero if you used a bit_flag setting, like you get with AdvancedFeatures in reflection.fbs), we weren't using BigInt. * Run generate_code.py * [DART] Handle deprecated fields & invalid enum defaults * Update .NET test
This commit is contained in:
@@ -227,7 +227,11 @@ class DartGenerator : public BaseGenerator {
|
||||
GenDocComment(enum_def.doc_comment, &code, "");
|
||||
|
||||
auto name = enum_def.is_union ? enum_def.name + "TypeId" : enum_def.name;
|
||||
auto is_bit_flags = enum_def.attributes.Lookup("bit_flags");
|
||||
const bool is_bit_flags =
|
||||
enum_def.attributes.Lookup("bit_flags") != nullptr;
|
||||
// The flatbuffer schema language allows bit flag enums to potentially have
|
||||
// a default value of zero, even if it's not a valid enum value...
|
||||
const bool permit_zero = is_bit_flags;
|
||||
|
||||
code += "class " + name + " {\n";
|
||||
code += " final int value;\n";
|
||||
@@ -235,8 +239,14 @@ class DartGenerator : public BaseGenerator {
|
||||
code += " factory " + name + ".fromValue(int value) {\n";
|
||||
code += " final result = values[value];\n";
|
||||
code += " if (result == null) {\n";
|
||||
code += " throw StateError('Invalid value $value for bit flag enum ";
|
||||
if (permit_zero) {
|
||||
code += " if (value == 0) {\n";
|
||||
code += " return " + name + "._(0);\n";
|
||||
code += " } else {\n";
|
||||
}
|
||||
code += " throw StateError('Invalid value $value for bit flag enum ";
|
||||
code += name + "');\n";
|
||||
if (permit_zero) { code += " }\n"; }
|
||||
code += " }\n";
|
||||
|
||||
code += " return result;\n";
|
||||
@@ -538,13 +548,11 @@ class DartGenerator : public BaseGenerator {
|
||||
if (!struct_def.fixed && !defaultValue.empty()) {
|
||||
if (IsEnum(field.value.type)) {
|
||||
auto &enum_def = *field.value.type.enum_def;
|
||||
for (auto enumIt = enum_def.Vals().begin();
|
||||
enumIt != enum_def.Vals().end(); ++enumIt) {
|
||||
auto &ev = **enumIt;
|
||||
if (enum_def.ToString(ev) == defaultValue) {
|
||||
constructor_args += " = " + enum_def.name + "." + ev.name;
|
||||
break;
|
||||
}
|
||||
if (auto val = enum_def.FindByValue(defaultValue)) {
|
||||
constructor_args += " = " + enum_def.name + "." + val->name;
|
||||
} else {
|
||||
constructor_args +=
|
||||
" = const " + enum_def.name + "._(" + defaultValue + ")";
|
||||
}
|
||||
} else {
|
||||
constructor_args += " = " + defaultValue;
|
||||
@@ -870,7 +878,7 @@ class DartGenerator : public BaseGenerator {
|
||||
|
||||
code += " void begin() {\n";
|
||||
code += " fbBuilder.startTable(" +
|
||||
NumToString(non_deprecated_fields.size()) + ");\n";
|
||||
NumToString(struct_def.fields.vec.size()) + ");\n";
|
||||
code += " }\n\n";
|
||||
|
||||
for (auto it = non_deprecated_fields.begin();
|
||||
@@ -1051,8 +1059,8 @@ class DartGenerator : public BaseGenerator {
|
||||
code += StructObjectBuilderBody(non_deprecated_fields, prependUnderscore,
|
||||
pack);
|
||||
} else {
|
||||
code += TableObjectBuilderBody(non_deprecated_fields, prependUnderscore,
|
||||
pack);
|
||||
code += TableObjectBuilderBody(struct_def, non_deprecated_fields,
|
||||
prependUnderscore, pack);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
@@ -1089,11 +1097,12 @@ class DartGenerator : public BaseGenerator {
|
||||
}
|
||||
|
||||
std::string TableObjectBuilderBody(
|
||||
const StructDef &struct_def,
|
||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields,
|
||||
bool prependUnderscore = true, bool pack = false) {
|
||||
std::string code;
|
||||
code += " fbBuilder.startTable(" +
|
||||
NumToString(non_deprecated_fields.size()) + ");\n";
|
||||
NumToString(struct_def.fields.vec.size()) + ");\n";
|
||||
|
||||
for (auto it = non_deprecated_fields.begin();
|
||||
it != non_deprecated_fields.end(); ++it) {
|
||||
|
||||
@@ -237,7 +237,16 @@ class TsGenerator : public BaseGenerator {
|
||||
} else {
|
||||
code += " " + ev.name;
|
||||
code += " = ";
|
||||
code += enum_def.ToString(ev);
|
||||
// Unfortunately, because typescript does not support bigint enums,
|
||||
// for 64-bit enums, we instead map the enum names to strings.
|
||||
switch (enum_def.underlying_type.base_type) {
|
||||
case BASE_TYPE_LONG:
|
||||
case BASE_TYPE_ULONG: {
|
||||
code += "'" + enum_def.ToString(ev) + "'";
|
||||
break;
|
||||
}
|
||||
default: code += enum_def.ToString(ev);
|
||||
}
|
||||
}
|
||||
|
||||
code += (it + 1) != enum_def.Vals().end() ? ",\n" : "\n";
|
||||
@@ -299,11 +308,23 @@ class TsGenerator : public BaseGenerator {
|
||||
const auto &value = field.value;
|
||||
if (value.type.enum_def && value.type.base_type != BASE_TYPE_UNION &&
|
||||
value.type.base_type != BASE_TYPE_VECTOR) {
|
||||
if (auto val = value.type.enum_def->FindByValue(value.constant)) {
|
||||
return AddImport(imports, *value.type.enum_def, *value.type.enum_def) +
|
||||
"." + val->name;
|
||||
} else {
|
||||
return value.constant;
|
||||
// If the value is an enum with a 64-bit base type, we have to just
|
||||
// return the bigint value directly since typescript does not support
|
||||
// enums with bigint backing types.
|
||||
switch (value.type.base_type) {
|
||||
case BASE_TYPE_LONG:
|
||||
case BASE_TYPE_ULONG: {
|
||||
return "BigInt('" + value.constant + "')";
|
||||
}
|
||||
default: {
|
||||
if (auto val = value.type.enum_def->FindByValue(value.constant)) {
|
||||
return AddImport(imports, *value.type.enum_def,
|
||||
*value.type.enum_def) +
|
||||
"." + val->name;
|
||||
} else {
|
||||
return value.constant;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user