mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-11 15:37:27 +00:00
Fix handling of +/-inf defaults in TS/rust/go/dart codegen (#7588)
+/-inf were not being handled, and so invalid typescript was being generated when a float/double had an infinite default value. NaN was being handled correctly. Co-authored-by: Derek Bailey <derekbailey@google.com> Co-authored-by: Casper <casperneo@uchicago.edu>
This commit is contained in:
@@ -470,6 +470,13 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
||||
std::string DefaultValue(const r::Field *field) const {
|
||||
const r::BaseType base_type = field->type()->base_type();
|
||||
if (IsFloatingPoint(base_type)) {
|
||||
if (field->default_real() != field->default_real()) {
|
||||
return "NaN";
|
||||
} else if (field->default_real() == std::numeric_limits<double>::infinity()) {
|
||||
return "Inf";
|
||||
} else if (field->default_real() == -std::numeric_limits<double>::infinity()) {
|
||||
return "-Inf";
|
||||
}
|
||||
return NumToString(field->default_real());
|
||||
}
|
||||
if (IsBool(base_type)) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
// independent from idl_parser, since this code is not needed for most clients
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
#include "flatbuffers/code_generators.h"
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
@@ -721,16 +722,17 @@ class DartGenerator : public BaseGenerator {
|
||||
if (!value.constant.empty() && value.constant != "0") {
|
||||
if (IsBool(value.type.base_type)) {
|
||||
return "true";
|
||||
} else if (value.constant == "nan" || value.constant == "+nan" ||
|
||||
value.constant == "-nan") {
|
||||
return "double.nan";
|
||||
} else if (value.constant == "inf" || value.constant == "+inf") {
|
||||
return "double.infinity";
|
||||
} else if (value.constant == "-inf") {
|
||||
return "double.negativeInfinity";
|
||||
} else {
|
||||
return value.constant;
|
||||
}
|
||||
if (IsScalar(value.type.base_type)) {
|
||||
if (StringIsFlatbufferNan(value.constant)) {
|
||||
return "double.nan";
|
||||
} else if (StringIsFlatbufferPositiveInfinity(value.constant)) {
|
||||
return "double.infinity";
|
||||
} else if (StringIsFlatbufferNegativeInfinity(value.constant)) {
|
||||
return "double.negativeInfinity";
|
||||
}
|
||||
}
|
||||
return value.constant;
|
||||
} else if (IsBool(value.type.base_type)) {
|
||||
return "false";
|
||||
} else if (IsScalar(value.type.base_type) && !IsUnion(value.type)) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
// independent from idl_parser, since this code is not needed for most clients
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
@@ -102,6 +103,7 @@ class GoGenerator : public BaseGenerator {
|
||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||
++it) {
|
||||
tracked_imported_namespaces_.clear();
|
||||
needs_math_import_ = false;
|
||||
needs_imports = false;
|
||||
std::string enumcode;
|
||||
GenEnum(**it, &enumcode);
|
||||
@@ -121,6 +123,7 @@ class GoGenerator : public BaseGenerator {
|
||||
for (auto it = parser_.structs_.vec.begin();
|
||||
it != parser_.structs_.vec.end(); ++it) {
|
||||
tracked_imported_namespaces_.clear();
|
||||
needs_math_import_ = false;
|
||||
std::string declcode;
|
||||
GenStruct(**it, &declcode);
|
||||
if (parser_.opts.one_file) {
|
||||
@@ -154,6 +157,7 @@ class GoGenerator : public BaseGenerator {
|
||||
}
|
||||
};
|
||||
std::set<const Namespace *, NamespacePtrLess> tracked_imported_namespaces_;
|
||||
bool needs_math_import_ = false;
|
||||
|
||||
// Most field accessors need to retrieve and test the field offset first,
|
||||
// this is the prefix code for that.
|
||||
@@ -1277,6 +1281,23 @@ class GoGenerator : public BaseGenerator {
|
||||
switch (field.value.type.base_type) {
|
||||
case BASE_TYPE_BOOL:
|
||||
return field.value.constant == "0" ? "false" : "true";
|
||||
case BASE_TYPE_FLOAT:
|
||||
case BASE_TYPE_DOUBLE: {
|
||||
const std::string float_type =
|
||||
field.value.type.base_type == BASE_TYPE_FLOAT ? "float32"
|
||||
: "float64";
|
||||
if (StringIsFlatbufferNan(field.value.constant)) {
|
||||
needs_math_import_ = true;
|
||||
return float_type + "(math.NaN())";
|
||||
} else if (StringIsFlatbufferPositiveInfinity(field.value.constant)) {
|
||||
needs_math_import_ = true;
|
||||
return float_type + "(math.Inf(1))";
|
||||
} else if (StringIsFlatbufferNegativeInfinity(field.value.constant)) {
|
||||
needs_math_import_ = true;
|
||||
return float_type + "(math.Inf(-1))";
|
||||
}
|
||||
return field.value.constant;
|
||||
}
|
||||
default: return field.value.constant;
|
||||
}
|
||||
}
|
||||
@@ -1330,6 +1351,8 @@ class GoGenerator : public BaseGenerator {
|
||||
if (needs_imports) {
|
||||
code += "import (\n";
|
||||
if (is_enum) { code += "\t\"strconv\"\n\n"; }
|
||||
// math is needed to support non-finite scalar default values.
|
||||
if (needs_math_import_) { code += "\t\"math\"\n\n"; }
|
||||
if (!parser_.opts.go_import.empty()) {
|
||||
code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n";
|
||||
} else {
|
||||
@@ -1346,6 +1369,10 @@ class GoGenerator : public BaseGenerator {
|
||||
code += ")\n\n";
|
||||
} else {
|
||||
if (is_enum) { code += "import \"strconv\"\n\n"; }
|
||||
if (needs_math_import_) {
|
||||
// math is needed to support non-finite scalar default values.
|
||||
code += "import \"math\"\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
// independent from idl_parser, since this code is not needed for most clients
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "flatbuffers/code_generators.h"
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
@@ -1046,8 +1048,19 @@ class RustGenerator : public BaseGenerator {
|
||||
if (field.IsOptional() && !IsUnion(field.value.type)) { return "None"; }
|
||||
}
|
||||
switch (GetFullType(field.value.type)) {
|
||||
case ftInteger:
|
||||
case ftInteger: {
|
||||
return field.value.constant;
|
||||
}
|
||||
case ftFloat: {
|
||||
const std::string float_prefix =
|
||||
(field.value.type.base_type == BASE_TYPE_FLOAT) ? "f32::" : "f64::";
|
||||
if (StringIsFlatbufferNan(field.value.constant)) {
|
||||
return float_prefix + "NAN";
|
||||
} else if (StringIsFlatbufferPositiveInfinity(field.value.constant)) {
|
||||
return float_prefix + "INFINITY";
|
||||
} else if (StringIsFlatbufferNegativeInfinity(field.value.constant)) {
|
||||
return float_prefix + "NEG_INFINITY";
|
||||
}
|
||||
return field.value.constant;
|
||||
}
|
||||
case ftBool: {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
@@ -454,9 +455,16 @@ class TsGenerator : public BaseGenerator {
|
||||
return "BigInt('" + value.constant + "')";
|
||||
}
|
||||
|
||||
default:
|
||||
if (value.constant == "nan") { return "NaN"; }
|
||||
default: {
|
||||
if (StringIsFlatbufferNan(value.constant)) {
|
||||
return "NaN";
|
||||
} else if (StringIsFlatbufferPositiveInfinity(value.constant)) {
|
||||
return "Infinity";
|
||||
} else if (StringIsFlatbufferNegativeInfinity(value.constant)) {
|
||||
return "-Infinity";
|
||||
}
|
||||
return value.constant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user