1
1
#include " Struct.h"
2
2
#include " ../Utils.h"
3
3
#include " types/ArrayType.h"
4
+ #include " types/PointerType.h"
4
5
#include " types/PrimitiveType.h"
5
6
#include < sstream>
6
7
7
8
Field::Field (std::string name, std::shared_ptr<Type> type)
8
9
: TypeAndName(std::move(name), std::move(type)) {}
9
10
11
+ Field::Field (std::string name, std::shared_ptr<Type> type, uint64_t offset)
12
+ : TypeAndName(std::move(name), std::move(type)), offset(offset) {}
13
+
14
+ uint64_t Field::getOffset () const { return offset; }
15
+
10
16
StructOrUnion::StructOrUnion (std::string name,
11
17
std::vector<std::shared_ptr<Field>> fields,
12
18
std::shared_ptr<Location> location)
@@ -41,6 +47,8 @@ std::shared_ptr<Location> StructOrUnion::getLocation() const {
41
47
return location;
42
48
}
43
49
50
+ bool StructOrUnion::hasHelperMethods () const { return !fields.empty (); }
51
+
44
52
Struct::Struct (std::string name, std::vector<std::shared_ptr<Field>> fields,
45
53
uint64_t typeSize, std::shared_ptr<Location> location,
46
54
bool isPacked)
@@ -65,19 +73,15 @@ std::shared_ptr<TypeDef> Struct::generateTypeDef() {
65
73
66
74
std::string Struct::generateHelperClass () const {
67
75
assert (hasHelperMethods ());
68
- /* struct is not empty and not represented as an array */
69
76
std::stringstream s;
70
77
std::string type = getTypeAlias ();
71
78
s << " implicit class " << type << " _ops(val p: native.Ptr[" << type
72
79
<< " ])"
73
80
<< " extends AnyVal {\n " ;
74
- unsigned fieldIndex = 0 ;
75
- for (const auto &field : fields) {
76
- if (!field->getName ().empty ()) {
77
- s << generateGetter (fieldIndex) << " \n " ;
78
- s << generateSetter (fieldIndex) << " \n " ;
79
- }
80
- fieldIndex++;
81
+ if (fields.size () <= SCALA_NATIVE_MAX_STRUCT_FIELDS) {
82
+ s << generateHelperClassMethodsForStructRepresentation ();
83
+ } else {
84
+ s << generateHelperClassMethodsForArrayRepresentation ();
81
85
}
82
86
s << " }\n\n " ;
83
87
@@ -96,6 +100,28 @@ bool Struct::hasHelperMethods() const {
96
100
return !isPacked && !fields.empty ();
97
101
}
98
102
103
+ std::string Struct::generateHelperClassMethodsForStructRepresentation () const {
104
+ std::stringstream s;
105
+ for (unsigned fieldIndex = 0 ; fieldIndex < fields.size (); fieldIndex++) {
106
+ if (!fields[fieldIndex]->getName ().empty ()) {
107
+ s << generateGetterForStructRepresentation (fieldIndex);
108
+ s << generateSetterForStructRepresentation (fieldIndex);
109
+ }
110
+ }
111
+ return s.str ();
112
+ }
113
+
114
+ std::string Struct::generateHelperClassMethodsForArrayRepresentation () const {
115
+ std::stringstream s;
116
+ for (unsigned fieldIndex = 0 ; fieldIndex < fields.size (); fieldIndex++) {
117
+ if (!fields[fieldIndex]->getName ().empty ()) {
118
+ s << generateGetterForArrayRepresentation (fieldIndex);
119
+ s << generateSetterForArrayRepresentation (fieldIndex);
120
+ }
121
+ }
122
+ return s.str ();
123
+ }
124
+
99
125
std::string Struct::getTypeAlias () const { return " struct_" + name; }
100
126
101
127
std::string Struct::str () const {
@@ -131,7 +157,8 @@ bool Struct::operator==(const Type &other) const {
131
157
return false ;
132
158
}
133
159
134
- std::string Struct::generateSetter (unsigned fieldIndex) const {
160
+ std::string
161
+ Struct::generateSetterForStructRepresentation (unsigned fieldIndex) const {
135
162
std::shared_ptr<Field> field = fields[fieldIndex];
136
163
std::string setter = handleReservedWords (field->getName (), " _=" );
137
164
std::string parameterType = field->getType ()->str ();
@@ -143,11 +170,12 @@ std::string Struct::generateSetter(unsigned fieldIndex) const {
143
170
}
144
171
std::stringstream s;
145
172
s << " def " << setter << " (value: " + parameterType + " ): Unit = !p._"
146
- << std::to_string (fieldIndex + 1 ) << " = " << value;
173
+ << std::to_string (fieldIndex + 1 ) << " = " << value << " \n " ;
147
174
return s.str ();
148
175
}
149
176
150
- std::string Struct::generateGetter (unsigned fieldIndex) const {
177
+ std::string
178
+ Struct::generateGetterForStructRepresentation (unsigned fieldIndex) const {
151
179
std::shared_ptr<Field> field = fields[fieldIndex];
152
180
std::string getter = handleReservedWords (field->getName ());
153
181
std::string returnType = field->getType ()->str ();
@@ -160,14 +188,49 @@ std::string Struct::generateGetter(unsigned fieldIndex) const {
160
188
methodBody = " !p._" + std::to_string (fieldIndex + 1 );
161
189
}
162
190
std::stringstream s;
163
- s << " def " << getter << " : " << returnType << " = " << methodBody;
191
+ s << " def " << getter << " : " << returnType << " = " << methodBody
192
+ << " \n " ;
164
193
return s.str ();
165
194
}
166
195
167
196
bool Struct::isRepresentedAsStruct () const {
168
197
return fields.size () <= SCALA_NATIVE_MAX_STRUCT_FIELDS;
169
198
}
170
199
200
+ std::string
201
+ Struct::generateSetterForArrayRepresentation (unsigned int fieldIndex) const {
202
+ return std::string ();
203
+ }
204
+
205
+ std::string
206
+ Struct::generateGetterForArrayRepresentation (unsigned fieldIndex) const {
207
+ std::shared_ptr<Field> field = fields[fieldIndex];
208
+ std::string getter = handleReservedWords (field->getName ());
209
+ std::string returnType;
210
+ std::string methodBody;
211
+
212
+ PointerType pointerToFieldType = PointerType (field->getType ());
213
+ if (field->getOffset () != 0 ) {
214
+ methodBody = " (p._1 + " + std::to_string (field->getOffset ()) + " )" ;
215
+ } else {
216
+ methodBody = " p._1" ;
217
+ }
218
+ methodBody = methodBody + " .cast[" + pointerToFieldType.str () + " ]" ;
219
+
220
+ if (isAliasForType<ArrayType>(field->getType ().get ()) ||
221
+ isAliasForType<Struct>(field->getType ().get ())) {
222
+ returnType = pointerToFieldType.str ();
223
+ } else {
224
+ methodBody = " !" + methodBody;
225
+ returnType = field->getType ()->str ();
226
+ }
227
+ std::stringstream s;
228
+ s << " def " << getter << " : " << returnType << " = " << methodBody
229
+ << " \n " ;
230
+ return s.str ();
231
+ return " " ;
232
+ }
233
+
171
234
Union::Union (std::string name, std::vector<std::shared_ptr<Field>> fields,
172
235
uint64_t maxSize, std::shared_ptr<Location> location)
173
236
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),
@@ -179,6 +242,7 @@ std::shared_ptr<TypeDef> Union::generateTypeDef() {
179
242
}
180
243
181
244
std::string Union::generateHelperClass () const {
245
+ assert (hasHelperMethods ());
182
246
std::stringstream s;
183
247
std::string type = getTypeAlias ();
184
248
s << " implicit class " << type << " _pos"
0 commit comments