Skip to content

Commit fb3c4de

Browse files
authored
Merge pull request #93 from kornilova-l/helpers-for-struct-and-array-fields
Helper methods use pointers for fields of type CArray and CStruct
2 parents 8c4f985 + 15fb8a7 commit fb3c4de

File tree

8 files changed

+61
-27
lines changed

8 files changed

+61
-27
lines changed

bindgen/Utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,9 @@ static inline bool startsWith(const std::string &str,
9595
return str.substr(0, prefix.size()) == prefix;
9696
}
9797

98+
template <typename T, typename PT> static inline bool isInstanceOf(PT *type) {
99+
auto *p = dynamic_cast<T *>(type);
100+
return p != nullptr;
101+
}
102+
98103
#endif // UTILS_H

bindgen/ir/Struct.cpp

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,38 @@
66
#include <utility>
77

88
Field::Field(std::string name, std::shared_ptr<Type> type)
9-
: TypeAndName(std::move(name), type) {}
9+
: TypeAndName(std::move(name), std::move(type)) {}
10+
11+
std::string Field::generateSetter(int fieldIndex) {
12+
std::string setter = handleReservedWords(getName(), "_=");
13+
std::string parameterType = type->str();
14+
std::string value = "value";
15+
if (isInstanceOf<ArrayType>(type.get()) ||
16+
isInstanceOf<Struct>(type.get())) {
17+
parameterType = "native.Ptr[" + parameterType + "]";
18+
value = "!" + value;
19+
}
20+
std::stringstream s;
21+
s << " def " << setter << "(value: " + parameterType + "): Unit = !p._"
22+
<< std::to_string(fieldIndex + 1) << " = " << value;
23+
return s.str();
24+
}
25+
26+
std::string Field::generateGetter(int fieldIndex) {
27+
std::string getter = handleReservedWords(getName());
28+
std::string returnType = type->str();
29+
std::string methodBody;
30+
if (isInstanceOf<ArrayType>(type.get()) ||
31+
isInstanceOf<Struct>(type.get())) {
32+
returnType = "native.Ptr[" + returnType + "]";
33+
methodBody = "p._" + std::to_string(fieldIndex + 1);
34+
} else {
35+
methodBody = "!p._" + std::to_string(fieldIndex + 1);
36+
}
37+
std::stringstream s;
38+
s << " def " << getter << ": " << returnType << " = " << methodBody;
39+
return s.str();
40+
}
1041

