Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helper methods use pointers for fields of type CArray and CStruct #93

Merged
merged 1 commit into from
Jul 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bindgen/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,9 @@ static inline bool startsWith(const std::string &str,
return str.substr(0, prefix.size()) == prefix;
}

template <typename T, typename PT> static inline bool isInstanceOf(PT *type) {
auto *p = dynamic_cast<T *>(type);
return p != nullptr;
}

#endif // UTILS_H
43 changes: 34 additions & 9 deletions bindgen/ir/Struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,38 @@
#include <utility>

Field::Field(std::string name, std::shared_ptr<Type> 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<ArrayType>(type.get()) ||
isInstanceOf<Struct>(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<ArrayType>(type.get()) ||
isInstanceOf<Struct>(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<Field *> fields)
: name(std::move(name)), fields(std::move(fields)) {}
Expand Down Expand Up @@ -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<Type> 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++;
}
Expand Down
4 changes: 4 additions & 0 deletions bindgen/ir/Struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
class Field : public TypeAndName {
public:
Field(std::string name, std::shared_ptr<Type> type);

std::string generateSetter(int fieldIndex);

std::string generateGetter(int fieldIndex);
};

class StructOrUnion {
Expand Down
6 changes: 3 additions & 3 deletions tests/samples/Extern.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
10 changes: 5 additions & 5 deletions tests/samples/PrivateMembers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
8 changes: 4 additions & 4 deletions tests/samples/ReservedWords.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
10 changes: 5 additions & 5 deletions tests/samples/Struct.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down