Added --filename-suffix and --filename-ext to flatc (#5778)

* Fixed refractoring issue in reflection/generate_code.sh. Also, mv deletes the original file, so I don't need to clean it up manually in that case.

* Added --filename-suffix and --filename-ext to flatc

* Fixed typo and added example generation of suffix and extension for C++

* Removed extra ;

* Removed clang-format block from a region that didn't need it. Fixed an auto format of another clang-format block

* Added docs, fixed pointer alignment, removed suffix test file
This commit is contained in:
Derek Bailey
2020-03-02 10:15:23 -08:00
committed by GitHub
parent c9a30c9ca2
commit 6ff1898413
33 changed files with 452 additions and 432 deletions

3
.gitignore vendored
View File

@@ -123,4 +123,5 @@ Cargo.lock
.corpus** .corpus**
.seed** .seed**
grpc/google/ grpc/google/
**/Package.resolved **/Package.resolved
.clangd/**

View File

@@ -188,6 +188,13 @@ Additional options:
- `--conform-includes PATH` : Include path for the schema given with - `--conform-includes PATH` : Include path for the schema given with
`--conform PATH`. `--conform PATH`.
- `--filename-suffix SUFFIX` : The suffix appended to the generated
file names. Default is '_generated'.
- `--filename-ext EXTENSION` : The extension appended to the generated
file names. Default is language-specific (e.g. "h" for C++). This
should not be used when multiple languages are specified.
- `--include-prefix PATH` : Prefix this path to any generated include - `--include-prefix PATH` : Prefix this path to any generated include
statements. statements.

View File

@@ -252,8 +252,8 @@ void builder_move_ctor_conversion_before_finish_test() {
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0); auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
flatbuffers::grpc::MessageBuilder mb(std::move(fbb)); flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
auto monster_offset = auto monster_offset =
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0, m1_color(), CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset); m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset); mb.Finish(monster_offset);
{ {
auto mon = flatbuffers::GetRoot<Monster>(mb.GetBufferPointer()); auto mon = flatbuffers::GetRoot<Monster>(mb.GetBufferPointer());
@@ -262,7 +262,7 @@ void builder_move_ctor_conversion_before_finish_test() {
TEST_EQ_STR(mon->name()->c_str(), m1_name().c_str()); TEST_EQ_STR(mon->name()->c_str(), m1_name().c_str());
TEST_EQ(mon->color(), m1_color()); TEST_EQ(mon->color(), m1_color());
} }
TEST_EQ(1, MyGame::Example::Color_Red); TEST_EQ(1, MyGame::Example::Color_Red);
TEST_EQ(1, m1_color()); TEST_EQ(1, m1_color());
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color())); TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0); TEST_EQ_FUNC(fbb.GetSize(), 0);
@@ -302,8 +302,8 @@ void builder_move_assign_conversion_before_finish_test() {
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0); auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
mb = std::move(fbb); mb = std::move(fbb);
auto monster_offset = auto monster_offset =
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0, m1_color(), CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset); m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset); mb.Finish(monster_offset);
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color())); TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0); TEST_EQ_FUNC(fbb.GetSize(), 0);

View File

@@ -94,15 +94,20 @@ class BaseGenerator {
static std::string NamespaceDir(const Parser &parser, const std::string &path, static std::string NamespaceDir(const Parser &parser, const std::string &path,
const Namespace &ns); const Namespace &ns);
std::string GeneratedFileName(const std::string &path,
const std::string &file_name,
const IDLOptions &options) const;
protected: protected:
BaseGenerator(const Parser &parser, const std::string &path, BaseGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, std::string qualifying_start, const std::string &file_name, std::string qualifying_start,
std::string qualifying_separator) std::string qualifying_separator, std::string default_extension)
: parser_(parser), : parser_(parser),
path_(path), path_(path),
file_name_(file_name), file_name_(file_name),
qualifying_start_(qualifying_start), qualifying_start_(qualifying_start),
qualifying_separator_(qualifying_separator) {} qualifying_separator_(qualifying_separator),
default_extension_(default_extension) {}
virtual ~BaseGenerator() {} virtual ~BaseGenerator() {}
// No copy/assign. // No copy/assign.
@@ -138,6 +143,7 @@ class BaseGenerator {
const std::string &file_name_; const std::string &file_name_;
const std::string qualifying_start_; const std::string qualifying_start_;
const std::string qualifying_separator_; const std::string qualifying_separator_;
const std::string default_extension_;
}; };
struct CommentConfig { struct CommentConfig {

View File

@@ -365,7 +365,7 @@ template<typename T> class Vector {
// This class is a pointer. Copying will therefore create an invalid object. // This class is a pointer. Copying will therefore create an invalid object.
// Private and unimplemented copy constructor. // Private and unimplemented copy constructor.
Vector(const Vector &); Vector(const Vector &);
Vector& operator=(const Vector&); Vector &operator=(const Vector &);
template<typename K> static int KeyCompare(const void *ap, const void *bp) { template<typename K> static int KeyCompare(const void *ap, const void *bp) {
const K *key = reinterpret_cast<const K *>(ap); const K *key = reinterpret_cast<const K *>(ap);
@@ -525,7 +525,7 @@ template<typename T, uint16_t length> class Array<Offset<T>, length> {
static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T"); static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
public: public:
typedef const void* return_type; typedef const void *return_type;
const uint8_t *Data() const { return data_; } const uint8_t *Data() const { return data_; }

View File

@@ -218,16 +218,17 @@ class Object {
class Sized : public Object { class Sized : public Object {
public: public:
// Size prefix. // Size prefix.
Sized(const uint8_t *data, uint8_t byte_width) : Sized(const uint8_t *data, uint8_t byte_width)
Object(data, byte_width), size_(read_size()) {} : Object(data, byte_width), size_(read_size()) {}
// Manual size. // Manual size.
Sized(const uint8_t *data, uint8_t byte_width, size_t sz) : Sized(const uint8_t *data, uint8_t byte_width, size_t sz)
Object(data, byte_width), size_(sz) {} : Object(data, byte_width), size_(sz) {}
size_t size() const { return size_; } size_t size() const { return size_; }
// Access size stored in `byte_width_` bytes before data_ pointer. // Access size stored in `byte_width_` bytes before data_ pointer.
size_t read_size() const { size_t read_size() const {
return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_)); return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_));
} }
protected: protected:
size_t size_; size_t size_;
}; };
@@ -235,11 +236,10 @@ class Sized : public Object {
class String : public Sized { class String : public Sized {
public: public:
// Size prefix. // Size prefix.
String(const uint8_t *data, uint8_t byte_width) String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
: Sized(data, byte_width) {}
// Manual size. // Manual size.
String(const uint8_t *data, uint8_t byte_width, size_t sz) String(const uint8_t *data, uint8_t byte_width, size_t sz)
: Sized(data, byte_width, sz) {} : Sized(data, byte_width, sz) {}
size_t length() const { return size(); } size_t length() const { return size(); }
const char *c_str() const { return reinterpret_cast<const char *>(data_); } const char *c_str() const { return reinterpret_cast<const char *>(data_); }
@@ -296,6 +296,7 @@ class TypedVector : public Sized {
Type ElementType() { return type_; } Type ElementType() { return type_; }
friend Reference; friend Reference;
private: private:
Type type_; Type type_;
@@ -614,8 +615,8 @@ class Reference {
TypedVector AsTypedVector() const { TypedVector AsTypedVector() const {
if (IsTypedVector()) { if (IsTypedVector()) {
auto tv = TypedVector(Indirect(), byte_width_, auto tv =
ToTypedVectorElementType(type_)); TypedVector(Indirect(), byte_width_, ToTypedVectorElementType(type_));
if (tv.type_ == FBT_STRING) { if (tv.type_ == FBT_STRING) {
// These can't be accessed as strings, since we don't know the bit-width // These can't be accessed as strings, since we don't know the bit-width
// of the size field, see the declaration of // of the size field, see the declaration of

View File

@@ -560,6 +560,8 @@ struct IDLOptions {
std::vector<std::string> cpp_includes; std::vector<std::string> cpp_includes;
std::string cpp_std; std::string cpp_std;
std::string proto_namespace_suffix; std::string proto_namespace_suffix;
std::string filename_suffix;
std::string filename_extension;
// Possible options for the more general generator below. // Possible options for the more general generator below.
enum Language { enum Language {
@@ -643,6 +645,8 @@ struct IDLOptions {
force_defaults(false), force_defaults(false),
java_primitive_has_method(false), java_primitive_has_method(false),
cs_gen_json_serializer(false), cs_gen_json_serializer(false),
filename_suffix("_generated"),
filename_extension(),
lang(IDLOptions::kJava), lang(IDLOptions::kJava),
mini_reflect(IDLOptions::kNone), mini_reflect(IDLOptions::kNone),
lang_to_generate(0), lang_to_generate(0),
@@ -1126,9 +1130,8 @@ bool GeneratePythonGRPC(const Parser &parser, const std::string &path,
// Generate GRPC Swift interfaces. // Generate GRPC Swift interfaces.
// See idl_gen_grpc.cpp. // See idl_gen_grpc.cpp.
extern bool GenerateSwiftGRPC(const Parser &parser, extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name);
const std::string &file_name);
} // namespace flatbuffers } // namespace flatbuffers

View File

@@ -636,30 +636,30 @@ inline bool EscapeString(const char *s, size_t length, std::string *_text,
return true; return true;
} }
inline std::string BufferToHexText(const void *buffer, size_t buffer_size, size_t max_length, inline std::string BufferToHexText(const void *buffer, size_t buffer_size,
size_t max_length,
const std::string &wrapped_line_prefix, const std::string &wrapped_line_prefix,
const std::string &wrapped_line_suffix) { const std::string &wrapped_line_suffix) {
std::string text = wrapped_line_prefix; std::string text = wrapped_line_prefix;
size_t start_offset = 0; size_t start_offset = 0;
const char *s = reinterpret_cast<const char *>(buffer); const char *s = reinterpret_cast<const char *>(buffer);
for (size_t i = 0; s && i < buffer_size; i++) { for (size_t i = 0; s && i < buffer_size; i++) {
// Last iteration or do we have more? // Last iteration or do we have more?
bool have_more= i + 1 < buffer_size; bool have_more = i + 1 < buffer_size;
text += "0x"; text += "0x";
text += IntToStringHex(static_cast<uint8_t>(s[i]), 2); text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
if (have_more) { if (have_more) { text += ','; }
text += ','; // If we have more to process and we reached max_length
} if (have_more &&
// If we have more to process and we reached max_length text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
if (have_more && text.size() + wrapped_line_suffix.size() >= start_offset + max_length) { text += wrapped_line_suffix;
text += wrapped_line_suffix; text += '\n';
text += '\n'; start_offset = text.size();
start_offset = text.size(); text += wrapped_line_prefix;
text += wrapped_line_prefix;
}
} }
text += wrapped_line_suffix; }
return text; text += wrapped_line_suffix;
return text;
} }
// Remove paired quotes in a string: "text"|'text' -> text. // Remove paired quotes in a string: "text"|'text' -> text.

View File

@@ -145,6 +145,14 @@ std::string BaseGenerator::GetNameSpace(const Definition &def) const {
return qualified_name; return qualified_name;
} }
std::string BaseGenerator::GeneratedFileName(const std::string &path,
const std::string &file_name,
const IDLOptions &options) const {
return path + file_name + options.filename_suffix + "." +
(options.filename_extension.empty() ? default_extension_
: options.filename_extension);
}
// Generate a documentation comment, if available. // Generate a documentation comment, if available.
void GenComment(const std::vector<std::string> &dc, std::string *code_ptr, void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
const CommentConfig *config, const char *prefix) { const CommentConfig *config, const char *prefix) {

View File

@@ -148,6 +148,10 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
" --conform FILE Specify a schema the following schemas should be\n" " --conform FILE Specify a schema the following schemas should be\n"
" an evolution of. Gives errors if not.\n" " an evolution of. Gives errors if not.\n"
" --conform-includes Include path for the schema given with --conform PATH\n" " --conform-includes Include path for the schema given with --conform PATH\n"
" --filename-suffix The suffix appended to the generated file names.\n"
" Default is '_generated'.\n"
" --filename-ext The extension appended to the generated file names.\n"
" Default is language-specific (e.g., '.h' for C++)\n"
" --include-prefix Prefix this path to any generated include statements.\n" " --include-prefix Prefix this path to any generated include statements.\n"
" PATH\n" " PATH\n"
" --keep-prefix Keep original prefix of schema include statement.\n" " --keep-prefix Keep original prefix of schema include statement.\n"
@@ -339,6 +343,12 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} else if (arg == "--root-type") { } else if (arg == "--root-type") {
if (++argi >= argc) Error("missing type following: " + arg, true); if (++argi >= argc) Error("missing type following: " + arg, true);
opts.root_type = argv[argi]; opts.root_type = argv[argi];
} else if (arg == "--filename-suffix") {
if (++argi >= argc) Error("missing filename suffix: " + arg, true);
opts.filename_suffix = argv[argi];
} else if (arg == "--filename-ext") {
if (++argi >= argc) Error("missing filename extension: " + arg, true);
opts.filename_extension = argv[argi];
} else if (arg == "--force-defaults") { } else if (arg == "--force-defaults") {
opts.force_defaults = true; opts.force_defaults = true;
} else if (arg == "--force-empty") { } else if (arg == "--force-empty") {
@@ -353,7 +363,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} else if (arg == "--flexbuffers") { } else if (arg == "--flexbuffers") {
opts.use_flexbuffers = true; opts.use_flexbuffers = true;
} else if (arg == "--cpp-std") { } else if (arg == "--cpp-std") {
if (++argi >= argc) Error("missing C++ standard specification" + arg, true); if (++argi >= argc)
Error("missing C++ standard specification" + arg, true);
opts.cpp_std = argv[argi]; opts.cpp_std = argv[argi];
} else { } else {
for (size_t i = 0; i < params_.num_generators; ++i) { for (size_t i = 0; i < params_.num_generators; ++i) {

View File

@@ -30,7 +30,9 @@ static void Error(const flatbuffers::FlatCompiler *flatc,
const std::string &err, bool usage, bool show_exe_name) { const std::string &err, bool usage, bool show_exe_name) {
if (show_exe_name) { printf("%s: ", g_program_name); } if (show_exe_name) { printf("%s: ", g_program_name); }
printf("error: %s\n", err.c_str()); printf("error: %s\n", err.c_str());
if (usage && flatc) { printf("%s", flatc->GetUsageString(g_program_name).c_str()); } if (usage && flatc) {
printf("%s", flatc->GetUsageString(g_program_name).c_str());
}
exit(1); exit(1);
} }
@@ -105,8 +107,8 @@ int main(int argc, const char *argv[]) {
{ flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema", { flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema",
true, nullptr, flatbuffers::IDLOptions::kJsonSchema, true, nullptr, flatbuffers::IDLOptions::kJsonSchema,
"Generate Json schema", nullptr }, "Generate Json schema", nullptr },
{ flatbuffers::GenerateSwift, nullptr, "--swift", "swift", { flatbuffers::GenerateSwift, nullptr, "--swift", "swift", true,
true, flatbuffers::GenerateSwiftGRPC, flatbuffers::IDLOptions::kSwift, flatbuffers::GenerateSwiftGRPC, flatbuffers::IDLOptions::kSwift,
"Generate Swift files for tables/structs", nullptr }, "Generate Swift files for tables/structs", nullptr },
}; };

View File

@@ -48,36 +48,29 @@ static inline std::string NumToStringCpp(std::string val, BaseType type) {
} }
} }
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.h";
}
static std::string GenIncludeGuard(const std::string &file_name, static std::string GenIncludeGuard(const std::string &file_name,
const Namespace &name_space, const Namespace &name_space,
const std::string &postfix= "") { const std::string &postfix = "") {
// Generate include guard. // Generate include guard.
std::string guard = file_name; std::string guard = file_name;
// Remove any non-alpha-numeric characters that may appear in a filename. // Remove any non-alpha-numeric characters that may appear in a filename.
struct IsAlnum { struct IsAlnum {
bool operator()(char c) const { return !is_alnum(c); } bool operator()(char c) const { return !is_alnum(c); }
}; };
guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()), guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()),
guard.end()); guard.end());
guard = "FLATBUFFERS_GENERATED_" + guard; guard = "FLATBUFFERS_GENERATED_" + guard;
guard += "_"; guard += "_";
// For further uniqueness, also add the namespace. // For further uniqueness, also add the namespace.
for (auto it = name_space.components.begin(); for (auto it = name_space.components.begin();
it != name_space.components.end(); ++it) { it != name_space.components.end(); ++it) {
guard += *it + "_"; guard += *it + "_";
} }
// Anything extra to add to the guard? // Anything extra to add to the guard?
if (!postfix.empty()) { if (!postfix.empty()) { guard += postfix + "_"; }
guard += postfix + "_"; guard += "H_";
} std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper);
guard += "H_"; return guard;
std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper);
return guard;
} }
namespace cpp { namespace cpp {
@@ -89,20 +82,16 @@ struct IDLOptionsCpp : public IDLOptions {
// All fields start with 'g_' prefix to distinguish from the base IDLOptions. // All fields start with 'g_' prefix to distinguish from the base IDLOptions.
CppStandard g_cpp_std; // Base version of C++ standard. CppStandard g_cpp_std; // Base version of C++ standard.
bool g_only_fixed_enums; // Generate underlaying type for all enums. bool g_only_fixed_enums; // Generate underlaying type for all enums.
// clang-format off
IDLOptionsCpp(const IDLOptions &opts) IDLOptionsCpp(const IDLOptions &opts)
: IDLOptions(opts), : IDLOptions(opts), g_cpp_std(CPP_STD_11), g_only_fixed_enums(true) {}
g_cpp_std(CPP_STD_11),
g_only_fixed_enums(true)
{}
// clang-format on
}; };
class CppGenerator : public BaseGenerator { class CppGenerator : public BaseGenerator {
public: public:
CppGenerator(const Parser &parser, const std::string &path, CppGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, IDLOptionsCpp opts) const std::string &file_name, IDLOptionsCpp opts)
: BaseGenerator(parser, path, file_name, "", "::"), : BaseGenerator(parser, path, file_name, "", "::", "h"),
cur_name_space_(nullptr), cur_name_space_(nullptr),
opts_(opts), opts_(opts),
float_const_gen_("std::numeric_limits<double>::", float_const_gen_("std::numeric_limits<double>::",
@@ -221,9 +210,10 @@ class CppGenerator : public BaseGenerator {
if (it->second.empty()) continue; if (it->second.empty()) continue;
auto noext = flatbuffers::StripExtension(it->second); auto noext = flatbuffers::StripExtension(it->second);
auto basename = flatbuffers::StripPath(noext); auto basename = flatbuffers::StripPath(noext);
auto includeName =
code_ += "#include \"" + opts_.include_prefix + GeneratedFileName(opts_.include_prefix,
(opts_.keep_include_path ? noext : basename) + "_generated.h\""; opts_.keep_include_path ? noext : basename, opts_);
code_ += "#include \"" + includeName + "\"";
num_includes++; num_includes++;
} }
if (num_includes) code_ += ""; if (num_includes) code_ += "";
@@ -256,7 +246,8 @@ class CppGenerator : public BaseGenerator {
code_ += "// Binary schema not generated, no root struct found"; code_ += "// Binary schema not generated, no root struct found";
} else { } else {
auto &struct_def = *parser_.root_struct_def_; auto &struct_def = *parser_.root_struct_def_;
const auto include_guard = GenIncludeGuard(file_name_, *struct_def.defined_namespace, "bfbs"); const auto include_guard =
GenIncludeGuard(file_name_, *struct_def.defined_namespace, "bfbs");
code_ += "#ifndef " + include_guard; code_ += "#ifndef " + include_guard;
code_ += "#define " + include_guard; code_ += "#define " + include_guard;
@@ -270,13 +261,15 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("STRUCT_NAME", name); code_.SetValue("STRUCT_NAME", name);
// Create code to return the binary schema data. // Create code to return the binary schema data.
auto binary_schema_hex_text = BufferToHexText(parser_.builder_.GetBufferPointer(), auto binary_schema_hex_text =
parser_.builder_.GetSize(), 105, " ", ""); BufferToHexText(parser_.builder_.GetBufferPointer(),
parser_.builder_.GetSize(), 105, " ", "");
code_ += "struct {{STRUCT_NAME}}BinarySchema {"; code_ += "struct {{STRUCT_NAME}}BinarySchema {";
code_ += " static const uint8_t *data() {"; code_ += " static const uint8_t *data() {";
code_ += " // Buffer containing the binary schema."; code_ += " // Buffer containing the binary schema.";
code_ += " static const uint8_t bfbsData[" + NumToString(parser_.builder_.GetSize()) + "] = {"; code_ += " static const uint8_t bfbsData[" +
NumToString(parser_.builder_.GetSize()) + "] = {";
code_ += binary_schema_hex_text; code_ += binary_schema_hex_text;
code_ += " };"; code_ += " };";
code_ += " return bfbsData;"; code_ += " return bfbsData;";
@@ -300,7 +293,8 @@ class CppGenerator : public BaseGenerator {
} }
// We are just adding "_bfbs" to the generated filename. // We are just adding "_bfbs" to the generated filename.
const auto file_path = GeneratedFileName(path_, file_name_ + "_bfbs"); const auto file_path =
GeneratedFileName(path_, file_name_ + "_bfbs", opts_);
const auto final_code = code_.ToString(); const auto final_code = code_.ToString();
return SaveFile(file_path.c_str(), final_code, false); return SaveFile(file_path.c_str(), final_code, false);
@@ -312,7 +306,8 @@ class CppGenerator : public BaseGenerator {
code_.Clear(); code_.Clear();
code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
const auto include_guard = GenIncludeGuard(file_name_, *parser_.current_namespace_); const auto include_guard =
GenIncludeGuard(file_name_, *parser_.current_namespace_);
code_ += "#ifndef " + include_guard; code_ += "#ifndef " + include_guard;
code_ += "#define " + include_guard; code_ += "#define " + include_guard;
code_ += ""; code_ += "";
@@ -582,12 +577,12 @@ class CppGenerator : public BaseGenerator {
// Close the include guard. // Close the include guard.
code_ += "#endif // " + include_guard; code_ += "#endif // " + include_guard;
const auto file_path = GeneratedFileName(path_, file_name_); const auto file_path = GeneratedFileName(path_, file_name_, opts_);
const auto final_code = code_.ToString(); const auto final_code = code_.ToString();
// Save the file and optionally generate the binary schema code. // Save the file and optionally generate the binary schema code.
return SaveFile(file_path.c_str(), final_code, false) && return SaveFile(file_path.c_str(), final_code, false) &&
(!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed()); (!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed());
} }
private: private:
@@ -625,9 +620,8 @@ class CppGenerator : public BaseGenerator {
return false; return false;
} }
bool VectorElementUserFacing(const Type& type) const { bool VectorElementUserFacing(const Type &type) const {
return opts_.g_cpp_std >= cpp::CPP_STD_17 && return opts_.g_cpp_std >= cpp::CPP_STD_17 && opts_.g_only_fixed_enums &&
opts_.g_only_fixed_enums &&
IsEnum(type); IsEnum(type);
} }
@@ -662,15 +656,15 @@ class CppGenerator : public BaseGenerator {
return "flatbuffers::String"; return "flatbuffers::String";
} }
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
const auto type_name = GenTypeWire(type.VectorType(), "", const auto type_name = GenTypeWire(
VectorElementUserFacing(type.VectorType())); type.VectorType(), "", VectorElementUserFacing(type.VectorType()));
return "flatbuffers::Vector<" + type_name + ">"; return "flatbuffers::Vector<" + type_name + ">";
} }
case BASE_TYPE_STRUCT: { case BASE_TYPE_STRUCT: {
return WrapInNameSpace(*type.struct_def); return WrapInNameSpace(*type.struct_def);
} }
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
// fall through // fall through
default: { default: {
return "void"; return "void";
} }
@@ -1065,9 +1059,7 @@ class CppGenerator : public BaseGenerator {
GenComment(enum_def.doc_comment); GenComment(enum_def.doc_comment);
code_ += code_ +=
(opts_.scoped_enums ? "enum class " : "enum ") + Name(enum_def) + "\\"; (opts_.scoped_enums ? "enum class " : "enum ") + Name(enum_def) + "\\";
if (opts_.g_only_fixed_enums) { if (opts_.g_only_fixed_enums) { code_ += " : {{BASE_TYPE}}\\"; }
code_ += " : {{BASE_TYPE}}\\";
}
code_ += " {"; code_ += " {";
code_.SetValue("SEP", ","); code_.SetValue("SEP", ",");
@@ -1912,9 +1904,7 @@ class CppGenerator : public BaseGenerator {
code_ += " typedef {{NATIVE_NAME}} NativeTableType;"; code_ += " typedef {{NATIVE_NAME}} NativeTableType;";
} }
code_ += " typedef {{STRUCT_NAME}}Builder Builder;"; code_ += " typedef {{STRUCT_NAME}}Builder Builder;";
if (opts_.g_cpp_std >= cpp::CPP_STD_17) { if (opts_.g_cpp_std >= cpp::CPP_STD_17) { code_ += " struct Traits;"; }
code_ += " struct Traits;";
}
if (opts_.mini_reflect != IDLOptions::kNone) { if (opts_.mini_reflect != IDLOptions::kNone) {
code_ += code_ +=
" static const flatbuffers::TypeTable *MiniReflectTypeTable() {"; " static const flatbuffers::TypeTable *MiniReflectTypeTable() {";
@@ -2329,8 +2319,8 @@ class CppGenerator : public BaseGenerator {
const auto type = WrapInNameSpace(*vtype.struct_def); const auto type = WrapInNameSpace(*vtype.struct_def);
code_ += "_fbb.CreateVectorOfSortedTables<" + type + ">\\"; code_ += "_fbb.CreateVectorOfSortedTables<" + type + ">\\";
} else { } else {
const auto type = GenTypeWire( const auto type =
vtype, "", VectorElementUserFacing(vtype)); GenTypeWire(vtype, "", VectorElementUserFacing(vtype));
code_ += "_fbb.CreateVector<" + type + ">\\"; code_ += "_fbb.CreateVector<" + type + ">\\";
} }
code_ += code_ +=
@@ -2362,8 +2352,7 @@ class CppGenerator : public BaseGenerator {
const char *vec_elem_access, const char *vec_elem_access,
const char *vec_type_access) { const char *vec_type_access) {
auto type_name = WrapInNameSpace(*afield.value.type.enum_def); auto type_name = WrapInNameSpace(*afield.value.type.enum_def);
return type_name + "Union::UnPack(" + "_e" + return type_name + "Union::UnPack(" + "_e" + vec_elem_access + ", " +
vec_elem_access + ", " +
EscapeKeyword(afield.name + UnionTypeFieldSuffix()) + "()" + EscapeKeyword(afield.name + UnionTypeFieldSuffix()) + "()" +
vec_type_access + ", _resolver)"; vec_type_access + ", _resolver)";
} }
@@ -2553,22 +2542,24 @@ class CppGenerator : public BaseGenerator {
// For optional fields, check to see if there actually is any data // For optional fields, check to see if there actually is any data
// in _o->field before attempting to access it. If there isn't, // in _o->field before attempting to access it. If there isn't,
// depending on set_empty_strings_to_null either set it to 0 or an empty string. // depending on set_empty_strings_to_null either set it to 0 or an empty
// string.
if (!field.required) { if (!field.required) {
auto empty_value = auto empty_value = opts_.set_empty_strings_to_null
opts_.set_empty_strings_to_null ? "0" : "_fbb.CreateSharedString(\"\")"; ? "0"
: "_fbb.CreateSharedString(\"\")";
code = value + ".empty() ? " + empty_value + " : " + code; code = value + ".empty() ? " + empty_value + " : " + code;
} }
break; break;
} }
// Vector fields come in several flavours, of the forms: // Vector fields come in several flavours, of the forms:
// _fbb.CreateVector(_o->field); // _fbb.CreateVector(_o->field);
// _fbb.CreateVector((const utype*)_o->field.data(), _o->field.size()); // _fbb.CreateVector((const utype*)_o->field.data(),
// _fbb.CreateVectorOfStrings(_o->field) // _o->field.size()); _fbb.CreateVectorOfStrings(_o->field)
// _fbb.CreateVectorOfStructs(_o->field) // _fbb.CreateVectorOfStructs(_o->field)
// _fbb.CreateVector<Offset<T>>(_o->field.size() [&](size_t i) { // _fbb.CreateVector<Offset<T>>(_o->field.size() [&](size_t i) {
// return CreateT(_fbb, _o->Get(i), rehasher); // return CreateT(_fbb, _o->Get(i), rehasher);
// }); // });
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
auto vector_type = field.value.type.VectorType(); auto vector_type = field.value.type.VectorType();
switch (vector_type.base_type) { switch (vector_type.base_type) {
@@ -2659,9 +2650,9 @@ class CppGenerator : public BaseGenerator {
} }
} }
// If set_empty_vectors_to_null option is enabled, for optional fields, check to // If set_empty_vectors_to_null option is enabled, for optional fields,
// see if there actually is any data in _o->field before attempting to // check to see if there actually is any data in _o->field before
// access it. // attempting to access it.
if (opts_.set_empty_vectors_to_null && !field.required) { if (opts_.set_empty_vectors_to_null && !field.required) {
code = value + ".size() ? " + code + " : 0"; code = value + ".size() ? " + code + " : 0";
} }
@@ -3120,8 +3111,10 @@ std::string CPPMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) { const std::string &file_name) {
const auto filebase = const auto filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
cpp::CppGenerator geneartor(parser, path, file_name, parser.opts);
const auto included_files = parser.GetIncludedFilesRecursive(file_name); const auto included_files = parser.GetIncludedFilesRecursive(file_name);
std::string make_rule = GeneratedFileName(path, filebase) + ": "; std::string make_rule =
geneartor.GeneratedFileName(path, filebase, parser.opts) + ": ";
for (auto it = included_files.begin(); it != included_files.end(); ++it) { for (auto it = included_files.begin(); it != included_files.end(); ++it) {
make_rule += " " + *it; make_rule += " " + *it;
} }

View File

@@ -41,7 +41,7 @@ class CSharpGenerator : public BaseGenerator {
public: public:
CSharpGenerator(const Parser &parser, const std::string &path, CSharpGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."), : BaseGenerator(parser, path, file_name, "", ".", "cs"),
cur_name_space_(nullptr) {} cur_name_space_(nullptr) {}
CSharpGenerator &operator=(const CSharpGenerator &); CSharpGenerator &operator=(const CSharpGenerator &);

View File

@@ -24,11 +24,6 @@
namespace flatbuffers { namespace flatbuffers {
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.dart";
}
namespace dart { namespace dart {
const std::string _kFb = "fb"; const std::string _kFb = "fb";
@@ -55,7 +50,7 @@ class DartGenerator : public BaseGenerator {
DartGenerator(const Parser &parser, const std::string &path, DartGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", ".") {} : BaseGenerator(parser, path, file_name, "", ".", "dart") {}
// Iterate through all definitions we haven't generate code for (enums, // Iterate through all definitions we haven't generate code for (enums,
// structs, and tables) and output them to a single file. // structs, and tables) and output them to a single file.
bool generate() { bool generate() {
@@ -84,21 +79,25 @@ class DartGenerator : public BaseGenerator {
for (auto kv2 = namespace_code.begin(); kv2 != namespace_code.end(); for (auto kv2 = namespace_code.begin(); kv2 != namespace_code.end();
++kv2) { ++kv2) {
if (kv2->first != kv->first) { if (kv2->first != kv->first) {
code += "import '" + code +=
GeneratedFileName( "import '" +
"./", file_name_ + GeneratedFileName(
(!kv2->first.empty() ? "_" + kv2->first : "")) + "./",
"' as " + ImportAliasName(kv2->first) + ";\n"; file_name_ + (!kv2->first.empty() ? "_" + kv2->first : ""),
parser_.opts) +
"' as " + ImportAliasName(kv2->first) + ";\n";
} }
} }
code += "\n"; code += "\n";
code += kv->second; code += kv->second;
if (!SaveFile(GeneratedFileName( if (!SaveFile(
path_, file_name_ + GeneratedFileName(
(!kv->first.empty() ? "_" + kv->first : "")) path_,
.c_str(), file_name_ + (!kv->first.empty() ? "_" + kv->first : ""),
code, false)) { parser_.opts)
.c_str(),
code, false)) {
return false; return false;
} }
} }
@@ -151,7 +150,8 @@ class DartGenerator : public BaseGenerator {
*code += *code +=
"import '" + "import '" +
GeneratedFileName( GeneratedFileName(
"", basename + (the_namespace == "" ? "" : "_" + the_namespace)) + "", basename + (the_namespace == "" ? "" : "_" + the_namespace),
parser_.opts) +
"';\n"; "';\n";
} }
} }
@@ -449,13 +449,13 @@ class DartGenerator : public BaseGenerator {
code += " final " + _kFb + ".BufferContext _bc;\n"; code += " final " + _kFb + ".BufferContext _bc;\n";
code += " final int _bcOffset;\n\n"; code += " final int _bcOffset;\n\n";
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields; std::vector<std::pair<int, FieldDef *>> non_deprecated_fields;
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
auto &field = **it; auto &field = **it;
if (field.deprecated) continue; if (field.deprecated) continue;
auto offset = static_cast<int>(it - struct_def.fields.vec.begin()); auto offset = static_cast<int>(it - struct_def.fields.vec.begin());
non_deprecated_fields.push_back(std::make_pair(offset, &field)); non_deprecated_fields.push_back(std::make_pair(offset, &field));
} }
GenImplementationGetters(struct_def, non_deprecated_fields, &code); GenImplementationGetters(struct_def, non_deprecated_fields, &code);
@@ -464,7 +464,8 @@ class DartGenerator : public BaseGenerator {
GenReader(struct_def, &reader_name, &reader_code); GenReader(struct_def, &reader_name, &reader_code);
GenBuilder(struct_def, non_deprecated_fields, &builder_name, &builder_code); GenBuilder(struct_def, non_deprecated_fields, &builder_name, &builder_code);
GenObjectBuilder(struct_def, non_deprecated_fields, &object_builder_name, &builder_code); GenObjectBuilder(struct_def, non_deprecated_fields, &object_builder_name,
&builder_code);
code += reader_code; code += reader_code;
code += builder_code; code += builder_code;
@@ -500,9 +501,10 @@ class DartGenerator : public BaseGenerator {
return ns + "." + parts.back(); return ns + "." + parts.back();
} }
void GenImplementationGetters(const StructDef &struct_def, void GenImplementationGetters(
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields, const StructDef &struct_def,
std::string *code_ptr) { std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
for (auto it = non_deprecated_fields.begin(); for (auto it = non_deprecated_fields.begin();
@@ -554,9 +556,12 @@ class DartGenerator : public BaseGenerator {
if (!field.value.constant.empty() && field.value.constant != "0") { if (!field.value.constant.empty() && field.value.constant != "0") {
if (IsBool(field.value.type.base_type)) { if (IsBool(field.value.type.base_type)) {
code += "true"; code += "true";
} else if (field.value.constant == "nan" || field.value.constant == "+nan" || field.value.constant == "-nan") { } else if (field.value.constant == "nan" ||
field.value.constant == "+nan" ||
field.value.constant == "-nan") {
code += "double.nan"; code += "double.nan";
} else if (field.value.constant == "inf" || field.value.constant == "+inf") { } else if (field.value.constant == "inf" ||
field.value.constant == "+inf") {
code += "double.infinity"; code += "double.infinity";
} else if (field.value.constant == "-inf") { } else if (field.value.constant == "-inf") {
code += "double.negativeInfinity"; code += "double.negativeInfinity";
@@ -626,9 +631,8 @@ class DartGenerator : public BaseGenerator {
} }
void GenBuilder(const StructDef &struct_def, void GenBuilder(const StructDef &struct_def,
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields, std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *builder_name_ptr, std::string *builder_name_ptr, std::string *code_ptr) {
std::string *code_ptr) {
if (non_deprecated_fields.size() == 0) { return; } if (non_deprecated_fields.size() == 0) { return; }
auto &code = *code_ptr; auto &code = *code_ptr;
auto &builder_name = *builder_name_ptr; auto &builder_name = *builder_name_ptr;
@@ -648,9 +652,10 @@ class DartGenerator : public BaseGenerator {
code += "}\n\n"; code += "}\n\n";
} }
void StructBuilderBody(const StructDef &struct_def, void StructBuilderBody(
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields, const StructDef &struct_def,
std::string *code_ptr) { std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
code += " int finish("; code += " int finish(";
@@ -692,9 +697,10 @@ class DartGenerator : public BaseGenerator {
code += " }\n\n"; code += " }\n\n";
} }
void TableBuilderBody(const StructDef &struct_def, void TableBuilderBody(
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields, const StructDef &struct_def,
std::string *code_ptr) { std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
code += " void begin() {\n"; code += " void begin() {\n";
@@ -736,10 +742,10 @@ class DartGenerator : public BaseGenerator {
code += " }\n"; code += " }\n";
} }
void GenObjectBuilder(const StructDef &struct_def, void GenObjectBuilder(
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields, const StructDef &struct_def,
std::string *builder_name_ptr, std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *code_ptr) { std::string *builder_name_ptr, std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
auto &builder_name = *builder_name_ptr; auto &builder_name = *builder_name_ptr;
@@ -855,9 +861,9 @@ class DartGenerator : public BaseGenerator {
code += "}\n"; code += "}\n";
} }
void StructObjectBuilderBody(std::vector<std::pair<int, FieldDef*>> non_deprecated_fields, void StructObjectBuilderBody(
std::string *code_ptr, std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
bool prependUnderscore = true) { std::string *code_ptr, bool prependUnderscore = true) {
auto &code = *code_ptr; auto &code = *code_ptr;
for (auto it = non_deprecated_fields.rbegin(); for (auto it = non_deprecated_fields.rbegin();
@@ -885,9 +891,9 @@ class DartGenerator : public BaseGenerator {
code += " return fbBuilder.offset;\n"; code += " return fbBuilder.offset;\n";
} }
void TableObjectBuilderBody(std::vector<std::pair<int, FieldDef*>> non_deprecated_fields, void TableObjectBuilderBody(
std::string *code_ptr, std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
bool prependUnderscore = true) { std::string *code_ptr, bool prependUnderscore = true) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += " fbBuilder.startTable();\n"; code += " fbBuilder.startTable();\n";
@@ -936,7 +942,9 @@ std::string DartMakeRule(const Parser &parser, const std::string &path,
auto filebase = auto filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
auto make_rule = GeneratedFileName(path, filebase) + ": "; dart::DartGenerator generator(parser, path, file_name);
auto make_rule =
generator.GeneratedFileName(path, file_name, parser.opts) + ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name); auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) { for (auto it = included_files.begin(); it != included_files.end(); ++it) {

View File

@@ -99,7 +99,9 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
for (auto enum_def_it = parser.enums_.vec.begin(); for (auto enum_def_it = parser.enums_.vec.begin();
enum_def_it != parser.enums_.vec.end(); ++enum_def_it) { enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
EnumDef &enum_def = **enum_def_it; EnumDef &enum_def = **enum_def_it;
if (parser.opts.include_dependence_headers && enum_def.generated) { continue; } if (parser.opts.include_dependence_headers && enum_def.generated) {
continue;
}
GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace); GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace);
GenComment(enum_def.doc_comment, &schema, nullptr); GenComment(enum_def.doc_comment, &schema, nullptr);
if (enum_def.is_union) if (enum_def.is_union)
@@ -121,7 +123,9 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end(); for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
++it) { ++it) {
StructDef &struct_def = **it; StructDef &struct_def = **it;
if (parser.opts.include_dependence_headers && struct_def.generated) { continue; } if (parser.opts.include_dependence_headers && struct_def.generated) {
continue;
}
GenNameSpace(*struct_def.defined_namespace, &schema, &last_namespace); GenNameSpace(*struct_def.defined_namespace, &schema, &last_namespace);
GenComment(struct_def.doc_comment, &schema, nullptr); GenComment(struct_def.doc_comment, &schema, nullptr);
schema += "table " + struct_def.name + " {\n"; schema += "table " + struct_def.name + " {\n";

View File

@@ -35,11 +35,6 @@
namespace flatbuffers { namespace flatbuffers {
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.go";
}
namespace go { namespace go {
// see https://golang.org/ref/spec#Keywords // see https://golang.org/ref/spec#Keywords
@@ -64,7 +59,7 @@ class GoGenerator : public BaseGenerator {
GoGenerator(const Parser &parser, const std::string &path, GoGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, const std::string &go_namespace) const std::string &file_name, const std::string &go_namespace)
: BaseGenerator(parser, path, file_name, "" /* not used*/, : BaseGenerator(parser, path, file_name, "" /* not used*/,
"" /* not used */), "" /* not used */, "go"),
cur_name_space_(nullptr) { cur_name_space_(nullptr) {
std::istringstream iss(go_namespace); std::istringstream iss(go_namespace);
std::string component; std::string component;
@@ -112,7 +107,8 @@ class GoGenerator : public BaseGenerator {
const bool is_enum = !parser_.enums_.vec.empty(); const bool is_enum = !parser_.enums_.vec.empty();
BeginFile(LastNamespacePart(go_namespace_), true, is_enum, &code); BeginFile(LastNamespacePart(go_namespace_), true, is_enum, &code);
code += one_file_code; code += one_file_code;
const std::string filename = GeneratedFileName(path_, file_name_); const std::string filename =
GeneratedFileName(path_, file_name_, parser_.opts);
return SaveFile(filename.c_str(), code, false); return SaveFile(filename.c_str(), code, false);
} }

View File

@@ -269,7 +269,7 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
public: public:
GoGRPCGenerator(const Parser &parser, const std::string &path, GoGRPCGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "" /*Unused*/), : BaseGenerator(parser, path, file_name, "", "" /*Unused*/, "go"),
parser_(parser), parser_(parser),
path_(path), path_(path),
file_name_(file_name) {} file_name_(file_name) {}
@@ -346,7 +346,7 @@ class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
public: public:
JavaGRPCGenerator(const Parser &parser, const std::string &path, JavaGRPCGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "." /*separator*/) {} : BaseGenerator(parser, path, file_name, "", "." /*separator*/, "java") {}
bool generate() { bool generate() {
FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageJava); FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageJava);
@@ -415,7 +415,7 @@ class SwiftGRPCGenerator : public flatbuffers::BaseGenerator {
public: public:
SwiftGRPCGenerator(const Parser &parser, const std::string &path, SwiftGRPCGenerator(const Parser &parser, const std::string &path,
const std::string &filename) const std::string &filename)
: BaseGenerator(parser, path, filename, "", "" /*Unused*/) {} : BaseGenerator(parser, path, filename, "", "" /*Unused*/, "swift") {}
bool generate() { bool generate() {
code_.Clear(); code_.Clear();

View File

@@ -42,7 +42,7 @@ class JavaGenerator : public BaseGenerator {
public: public:
JavaGenerator(const Parser &parser, const std::string &path, JavaGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."), : BaseGenerator(parser, path, file_name, "", ".", "java"),
cur_name_space_(nullptr) {} cur_name_space_(nullptr) {}
JavaGenerator &operator=(const JavaGenerator &); JavaGenerator &operator=(const JavaGenerator &);

View File

@@ -26,8 +26,6 @@
namespace flatbuffers { namespace flatbuffers {
const std::string kGeneratedFileNamePostfix = "_generated";
struct JsTsLanguageParameters { struct JsTsLanguageParameters {
IDLOptions::Language language; IDLOptions::Language language;
std::string file_extension; std::string file_extension;
@@ -61,12 +59,6 @@ const JsTsLanguageParameters &GetJsLangParams(IDLOptions::Language lang) {
} }
} }
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name,
const JsTsLanguageParameters &lang) {
return path + file_name + kGeneratedFileNamePostfix + lang.file_extension;
}
namespace jsts { namespace jsts {
// Iterate through all definitions we haven't generate code for (enums, structs, // Iterate through all definitions we haven't generate code for (enums, structs,
// and tables) and output them to a single file. // and tables) and output them to a single file.
@@ -78,7 +70,8 @@ class JsTsGenerator : public BaseGenerator {
JsTsGenerator(const Parser &parser, const std::string &path, JsTsGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."), : BaseGenerator(parser, path, file_name, "", ".",
parser.opts.lang == IDLOptions::kJs ? "js" : "ts"),
lang_(GetJsLangParams(parser_.opts.lang)) {} lang_(GetJsLangParams(parser_.opts.lang)) {}
// Iterate through all definitions we haven't generate code for (enums, // Iterate through all definitions we haven't generate code for (enums,
// structs, and tables) and output them to a single file. // structs, and tables) and output them to a single file.
@@ -112,8 +105,8 @@ class JsTsGenerator : public BaseGenerator {
code += exports_code; code += exports_code;
} }
return SaveFile(GeneratedFileName(path_, file_name_, lang_).c_str(), code, return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(),
false); code, false);
} }
private: private:
@@ -524,10 +517,10 @@ class JsTsGenerator : public BaseGenerator {
if (parser_.opts.keep_include_path) { if (parser_.opts.keep_include_path) {
auto it = parser_.included_files_.find(full_file_name); auto it = parser_.included_files_.find(full_file_name);
FLATBUFFERS_ASSERT(it != parser_.included_files_.end()); FLATBUFFERS_ASSERT(it != parser_.included_files_.end());
path = path = flatbuffers::StripExtension(it->second) +
flatbuffers::StripExtension(it->second) + kGeneratedFileNamePostfix; parser_.opts.filename_suffix;
} else { } else {
path = base_name + kGeneratedFileNamePostfix; path = base_name + parser_.opts.filename_suffix;
} }
// Add the include prefix and make the path always relative // Add the include prefix and make the path always relative
@@ -601,7 +594,8 @@ class JsTsGenerator : public BaseGenerator {
} }
std::string GenerateNewExpression(const std::string &object_name) { std::string GenerateNewExpression(const std::string &object_name) {
return "new " + object_name + (lang_.language == IDLOptions::kTs ? "()" : ""); return "new " + object_name +
(lang_.language == IDLOptions::kTs ? "()" : "");
} }
void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr, void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr,
@@ -624,7 +618,9 @@ class JsTsGenerator : public BaseGenerator {
code += " = function(bb, obj) {\n"; code += " = function(bb, obj) {\n";
} }
if (size_prefixed) { if (size_prefixed) {
code += " bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);\n"; code +=
" bb.setPosition(bb.position() + "
"flatbuffers.SIZE_PREFIX_LENGTH);\n";
} }
code += " return (obj || " + GenerateNewExpression(object_name); code += " return (obj || " + GenerateNewExpression(object_name);
code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n"; code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n";
@@ -870,7 +866,8 @@ class JsTsGenerator : public BaseGenerator {
code += code +=
MaybeAdd(field.value.offset) + ", " + GenBBAccess() + ");\n"; MaybeAdd(field.value.offset) + ", " + GenBBAccess() + ");\n";
} else { } else {
code += offset_prefix + "(obj || " + GenerateNewExpression(type) + ").__init("; code += offset_prefix + "(obj || " + GenerateNewExpression(type) +
").__init(";
code += field.value.type.struct_def->fixed code += field.value.type.struct_def->fixed
? "this.bb_pos + offset" ? "this.bb_pos + offset"
: GenBBAccess() + ".__indirect(this.bb_pos + offset)"; : GenBBAccess() + ".__indirect(this.bb_pos + offset)";
@@ -952,7 +949,8 @@ class JsTsGenerator : public BaseGenerator {
} }
if (vectortype.base_type == BASE_TYPE_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT) {
code += offset_prefix + "(obj || " + GenerateNewExpression(vectortypename); code += offset_prefix + "(obj || " +
GenerateNewExpression(vectortypename);
code += ").__init("; code += ").__init(";
code += vectortype.struct_def->fixed code += vectortype.struct_def->fixed
? index ? index
@@ -1388,11 +1386,12 @@ bool GenerateJSTS(const Parser &parser, const std::string &path,
std::string JSTSMakeRule(const Parser &parser, const std::string &path, std::string JSTSMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) { const std::string &file_name) {
FLATBUFFERS_ASSERT(parser.opts.lang <= IDLOptions::kMAX); FLATBUFFERS_ASSERT(parser.opts.lang <= IDLOptions::kMAX);
const auto &lang = GetJsLangParams(parser.opts.lang);
std::string filebase = std::string filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
std::string make_rule = GeneratedFileName(path, filebase, lang) + ": "; jsts::JsTsGenerator generator(parser, path, file_name);
std::string make_rule =
generator.GeneratedFileName(path, filebase, parser.opts) + ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name); auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) { for (auto it = included_files.begin(); it != included_files.end(); ++it) {

View File

@@ -22,11 +22,6 @@
namespace flatbuffers { namespace flatbuffers {
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + ".schema.json";
}
namespace jsons { namespace jsons {
std::string GenNativeType(BaseType type) { std::string GenNativeType(BaseType type) {
@@ -116,11 +111,18 @@ class JsonSchemaGenerator : public BaseGenerator {
public: public:
JsonSchemaGenerator(const Parser &parser, const std::string &path, JsonSchemaGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "") {} : BaseGenerator(parser, path, file_name, "", "", "json") {}
explicit JsonSchemaGenerator(const BaseGenerator &base_generator) explicit JsonSchemaGenerator(const BaseGenerator &base_generator)
: BaseGenerator(base_generator) {} : BaseGenerator(base_generator) {}
std::string GeneratedFileName(const std::string &path,
const std::string &file_name,
const IDLOptions &options /* unused */) const {
(void)options;
return path + file_name + ".schema.json";
}
bool generate() { bool generate() {
if (parser_.root_struct_def_ == nullptr) { return false; } if (parser_.root_struct_def_ == nullptr) { return false; }
code_.Clear(); code_.Clear();
@@ -203,7 +205,8 @@ class JsonSchemaGenerator : public BaseGenerator {
GenFullName(parser_.root_struct_def_) + "\""; GenFullName(parser_.root_struct_def_) + "\"";
code_ += "}"; // close schema root code_ += "}"; // close schema root
const std::string file_path = GeneratedFileName(path_, file_name_); const std::string file_path =
GeneratedFileName(path_, file_name_, parser_.opts);
const std::string final_code = code_.ToString(); const std::string final_code = code_.ToString();
return SaveFile(file_path.c_str(), final_code, false); return SaveFile(file_path.c_str(), final_code, false);
} }

View File

@@ -59,7 +59,7 @@ class KotlinGenerator : public BaseGenerator {
public: public:
KotlinGenerator(const Parser &parser, const std::string &path, KotlinGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."), : BaseGenerator(parser, path, file_name, "", ".", "kt"),
cur_name_space_(nullptr) {} cur_name_space_(nullptr) {}
KotlinGenerator &operator=(const KotlinGenerator &); KotlinGenerator &operator=(const KotlinGenerator &);

View File

@@ -29,7 +29,8 @@ class LobsterGenerator : public BaseGenerator {
public: public:
LobsterGenerator(const Parser &parser, const std::string &path, LobsterGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */, "_") { : BaseGenerator(parser, path, file_name, "" /* not used */, "_",
"lobster") {
static const char *const keywords[] = { static const char *const keywords[] = {
"nil", "true", "false", "return", "struct", "class", "nil", "true", "false", "return", "struct", "class",
"import", "int", "float", "string", "any", "def", "import", "int", "float", "string", "any", "def",
@@ -367,8 +368,8 @@ class LobsterGenerator : public BaseGenerator {
auto &struct_def = **it; auto &struct_def = **it;
GenStruct(struct_def, &code); GenStruct(struct_def, &code);
} }
return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(), code, return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(),
false); code, false);
} }
private: private:

View File

@@ -42,7 +42,7 @@ class LuaGenerator : public BaseGenerator {
LuaGenerator(const Parser &parser, const std::string &path, LuaGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */, : BaseGenerator(parser, path, file_name, "" /* not used */,
"" /* not used */) { "" /* not used */, "lua") {
static const char *const keywords[] = { static const char *const keywords[] = {
"and", "break", "do", "else", "elseif", "end", "false", "for", "and", "break", "do", "else", "elseif", "end", "false", "for",
"function", "goto", "if", "in", "local", "nil", "not", "or", "function", "goto", "if", "in", "local", "nil", "not", "or",

View File

@@ -31,7 +31,7 @@ class PhpGenerator : public BaseGenerator {
public: public:
PhpGenerator(const Parser &parser, const std::string &path, PhpGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "\\", "\\") {} : BaseGenerator(parser, path, file_name, "\\", "\\", "php") {}
bool generate() { bool generate() {
if (!GenerateEnums()) return false; if (!GenerateEnums()) return false;
if (!GenerateStructs()) return false; if (!GenerateStructs()) return false;

View File

@@ -39,7 +39,7 @@ class PythonGenerator : public BaseGenerator {
PythonGenerator(const Parser &parser, const std::string &path, PythonGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */, : BaseGenerator(parser, path, file_name, "" /* not used */,
"" /* not used */), "" /* not used */, "py"),
float_const_gen_("float('nan')", "float('inf')", "float('-inf')") { float_const_gen_("float('nan')", "float('inf')", "float('-inf')") {
static const char *const keywords[] = { static const char *const keywords[] = {
"False", "None", "True", "and", "as", "assert", "break", "False", "None", "True", "and", "as", "assert", "break",
@@ -139,8 +139,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Initialize an existing object with other data, to avoid an allocation. // Initialize an existing object with other data, to avoid an allocation.
void InitializeExisting(const StructDef &struct_def, void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -178,8 +177,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a struct's scalar. // Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def, void GetScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -216,8 +214,7 @@ class PythonGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Struct. // Specific to Struct.
void GetStructFieldOfStruct(const StructDef &struct_def, void GetStructFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
@@ -301,7 +298,8 @@ class PythonGenerator : public BaseGenerator {
// TODO(rw): this works and is not the good way to it: // TODO(rw): this works and is not the good way to it:
bool is_native_table = TypeName(field) == "*flatbuffers.Table"; bool is_native_table = TypeName(field) == "*flatbuffers.Table";
if (is_native_table) { if (is_native_table) {
code += Indent + Indent + Indent + "from flatbuffers.table import Table\n"; code +=
Indent + Indent + Indent + "from flatbuffers.table import Table\n";
} else if (parser_.opts.include_dependence_headers) { } else if (parser_.opts.include_dependence_headers) {
code += Indent + Indent + Indent; code += Indent + Indent + Indent;
code += "from " + GenPackageReference(field.value.type) + " import " + code += "from " + GenPackageReference(field.value.type) + " import " +
@@ -330,8 +328,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a vector's struct member. // Get the value of a vector's struct member.
void GetMemberOfVectorOfStruct(const StructDef &struct_def, void GetMemberOfVectorOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
@@ -412,8 +409,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Begin the creator function signature. // Begin the creator function signature.
void BeginBuilderArgs(const StructDef &struct_def, void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
code += "\n"; code += "\n";
@@ -447,9 +443,7 @@ class PythonGenerator : public BaseGenerator {
} else { } else {
auto &code = *code_ptr; auto &code = *code_ptr;
code += std::string(", ") + nameprefix; code += std::string(", ") + nameprefix;
if (has_field_name) { if (has_field_name) { code += MakeCamel(NormalizedName(field), false); }
code += MakeCamel(NormalizedName(field), false);
}
code += namesuffix; code += namesuffix;
} }
} }
@@ -517,8 +511,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the value of a table's starting offset. // Get the value of a table's starting offset.
void GetStartOfTable(const StructDef &struct_def, void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start"; code += "def " + NormalizedName(struct_def) + "Start";
code += "(builder): "; code += "(builder): ";
@@ -528,11 +521,11 @@ class PythonGenerator : public BaseGenerator {
} }
// Set the value of a table's field. // Set the value of a table's field.
void BuildFieldOfTable(const StructDef &struct_def, void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, const size_t offset, const size_t offset, std::string *code_ptr) {
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Add" + MakeCamel(NormalizedName(field)); code += "def " + NormalizedName(struct_def) + "Add" +
MakeCamel(NormalizedName(field));
code += "(builder, "; code += "(builder, ";
code += MakeCamel(NormalizedName(field), false); code += MakeCamel(NormalizedName(field), false);
code += "): "; code += "): ";
@@ -554,8 +547,8 @@ class PythonGenerator : public BaseGenerator {
} }
// Set the value of one of the members of a table's vector. // Set the value of one of the members of a table's vector.
void BuildVectorOfTable(const StructDef &struct_def, void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start"; code += "def " + NormalizedName(struct_def) + "Start";
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
@@ -569,8 +562,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the offset of the end of a table. // Get the offset of the end of a table.
void GetEndOffsetOnTable(const StructDef &struct_def, void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
auto &code = *code_ptr; auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "End"; code += "def " + NormalizedName(struct_def) + "End";
code += "(builder): "; code += "(builder): ";
@@ -777,14 +769,9 @@ class PythonGenerator : public BaseGenerator {
import_list->insert("import " + package_reference); import_list->insert("import " + package_reference);
} }
break; break;
case BASE_TYPE_STRING: case BASE_TYPE_STRING: field_type += "str"; break;
field_type += "str"; case BASE_TYPE_NONE: field_type += "None"; break;
break; default: break;
case BASE_TYPE_NONE:
field_type += "None";
break;
default:
break;
} }
field_types += field_type + separator_string; field_types += field_type + separator_string;
} }
@@ -806,8 +793,7 @@ class PythonGenerator : public BaseGenerator {
} }
} }
void GenStructInit(const FieldDef &field, void GenStructInit(const FieldDef &field, std::string *field_type_ptr,
std::string *field_type_ptr,
std::set<std::string> *import_list, std::set<std::string> *import_list,
std::set<std::string> *import_typing_list) { std::set<std::string> *import_typing_list) {
import_typing_list->insert("Optional"); import_typing_list->insert("Optional");
@@ -1118,8 +1104,7 @@ class PythonGenerator : public BaseGenerator {
GenUnPackForScalarVector(struct_def, field, &code); GenUnPackForScalarVector(struct_def, field, &code);
break; break;
} }
default: default: GenUnPackForScalar(struct_def, field, &code);
GenUnPackForScalar(struct_def, field, &code);
} }
} }
@@ -1228,45 +1213,19 @@ class PythonGenerator : public BaseGenerator {
std::string type_name; std::string type_name;
switch (vectortype.base_type) { switch (vectortype.base_type) {
case BASE_TYPE_BOOL: case BASE_TYPE_BOOL: type_name = "Bool"; break;
type_name = "Bool"; case BASE_TYPE_CHAR: type_name = "Byte"; break;
break; case BASE_TYPE_UCHAR: type_name = "Uint8"; break;
case BASE_TYPE_CHAR: case BASE_TYPE_SHORT: type_name = "Int16"; break;
type_name = "Byte"; case BASE_TYPE_USHORT: type_name = "Uint16"; break;
break; case BASE_TYPE_INT: type_name = "Int32"; break;
case BASE_TYPE_UCHAR: case BASE_TYPE_UINT: type_name = "Uint32"; break;
type_name = "Uint8"; case BASE_TYPE_LONG: type_name = "Int64"; break;
break; case BASE_TYPE_ULONG: type_name = "Uint64"; break;
case BASE_TYPE_SHORT: case BASE_TYPE_FLOAT: type_name = "Float32"; break;
type_name = "Int16"; case BASE_TYPE_DOUBLE: type_name = "Float64"; break;
break; case BASE_TYPE_STRING: type_name = "UOffsetTRelative"; break;
case BASE_TYPE_USHORT: default: type_name = "VOffsetT"; break;
type_name = "Uint16";
break;
case BASE_TYPE_INT:
type_name = "Int32";
break;
case BASE_TYPE_UINT:
type_name = "Uint32";
break;
case BASE_TYPE_LONG:
type_name = "Int64";
break;
case BASE_TYPE_ULONG:
type_name = "Uint64";
break;
case BASE_TYPE_FLOAT:
type_name = "Float32";
break;
case BASE_TYPE_DOUBLE:
type_name = "Float64";
break;
case BASE_TYPE_STRING:
type_name = "UOffsetTRelative";
break;
default:
type_name = "VOffsetT";
break;
} }
code += type_name; code += type_name;
} }
@@ -1527,8 +1486,7 @@ class PythonGenerator : public BaseGenerator {
case BASE_TYPE_STRING: case BASE_TYPE_STRING:
GenUnionCreatorForString(enum_def, ev, &code); GenUnionCreatorForString(enum_def, ev, &code);
break; break;
default: default: break;
break;
} }
} }
code += GenIndents(1) + "return None"; code += GenIndents(1) + "return None";

View File

@@ -23,11 +23,6 @@
namespace flatbuffers { namespace flatbuffers {
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.rs";
}
// Convert a camelCaseIdentifier or CamelCaseIdentifier to a // Convert a camelCaseIdentifier or CamelCaseIdentifier to a
// snake_case_indentifier. // snake_case_indentifier.
std::string MakeSnakeCase(const std::string &in) { std::string MakeSnakeCase(const std::string &in) {
@@ -188,7 +183,7 @@ class RustGenerator : public BaseGenerator {
public: public:
RustGenerator(const Parser &parser, const std::string &path, RustGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "::"), : BaseGenerator(parser, path, file_name, "", "::", "rs"),
cur_name_space_(nullptr) { cur_name_space_(nullptr) {
const char *keywords[] = { const char *keywords[] = {
// list taken from: // list taken from:
@@ -292,7 +287,7 @@ class RustGenerator : public BaseGenerator {
} }
if (cur_name_space_) SetNameSpace(nullptr); if (cur_name_space_) SetNameSpace(nullptr);
const auto file_path = GeneratedFileName(path_, file_name_); const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts);
const auto final_code = code_.ToString(); const auto final_code = code_.ToString();
return SaveFile(file_path.c_str(), final_code, false); return SaveFile(file_path.c_str(), final_code, false);
} }
@@ -1329,16 +1324,17 @@ class RustGenerator : public BaseGenerator {
// If the user defined schemas name a field that clashes with a // If the user defined schemas name a field that clashes with a
// language reserved word, flatc will try to escape the field name by // language reserved word, flatc will try to escape the field name by
// appending an underscore. This works well for most cases, except // appending an underscore. This works well for most cases, except
// one. When generating union accessors (and referring to them // one. When generating union accessors (and referring to them
// internally within the code generated here), an extra underscore // internally within the code generated here), an extra underscore
// will be appended to the name, causing build failures. // will be appended to the name, causing build failures.
// //
// This only happens when unions have members that overlap with // This only happens when unions have members that overlap with
// language reserved words. // language reserved words.
// //
// To avoid this problem the type field name is used unescaped here: // To avoid this problem the type field name is used unescaped here:
code_ += code_ +=
" if self.{{FIELD_TYPE_FIELD_NAME}}_type() == {{U_ELEMENT_ENUM_TYPE}} {"; " if self.{{FIELD_TYPE_FIELD_NAME}}_type() == "
"{{U_ELEMENT_ENUM_TYPE}} {";
code_ += code_ +=
" self.{{FIELD_NAME}}().map(|u| " " self.{{FIELD_NAME}}().map(|u| "
"{{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))"; "{{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))";
@@ -1764,7 +1760,7 @@ class RustGenerator : public BaseGenerator {
std::string indent = std::string(white_spaces, ' '); std::string indent = std::string(white_spaces, ' ');
code_ += ""; code_ += "";
for (auto it = parser_.included_files_.begin(); for (auto it = parser_.included_files_.begin();
it != parser_.included_files_.end(); ++it) { it != parser_.included_files_.end(); ++it) {
if (it->second.empty()) continue; if (it->second.empty()) continue;
auto noext = flatbuffers::StripExtension(it->second); auto noext = flatbuffers::StripExtension(it->second);
auto basename = flatbuffers::StripPath(noext); auto basename = flatbuffers::StripPath(noext);
@@ -1834,7 +1830,9 @@ std::string RustMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) { const std::string &file_name) {
std::string filebase = std::string filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
std::string make_rule = GeneratedFileName(path, filebase) + ": "; rust::RustGenerator generator(parser, path, file_name);
std::string make_rule =
generator.GeneratedFileName(path, filebase, parser.opts) + ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name); auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) { for (auto it = included_files.begin(); it != included_files.end(); ++it) {

View File

@@ -49,7 +49,7 @@ class SwiftGenerator : public BaseGenerator {
public: public:
SwiftGenerator(const Parser &parser, const std::string &path, SwiftGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."), : BaseGenerator(parser, path, file_name, "", ".", "swift"),
cur_name_space_(nullptr) { cur_name_space_(nullptr) {
namespace_depth = 0; namespace_depth = 0;
static const char *const keywords[] = { static const char *const keywords[] = {
@@ -181,7 +181,7 @@ class SwiftGenerator : public BaseGenerator {
if (cur_name_space_) SetNameSpace(nullptr); if (cur_name_space_) SetNameSpace(nullptr);
const auto filename = GeneratedFileName(path_, file_name_); const auto filename = GeneratedFileName(path_, file_name_, parser_.opts);
const auto final_code = code_.ToString(); const auto final_code = code_.ToString();
return SaveFile(filename.c_str(), final_code, false); return SaveFile(filename.c_str(), final_code, false);
} }
@@ -843,10 +843,6 @@ class SwiftGenerator : public BaseGenerator {
return EscapeKeyword(MakeCamel(def.name, false)); return EscapeKeyword(MakeCamel(def.name, false));
} }
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.swift";
}
// MARK: - Copied from the cpp implementation, needs revisiting // MARK: - Copied from the cpp implementation, needs revisiting
void SetNameSpace(const Namespace *ns) { void SetNameSpace(const Namespace *ns) {
if (cur_name_space_ == ns) { return; } if (cur_name_space_ == ns) { return; }

View File

@@ -3231,8 +3231,8 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
// Is uint64>max(int64) tested? // Is uint64>max(int64) tested?
IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0, IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0,
// result may be platform-dependent if underlying is float (not double) // result may be platform-dependent if underlying is float (not double)
IsFloat(value.type.base_type) ? d : 0.0, IsFloat(value.type.base_type) ? d : 0.0, deprecated, required, key,
deprecated, required, key, attr__, docs__); attr__, docs__);
// TODO: value.constant is almost always "0", we could save quite a bit of // TODO: value.constant is almost always "0", we could save quite a bit of
// space by sharing it. Same for common values of value.type. // space by sharing it. Same for common values of value.type.
} }

View File

@@ -274,5 +274,4 @@ void SetupDefaultCRTReportMode() {
// clang-format on // clang-format on
} }
} // namespace flatbuffers } // namespace flatbuffers

View File

@@ -49,6 +49,18 @@ $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS -o namespace_test namespace_te
../flatc --python $TEST_BASE_FLAGS arrays_test.fbs ../flatc --python $TEST_BASE_FLAGS arrays_test.fbs
../flatc --dart monster_extra.fbs ../flatc --dart monster_extra.fbs
# Tests if the --filename-suffix and --filename-ext works and produces the same
# outputs.
../flatc --cpp --filename-suffix _suffix --filename-ext hpp $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS -I include_test monster_test.fbs
if [ -f "monster_test_suffix.hpp" ]; then
if ! cmp -s "monster_test_suffix.hpp" "monster_test_generated.h"; then
echo "[Error] Filename suffix option did not produce identical results"
fi
rm "monster_test_suffix.hpp"
else
echo "[Error] Filename suffix option did not produce a file"
fi
# Flag c++17 requires Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher. # Flag c++17 requires Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher.
TEST_CPP17_FLAGS="--cpp --cpp-std c++17 -o ./cpp17/generated_cpp17 $TEST_NOINCL_FLAGS" TEST_CPP17_FLAGS="--cpp --cpp-std c++17 -o ./cpp17/generated_cpp17 $TEST_NOINCL_FLAGS"
../flatc $TEST_CPP17_FLAGS -I include_test monster_test.fbs ../flatc $TEST_CPP17_FLAGS -I include_test monster_test.fbs

View File

@@ -45,7 +45,7 @@
#include "test_assert.h" #include "test_assert.h"
#include "flatbuffers/flexbuffers.h" #include "flatbuffers/flexbuffers.h"
#include "monster_test_bfbs_generated.h" // Generated using --bfbs-comments --bfbs-builtins --cpp --bfbs-gen-embed #include "monster_test_bfbs_generated.h" // Generated using --bfbs-comments --bfbs-builtins --cpp --bfbs-gen-embed
// clang-format off // clang-format off
// Check that char* and uint8_t* are interoperable types. // Check that char* and uint8_t* are interoperable types.
@@ -1151,13 +1151,13 @@ void ParseProtoTestWithSuffix() {
flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(), flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(),
false, &protofile), false, &protofile),
true); true);
TEST_EQ(
flatbuffers::LoadFile((test_data_path + "prototest/test_suffix.golden").c_str(),
false, &goldenfile),
true);
TEST_EQ(flatbuffers::LoadFile( TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_union_suffix.golden").c_str(), false, (test_data_path + "prototest/test_suffix.golden").c_str(), false,
&goldenunionfile), &goldenfile),
true);
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_union_suffix.golden").c_str(),
false, &goldenunionfile),
true); true);
flatbuffers::IDLOptions opts; flatbuffers::IDLOptions opts;
@@ -1204,17 +1204,17 @@ void ParseProtoTestWithIncludes() {
flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(), flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(),
false, &protofile), false, &protofile),
true); true);
TEST_EQ(
flatbuffers::LoadFile((test_data_path + "prototest/imported.proto").c_str(),
false, &importprotofile),
true);
TEST_EQ(
flatbuffers::LoadFile((test_data_path + "prototest/test_include.golden").c_str(),
false, &goldenfile),
true);
TEST_EQ(flatbuffers::LoadFile( TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_union_include.golden").c_str(), false, (test_data_path + "prototest/imported.proto").c_str(), false,
&goldenunionfile), &importprotofile),
true);
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_include.golden").c_str(), false,
&goldenfile),
true);
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_union_include.golden").c_str(),
false, &goldenunionfile),
true); true);
flatbuffers::IDLOptions opts; flatbuffers::IDLOptions opts;
@@ -1232,12 +1232,15 @@ void ParseProtoTestWithIncludes() {
// Generate fbs from import.proto // Generate fbs from import.proto
flatbuffers::Parser import_parser(opts); flatbuffers::Parser import_parser(opts);
TEST_EQ(import_parser.Parse(importprotofile.c_str(), include_directories), true); TEST_EQ(import_parser.Parse(importprotofile.c_str(), include_directories),
true);
auto import_fbs = flatbuffers::GenerateFBS(import_parser, "test"); auto import_fbs = flatbuffers::GenerateFBS(import_parser, "test");
// Ensure generated file is parsable. // Ensure generated file is parsable.
flatbuffers::Parser parser2; flatbuffers::Parser parser2;
TEST_EQ(parser2.Parse(import_fbs.c_str(), include_directories, "imported.fbs"), true); TEST_EQ(
parser2.Parse(import_fbs.c_str(), include_directories, "imported.fbs"),
true);
TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true); TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
TEST_EQ_STR(fbs.c_str(), goldenfile.c_str()); TEST_EQ_STR(fbs.c_str(), goldenfile.c_str());
@@ -1523,7 +1526,7 @@ void FuzzTest2() {
break; break;
} }
} }
TEST_NOTNULL(nullptr); //-V501 (this comment supresses CWE-570 warning) TEST_NOTNULL(nullptr); //-V501 (this comment supresses CWE-570 warning)
} }
// clang-format off // clang-format off
@@ -2444,68 +2447,72 @@ void InvalidNestedFlatbufferTest() {
void EvolutionTest() { void EvolutionTest() {
// VS10 does not support typed enums, exclude from tests // VS10 does not support typed enums, exclude from tests
#if !defined(_MSC_VER) || _MSC_VER >= 1700 #if !defined(_MSC_VER) || _MSC_VER >= 1700
const int NUM_VERSIONS = 2; const int NUM_VERSIONS = 2;
std::string schemas[NUM_VERSIONS]; std::string schemas[NUM_VERSIONS];
std::string jsonfiles[NUM_VERSIONS]; std::string jsonfiles[NUM_VERSIONS];
std::vector<uint8_t> binaries[NUM_VERSIONS]; std::vector<uint8_t> binaries[NUM_VERSIONS];
flatbuffers::IDLOptions idl_opts; flatbuffers::IDLOptions idl_opts;
idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary; idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
flatbuffers::Parser parser(idl_opts); flatbuffers::Parser parser(idl_opts);
// Load all the schema versions and their associated data. // Load all the schema versions and their associated data.
for (int i = 0; i < NUM_VERSIONS; ++i) { for (int i = 0; i < NUM_VERSIONS; ++i) {
std::string schema = test_data_path + "evolution_test/evolution_v" + std::string schema = test_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".fbs"; flatbuffers::NumToString(i + 1) + ".fbs";
TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i])); TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i]));
std::string json = test_data_path + "evolution_test/evolution_v" + std::string json = test_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".json"; flatbuffers::NumToString(i + 1) + ".json";
TEST_ASSERT(flatbuffers::LoadFile(json.c_str(), false, &jsonfiles[i])); TEST_ASSERT(flatbuffers::LoadFile(json.c_str(), false, &jsonfiles[i]));
TEST_ASSERT(parser.Parse(schemas[i].c_str())); TEST_ASSERT(parser.Parse(schemas[i].c_str()));
TEST_ASSERT(parser.Parse(jsonfiles[i].c_str())); TEST_ASSERT(parser.Parse(jsonfiles[i].c_str()));
auto bufLen = parser.builder_.GetSize(); auto bufLen = parser.builder_.GetSize();
auto buf = parser.builder_.GetBufferPointer(); auto buf = parser.builder_.GetBufferPointer();
binaries[i].reserve(bufLen); binaries[i].reserve(bufLen);
std::copy(buf, buf + bufLen, std::back_inserter(binaries[i])); std::copy(buf, buf + bufLen, std::back_inserter(binaries[i]));
} }
// Assert that all the verifiers for the different schema versions properly verify any version data. // Assert that all the verifiers for the different schema versions properly
for (int i = 0; i < NUM_VERSIONS; ++i) { // verify any version data.
flatbuffers::Verifier verifier(&binaries[i].front(), binaries[i].size()); for (int i = 0; i < NUM_VERSIONS; ++i) {
TEST_ASSERT(Evolution::V1::VerifyRootBuffer(verifier)); flatbuffers::Verifier verifier(&binaries[i].front(), binaries[i].size());
TEST_ASSERT(Evolution::V2::VerifyRootBuffer(verifier)); TEST_ASSERT(Evolution::V1::VerifyRootBuffer(verifier));
} TEST_ASSERT(Evolution::V2::VerifyRootBuffer(verifier));
}
// Test backwards compatibility by reading old data with an evolved schema. // Test backwards compatibility by reading old data with an evolved schema.
auto root_v1_viewed_from_v2 = Evolution::V2::GetRoot(&binaries[0].front()); auto root_v1_viewed_from_v2 = Evolution::V2::GetRoot(&binaries[0].front());
// field 'j' is new in version 2, so it should be null. // field 'j' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->j()); TEST_ASSERT(nullptr == root_v1_viewed_from_v2->j());
// field 'k' is new in version 2 with a default of 56. // field 'k' is new in version 2 with a default of 56.
TEST_EQ(root_v1_viewed_from_v2->k(), 56); TEST_EQ(root_v1_viewed_from_v2->k(), 56);
// field 'c' of 'TableA' is new in version 2, so it should be null. // field 'c' of 'TableA' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->e()->c()); TEST_ASSERT(nullptr == root_v1_viewed_from_v2->e()->c());
// 'TableC' was added to field 'c' union in version 2, so it should be null. // 'TableC' was added to field 'c' union in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->c_as_TableC()); TEST_ASSERT(nullptr == root_v1_viewed_from_v2->c_as_TableC());
// The field 'c' union should be of type 'TableB' regardless of schema version // The field 'c' union should be of type 'TableB' regardless of schema version
TEST_ASSERT(root_v1_viewed_from_v2->c_type() == Evolution::V2::Union::TableB); TEST_ASSERT(root_v1_viewed_from_v2->c_type() == Evolution::V2::Union::TableB);
// The field 'f' was renamed to 'ff' in version 2, it should still be readable. // The field 'f' was renamed to 'ff' in version 2, it should still be
TEST_EQ(root_v1_viewed_from_v2->ff()->a(), 16); // readable.
TEST_EQ(root_v1_viewed_from_v2->ff()->a(), 16);
// Test forwards compatibility by reading new data with an old schema. // Test forwards compatibility by reading new data with an old schema.
auto root_v2_viewed_from_v1 = Evolution::V1::GetRoot(&binaries[1].front()); auto root_v2_viewed_from_v1 = Evolution::V1::GetRoot(&binaries[1].front());
// The field 'c' union in version 2 is a new table (index = 3) and should still be accessible, // The field 'c' union in version 2 is a new table (index = 3) and should
// but not interpretable. // still be accessible, but not interpretable.
TEST_EQ(static_cast<uint8_t>(root_v2_viewed_from_v1->c_type()), 3); TEST_EQ(static_cast<uint8_t>(root_v2_viewed_from_v1->c_type()), 3);
TEST_NOTNULL(root_v2_viewed_from_v1->c()); TEST_NOTNULL(root_v2_viewed_from_v1->c());
// The field 'd' enum in verison 2 has new members and should still be accessible, but not interpretable. // The field 'd' enum in verison 2 has new members and should still be
TEST_EQ(static_cast<int8_t>(root_v2_viewed_from_v1->d()), 3); // accessible, but not interpretable.
// The field 'a' in version 2 is deprecated and should return the default value (0) instead of the value stored in TEST_EQ(static_cast<int8_t>(root_v2_viewed_from_v1->d()), 3);
// the in the buffer (42). // The field 'a' in version 2 is deprecated and should return the default
TEST_EQ(root_v2_viewed_from_v1->a(), 0); // value (0) instead of the value stored in the in the buffer (42).
// The field 'ff' was originally named 'f' in version 1, it should still be readable. TEST_EQ(root_v2_viewed_from_v1->a(), 0);
TEST_EQ(root_v2_viewed_from_v1->f()->a(), 35); // The field 'ff' was originally named 'f' in version 1, it should still be
// readable.
TEST_EQ(root_v2_viewed_from_v1->f()->a(), 35);
#endif #endif
} }
@@ -3290,45 +3297,51 @@ void FixedLengthArrayJsonTest(bool binary) {
} }
void TestEmbeddedBinarySchema() { void TestEmbeddedBinarySchema() {
// load JSON from disk // load JSON from disk
std::string jsonfile; std::string jsonfile;
TEST_EQ(flatbuffers::LoadFile((test_data_path + "monsterdata_test.golden").c_str(), TEST_EQ(flatbuffers::LoadFile(
false, &jsonfile), true); (test_data_path + "monsterdata_test.golden").c_str(), false,
&jsonfile),
true);
// parse schema first, so we can use it to parse the data after // parse schema first, so we can use it to parse the data after
flatbuffers::Parser parserOrg, parserGen; flatbuffers::Parser parserOrg, parserGen;
flatbuffers::Verifier verifier(MyGame::Example::MonsterBinarySchema::data(), flatbuffers::Verifier verifier(MyGame::Example::MonsterBinarySchema::data(),
MyGame::Example::MonsterBinarySchema::size()); MyGame::Example::MonsterBinarySchema::size());
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true); TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
TEST_EQ(parserOrg.Deserialize(MyGame::Example::MonsterBinarySchema::data(), TEST_EQ(parserOrg.Deserialize(MyGame::Example::MonsterBinarySchema::data(),
MyGame::Example::MonsterBinarySchema::size()), true); MyGame::Example::MonsterBinarySchema::size()),
TEST_EQ(parserGen.Deserialize(MyGame::Example::MonsterBinarySchema::data(), true);
MyGame::Example::MonsterBinarySchema::size()), true); TEST_EQ(parserGen.Deserialize(MyGame::Example::MonsterBinarySchema::data(),
TEST_EQ(parserOrg.Parse(jsonfile.c_str()), true); MyGame::Example::MonsterBinarySchema::size()),
true);
TEST_EQ(parserOrg.Parse(jsonfile.c_str()), true);
// First, verify it, just in case: // First, verify it, just in case:
flatbuffers::Verifier verifierOrg(parserOrg.builder_.GetBufferPointer(), flatbuffers::Verifier verifierOrg(parserOrg.builder_.GetBufferPointer(),
parserOrg.builder_.GetSize()); parserOrg.builder_.GetSize());
TEST_EQ(VerifyMonsterBuffer(verifierOrg), true); TEST_EQ(VerifyMonsterBuffer(verifierOrg), true);
// Export to JSON // Export to JSON
std::string jsonGen; std::string jsonGen;
TEST_EQ(GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen), true); TEST_EQ(
GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen),
true);
// Import from JSON // Import from JSON
TEST_EQ(parserGen.Parse(jsonGen.c_str()), true); TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
// Verify buffer from generated JSON // Verify buffer from generated JSON
flatbuffers::Verifier verifierGen(parserGen.builder_.GetBufferPointer(), flatbuffers::Verifier verifierGen(parserGen.builder_.GetBufferPointer(),
parserGen.builder_.GetSize()); parserGen.builder_.GetSize());
TEST_EQ(VerifyMonsterBuffer(verifierGen), true); TEST_EQ(VerifyMonsterBuffer(verifierGen), true);
// Compare generated buffer to original // Compare generated buffer to original
TEST_EQ(parserOrg.builder_.GetSize(), parserGen.builder_.GetSize()); TEST_EQ(parserOrg.builder_.GetSize(), parserGen.builder_.GetSize());
TEST_EQ(std::memcmp(parserOrg.builder_.GetBufferPointer(), TEST_EQ(std::memcmp(parserOrg.builder_.GetBufferPointer(),
parserGen.builder_.GetBufferPointer(), parserGen.builder_.GetBufferPointer(),
parserOrg.builder_.GetSize()), parserOrg.builder_.GetSize()),
0); 0);
} }
int FlatBufferTests() { int FlatBufferTests() {

View File

@@ -26,7 +26,9 @@ void TestFail(const char *expval, const char *val, const char *exp,
void TestEqStr(const char *expval, const char *val, const char *exp, void TestEqStr(const char *expval, const char *val, const char *exp,
const char *file, int line, const char *func) { const char *file, int line, const char *func) {
if (strcmp(expval, val) != 0) { TestFail(expval, val, exp, file, line, func); } if (strcmp(expval, val) != 0) {
TestFail(expval, val, exp, file, line, func);
}
} }
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \ #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \

View File

@@ -155,5 +155,4 @@ void FlatBufferBuilderTest() {
} }
// Link-time check using pointer type. // Link-time check using pointer type.
void CheckTestGeneratedIsValid(const MyGame::Example::Color&) void CheckTestGeneratedIsValid(const MyGame::Example::Color &) {}
{}