1142
StructOrUnion::StructOrUnion(std::string name, std::vector<Field *> fields)
1243
: name(std::move(name)), fields(std::move(fields)) {}
@@ -47,14 +78,8 @@ std::string Struct::generateHelperClass() const {
4778
int fieldIndex = 0;
4879
for (const auto &field : fields) {
4980
if (!field->getName().empty()) {
50-
std::string getter = handleReservedWords(field->getName());
51-
std::string setter = handleReservedWords(field->getName(), "_=");
52-
std::shared_ptr<Type> ftype = field->getType();
53-
s << " def " << getter << ": " << ftype->str() << " = !p._"
54-
<< std::to_string(fieldIndex + 1) << "\n"
55-
<< " def " << setter
56-
<< "(value: " + ftype->str() + "):Unit = !p._"
57-
<< std::to_string(fieldIndex + 1) << " = value\n";
81+
s << field->generateGetter(fieldIndex) << "\n";
82+
s << field->generateSetter(fieldIndex) << "\n";
5883
}
5984
fieldIndex++;
6085
}

bindgen/ir/Struct.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
class Field : public TypeAndName {
1313
public:
1414
Field(std::string name, std::shared_ptr<Type> type);
15+
16+
std::string generateSetter(int fieldIndex);
17+
18+
std::string generateGetter(int fieldIndex);
1519
};
1620

1721
class StructOrUnion {

tests/samples/Extern.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ object ExternHelpers {
2525

2626
implicit class struct_version_ops(val p: native.Ptr[struct_version]) extends AnyVal {
2727
def major: native.CInt = !p._1
28-
def major_=(value: native.CInt):Unit = !p._1 = value
28+
def major_=(value: native.CInt): Unit = !p._1 = value
2929
def minor: native.CInt = !p._2
30-
def minor_=(value: native.CInt):Unit = !p._2 = value
30+
def minor_=(value: native.CInt): Unit = !p._2 = value
3131
def patch: native.CInt = !p._3
32-
def patch_=(value: native.CInt):Unit = !p._3 = value
32+
def patch_=(value: native.CInt): Unit = !p._3 = value
3333
}
3434

3535
def struct_version()(implicit z: native.Zone): native.Ptr[struct_version] = native.alloc[struct_version]

tests/samples/PrivateMembers.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,30 +41,30 @@ object PrivateMembersHelpers {
4141

4242
implicit class struct_structWithPrivateType_ops(val p: native.Ptr[struct_structWithPrivateType]) extends AnyVal {
4343
def field1: native.CInt = !p._1
44-
def field1_=(value: native.CInt):Unit = !p._1 = value
44+
def field1_=(value: native.CInt): Unit = !p._1 = value
4545
def field2: __private_type = !p._2
46-
def field2_=(value: __private_type):Unit = !p._2 = value
46+
def field2_=(value: __private_type): Unit = !p._2 = value
4747
}
4848

4949
def struct_structWithPrivateType()(implicit z: native.Zone): native.Ptr[struct_structWithPrivateType] = native.alloc[struct_structWithPrivateType]
5050

5151
implicit class struct_structWithPrivateStruct_ops(val p: native.Ptr[struct_structWithPrivateStruct]) extends AnyVal {
5252
def s: native.Ptr[struct_structWithPrivateType] = !p._1
53-
def s_=(value: native.Ptr[struct_structWithPrivateType]):Unit = !p._1 = value
53+
def s_=(value: native.Ptr[struct_structWithPrivateType]): Unit = !p._1 = value
5454
}
5555

5656
def struct_structWithPrivateStruct()(implicit z: native.Zone): native.Ptr[struct_structWithPrivateStruct] = native.alloc[struct_structWithPrivateStruct]
5757

5858
implicit class struct_normalStruct_ops(val p: native.Ptr[struct_normalStruct]) extends AnyVal {
5959
def a: native.CInt = !p._1
60-
def a_=(value: native.CInt):Unit = !p._1 = value
60+
def a_=(value: native.CInt): Unit = !p._1 = value
6161
}
6262

6363
def struct_normalStruct()(implicit z: native.Zone): native.Ptr[struct_normalStruct] = native.alloc[struct_normalStruct]
6464

6565
implicit class struct_privateStructWithTypedef_ops(val p: native.Ptr[struct_privateStructWithTypedef]) extends AnyVal {
6666
def a: native.Ptr[__private_type] = !p._1
67-
def a_=(value: native.Ptr[__private_type]):Unit = !p._1 = value
67+
def a_=(value: native.Ptr[__private_type]): Unit = !p._1 = value
6868
}
6969

7070
def struct_privateStructWithTypedef()(implicit z: native.Zone): native.Ptr[struct_privateStructWithTypedef] = native.alloc[struct_privateStructWithTypedef]

tests/samples/ReservedWords.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ object ReservedWordsHelpers {
2727

2828
implicit class struct_object_ops(val p: native.Ptr[struct_object]) extends AnyVal {
2929
def `yield`: `match` = !p._1
30-
def `yield_=`(value: `match`):Unit = !p._1 = value
30+
def `yield_=`(value: `match`): Unit = !p._1 = value
3131
def `val`: native.CInt = !p._2
32-
def `val_=`(value: native.CInt):Unit = !p._2 = value
32+
def `val_=`(value: native.CInt): Unit = !p._2 = value
3333
}
3434

3535
def struct_object()(implicit z: native.Zone): native.Ptr[struct_object] = native.alloc[struct_object]
3636

3737
implicit class struct_finally_ops(val p: native.Ptr[struct_finally]) extends AnyVal {
3838
def `val`: `def` = !p._1
39-
def `val_=`(value: `def`):Unit = !p._1 = value
39+
def `val_=`(value: `def`): Unit = !p._1 = value
4040
def `finally`: `lazy` = !p._2
41-
def `finally_=`(value: `lazy`):Unit = !p._2 = value
41+
def `finally_=`(value: `lazy`): Unit = !p._2 = value
4242
}
4343

4444
def struct_finally()(implicit z: native.Zone): native.Ptr[struct_finally] = native.alloc[struct_finally]

tests/samples/Struct.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@ object StructHelpers {
2222

2323
implicit class struct_point_ops(val p: native.Ptr[struct_point]) extends AnyVal {
2424
def x: native.CInt = !p._1
25-
def x_=(value: native.CInt):Unit = !p._1 = value
25+
def x_=(value: native.CInt): Unit = !p._1 = value
2626
def y: native.CInt = !p._2
27-
def y_=(value: native.CInt):Unit = !p._2 = value
27+
def y_=(value: native.CInt): Unit = !p._2 = value
2828
}
2929

3030
def struct_point()(implicit z: native.Zone): native.Ptr[struct_point] = native.alloc[struct_point]
3131

3232
implicit class struct_structWithAnonymousStruct_ops(val p: native.Ptr[struct_structWithAnonymousStruct]) extends AnyVal {
3333
def a: native.CInt = !p._1
34-
def a_=(value: native.CInt):Unit = !p._1 = value
35-
def anonymousStruct: native.CArray[Byte, native.Nat._8] = !p._2
36-
def anonymousStruct_=(value: native.CArray[Byte, native.Nat._8]):Unit = !p._2 = value
34+
def a_=(value: native.CInt): Unit = !p._1 = value
35+
def anonymousStruct: native.Ptr[native.CArray[Byte, native.Nat._8]] = p._2
36+
def anonymousStruct_=(value: native.Ptr[native.CArray[Byte, native.Nat._8]]): Unit = !p._2 = !value
3737
}
3838

3939
def struct_structWithAnonymousStruct()(implicit z: native.Zone): native.Ptr[struct_structWithAnonymousStruct] = native.alloc[struct_structWithAnonymousStruct]

tests/samples/src/test/scala/org/scalanative/bindgen/samples/StructTests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ object StructTests extends TestSuite {
2828

2929
val structWithAnonymousStruct = struct_structWithAnonymousStruct()
3030
val array = anonymousStruct.cast[Ptr[CArray[Byte, Nat._8]]]
31-
!structWithAnonymousStruct._2 = !array
31+
structWithAnonymousStruct.anonymousStruct_=(array)
3232

3333
assert('a' == Struct.getCharFromAnonymousStruct(structWithAnonymousStruct))
3434
assert(42 == Struct.getIntFromAnonymousStruct(structWithAnonymousStruct))

0 commit comments

Comments
 (0)