mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-30 12:10:01 +00:00
Annotate getters with @Pure when --java-checkerframework is specified. (#5510)
Together with @Nullable, this allows users to use static analysis tools like CheckerFramework to catch NPEs caused by unset fields.
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
3bfc86eaff
commit
782b865c55
@@ -514,6 +514,7 @@ struct IDLOptions {
|
|||||||
std::string cpp_object_api_string_type;
|
std::string cpp_object_api_string_type;
|
||||||
bool cpp_object_api_string_flexible_constructor;
|
bool cpp_object_api_string_flexible_constructor;
|
||||||
bool gen_nullable;
|
bool gen_nullable;
|
||||||
|
bool java_checkerframework;
|
||||||
bool gen_generated;
|
bool gen_generated;
|
||||||
std::string object_prefix;
|
std::string object_prefix;
|
||||||
std::string object_suffix;
|
std::string object_suffix;
|
||||||
@@ -594,6 +595,7 @@ struct IDLOptions {
|
|||||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||||
cpp_object_api_string_flexible_constructor(false),
|
cpp_object_api_string_flexible_constructor(false),
|
||||||
gen_nullable(false),
|
gen_nullable(false),
|
||||||
|
java_checkerframework(false),
|
||||||
gen_generated(false),
|
gen_generated(false),
|
||||||
object_suffix("T"),
|
object_suffix("T"),
|
||||||
union_value_namespacing(true),
|
union_value_namespacing(true),
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
|
|||||||
" --gen-object-api Generate an additional object-based API.\n"
|
" --gen-object-api Generate an additional object-based API.\n"
|
||||||
" --gen-compare Generate operator== for object-based API types.\n"
|
" --gen-compare Generate operator== for object-based API types.\n"
|
||||||
" --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
|
" --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
|
||||||
|
" --java-checkerframework Add @Pure for Java.\n"
|
||||||
" --gen-generated Add @Generated annotation for Java\n"
|
" --gen-generated Add @Generated annotation for Java\n"
|
||||||
" --gen-all Generate not just code for the current schema files,\n"
|
" --gen-all Generate not just code for the current schema files,\n"
|
||||||
" but for all files it includes as well.\n"
|
" but for all files it includes as well.\n"
|
||||||
@@ -261,6 +262,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
|||||||
opts.cpp_object_api_string_flexible_constructor = true;
|
opts.cpp_object_api_string_flexible_constructor = true;
|
||||||
} else if (arg == "--gen-nullable") {
|
} else if (arg == "--gen-nullable") {
|
||||||
opts.gen_nullable = true;
|
opts.gen_nullable = true;
|
||||||
|
} else if (arg == "--java-checkerframework") {
|
||||||
|
opts.java_checkerframework = true;
|
||||||
} else if (arg == "--gen-generated") {
|
} else if (arg == "--gen-generated") {
|
||||||
opts.gen_generated = true;
|
opts.gen_generated = true;
|
||||||
} else if (arg == "--object-prefix") {
|
} else if (arg == "--object-prefix") {
|
||||||
|
|||||||
@@ -228,6 +228,9 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
if (parser_.opts.gen_nullable) {
|
if (parser_.opts.gen_nullable) {
|
||||||
code += "\nimport javax.annotation.Nullable;\n";
|
code += "\nimport javax.annotation.Nullable;\n";
|
||||||
}
|
}
|
||||||
|
if (parser_.opts.java_checkerframework) {
|
||||||
|
code += "\nimport org.checkerframework.dataflow.qual.Pure;\n";
|
||||||
|
}
|
||||||
code += lang_.class_annotation;
|
code += lang_.class_annotation;
|
||||||
}
|
}
|
||||||
if (parser_.opts.gen_generated) {
|
if (parser_.opts.gen_generated) {
|
||||||
@@ -254,6 +257,14 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GenPureAnnotation(const Type &t) const {
|
||||||
|
return lang_.language == IDLOptions::kJava &&
|
||||||
|
parser_.opts.java_checkerframework &&
|
||||||
|
!IsScalar(DestinationType(t, true).base_type)
|
||||||
|
? " @Pure "
|
||||||
|
: "";
|
||||||
|
}
|
||||||
|
|
||||||
std::string GenTypeBasic(const Type &type, bool enableLangOverrides) const {
|
std::string GenTypeBasic(const Type &type, bool enableLangOverrides) const {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const char * const java_typename[] = {
|
static const char * const java_typename[] = {
|
||||||
@@ -969,10 +980,11 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
std::string dest_mask = DestinationMask(field.value.type, true);
|
std::string dest_mask = DestinationMask(field.value.type, true);
|
||||||
std::string dest_cast = DestinationCast(field.value.type);
|
std::string dest_cast = DestinationCast(field.value.type);
|
||||||
std::string src_cast = SourceCast(field.value.type);
|
std::string src_cast = SourceCast(field.value.type);
|
||||||
std::string method_start = " public " +
|
std::string method_start =
|
||||||
(field.required ? "" : GenNullableAnnotation(field.value.type)) +
|
" public " +
|
||||||
type_name_dest + optional + " " +
|
(field.required ? "" : GenNullableAnnotation(field.value.type)) +
|
||||||
MakeCamel(field.name, lang_.first_camel_upper);
|
GenPureAnnotation(field.value.type) + type_name_dest + optional +
|
||||||
|
" " + MakeCamel(field.name, lang_.first_camel_upper);
|
||||||
std::string obj = lang_.language == IDLOptions::kCSharp
|
std::string obj = lang_.language == IDLOptions::kCSharp
|
||||||
? "(new " + type_name + "())"
|
? "(new " + type_name + "())"
|
||||||
: "obj";
|
: "obj";
|
||||||
|
|||||||
Reference in New Issue
Block a user