Skip to content

Commit

Permalink
[Kotlin] Improve field nullability based on (required) (google#7658)
Browse files Browse the repository at this point in the history
* [Kotlin] Only generate nullable return types if the field is not required

* [Kotlin] Fix generated code formatting according to kotlin style guide

Co-authored-by: Derek Bailey <[email protected]>
Co-authored-by: Paulo Pinheiro <[email protected]>
  • Loading branch information
3 people authored Jan 6, 2023
1 parent 74b5195 commit e61b003
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
45 changes: 38 additions & 7 deletions src/idl_gen_kotlin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,11 @@ class KotlinGenerator : public BaseGenerator {
auto r_type = GenTypeGet(field.value.type);
if (field.IsScalarOptional() ||
// string, structs and unions
(base_type == BASE_TYPE_STRING || base_type == BASE_TYPE_STRUCT ||
base_type == BASE_TYPE_UNION) ||
(!field.IsRequired() &&
(base_type == BASE_TYPE_STRING || base_type == BASE_TYPE_STRUCT ||
base_type == BASE_TYPE_UNION)) ||
// vector of anything not scalar
(base_type == BASE_TYPE_VECTOR &&
(base_type == BASE_TYPE_VECTOR && !field.IsRequired() &&
!IsScalar(field.value.type.VectorType().base_type))) {
r_type += "?";
}
Expand Down Expand Up @@ -998,7 +999,15 @@ class KotlinGenerator : public BaseGenerator {
OffsetWrapper(
writer, offset_val,
[&]() { writer += "obj.__assign({{seek}}, bb)"; },
[&]() { writer += "null"; });
[&]() {
if (field.IsRequired()) {
writer +=
"throw AssertionError(\"No value for "
"(required) field {{field_name}}\")";
} else {
writer += "null";
}
});
});
}
break;
Expand All @@ -1008,12 +1017,30 @@ class KotlinGenerator : public BaseGenerator {
// val Name : String?
// get() = {
// val o = __offset(10)
// return if (o != 0) __string(o + bb_pos) else null
// return if (o != 0) {
// __string(o + bb_pos)
// } else {
// null
// }
// }
// ? adds nullability annotation
GenerateGetter(writer, field_name, return_type, [&]() {
writer += "val o = __offset({{offset}})";
writer += "return if (o != 0) __string(o + bb_pos) else null";
writer += "return if (o != 0) {";
writer.IncrementIdentLevel();
writer += "__string(o + bb_pos)";
writer.DecrementIdentLevel();
writer += "} else {";
writer.IncrementIdentLevel();
if (field.IsRequired()) {
writer +=
"throw AssertionError(\"No value for (required) field "
"{{field_name}}\")";
} else {
writer += "null";
}
writer.DecrementIdentLevel();
writer += "}";
});
break;
case BASE_TYPE_VECTOR: {
Expand All @@ -1038,7 +1065,11 @@ class KotlinGenerator : public BaseGenerator {
GenerateFun(writer, field_name, params, return_type, [&]() {
auto inline_size = NumToString(InlineSize(vectortype));
auto index = "__vector(o) + j * " + inline_size;
auto not_found = NotFoundReturn(field.value.type.element);
auto not_found =
field.IsRequired()
? "throw IndexOutOfBoundsException(\"Index out of range: "
"$j, vector {{field_name}} is empty\")"
: NotFoundReturn(field.value.type.element);
auto found = "";
writer.SetValue("index", index);
switch (vectortype.base_type) {
Expand Down
8 changes: 6 additions & 2 deletions tests/MyGame/Example/Monster.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,14 @@ class Monster : Table() {
false
}
}
val name : String?
val name : String
get() {
val o = __offset(10)
return if (o != 0) __string(o + bb_pos) else null
return if (o != 0) {
__string(o + bb_pos)
} else {
throw AssertionError("No value for (required) field name")
}
}
val nameAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(10, 1)
fun nameInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 10, 1)
Expand Down
6 changes: 5 additions & 1 deletion tests/MyGame/Example/Stat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ class Stat : Table() {
val id : String?
get() {
val o = __offset(4)
return if (o != 0) __string(o + bb_pos) else null
return if (o != 0) {
__string(o + bb_pos)
} else {
null
}
}
val idAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1)
fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
Expand Down

0 comments on commit e61b003

Please sign in to comment.