diff options
author | Kamil Rojewski <kamil.rojewski@gmail.com> | 2020-10-28 17:45:23 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-28 09:45:23 -0700 |
commit | a0182cdb118c26eb9ee2ef683a37d3626ec7d0bd (patch) | |
tree | 674b518224cafc0877cb6b9d93814fa53d469706 /src | |
parent | 0dfcc0a378346810b6294c66dc738c21fb9b75e3 (diff) | |
download | flatbuffers-a0182cdb118c26eb9ee2ef683a37d3626ec7d0bd.tar.gz flatbuffers-a0182cdb118c26eb9ee2ef683a37d3626ec7d0bd.tar.bz2 flatbuffers-a0182cdb118c26eb9ee2ef683a37d3626ec7d0bd.zip |
optional scalars for ts/js (#6215)
* optional scalars for ts/js
* removed range based for
* removed range based for
Diffstat (limited to 'src')
-rw-r--r-- | src/idl_gen_js_ts.cpp | 101 | ||||
-rw-r--r-- | src/idl_parser.cpp | 3 |
2 files changed, 65 insertions, 39 deletions
diff --git a/src/idl_gen_js_ts.cpp b/src/idl_gen_js_ts.cpp index cd3b9221..0240f513 100644 --- a/src/idl_gen_js_ts.cpp +++ b/src/idl_gen_js_ts.cpp @@ -442,11 +442,16 @@ class JsTsGenerator : public BaseGenerator { } } - std::string GenBBAccess() { + std::string GenBBAccess() const { return lang_.language == IDLOptions::kTs ? "this.bb!" : "this.bb"; } - std::string GenDefaultValue(const Value &value, const std::string &context) { + std::string GenDefaultValue(const FieldDef &field, const std::string &context) { + if (field.IsScalarOptional()) { + return "null"; + } + + 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)) { @@ -503,13 +508,17 @@ class JsTsGenerator : public BaseGenerator { } switch (type.base_type) { - case BASE_TYPE_BOOL: return "boolean"; + case BASE_TYPE_BOOL: return (allowNull) ? ("boolean|null") : ("boolean"); case BASE_TYPE_LONG: - case BASE_TYPE_ULONG: return "flatbuffers.Long"; + case BASE_TYPE_ULONG: return (allowNull) ? ("flatbuffers.Long|null") : ("flatbuffers.Long"); default: if (IsScalar(type.base_type)) { - if (type.enum_def) { return WrapInNameSpace(*type.enum_def); } - return "number"; + if (type.enum_def) { + const auto enum_name = WrapInNameSpace(*type.enum_def); + return (allowNull) ? (enum_name + "|null") : (enum_name); + } + + return (allowNull) ? ("number|null") : ("number"); } return "flatbuffers.Offset"; } @@ -576,10 +585,6 @@ class JsTsGenerator : public BaseGenerator { return GenFileNamespacePrefix(file) + "." + typeName; } - std::string GenFullNameSpace(const Definition &def, const std::string &file) { - return GenPrefixedTypeName(GetNameSpace(def), file); - } - void GenStructArgs(const StructDef &struct_def, std::string *annotations, std::string *arguments, const std::string &nameprefix) { for (auto it = struct_def.fields.vec.begin(); @@ -593,11 +598,11 @@ class JsTsGenerator : public BaseGenerator { nameprefix + field.name + "_"); } else { *annotations += - GenTypeAnnotation(kParam, GenTypeName(field.value.type, true), + GenTypeAnnotation(kParam, GenTypeName(field.value.type, true, field.optional), nameprefix + field.name); if (lang_.language == IDLOptions::kTs) { *arguments += ", " + nameprefix + field.name + ": " + - GenTypeName(field.value.type, true); + GenTypeName(field.value.type, true, field.optional); } else { *arguments += ", " + nameprefix + field.name; } @@ -879,7 +884,7 @@ class JsTsGenerator : public BaseGenerator { const auto union_has_string = UnionHasStringType(enum_def); const auto field_binded_method = "this." + field_name + ".bind(this)"; - std::string ret = ""; + std::string ret; if (!is_array) { const auto conversion_function = @@ -935,7 +940,7 @@ class JsTsGenerator : public BaseGenerator { return ""; } - std::string GenNullCheckConditional(const std::string &nullCheckVar, + static std::string GenNullCheckConditional(const std::string &nullCheckVar, const std::string &trueVal, const std::string &falseVal = "null") { return "(" + nullCheckVar + " !== null ? " + trueVal + " : " + falseVal + @@ -1039,21 +1044,23 @@ class JsTsGenerator : public BaseGenerator { // the variable name from field_offset_decl std::string field_offset_val; const auto field_default_val = - GenDefaultValue(field.value, "flatbuffers"); + GenDefaultValue(field, "flatbuffers"); // Emit a scalar field - if (IsScalar(field.value.type.base_type) || - IsString(field.value.type)) { + const auto is_string = IsString(field.value.type); + if (IsScalar(field.value.type.base_type) || is_string) { + const auto has_null_default = is_string || HasNullDefault(field); + if (field.value.type.enum_def) { if (!parser_.opts.generate_all) { imported_files.insert(field.value.type.enum_def->file); } field_type += - GenPrefixedTypeName(GenTypeName(field.value.type, false, true), + GenPrefixedTypeName(GenTypeName(field.value.type, false, has_null_default), field.value.type.enum_def->file); } else { - field_type += GenTypeName(field.value.type, false, true); + field_type += GenTypeName(field.value.type, false, has_null_default); } field_val = "this." + field_name + "()"; @@ -1162,7 +1169,7 @@ class JsTsGenerator : public BaseGenerator { } field_type += - GenPrefixedTypeName(GenTypeName(vectortype, false, true), + GenPrefixedTypeName(GenTypeName(vectortype, false, HasNullDefault(field)), vectortype.enum_def->file); } else { field_type += vectortypename; @@ -1281,7 +1288,7 @@ class JsTsGenerator : public BaseGenerator { obj_api_unpack_func = unpack_func + "\n\n" + unpack_to_func; } - bool CanCreateFactoryMethod(const StructDef &struct_def) { + static bool CanCreateFactoryMethod(const StructDef &struct_def) { // to preserve backwards compatibility, we allow the first field to be a // struct return struct_def.fields.vec.size() < 2 || @@ -1411,20 +1418,22 @@ class JsTsGenerator : public BaseGenerator { NumToString(field.value.offset) + ");\n return offset ? "; // Emit a scalar field - if (IsScalar(field.value.type.base_type) || - IsString(field.value.type)) { + const auto is_string = IsString(field.value.type); + if (IsScalar(field.value.type.base_type) || is_string) { + const auto has_null_default = is_string || HasNullDefault(field); + GenDocComment( field.doc_comment, code_ptr, - std::string(IsString(field.value.type) + std::string(is_string ? GenTypeAnnotation(kParam, "flatbuffers.Encoding=", "optionalEncoding") : "") + GenTypeAnnotation(kReturns, - GenTypeName(field.value.type, false, true), + GenTypeName(field.value.type, false, has_null_default), "", false)); if (lang_.language == IDLOptions::kTs) { std::string prefix = MakeCamel(field.name, false) + "("; - if (IsString(field.value.type)) { + if (is_string) { code += prefix + "):string|null\n"; code += prefix + "optionalEncoding:flatbuffers.Encoding" + "):" + GenTypeName(field.value.type, false, true) + "\n"; @@ -1435,7 +1444,7 @@ class JsTsGenerator : public BaseGenerator { if (field.value.type.enum_def) { code += "):" + - GenPrefixedTypeName(GenTypeName(field.value.type, false, true), + GenPrefixedTypeName(GenTypeName(field.value.type, false, field.optional), field.value.type.enum_def->file) + " {\n"; @@ -1443,12 +1452,12 @@ class JsTsGenerator : public BaseGenerator { imported_files.insert(field.value.type.enum_def->file); } } else { - code += "):" + GenTypeName(field.value.type, false, true) + " {\n"; + code += "):" + GenTypeName(field.value.type, false, has_null_default) + " {\n"; } } else { code += object_name + ".prototype." + MakeCamel(field.name, false); code += " = function("; - if (IsString(field.value.type)) { + if (is_string) { code += "optionalEncoding"; } code += ") {\n"; @@ -1462,12 +1471,12 @@ class JsTsGenerator : public BaseGenerator { ";\n"; } else { std::string index = "this.bb_pos + offset"; - if (IsString(field.value.type)) { + if (is_string) { index += ", optionalEncoding"; } code += offset_prefix + GenGetter(field.value.type, "(" + index + ")") + " : " + - GenDefaultValue(field.value, GenBBAccess()); + GenDefaultValue(field, GenBBAccess()); code += ";\n"; } } @@ -1865,7 +1874,7 @@ class JsTsGenerator : public BaseGenerator { if (lang_.language == IDLOptions::kTs) { code += "static add" + MakeCamel(field.name); code += "(builder:flatbuffers.Builder, " + argname + ":" + - GetArgType(field) + ") {\n"; + GetArgType(field, false) + ") {\n"; } else { code += object_name + ".add" + MakeCamel(field.name); code += " = function(builder, " + argname + ") {\n"; @@ -1877,9 +1886,15 @@ class JsTsGenerator : public BaseGenerator { code += argname + ", "; if (!IsScalar(field.value.type.base_type)) { code += "0"; + } else if (HasNullDefault(field)) { + if (IsLong(field.value.type.base_type)) { + code += "builder.createLong(0, 0)"; + } else { + code += "0"; + } } else { if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; } - code += GenDefaultValue(field.value, "builder"); + code += GenDefaultValue(field, "builder"); } code += ");\n};\n\n"; @@ -2010,7 +2025,7 @@ class JsTsGenerator : public BaseGenerator { const auto &field = **it; if (field.deprecated) continue; paramDoc += - GenTypeAnnotation(kParam, GetArgType(field), GetArgName(field)); + GenTypeAnnotation(kParam, GetArgType(field, true), GetArgName(field)); } paramDoc += GenTypeAnnotation(kReturns, "flatbuffers.Offset", "", false); @@ -2031,7 +2046,7 @@ class JsTsGenerator : public BaseGenerator { if (field.deprecated) continue; if (lang_.language == IDLOptions::kTs) { - code += ", " + GetArgName(field) + ":" + GetArgType(field); + code += ", " + GetArgName(field) + ":" + GetArgType(field, true); } else { code += ", " + GetArgName(field); } @@ -2054,8 +2069,14 @@ class JsTsGenerator : public BaseGenerator { const auto &field = **it; if (field.deprecated) continue; + const auto arg_name = GetArgName(field); + + if (field.IsScalarOptional()) { + code += " if (" + arg_name + " !== null)\n "; + } + code += " " + methodPrefix + ".add" + MakeCamel(field.name) + "("; - code += "builder, " + GetArgName(field) + ");\n"; + code += "builder, " + arg_name + ");\n"; } code += " return " + methodPrefix + ".end" + Verbose(struct_def) + @@ -2094,9 +2115,13 @@ class JsTsGenerator : public BaseGenerator { if (!object_namespace.empty()) { code += "}\n"; } } } + + static bool HasNullDefault(const FieldDef &field) { + return field.optional && field.value.constant == "null"; + } - std::string GetArgType(const FieldDef &field) { - auto type_name = GenTypeName(field.value.type, true); + std::string GetArgType(const FieldDef &field, bool allowNull) { + auto type_name = GenTypeName(field.value.type, true, allowNull && field.optional); if (field.value.type.enum_def) { if (IsScalar(field.value.type.base_type)) { diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 37d61a78..9eebac9d 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -2282,7 +2282,8 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields, bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions &opts) { static FLATBUFFERS_CONSTEXPR unsigned long supported_langs = IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster | - IDLOptions::kKotlin | IDLOptions::kCpp | IDLOptions::kJava; + IDLOptions::kKotlin | IDLOptions::kCpp | IDLOptions::kJava | + IDLOptions::kTs | IDLOptions::kJs; unsigned long langs = opts.lang_to_generate; return (langs > 0 && langs < IDLOptions::kMAX) && !(langs & ~supported_langs); } |