From 15fb8a74ea89822a2cb47d149bfb3ea40c4734d3 Mon Sep 17 00:00:00 2001 From: kornilova-l Date: Mon, 2 Jul 2018 13:07:07 +0400 Subject: [PATCH] Helper methods use pointers for fields of type CArray and CStruct --- bindgen/Utils.h | 5 +++ bindgen/ir/Struct.cpp | 43 +++++++++++++++---- bindgen/ir/Struct.h | 4 ++ tests/samples/Extern.scala | 6 +-- tests/samples/PrivateMembers.scala | 10 ++--- tests/samples/ReservedWords.scala | 8 ++-- tests/samples/Struct.scala | 10 ++--- .../bindgen/samples/StructTests.scala | 2 +- 8 files changed, 61 insertions(+), 27 deletions(-) diff --git a/bindgen/Utils.h b/bindgen/Utils.h index 4e73ebd..25af2b7 100644 --- a/bindgen/Utils.h +++ b/bindgen/Utils.h @@ -95,4 +95,9 @@ static inline bool startsWith(const std::string &str, return str.substr(0, prefix.size()) == prefix; } +template static inline bool isInstanceOf(PT *type) { + auto *p = dynamic_cast(type); + return p != nullptr; +} + #endif // UTILS_H diff --git a/bindgen/ir/Struct.cpp b/bindgen/ir/Struct.cpp index 7283831..c850efe 100644 --- a/bindgen/ir/Struct.cpp +++ b/bindgen/ir/Struct.cpp @@ -6,7 +6,38 @@ #include Field::Field(std::string name, std::shared_ptr type) - : TypeAndName(std::move(name), type) {} + : TypeAndName(std::move(name), std::move(type)) {} + +std::string Field::generateSetter(int fieldIndex) { + std::string setter = handleReservedWords(getName(), "_="); + std::string parameterType = type->str(); + std::string value = "value"; + if (isInstanceOf(type.get()) || + isInstanceOf(type.get())) { + parameterType = "native.Ptr[" + parameterType + "]"; + value = "!" + value; + } + std::stringstream s; + s << " def " << setter << "(value: " + parameterType + "): Unit = !p._" + << std::to_string(fieldIndex + 1) << " = " << value; + return s.str(); +} + +std::string Field::generateGetter(int fieldIndex) { + std::string getter = handleReservedWords(getName()); + std::string returnType = type->str(); + std::string methodBody; + if (isInstanceOf(type.get()) || + isInstanceOf(type.get())) { + returnType = "native.Ptr[" + returnType + "]"; + methodBody = "p._" + std::to_string(fieldIndex + 1); + } else { + methodBody = "!p._" + std::to_string(fieldIndex + 1); + } + std::stringstream s; + s << " def " << getter << ": " << returnType << " = " << methodBody; + return s.str(); +} StructOrUnion::StructOrUnion(std::string name, std::vector fields) : name(std::move(name)), fields(std::move(fields)) {} @@ -47,14 +78,8 @@ std::string Struct::generateHelperClass() const { int fieldIndex = 0; for (const auto &field : fields) { if (!field->getName().empty()) { - std::string getter = handleReservedWords(field->getName()); - std::string setter = handleReservedWords(field->getName(), "_="); - std::shared_ptr ftype = field->getType(); - s << " def " << getter << ": " << ftype->str() << " = !p._" - << std::to_string(fieldIndex + 1) << "\n" - << " def " << setter - << "(value: " + ftype->str() + "):Unit = !p._" - << std::to_string(fieldIndex + 1) << " = value\n"; + s << field->generateGetter(fieldIndex) << "\n"; + s << field->generateSetter(fieldIndex) << "\n"; } fieldIndex++; } diff --git a/bindgen/ir/Struct.h b/bindgen/ir/Struct.h index cac5aec..a3f0e05 100644 --- a/bindgen/ir/Struct.h +++ b/bindgen/ir/Struct.h @@ -12,6 +12,10 @@ class Field : public TypeAndName { public: Field(std::string name, std::shared_ptr type); + + std::string generateSetter(int fieldIndex); + + std::string generateGetter(int fieldIndex); }; class StructOrUnion { diff --git a/tests/samples/Extern.scala b/tests/samples/Extern.scala index 6cdcfd8..ad60e7e 100644 --- a/tests/samples/Extern.scala +++ b/tests/samples/Extern.scala @@ -25,11 +25,11 @@ object ExternHelpers { implicit class struct_version_ops(val p: native.Ptr[struct_version]) extends AnyVal { def major: native.CInt = !p._1 - def major_=(value: native.CInt):Unit = !p._1 = value + def major_=(value: native.CInt): Unit = !p._1 = value def minor: native.CInt = !p._2 - def minor_=(value: native.CInt):Unit = !p._2 = value + def minor_=(value: native.CInt): Unit = !p._2 = value def patch: native.CInt = !p._3 - def patch_=(value: native.CInt):Unit = !p._3 = value + def patch_=(value: native.CInt): Unit = !p._3 = value } def struct_version()(implicit z: native.Zone): native.Ptr[struct_version] = native.alloc[struct_version] diff --git a/tests/samples/PrivateMembers.scala b/tests/samples/PrivateMembers.scala index dfc9ace..6817edf 100644 --- a/tests/samples/PrivateMembers.scala +++ b/tests/samples/PrivateMembers.scala @@ -41,30 +41,30 @@ object PrivateMembersHelpers { implicit class struct_structWithPrivateType_ops(val p: native.Ptr[struct_structWithPrivateType]) extends AnyVal { def field1: native.CInt = !p._1 - def field1_=(value: native.CInt):Unit = !p._1 = value + def field1_=(value: native.CInt): Unit = !p._1 = value def field2: __private_type = !p._2 - def field2_=(value: __private_type):Unit = !p._2 = value + def field2_=(value: __private_type): Unit = !p._2 = value } def struct_structWithPrivateType()(implicit z: native.Zone): native.Ptr[struct_structWithPrivateType] = native.alloc[struct_structWithPrivateType] implicit class struct_structWithPrivateStruct_ops(val p: native.Ptr[struct_structWithPrivateStruct]) extends AnyVal { def s: native.Ptr[struct_structWithPrivateType] = !p._1 - def s_=(value: native.Ptr[struct_structWithPrivateType]):Unit = !p._1 = value + def s_=(value: native.Ptr[struct_structWithPrivateType]): Unit = !p._1 = value } def struct_structWithPrivateStruct()(implicit z: native.Zone): native.Ptr[struct_structWithPrivateStruct] = native.alloc[struct_structWithPrivateStruct] implicit class struct_normalStruct_ops(val p: native.Ptr[struct_normalStruct]) extends AnyVal { def a: native.CInt = !p._1 - def a_=(value: native.CInt):Unit = !p._1 = value + def a_=(value: native.CInt): Unit = !p._1 = value } def struct_normalStruct()(implicit z: native.Zone): native.Ptr[struct_normalStruct] = native.alloc[struct_normalStruct] implicit class struct_privateStructWithTypedef_ops(val p: native.Ptr[struct_privateStructWithTypedef]) extends AnyVal { def a: native.Ptr[__private_type] = !p._1 - def a_=(value: native.Ptr[__private_type]):Unit = !p._1 = value + def a_=(value: native.Ptr[__private_type]): Unit = !p._1 = value } def struct_privateStructWithTypedef()(implicit z: native.Zone): native.Ptr[struct_privateStructWithTypedef] = native.alloc[struct_privateStructWithTypedef] diff --git a/tests/samples/ReservedWords.scala b/tests/samples/ReservedWords.scala index 80e04eb..b3e5cdd 100644 --- a/tests/samples/ReservedWords.scala +++ b/tests/samples/ReservedWords.scala @@ -27,18 +27,18 @@ object ReservedWordsHelpers { implicit class struct_object_ops(val p: native.Ptr[struct_object]) extends AnyVal { def `yield`: `match` = !p._1 - def `yield_=`(value: `match`):Unit = !p._1 = value + def `yield_=`(value: `match`): Unit = !p._1 = value def `val`: native.CInt = !p._2 - def `val_=`(value: native.CInt):Unit = !p._2 = value + def `val_=`(value: native.CInt): Unit = !p._2 = value } def struct_object()(implicit z: native.Zone): native.Ptr[struct_object] = native.alloc[struct_object] implicit class struct_finally_ops(val p: native.Ptr[struct_finally]) extends AnyVal { def `val`: `def` = !p._1 - def `val_=`(value: `def`):Unit = !p._1 = value + def `val_=`(value: `def`): Unit = !p._1 = value def `finally`: `lazy` = !p._2 - def `finally_=`(value: `lazy`):Unit = !p._2 = value + def `finally_=`(value: `lazy`): Unit = !p._2 = value } def struct_finally()(implicit z: native.Zone): native.Ptr[struct_finally] = native.alloc[struct_finally] diff --git a/tests/samples/Struct.scala b/tests/samples/Struct.scala index 5ef17ec..140ee22 100644 --- a/tests/samples/Struct.scala +++ b/tests/samples/Struct.scala @@ -22,18 +22,18 @@ object StructHelpers { implicit class struct_point_ops(val p: native.Ptr[struct_point]) extends AnyVal { def x: native.CInt = !p._1 - def x_=(value: native.CInt):Unit = !p._1 = value + def x_=(value: native.CInt): Unit = !p._1 = value def y: native.CInt = !p._2 - def y_=(value: native.CInt):Unit = !p._2 = value + def y_=(value: native.CInt): Unit = !p._2 = value } def struct_point()(implicit z: native.Zone): native.Ptr[struct_point] = native.alloc[struct_point] implicit class struct_structWithAnonymousStruct_ops(val p: native.Ptr[struct_structWithAnonymousStruct]) extends AnyVal { def a: native.CInt = !p._1 - def a_=(value: native.CInt):Unit = !p._1 = value - def anonymousStruct: native.CArray[Byte, native.Nat._8] = !p._2 - def anonymousStruct_=(value: native.CArray[Byte, native.Nat._8]):Unit = !p._2 = value + def a_=(value: native.CInt): Unit = !p._1 = value + def anonymousStruct: native.Ptr[native.CArray[Byte, native.Nat._8]] = p._2 + def anonymousStruct_=(value: native.Ptr[native.CArray[Byte, native.Nat._8]]): Unit = !p._2 = !value } def struct_structWithAnonymousStruct()(implicit z: native.Zone): native.Ptr[struct_structWithAnonymousStruct] = native.alloc[struct_structWithAnonymousStruct] diff --git a/tests/samples/src/test/scala/org/scalanative/bindgen/samples/StructTests.scala b/tests/samples/src/test/scala/org/scalanative/bindgen/samples/StructTests.scala index a721c52..5c6b936 100644 --- a/tests/samples/src/test/scala/org/scalanative/bindgen/samples/StructTests.scala +++ b/tests/samples/src/test/scala/org/scalanative/bindgen/samples/StructTests.scala @@ -28,7 +28,7 @@ object StructTests extends TestSuite { val structWithAnonymousStruct = struct_structWithAnonymousStruct() val array = anonymousStruct.cast[Ptr[CArray[Byte, Nat._8]]] - !structWithAnonymousStruct._2 = !array + structWithAnonymousStruct.anonymousStruct_=(array) assert('a' == Struct.getCharFromAnonymousStruct(structWithAnonymousStruct)) assert(42 == Struct.getIntFromAnonymousStruct(structWithAnonymousStruct))