Skip to content

Commit

Permalink
BugFix: Optional enum when it is null (#6835)
Browse files Browse the repository at this point in the history
* Test to make sure optional enum is written properly

* Handle optional enum codegen: when cast optional enum add `?`

* Run `tests/generate_code.sh` to generate code from schema

* Fix type casting in case of CreateXXXTypeVector

* Reason why vector's type is not optional
  • Loading branch information
REASY authored Sep 10, 2021
1 parent 8fb8c2c commit 47d35f1
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
14 changes: 8 additions & 6 deletions src/idl_gen_csharp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,17 +309,17 @@ class CSharpGenerator : public BaseGenerator {
// would be cast down to int before being put onto the buffer. In C#, one cast
// directly cast an Enum to its underlying type, which is essential before
// putting it onto the buffer.
std::string SourceCast(const Type &type) const {
std::string SourceCast(const Type &type, const bool isOptional=false) const {
if (IsSeries(type)) {
return SourceCast(type.VectorType());
} else {
if (IsEnum(type)) return "(" + GenTypeBasic(type, false) + ")";
if (IsEnum(type)) return "(" + GenTypeBasic(type, false) + (isOptional ? "?": "") + ")";
}
return "";
}

std::string SourceCastBasic(const Type &type) const {
return IsScalar(type.base_type) ? SourceCast(type) : "";
std::string SourceCastBasic(const Type &type, const bool isOptional) const {
return IsScalar(type.base_type) ? SourceCast(type, isOptional) : "";
}

std::string GenEnumDefaultValue(const FieldDef &field) const {
Expand Down Expand Up @@ -1191,7 +1191,7 @@ class CSharpGenerator : public BaseGenerator {
code += " " + EscapeKeyword(argname) + ") { builder.Add";
code += GenMethod(field.value.type) + "(";
code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
code += SourceCastBasic(field.value.type);
code += SourceCastBasic(field.value.type, field.IsScalarOptional());
code += EscapeKeyword(argname);
if (!IsScalar(field.value.type.base_type) &&
field.value.type.base_type != BASE_TYPE_UNION) {
Expand Down Expand Up @@ -1225,7 +1225,9 @@ class CSharpGenerator : public BaseGenerator {
code += "Add";
code += GenMethod(vector_type);
code += "(";
code += SourceCastBasic(vector_type);
// At the moment there is no support of the type Vector with optional enum,
// e.g. if we have enum type SomeEnum there is no way to define `SomeEmum?[] enums` in FlatBuffer schema, so isOptional = false
code += SourceCastBasic(vector_type, false);
code += "data[i]";
if (vector_type.base_type == BASE_TYPE_STRUCT ||
IsString(vector_type))
Expand Down
13 changes: 13 additions & 0 deletions tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1139,5 +1139,18 @@ public void TestKeywordEscaping() {
Assert.AreEqual(keywordsInTable.Is, KeywordTest.ABC.@stackalloc);
Assert.AreEqual(keywordsInTable.Private, KeywordTest.@public.NONE);
}


[FlatBuffersTestMethod]
public void AddOptionalEnum_WhenPassNull_ShouldWorkProperly() {
var fbb = new FlatBufferBuilder(1);
ScalarStuff.StartScalarStuff(fbb);
ScalarStuff.AddMaybeEnum(fbb, null);
var offset = ScalarStuff.EndScalarStuff(fbb);
ScalarStuff.FinishScalarStuffBuffer(fbb, offset);

ScalarStuff scalarStuff = ScalarStuff.GetRootAsScalarStuff(fbb.DataBuffer);
Assert.AreEqual(null, scalarStuff.MaybeEnum);
}
}
}
2 changes: 1 addition & 1 deletion tests/optional_scalars/ScalarStuff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public struct ScalarStuff : IFlatbufferObject
public static void AddMaybeBool(FlatBufferBuilder builder, bool? maybeBool) { builder.AddBool(31, maybeBool); }
public static void AddDefaultBool(FlatBufferBuilder builder, bool defaultBool) { builder.AddBool(32, defaultBool, true); }
public static void AddJustEnum(FlatBufferBuilder builder, optional_scalars.OptionalByte justEnum) { builder.AddSbyte(33, (sbyte)justEnum, 0); }
public static void AddMaybeEnum(FlatBufferBuilder builder, optional_scalars.OptionalByte? maybeEnum) { builder.AddSbyte(34, (sbyte)maybeEnum); }
public static void AddMaybeEnum(FlatBufferBuilder builder, optional_scalars.OptionalByte? maybeEnum) { builder.AddSbyte(34, (sbyte?)maybeEnum); }
public static void AddDefaultEnum(FlatBufferBuilder builder, optional_scalars.OptionalByte defaultEnum) { builder.AddSbyte(35, (sbyte)defaultEnum, 1); }
public static Offset<optional_scalars.ScalarStuff> EndScalarStuff(FlatBufferBuilder builder) {
int o = builder.EndTable();
Expand Down

0 comments on commit 47d35f1

Please sign in to comment.