mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-02 04:04:19 +00:00
[TS] Escape keywords in typescript object names (#7137)
* Add Object to the list of reserved keywords. * Properly escape keywords in type names. * Properly escape keywords in enum names. * Properly escape keywords in enum field names.
This commit is contained in:
@@ -80,6 +80,7 @@ class TsGenerator : public BaseGenerator {
|
||||
"instanceof",
|
||||
"new",
|
||||
"null",
|
||||
"Object",
|
||||
"return",
|
||||
"super",
|
||||
"switch",
|
||||
@@ -219,9 +220,7 @@ class TsGenerator : public BaseGenerator {
|
||||
if (reverse) return; // FIXME.
|
||||
std::string &code = *code_ptr;
|
||||
GenDocComment(enum_def.doc_comment, code_ptr);
|
||||
std::string ns = GetNameSpace(enum_def);
|
||||
std::string enum_def_name = enum_def.name + (reverse ? "Name" : "");
|
||||
code += "export enum " + enum_def.name + "{\n";
|
||||
code += "export enum " + EscapeKeyword(enum_def.name) + "{\n";
|
||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||
auto &ev = **it;
|
||||
if (!ev.doc_comment.empty()) {
|
||||
@@ -229,13 +228,15 @@ class TsGenerator : public BaseGenerator {
|
||||
GenDocComment(ev.doc_comment, code_ptr, " ");
|
||||
}
|
||||
|
||||
const std::string escaped_name = EscapeKeyword(ev.name);
|
||||
|
||||
// Generate mapping between EnumName: EnumValue(int)
|
||||
if (reverse) {
|
||||
code += " '" + enum_def.ToString(ev) + "'";
|
||||
code += " = ";
|
||||
code += "'" + ev.name + "'";
|
||||
code += "'" + escaped_name + "'";
|
||||
} else {
|
||||
code += " " + ev.name;
|
||||
code += " " + escaped_name;
|
||||
code += " = ";
|
||||
// Unfortunately, because typescript does not support bigint enums,
|
||||
// for 64-bit enums, we instead map the enum names to strings.
|
||||
@@ -318,9 +319,9 @@ class TsGenerator : public BaseGenerator {
|
||||
}
|
||||
default: {
|
||||
if (auto val = value.type.enum_def->FindByValue(value.constant)) {
|
||||
return AddImport(imports, *value.type.enum_def,
|
||||
*value.type.enum_def) +
|
||||
"." + val->name;
|
||||
return EscapeKeyword(AddImport(imports, *value.type.enum_def,
|
||||
*value.type.enum_def)) +
|
||||
"." + EscapeKeyword(val->name);
|
||||
} else {
|
||||
return value.constant;
|
||||
}
|
||||
@@ -357,7 +358,7 @@ class TsGenerator : public BaseGenerator {
|
||||
if (IsString(type)) {
|
||||
name = "string|Uint8Array";
|
||||
} else {
|
||||
name = AddImport(imports, owner, *type.struct_def);
|
||||
name = EscapeKeyword(AddImport(imports, owner, *type.struct_def));
|
||||
}
|
||||
return allowNull ? (name + "|null") : name;
|
||||
}
|
||||
@@ -450,7 +451,7 @@ class TsGenerator : public BaseGenerator {
|
||||
}
|
||||
|
||||
std::string GenerateNewExpression(const std::string &object_name) {
|
||||
return "new " + object_name + "()";
|
||||
return "new " + EscapeKeyword(object_name) + "()";
|
||||
}
|
||||
|
||||
void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr,
|
||||
@@ -570,11 +571,12 @@ class TsGenerator : public BaseGenerator {
|
||||
export_statement += "export { ";
|
||||
std::string symbols_expression;
|
||||
if (long_import_name.empty()) {
|
||||
symbols_expression += import_name;
|
||||
symbols_expression += EscapeKeyword(import_name);
|
||||
if (parser_.opts.generate_object_based_api)
|
||||
symbols_expression += ", " + import_name + "T";
|
||||
} else {
|
||||
symbols_expression += dependency.name + " as " + long_import_name;
|
||||
symbols_expression += EscapeKeyword(dependency.name) + " as " +
|
||||
EscapeKeyword(long_import_name);
|
||||
if (parser_.opts.generate_object_based_api)
|
||||
symbols_expression +=
|
||||
", " + dependency.name + "T as " + long_import_name + "T";
|
||||
@@ -616,7 +618,7 @@ class TsGenerator : public BaseGenerator {
|
||||
const auto &depc_comps = dependency.defined_namespace->components;
|
||||
for (auto it = depc_comps.begin(); it != depc_comps.end(); it++) ns += *it;
|
||||
std::string unique_name = ns + dependency.name;
|
||||
std::string import_name = dependency.name;
|
||||
std::string import_name = EscapeKeyword(dependency.name);
|
||||
std::string long_import_name;
|
||||
if (imports.find(unique_name) != imports.end())
|
||||
return imports.find(unique_name)->second.name;
|
||||
@@ -900,7 +902,8 @@ class TsGenerator : public BaseGenerator {
|
||||
std::string pack_func_offset_decl;
|
||||
std::string pack_func_create_call;
|
||||
|
||||
const auto struct_name = AddImport(imports, struct_def, struct_def);
|
||||
const auto struct_name =
|
||||
EscapeKeyword(AddImport(imports, struct_def, struct_def));
|
||||
|
||||
if (has_create) {
|
||||
pack_func_create_call = " return " + struct_name + ".create" +
|
||||
@@ -1096,6 +1099,8 @@ class TsGenerator : public BaseGenerator {
|
||||
unpack_func += " " + field_val;
|
||||
unpack_to_func += " _o." + field_name_escaped + " = " + field_val + ";";
|
||||
|
||||
// FIXME: if field_type and field_name_escaped are identical, then
|
||||
// this generates invalid typescript.
|
||||
constructor_func += " public " + field_name_escaped + ": " + field_type +
|
||||
" = " +
|
||||
field_default_val;
|
||||
@@ -1184,9 +1189,9 @@ class TsGenerator : public BaseGenerator {
|
||||
std::string object_namespace = GetNameSpace(struct_def);
|
||||
|
||||
// Emit constructor
|
||||
object_name = struct_def.name;
|
||||
object_name = EscapeKeyword(struct_def.name);
|
||||
GenDocComment(struct_def.doc_comment, code_ptr);
|
||||
code += "export class " + struct_def.name;
|
||||
code += "export class " + object_name;
|
||||
code += " {\n";
|
||||
code += " bb: flatbuffers.ByteBuffer|null = null;\n";
|
||||
code += " bb_pos = 0;\n";
|
||||
@@ -1274,8 +1279,8 @@ class TsGenerator : public BaseGenerator {
|
||||
else {
|
||||
switch (field.value.type.base_type) {
|
||||
case BASE_TYPE_STRUCT: {
|
||||
const auto type =
|
||||
AddImport(imports, struct_def, *field.value.type.struct_def);
|
||||
const auto type = EscapeKeyword(
|
||||
AddImport(imports, struct_def, *field.value.type.struct_def));
|
||||
GenDocComment(field.doc_comment, code_ptr);
|
||||
code += ConvertCase(field.name, Case::kLowerCamel);
|
||||
code += "(obj?:" + type + "):" + type + "|null {\n";
|
||||
@@ -1617,10 +1622,10 @@ class TsGenerator : public BaseGenerator {
|
||||
}
|
||||
|
||||
code += "):flatbuffers.Offset {\n";
|
||||
code += " " + struct_def.name + ".start" +
|
||||
code += " " + object_name + ".start" +
|
||||
GetPrefixedName(struct_def) + "(builder);\n";
|
||||
|
||||
std::string methodPrefix = struct_def.name;
|
||||
std::string methodPrefix = object_name;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto &field = **it;
|
||||
@@ -1651,8 +1656,10 @@ class TsGenerator : public BaseGenerator {
|
||||
code += "}\n";
|
||||
|
||||
code += "\n";
|
||||
code += "static deserialize(buffer: Uint8Array):" + name + " {\n";
|
||||
code += " return " + AddImport(imports, struct_def, struct_def) +
|
||||
code += "static deserialize(buffer: Uint8Array):" + EscapeKeyword(name) +
|
||||
" {\n";
|
||||
code += " return " +
|
||||
EscapeKeyword(AddImport(imports, struct_def, struct_def)) +
|
||||
".getRootAs" + name + "(new flatbuffers.ByteBuffer(buffer))\n";
|
||||
code += "}\n";
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ if [ -x ../flatc ]; then
|
||||
../flatc --gen-object-api -b -I include_test monster_test.fbs unicode_test.json
|
||||
../flatc --ts --gen-name-strings --gen-mutable --gen-object-api -o union_vector union_vector/union_vector.fbs
|
||||
../flatc --ts --gen-name-strings optional_scalars.fbs
|
||||
../flatc --ts --gen-name-strings --gen-object-api --gen-mutable typescript_keywords.fbs
|
||||
fi
|
||||
tsc
|
||||
node -r esm JavaScriptTest
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
},
|
||||
"include": [
|
||||
"monster_test.ts",
|
||||
"typescript_keywords.ts",
|
||||
"my-game/**/*.ts",
|
||||
"typescript/**/*.ts",
|
||||
"optional_scalars/**/*.ts",
|
||||
"namespace_test/**/*.ts",
|
||||
"union_vector/**/*.ts"
|
||||
|
||||
15
tests/typescript_keywords.fbs
Normal file
15
tests/typescript_keywords.fbs
Normal file
@@ -0,0 +1,15 @@
|
||||
// This file includes a variety of keywords meant to deliberately interfere
|
||||
// with typescript keywords.
|
||||
namespace typescript;
|
||||
|
||||
enum class: int {
|
||||
new,
|
||||
instanceof,
|
||||
}
|
||||
|
||||
table Object {
|
||||
return:int;
|
||||
if:int;
|
||||
switch:int;
|
||||
enum:class;
|
||||
}
|
||||
Reference in New Issue
Block a user