From eabdbda7555a66c59688b513c135e207a93f014a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Harrtell?= Date: Tue, 1 Jun 2021 18:09:55 +0200 Subject: [PATCH] [TS] Generate entry point module (#6674) --- src/idl_gen_ts.cpp | 93 +++++++++++++++++++++--------- tests/monster_test.js | 16 +++++ tests/monster_test.ts | 16 +++++ tests/tsconfig.json | 3 +- tests/union_vector/union_vector.js | 5 ++ tests/union_vector/union_vector.ts | 5 ++ 6 files changed, 109 insertions(+), 29 deletions(-) create mode 100644 tests/monster_test.js create mode 100644 tests/monster_test.ts create mode 100644 tests/union_vector/union_vector.js create mode 100644 tests/union_vector/union_vector.ts diff --git a/src/idl_gen_ts.cpp b/src/idl_gen_ts.cpp index 9128ce1e2..bd48d630d 100644 --- a/src/idl_gen_ts.cpp +++ b/src/idl_gen_ts.cpp @@ -29,7 +29,10 @@ namespace flatbuffers { struct ImportDefinition { std::string name; - std::string statement; + std::string import_statement; + std::string export_statement; + std::string bare_file_path; + std::string rel_file_path; const Definition *dependent; const Definition *dependency; }; @@ -49,6 +52,7 @@ class TsGenerator : public BaseGenerator { bool generate() { generateEnums(); generateStructs(); + generateEntry(); return true; } @@ -62,12 +66,12 @@ class TsGenerator : public BaseGenerator { "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; for (auto it = bare_imports.begin(); it != bare_imports.end(); it++) - code += it->second.statement + "\n"; + code += it->second.import_statement + "\n"; if (!bare_imports.empty()) code += "\n"; for (auto it = imports.begin(); it != imports.end(); it++) if (it->second.dependency != &definition) // do not import itself - code += it->second.statement + "\n"; + code += it->second.import_statement + "\n"; if (!imports.empty()) code += "\n\n"; code += classcode; @@ -77,6 +81,8 @@ class TsGenerator : public BaseGenerator { } private: + import_set imports_all_; + // Generate code for all enums. void generateEnums() { for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); @@ -88,6 +94,7 @@ class TsGenerator : public BaseGenerator { GenEnum(enum_def, &enumcode, imports, false); GenEnum(enum_def, &enumcode, imports, true); SaveType(enum_def, enumcode, imports, bare_imports); + imports_all_.insert(imports.begin(), imports.end()); } } @@ -102,9 +109,19 @@ class TsGenerator : public BaseGenerator { std::string declcode; GenStruct(parser_, struct_def, &declcode, imports); SaveType(struct_def, declcode, imports, bare_imports); + imports_all_.insert(imports.begin(), imports.end()); } } + // Generate code for a single entry point module. + void generateEntry() { + std::string code; + for (auto it = imports_all_.begin(); it != imports_all_.end(); it++) + code += it->second.export_statement + "\n"; + std::string path = "./" + path_ + file_name_ + ".ts"; + SaveFile(path.c_str(), code, false); + } + // Generate a documentation comment, if available. static void GenDocComment(const std::vector &dc, std::string *code_ptr, @@ -465,30 +482,40 @@ class TsGenerator : public BaseGenerator { } } std::string import_statement; + std::string export_statement; import_statement += "import { "; + export_statement += "export { "; + std::string symbols_expression; if (long_import_name.empty()) { - import_statement += import_name; + symbols_expression += import_name; if (parser_.opts.generate_object_based_api) - import_statement += ", " + import_name + "T"; + symbols_expression += ", " + import_name + "T"; } else { - import_statement += dependency.name + " as " + long_import_name; + symbols_expression += dependency.name + " as " + long_import_name; if (parser_.opts.generate_object_based_api) - import_statement += + symbols_expression += ", " + dependency.name + "T as " + long_import_name + "T"; } - import_statement += " } from '"; - std::string file_name; + import_statement += symbols_expression + " } from '"; + export_statement += symbols_expression + " } from '"; + std::string bare_file_path; + std::string rel_file_path; const auto &dep_comps = dependent.defined_namespace->components; for (size_t i = 0; i < dep_comps.size(); i++) - file_name += i == 0 ? ".." : (kPathSeparator + std::string("..")); - if (dep_comps.size() == 0) file_name += "."; + rel_file_path += i == 0 ? ".." : (kPathSeparator + std::string("..")); + if (dep_comps.size() == 0) rel_file_path += "."; for (auto it = depc_comps.begin(); it != depc_comps.end(); it++) - file_name += kPathSeparator + ToDasherizedCase(*it); - file_name += kPathSeparator + ToDasherizedCase(dependency.name); - import_statement += file_name + "';"; + bare_file_path += kPathSeparator + ToDasherizedCase(*it); + bare_file_path += kPathSeparator + ToDasherizedCase(dependency.name); + rel_file_path += bare_file_path; + import_statement += rel_file_path + "';"; + export_statement += "." + bare_file_path + "';"; ImportDefinition import; import.name = long_import_name.empty() ? import_name : long_import_name; - import.statement = import_statement; + import.bare_file_path = bare_file_path; + import.rel_file_path = rel_file_path; + import.import_statement = import_statement; + import.export_statement = export_statement; import.dependency = &dependency; import.dependent = &dependent; imports.insert(std::make_pair(unique_name, import)); @@ -514,28 +541,38 @@ class TsGenerator : public BaseGenerator { } } std::string import_statement; + std::string export_statement; import_statement += "import { "; + export_statement += "export { "; + std::string symbols_expression; if (long_import_name.empty()) - import_statement += import_name; + symbols_expression += import_name; else - import_statement += dependency.name + " as " + long_import_name; + symbols_expression += dependency.name + " as " + long_import_name; if (dependency.is_union) { - import_statement += ", unionTo" + import_name; - import_statement += ", unionListTo" + import_name; + symbols_expression += ", unionTo" + import_name; + symbols_expression += ", unionListTo" + import_name; } - import_statement += " } from '"; - std::string file_name; + import_statement += symbols_expression + " } from '"; + export_statement += symbols_expression + " } from '"; + std::string bare_file_path; + std::string rel_file_path; const auto &dep_comps = dependent.defined_namespace->components; for (size_t i = 0; i < dep_comps.size(); i++) - file_name += i == 0 ? ".." : (kPathSeparator + std::string("..")); - if (dep_comps.size() == 0) file_name += "."; + rel_file_path += i == 0 ? ".." : (kPathSeparator + std::string("..")); + if (dep_comps.size() == 0) rel_file_path += "."; for (auto it = depc_comps.begin(); it != depc_comps.end(); it++) - file_name += kPathSeparator + ToDasherizedCase(*it); - file_name += kPathSeparator + ToDasherizedCase(dependency.name); - import_statement += file_name + "';"; + bare_file_path += kPathSeparator + ToDasherizedCase(*it); + bare_file_path += kPathSeparator + ToDasherizedCase(dependency.name); + rel_file_path += bare_file_path; + import_statement += rel_file_path + "';"; + export_statement += "." + bare_file_path + "';"; ImportDefinition import; import.name = long_import_name.empty() ? import_name : long_import_name; - import.statement = import_statement; + import.bare_file_path = bare_file_path; + import.rel_file_path = rel_file_path; + import.import_statement = import_statement; + import.export_statement = export_statement; import.dependency = &dependency; import.dependent = &dependent; imports.insert(std::make_pair(unique_name, import)); @@ -546,7 +583,7 @@ class TsGenerator : public BaseGenerator { std::string fileName) { ImportDefinition import; import.name = import_name; - import.statement = "import " + import_name + " from '" + fileName + "';"; + import.import_statement = "import " + import_name + " from '" + fileName + "';"; imports.insert(std::make_pair(import_name, import)); } diff --git a/tests/monster_test.js b/tests/monster_test.js new file mode 100644 index 000000000..b4e13d14b --- /dev/null +++ b/tests/monster_test.js @@ -0,0 +1,16 @@ +export { Monster as MyGameExample2Monster, MonsterT as MyGameExample2MonsterT } from './my-game/example2/monster'; +export { Ability, AbilityT } from './my-game/example/ability'; +export { Any, unionToAny, unionListToAny } from './my-game/example/any'; +export { AnyAmbiguousAliases, unionToAnyAmbiguousAliases, unionListToAnyAmbiguousAliases } from './my-game/example/any-ambiguous-aliases'; +export { AnyUniqueAliases, unionToAnyUniqueAliases, unionListToAnyUniqueAliases } from './my-game/example/any-unique-aliases'; +export { Color } from './my-game/example/color'; +export { Monster, MonsterT } from './my-game/example/monster'; +export { Race } from './my-game/example/race'; +export { Referrable, ReferrableT } from './my-game/example/referrable'; +export { Stat, StatT } from './my-game/example/stat'; +export { StructOfStructs, StructOfStructsT } from './my-game/example/struct-of-structs'; +export { Test, TestT } from './my-game/example/test'; +export { TestSimpleTableWithEnum, TestSimpleTableWithEnumT } from './my-game/example/test-simple-table-with-enum'; +export { TypeAliases, TypeAliasesT } from './my-game/example/type-aliases'; +export { Vec3, Vec3T } from './my-game/example/vec3'; +export { InParentNamespace, InParentNamespaceT } from './my-game/in-parent-namespace'; diff --git a/tests/monster_test.ts b/tests/monster_test.ts new file mode 100644 index 000000000..b4e13d14b --- /dev/null +++ b/tests/monster_test.ts @@ -0,0 +1,16 @@ +export { Monster as MyGameExample2Monster, MonsterT as MyGameExample2MonsterT } from './my-game/example2/monster'; +export { Ability, AbilityT } from './my-game/example/ability'; +export { Any, unionToAny, unionListToAny } from './my-game/example/any'; +export { AnyAmbiguousAliases, unionToAnyAmbiguousAliases, unionListToAnyAmbiguousAliases } from './my-game/example/any-ambiguous-aliases'; +export { AnyUniqueAliases, unionToAnyUniqueAliases, unionListToAnyUniqueAliases } from './my-game/example/any-unique-aliases'; +export { Color } from './my-game/example/color'; +export { Monster, MonsterT } from './my-game/example/monster'; +export { Race } from './my-game/example/race'; +export { Referrable, ReferrableT } from './my-game/example/referrable'; +export { Stat, StatT } from './my-game/example/stat'; +export { StructOfStructs, StructOfStructsT } from './my-game/example/struct-of-structs'; +export { Test, TestT } from './my-game/example/test'; +export { TestSimpleTableWithEnum, TestSimpleTableWithEnumT } from './my-game/example/test-simple-table-with-enum'; +export { TypeAliases, TypeAliasesT } from './my-game/example/type-aliases'; +export { Vec3, Vec3T } from './my-game/example/vec3'; +export { InParentNamespace, InParentNamespaceT } from './my-game/in-parent-namespace'; diff --git a/tests/tsconfig.json b/tests/tsconfig.json index 7d126a28e..b2634d63b 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -12,7 +12,8 @@ "baseUrl": ".", "noEmit": false }, - "include": [ + "include": [ + "monster_test.ts", "my-game/**/*.ts", "optional_scalars/**/*.ts", "namespace_test/**/*.ts", diff --git a/tests/union_vector/union_vector.js b/tests/union_vector/union_vector.js new file mode 100644 index 000000000..3ef0d175a --- /dev/null +++ b/tests/union_vector/union_vector.js @@ -0,0 +1,5 @@ +export { Attacker, AttackerT } from './attacker'; +export { BookReader, BookReaderT } from './book-reader'; +export { Character, unionToCharacter, unionListToCharacter } from './character'; +export { Movie, MovieT } from './movie'; +export { Rapunzel, RapunzelT } from './rapunzel'; diff --git a/tests/union_vector/union_vector.ts b/tests/union_vector/union_vector.ts new file mode 100644 index 000000000..3ef0d175a --- /dev/null +++ b/tests/union_vector/union_vector.ts @@ -0,0 +1,5 @@ +export { Attacker, AttackerT } from './attacker'; +export { BookReader, BookReaderT } from './book-reader'; +export { Character, unionToCharacter, unionListToCharacter } from './character'; +export { Movie, MovieT } from './movie'; +export { Rapunzel, RapunzelT } from './rapunzel';