diff --git a/.gitignore b/.gitignore index 07531061d..9c8393b08 100755 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.o.d *.class *.a +*.swp *~ *.vcxproj *.vcxproj.filters @@ -43,6 +44,7 @@ flatsampletext.exe grpctest grpctest.exe snapshot.sh +tags tests/go_gen tests/monsterdata_java_wire.mon tests/monsterdata_go_wire.mon diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index b55e51b89..c0408de63 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -372,7 +372,7 @@ struct IDLOptions { bool generate_object_based_api; std::string cpp_object_api_pointer_type; std::string cpp_object_api_string_type; - bool clang_nullable; + bool gen_nullable; std::string object_prefix; std::string object_suffix; bool union_value_namespacing; @@ -428,7 +428,7 @@ struct IDLOptions { generate_name_strings(false), generate_object_based_api(false), cpp_object_api_pointer_type("std::unique_ptr"), - clang_nullable(false), + gen_nullable(false), object_suffix("T"), union_value_namespacing(true), allow_non_utf8(false), diff --git a/src/flatc.cpp b/src/flatc.cpp index da26fe10c..1f8658112 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -89,7 +89,7 @@ std::string FlatCompiler::GetUsageString(const char* program_name) const { " --cpp-ptr-type T Set object API pointer type (default std::unique_ptr)\n" " --cpp-str-type T Set object API string type (default std::string)\n" " T::c_str() and T::length() must be supported\n" - " --clang-nullable Add Clang _Nullable for C++ pointers.\n" + " --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n" " --object-prefix Customise class prefix for C++ object-based API.\n" " --object-suffix Customise class suffix for C++ object-based API.\n" " Default value is \"T\"\n" @@ -211,8 +211,8 @@ int FlatCompiler::Compile(int argc, const char** argv) { } else if (arg == "--cpp-str-type") { if (++argi >= argc) Error("missing type following" + arg, true); opts.cpp_object_api_string_type = argv[argi]; - } else if (arg == "--clang-nullable") { - opts.clang_nullable = true; + } else if (arg == "--gen-nullable") { + opts.gen_nullable = true; } else if (arg == "--object-prefix") { if (++argi >= argc) Error("missing prefix following" + arg, true); opts.object_prefix = argv[argi]; diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 6df59e21c..b94c2f7b0 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -127,7 +127,7 @@ class CppGenerator : public BaseGenerator { code_ += "#define " + include_guard; code_ += ""; - if (parser_.opts.clang_nullable) { + if (parser_.opts.gen_nullable) { code_ += "#pragma clang system_header\n\n"; } @@ -433,7 +433,7 @@ class CppGenerator : public BaseGenerator { } std::string NullableExtension() { - return parser_.opts.clang_nullable ? " _Nullable " : ""; + return parser_.opts.gen_nullable ? " _Nullable " : ""; } static std::string NativeName(const std::string &name, const StructDef *sd, const IDLOptions & opts) { diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index 0a7b3b82d..d0a7c6d81 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -70,6 +70,7 @@ struct LanguageParameters { std::string accessor_prefix_static; std::string optional_suffix; std::string includes; + std::string class_annotation; CommentConfig comment_config; }; @@ -99,8 +100,8 @@ const LanguageParameters& GetLangParams(IDLOptions::Language lang) { "", "", "", - "import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\n" - "import com.google.flatbuffers.*;\n\n@SuppressWarnings(\"unused\")\n", + "import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\nimport com.google.flatbuffers.*;\n", + "\n@SuppressWarnings(\"unused\")\n", { "/**", " *", @@ -132,6 +133,7 @@ const LanguageParameters& GetLangParams(IDLOptions::Language lang) { "Table.", "?", "using global::System;\nusing global::FlatBuffers;\n\n", + "", { nullptr, "///", @@ -220,7 +222,13 @@ class GeneralGenerator : public BaseGenerator { code += lang_.namespace_ident + namespace_name + lang_.namespace_begin; code += "\n\n"; } - if (needs_includes) code += lang_.includes; + if (needs_includes) { + code += lang_.includes; + if (parser_.opts.gen_nullable) { + code += "\nimport javax.annotation.Nullable;\n"; + } + code += lang_.class_annotation; + } code += classcode; if (!namespace_name.empty()) code += lang_.namespace_end; auto filename = NamespaceDir(ns) + defname + lang_.file_extension; @@ -235,6 +243,12 @@ class GeneralGenerator : public BaseGenerator { : upper); } +std::string GenNullableAnnotation(const Type& t) { + return lang_.language == IDLOptions::kJava + && parser_.opts.gen_nullable + && !IsScalar(DestinationType(t, true).base_type) ? " @Nullable ": ""; +} + static bool IsEnum(const Type& type) { return type.enum_def != nullptr && IsInteger(type.base_type); } @@ -869,7 +883,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) { std::string dest_mask = DestinationMask(field.value.type, true); std::string dest_cast = DestinationCast(field.value.type); std::string src_cast = SourceCast(field.value.type); - std::string method_start = " public " + type_name_dest + optional + " " + + std::string method_start = " public " + GenNullableAnnotation(field.value.type) + + type_name_dest + optional + " " + MakeCamel(field.name, lang_.first_camel_upper); std::string obj = lang_.language == IDLOptions::kCSharp ? "(new " + type_name + "())"