@@ -44,11 +44,6 @@ Struct::generateHelperClass(const LocationManager &locationManager) const {
44
44
}
45
45
s << " }\n " ;
46
46
47
- /* makes struct instantiation easier */
48
- s << " def "
49
- << type + " ()(implicit z: native.Zone): native.Ptr[" + type + " ]"
50
- << " = native.alloc[" + type + " ]\n " ;
51
-
52
47
return s.str ();
53
48
}
54
49
@@ -132,7 +127,8 @@ std::string Struct::generateSetterForStructRepresentation(
132
127
unsigned fieldIndex, const LocationManager &locationManager) const {
133
128
std::shared_ptr<Field> field = fields[fieldIndex];
134
129
std::string setter = handleReservedWords (field->getName (), " _=" );
135
- std::string parameterType = field->getType ()->str (locationManager);
130
+ std::string parameterType =
131
+ wrapArrayOrRecordInPointer (field->getType ())->str (locationManager);
136
132
std::string value = " value" ;
137
133
std::vector<std::shared_ptr<const Struct>> structTypesThatShouldBeReplaced =
138
134
shouldFieldBreakCycle (field);
@@ -141,9 +137,7 @@ std::string Struct::generateSetterForStructRepresentation(
141
137
std::shared_ptr<const Type> typeReplacement = getTypeReplacement (
142
138
field->getType (), structTypesThatShouldBeReplaced);
143
139
value = value + " .cast[" + typeReplacement->str (locationManager) + " ]" ;
144
- } else if (isAliasForType<ArrayType>(field->getType ().get ()) ||
145
- isAliasForType<Struct>(field->getType ().get ())) {
146
- parameterType = " native.Ptr[" + parameterType + " ]" ;
140
+ } else if (isArrayOrRecord (field->getType ())) {
147
141
value = " !" + value;
148
142
}
149
143
std::stringstream s;
@@ -156,17 +150,16 @@ std::string Struct::generateGetterForStructRepresentation(
156
150
unsigned fieldIndex, const LocationManager &locationManager) const {
157
151
std::shared_ptr<Field> field = fields[fieldIndex];
158
152
std::string getter = handleReservedWords (field->getName ());
159
- std::string returnType = field->getType ()->str (locationManager);
153
+ std::string returnType =
154
+ wrapArrayOrRecordInPointer (field->getType ())->str (locationManager);
160
155
std::string methodBody = " p._" + std::to_string (fieldIndex + 1 );
161
- if (isAliasForType<ArrayType>(field->getType ().get ()) ||
162
- isAliasForType<Struct>(field->getType ().get ())) {
163
- returnType = " native.Ptr[" + returnType + " ]" ;
164
- } else if (!shouldFieldBreakCycle (field).empty ()) {
165
- /* field type is changed to avoid cyclic types in generated code */
166
- methodBody = " (!" + methodBody + " ).cast[" +
167
- field->getType ()->str (locationManager) + " ]" ;
168
- } else {
156
+ if (!isArrayOrRecord (field->getType ())) {
169
157
methodBody = " !" + methodBody;
158
+ if (!shouldFieldBreakCycle (field).empty ()) {
159
+ /* field type is changed to avoid cyclic types in generated code */
160
+ methodBody = " (" + methodBody + " ).cast[" +
161
+ field->getType ()->str (locationManager) + " ]" ;
162
+ }
170
163
}
171
164
std::stringstream s;
172
165
s << " def " << getter << " : " << returnType << " = " << methodBody
@@ -182,7 +175,8 @@ std::string Struct::generateSetterForArrayRepresentation(
182
175
unsigned int fieldIndex, const LocationManager &locationManager) const {
183
176
std::shared_ptr<Field> field = fields[fieldIndex];
184
177
std::string setter = handleReservedWords (field->getName (), " _=" );
185
- std::string parameterType = field->getType ()->str (locationManager);
178
+ std::string parameterType =
179
+ wrapArrayOrRecordInPointer (field->getType ())->str (locationManager);
186
180
std::string value = " value" ;
187
181
std::string castedField = " p._1" ;
188
182
@@ -201,9 +195,7 @@ std::string Struct::generateSetterForArrayRepresentation(
201
195
std::shared_ptr<const Type> typeReplacement = getTypeReplacement (
202
196
field->getType (), structTypesThatShouldBeReplaced);
203
197
value = value + " .cast[" + typeReplacement->str (locationManager) + " ]" ;
204
- } else if (isAliasForType<ArrayType>(field->getType ().get ()) ||
205
- isAliasForType<Struct>(field->getType ().get ())) {
206
- parameterType = pointerToFieldType.str (locationManager);
198
+ } else if (isArrayOrRecord (field->getType ())) {
207
199
value = " !" + value;
208
200
}
209
201
std::stringstream s;
@@ -217,7 +209,8 @@ std::string Struct::generateGetterForArrayRepresentation(
217
209
unsigned fieldIndex, const LocationManager &locationManager) const {
218
210
std::shared_ptr<Field> field = fields[fieldIndex];
219
211
std::string getter = handleReservedWords (field->getName ());
220
- std::string returnType;
212
+ std::string returnType =
213
+ wrapArrayOrRecordInPointer (field->getType ())->str (locationManager);
221
214
std::string methodBody;
222
215
223
216
PointerType pointerToFieldType = PointerType (field->getType ());
@@ -230,17 +223,13 @@ std::string Struct::generateGetterForArrayRepresentation(
230
223
methodBody =
231
224
methodBody + " .cast[" + pointerToFieldType.str (locationManager) + " ]" ;
232
225
233
- if (isAliasForType<ArrayType>(field->getType ().get ()) ||
234
- isAliasForType<Struct>(field->getType ().get ())) {
235
- returnType = pointerToFieldType.str (locationManager);
236
- } else if (!shouldFieldBreakCycle (field).empty ()) {
237
- /* field type is changed to avoid cyclic types in generated code */
238
- methodBody = " (!" + methodBody + " ).cast[" +
239
- field->getType ()->str (locationManager) + " ]" ;
240
- returnType = field->getType ()->str (locationManager);
241
- } else {
226
+ if (!isArrayOrRecord (field->getType ())) {
242
227
methodBody = " !" + methodBody;
243
- returnType = field->getType ()->str (locationManager);
228
+ if (!shouldFieldBreakCycle (field).empty ()) {
229
+ /* field type is changed to avoid cyclic types in generated code */
230
+ methodBody = " (" + methodBody + " ).cast[" +
231
+ field->getType ()->str (locationManager) + " ]" ;
232
+ }
244
233
}
245
234
std::stringstream s;
246
235
s << " def " << getter << " : " << returnType << " = " << methodBody
@@ -352,3 +341,47 @@ bool Struct::hasBiggestName(const CycleNode &node,
352
341
}
353
342
return false ;
354
343
}
344
+
345
+ std::string
346
+ Struct::getConstructorHelper (const LocationManager &locationManager) const {
347
+ std::stringstream s;
348
+ std::string type = replaceChar (getTypeName (), " " , " _" );
349
+ s << " object " << type << " {\n "
350
+ << " import implicits._\n " ;
351
+
352
+ /* constructor with no parameters */
353
+ s << " def apply()(implicit z: native.Zone): native.Ptr[" + type + " ]"
354
+ << " = native.alloc[" + type + " ]\n " ;
355
+
356
+ /* constructor that initializes all fields */
357
+ s << " def apply(" ;
358
+ std::string sep = " " ;
359
+ for (const auto &field : fields) {
360
+ s << sep << handleReservedWords (field->getName ()) << " : "
361
+ << wrapArrayOrRecordInPointer (field->getType ())->str (locationManager);
362
+ sep = " , " ;
363
+ }
364
+ s << " )(implicit z: native.Zone): native.Ptr[" << type << " ] = {\n "
365
+ << " val ptr = native.alloc[" << type << " ]\n " ;
366
+ for (const auto &field : fields) {
367
+ std::string name = handleReservedWords (field->getName ());
368
+ s << " ptr." << name << " = " << name << " \n " ;
369
+ }
370
+ s << " ptr\n "
371
+ << " }\n "
372
+ << " }\n " ;
373
+ return s.str ();
374
+ }
375
+
376
+ bool Struct::isArrayOrRecord (std::shared_ptr<const Type> type) const {
377
+ return isAliasForType<ArrayType>(type.get ()) ||
378
+ isAliasForType<Struct>(type.get ());
379
+ }
380
+
381
+ std::shared_ptr<const Type>
382
+ Struct::wrapArrayOrRecordInPointer (std::shared_ptr<const Type> type) const {
383
+ if (isArrayOrRecord (type)) {
384
+ return std::make_shared<PointerType>(type);
385
+ }
386
+ return type;
387
+ }
0 commit comments