json-as 0.9.22 → 0.9.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,89 +1,119 @@
1
- import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, Expression, CommonFlags, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, DeclarationStatement, NamedTypeNode } from "assemblyscript/dist/assemblyscript.js";
1
+ import {
2
+ ClassDeclaration,
3
+ FieldDeclaration,
4
+ IdentifierExpression,
5
+ Parser,
6
+ Source,
7
+ NodeKind,
8
+ Expression,
9
+ CommonFlags,
10
+ StringLiteralExpression,
11
+ IntegerLiteralExpression,
12
+ FloatLiteralExpression,
13
+ NullExpression,
14
+ TrueExpression,
15
+ FalseExpression,
16
+ } from "assemblyscript/dist/assemblyscript.js";
2
17
 
3
18
  import { toString, isStdlib } from "visitor-as/dist/utils.js";
4
19
  import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
5
20
  import { Transform } from "assemblyscript/dist/transform.js";
6
- import chalk from "chalk";
7
-
8
- const json_types = ["Array", "string", "String", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean", "Map", "Date"];
9
21
 
10
22
  class JSONTransform extends BaseVisitor {
11
- public types = json_types;
12
23
  public schemasList: SchemaData[] = [];
13
24
  public currentClass!: SchemaData;
14
25
  public sources = new Set<Source>();
15
26
 
16
- appendParentFields(node: ClassDeclaration, schema: SchemaData, members: DeclarationStatement[]): void {
27
+ visitMethodDeclaration(): void { }
28
+ visitClassDeclaration(node: ClassDeclaration): void {
29
+ if (!node.decorators?.length) return;
30
+
31
+ let found = false;
32
+ for (const decorator of node.decorators) {
33
+ const name = (<IdentifierExpression>decorator.name).text;
34
+ if (name === "json" || name === "serializable") {
35
+ found = true;
36
+ break;
37
+ }
38
+ }
39
+ if (!found) return;
40
+
41
+ const schema = new SchemaData();
42
+ schema.node = node;
43
+ schema.name = node.name.text;
44
+
45
+ const members = [
46
+ ...node.members.filter((v) => v.kind === NodeKind.FieldDeclaration),
47
+ ];
48
+
17
49
  if (node.extendsType) {
50
+ schema.parent = this.schemasList.find(
51
+ (v) => v.name == node.extendsType?.name.identifier.text,
52
+ ) as SchemaData | null;
53
+
18
54
  if (schema.parent?.members) {
19
55
  for (let i = schema.parent.members.length - 1; i >= 0; i--) {
20
- const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
56
+ const replace = schema.members.find(
57
+ (v) => v.name == schema.parent?.members[i]?.name,
58
+ );
21
59
  if (!replace) {
22
60
  members.unshift(schema.parent?.members[i]!.node);
23
61
  }
24
62
  }
25
- this.appendParentFields(schema.parent.node, schema, members);
26
63
  }
27
64
  }
28
- }
29
-
30
- handleEmptyClass(node: ClassDeclaration, schema: SchemaData, members: DeclarationStatement[]): void {
31
- let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}';
32
- let SERIALIZE_PRETTY_EMPTY = '__SERIALIZE_PRETTY(): string {\n return "{}";\n}';
33
-
34
- let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
35
-
36
- let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
37
-
38
- if (process.env["JSON_DEBUG"]) {
39
- console.log(SERIALIZE_RAW_EMPTY);
40
- console.log(SERIALIZE_PRETTY_EMPTY);
41
- console.log(INITIALIZE_EMPTY);
42
- console.log(DESERIALIZE_EMPTY);
43
- }
44
-
45
- const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
46
- const SERIALIZE_PRETTY_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_PRETTY_EMPTY, node);
47
- const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
48
- const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
49
-
50
- if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
51
- if (!node.members.find((v) => v.name.text == "__SERIALIZE_PRETTY")) node.members.push(SERIALIZE_PRETTY_METHOD_EMPTY);
52
- if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD_EMPTY);
53
- if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD_EMPTY);
54
- }
55
- filterMembers(members: DeclarationStatement[]): FieldDeclaration[] {
56
- return members.filter((v) => v instanceof FieldDeclaration && !v.decorators?.find((v) => (<IdentifierExpression>v.name).text == "omit")) as FieldDeclaration[];
57
- }
58
- visitClassDeclaration(node: ClassDeclaration): void {
59
- if (!node.decorators?.length) return;
60
- if (!node.decorators.find((v) => (<IdentifierExpression>v.name).text == "json" || (<IdentifierExpression>v.name).text == "serializable")) return;
61
- this.types = json_types;
62
-
63
- const schema = new SchemaData();
64
- schema.node = node;
65
- schema.name = node.name.text;
66
65
 
67
- if (node.extendsType) {
68
- schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text) as SchemaData | null;
69
- }
66
+ if (!members.length) {
67
+ let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}';
68
+ //let SERIALIZE_PRETTY_EMPTY = "__SERIALIZE_PRETTY(): string {\n return \"{}\";\n}";
70
69
 
71
- const _members = [...node.members];
70
+ let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
72
71
 
73
- this.appendParentFields(node, schema, _members);
72
+ let DESERIALIZE_EMPTY =
73
+ "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
74
74
 
75
- const members = this.filterMembers(_members);
75
+ if (process.env["JSON_DEBUG"]) {
76
+ console.log(SERIALIZE_RAW_EMPTY);
77
+ //console.log(SERIALIZE_PRETTY_EMPTY);
78
+ console.log(INITIALIZE_EMPTY);
79
+ console.log(DESERIALIZE_EMPTY);
80
+ }
76
81
 
77
- if (!members.length) {
78
- this.handleEmptyClass(node, schema, members);
82
+ const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(
83
+ SERIALIZE_RAW_EMPTY,
84
+ node,
85
+ );
86
+ //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
87
+ const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(
88
+ INITIALIZE_EMPTY,
89
+ node,
90
+ );
91
+ const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(
92
+ DESERIALIZE_EMPTY,
93
+ node,
94
+ );
95
+
96
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
97
+ node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
98
+ if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
99
+ node.members.push(INITIALIZE_METHOD_EMPTY);
100
+ if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
101
+ node.members.push(DESERIALIZE_METHOD_EMPTY);
102
+
103
+ this.schemasList.push(schema);
79
104
  }
80
105
 
81
106
  for (const member of members) {
82
107
  const name = member.name;
108
+ if (!(member instanceof FieldDeclaration)) continue;
83
109
  if (!member.type) {
84
- throw new Error("Fields must be strongly typed! Found " + toString(member) + " at " + node.range.source.normalizedPath);
110
+ throw new Error(
111
+ "Fields must be strongly typed! Found " +
112
+ toString(member) +
113
+ " at " +
114
+ node.range.source.normalizedPath,
115
+ );
85
116
  }
86
-
87
117
  const type = toString(member.type!);
88
118
  if (type.startsWith("(") && type.includes("=>")) continue;
89
119
  const value = member.initializer ? toString(member.initializer!) : null;
@@ -114,7 +144,11 @@ class JSONTransform extends BaseVisitor {
114
144
 
115
145
  switch (decoratorName) {
116
146
  case "alias": {
117
- if (!args.length) throw new Error("Expected 1 argument but got zero at @alias in " + node.range.source.normalizedPath);
147
+ if (!args.length)
148
+ throw new Error(
149
+ "Expected 1 argument but got zero at @alias in " +
150
+ node.range.source.normalizedPath,
151
+ );
118
152
  mem.alias = args[0]!;
119
153
  mem.flags.set(PropertyFlags.Alias, args);
120
154
  break;
@@ -124,7 +158,11 @@ class JSONTransform extends BaseVisitor {
124
158
  break;
125
159
  }
126
160
  case "omitif": {
127
- if (!decorator.args?.length) throw new Error("Expected 1 argument but got zero at @omitif in " + node.range.source.normalizedPath);
161
+ if (!decorator.args?.length)
162
+ throw new Error(
163
+ "Expected 1 argument but got zero at @omitif in " +
164
+ node.range.source.normalizedPath,
165
+ );
128
166
  mem.flags.set(PropertyFlags.OmitIf, args);
129
167
  break;
130
168
  }
@@ -136,10 +174,23 @@ class JSONTransform extends BaseVisitor {
136
174
  }
137
175
  }
138
176
 
139
- if (!mem.flags.get(PropertyFlags.Omit)) mem.generate();
177
+ mem.generate();
140
178
 
141
179
  if (this.schemasList.find((v) => v.name == type)) {
142
- mem.initialize = "this." + name.text + " = changetype<nonnull<" + mem.type + ">>(__new(offsetof<nonnull<" + mem.type + ">>(), idof<nonnull<" + mem.type + ">>()));\n changetype<nonnull<" + mem.type + ">>(this." + name.text + ").__INITIALIZE()";
180
+ mem.initialize =
181
+ "this." +
182
+ name.text +
183
+ " = changetype<nonnull<" +
184
+ mem.type +
185
+ ">>(__new(offsetof<nonnull<" +
186
+ mem.type +
187
+ ">>(), idof<nonnull<" +
188
+ mem.type +
189
+ ">>()));\n changetype<nonnull<" +
190
+ mem.type +
191
+ ">>(this." +
192
+ name.text +
193
+ ").__INITIALIZE()";
143
194
  } else if (mem.value) {
144
195
  mem.initialize = "this." + name.text + " = " + mem.value;
145
196
  } else if (type === "Map") {
@@ -147,12 +198,22 @@ class JSONTransform extends BaseVisitor {
147
198
  } else if (type === "string") {
148
199
  mem.initialize = "this." + name.text + ' = ""';
149
200
  } else if (type === "Array") {
150
- mem.initialize = "this." + name.text + " = instantiate<" + mem.type + ">()";
201
+ mem.initialize =
202
+ "this." + name.text + " = instantiate<" + mem.type + ">()";
151
203
  } else if (type === "bool" || type === "boolean") {
152
204
  mem.initialize = "this." + name.text + " = false";
153
205
  } else if (type === "JSON.Raw") {
154
206
  mem.initialize = "this." + name.text + ' = ""';
155
- } else if (type === "u8" || type === "u16" || type === "u32" || type === "u64" || type === "i8" || type === "i16" || type === "i32" || type === "i64") {
207
+ } else if (
208
+ type === "u8" ||
209
+ type === "u16" ||
210
+ type === "u32" ||
211
+ type === "u64" ||
212
+ type === "i8" ||
213
+ type === "i16" ||
214
+ type === "i32" ||
215
+ type === "i64"
216
+ ) {
156
217
  mem.initialize = "this." + name.text + " = 0";
157
218
  } else if (type === "f32" || type === "f64") {
158
219
  mem.initialize = "this." + name.text + " = 0.0";
@@ -166,41 +227,50 @@ class JSONTransform extends BaseVisitor {
166
227
 
167
228
  let INITIALIZE = "__INITIALIZE(): this {\n";
168
229
 
169
- let DESERIALIZE = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n";
230
+ let DESERIALIZE =
231
+ "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n";
170
232
  let indent = " ";
171
233
 
172
234
  if (!schema.members.length) return;
173
235
 
174
- let found = false;
236
+ found = false;
175
237
 
176
- if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) || schema.members[0]?.flags.has(PropertyFlags.OmitIf)) {
238
+ if (
239
+ schema.members[0]?.flags.has(PropertyFlags.OmitNull) ||
240
+ schema.members[0]?.flags.has(PropertyFlags.OmitIf)
241
+ ) {
177
242
  SERIALIZE_RAW += schema.members[0]?.serialize;
178
- SERIALIZE_PRETTY += "\\n" + indent + schema.members[0]?.serialize_pretty;
243
+ SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
179
244
  } else {
180
245
  SERIALIZE_RAW += schema.members[0]?.serialize + ",";
181
- SERIALIZE_PRETTY += "\\n" + indent + schema.members[0]?.serialize_pretty + ",\\n";
246
+ SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n";
182
247
  found = true;
183
248
  }
184
249
 
185
- if (schema.members[0]?.initialize) INITIALIZE += " " + schema.members[0]?.initialize + ";\n";
250
+ if (schema.members[0]?.initialize)
251
+ INITIALIZE += " " + schema.members[0]?.initialize + ";\n";
186
252
 
187
253
  for (let i = 1; i < schema.members.length; i++) {
188
254
  const member = schema.members[i]!;
189
255
  if (member.initialize) INITIALIZE += " " + member.initialize + ";\n";
190
- if (member.flags.has(PropertyFlags.Omit)) continue;
191
- if (member.flags.has(PropertyFlags.OmitNull) || member.flags.has(PropertyFlags.OmitIf)) {
256
+ if (
257
+ member.flags.has(PropertyFlags.OmitNull) ||
258
+ member.flags.has(PropertyFlags.OmitIf)
259
+ ) {
192
260
  SERIALIZE_RAW += member.serialize;
193
- SERIALIZE_PRETTY += member.serialize_pretty;
261
+ SERIALIZE_PRETTY += member.serialize;
194
262
  } else {
195
263
  SERIALIZE_RAW += member.serialize + ",";
196
- SERIALIZE_PRETTY += indent + member.serialize_pretty + ",\\n";
264
+ SERIALIZE_PRETTY += indent + member.serialize + ",\\n";
197
265
  found = true;
198
266
  }
199
267
  }
200
268
 
201
269
  if (found) {
202
- SERIALIZE_RAW += "`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
203
- SERIALIZE_PRETTY += "`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
270
+ SERIALIZE_RAW +=
271
+ "`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
272
+ SERIALIZE_PRETTY +=
273
+ "`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
204
274
  } else {
205
275
  SERIALIZE_RAW += "}`;\n return out;\n}";
206
276
  SERIALIZE_PRETTY += "}`;\n return out;\n}";
@@ -209,7 +279,9 @@ class JSONTransform extends BaseVisitor {
209
279
  INITIALIZE += " return this;\n}";
210
280
 
211
281
  const sortedMembers: Property[][] = [];
212
- const _sorted = schema.members.sort((a, b) => (a.alias?.length! || a.name.length) - (b.alias?.length! || b.name.length));
282
+ const _sorted = schema.members.sort(
283
+ (a, b) => (a.alias?.length! || a.name.length) - (b.alias?.length! || b.name.length),
284
+ );
213
285
  let len = -1;
214
286
  let offset = -1;
215
287
  for (let i = 0; i < _sorted.length; i++) {
@@ -230,24 +302,30 @@ class JSONTransform extends BaseVisitor {
230
302
  const _name = encodeKey(firstMember.alias || firstMember.name);
231
303
  if (_name.length === 1) {
232
304
  if (first) {
233
- DESERIALIZE += " if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
305
+ DESERIALIZE +=
306
+ " if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
234
307
  first = false;
235
308
  } else {
236
- DESERIALIZE += "else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
309
+ DESERIALIZE +=
310
+ "else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
237
311
  }
238
312
  } else if (_name.length === 2) {
239
313
  if (first) {
240
- DESERIALIZE += " if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
314
+ DESERIALIZE +=
315
+ " if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
241
316
  first = false;
242
317
  } else {
243
- DESERIALIZE += "else if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
318
+ DESERIALIZE +=
319
+ "else if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
244
320
  }
245
321
  } else if (_name.length === 4) {
246
322
  if (first) {
247
- DESERIALIZE += " if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
323
+ DESERIALIZE +=
324
+ " if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
248
325
  first = false;
249
326
  } else {
250
- DESERIALIZE += "else if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
327
+ DESERIALIZE +=
328
+ "else if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
251
329
  }
252
330
  } else {
253
331
  if (first) {
@@ -271,23 +349,31 @@ class JSONTransform extends BaseVisitor {
271
349
  f = false;
272
350
  DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
273
351
  } else {
274
- DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
352
+ DESERIALIZE =
353
+ DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
354
+ `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
275
355
  }
276
356
  } else {
277
357
  if (f) {
278
358
  f = false;
279
359
  DESERIALIZE += ` if (0 === memory.compare(changetype<usize>("${escapeQuote(escapeSlash(_name))}"), changetype<usize>(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
280
360
  } else {
281
- DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else if (0 === memory.compare(changetype<usize>("${escapeQuote(escapeSlash(_name))}"), changetype<usize>(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
361
+ DESERIALIZE =
362
+ DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
363
+ ` else if (0 === memory.compare(changetype<usize>("${escapeQuote(escapeSlash(_name))}"), changetype<usize>(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
282
364
  }
283
365
  }
284
366
  }
285
367
  if (_name.length < 3) {
286
368
  DESERIALIZE += ` default: {\n return false;\n }\n }\n`;
287
369
  } else if (_name.length == 4) {
288
- DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
370
+ DESERIALIZE =
371
+ DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
372
+ ` else {\n return false;\n }\n`;
289
373
  } else {
290
- DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
374
+ DESERIALIZE =
375
+ DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
376
+ ` else {\n return false;\n }\n`;
291
377
  }
292
378
  DESERIALIZE += " } ";
293
379
  }
@@ -298,20 +384,25 @@ class JSONTransform extends BaseVisitor {
298
384
 
299
385
  if (process.env["JSON_DEBUG"]) {
300
386
  console.log(SERIALIZE_RAW);
301
- console.log(SERIALIZE_PRETTY);
387
+ //console.log(SERIALIZE_PRETTY);
302
388
  console.log(INITIALIZE);
303
389
  console.log(DESERIALIZE);
304
390
  }
305
391
 
306
- const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node);
307
- const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
392
+ const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(
393
+ SERIALIZE_RAW,
394
+ node,
395
+ );
396
+ //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
308
397
  const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
309
398
  const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
310
399
 
311
- if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_METHOD);
312
- if (!node.members.find((v) => v.name.text == "__SERIALIZE_PRETTY")) node.members.push(SERIALIZE_PRETTY_METHOD);
313
- if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD);
314
- if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD);
400
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
401
+ node.members.push(SERIALIZE_RAW_METHOD);
402
+ if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
403
+ node.members.push(INITIALIZE_METHOD);
404
+ if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
405
+ node.members.push(DESERIALIZE_METHOD);
315
406
 
316
407
  this.schemasList.push(schema);
317
408
  }
@@ -337,13 +428,13 @@ export default class Transformer extends Transform {
337
428
  .sort((_a, _b) => {
338
429
  const a = _a.internalPath;
339
430
  const b = _b.internalPath;
340
- if (a[0] !== "~" && b[0] === "~") {
341
- return 1;
342
- }
343
431
  if (a[0] === "~" && b[0] !== "~") {
344
432
  return -1;
433
+ } else if (a[0] !== "~" && b[0] === "~") {
434
+ return 1;
435
+ } else {
436
+ return 0;
345
437
  }
346
- return 0;
347
438
  });
348
439
 
349
440
  // Loop over every source
@@ -356,85 +447,17 @@ export default class Transformer extends Transform {
356
447
  // Check that every parent and child class is hooked up correctly
357
448
  const schemas = transformer.schemasList;
358
449
  for (const schema of schemas) {
359
- checkInheritance(schema, schemas);
360
- const invalidType = checkTypeCorrectness(schema, schemas);
361
- if (invalidType) {
362
- logError(`Type ${invalidType.type} implemented in property ${invalidType.path} is not a JSON-compatible type!\nEither decorate it with @omit or fix it!`);
450
+ if (schema.parent) {
451
+ const parent = schemas.find((v) => v.name === schema.parent?.name);
452
+ if (!parent)
453
+ throw new Error(
454
+ `Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator! Add the decorator and rebuild.`,
455
+ );
363
456
  }
364
457
  }
365
458
  }
366
459
  }
367
460
 
368
- function checkInheritance(schema: SchemaData, schemas: SchemaData[]): void {
369
- if (!schema.parent && schema.node.extendsType) {
370
- if (schemas.find(v => v.node.name.text === schema.node.extendsType?.name.identifier.text!)) return;
371
- const extending = toString(schema.node.extendsType);
372
- logError(`Schema ${schema.name} extends ${extending}, but ${extending} does not include the @json decorator!`);
373
- }
374
- }
375
-
376
- function checkTypeCorrectness(
377
- schema: SchemaData,
378
- schemas: SchemaData[]
379
- ): {
380
- type: string;
381
- path: string;
382
- } | null {
383
- const parent = schemas.find((v) => v.name === schema.parent?.name);
384
- const generic_types = [...(schema?.node.typeParameters?.map<string>((v) => v.name.text) || []), ...(parent?.node.typeParameters?.map<string>((v) => v.name.text) || [])];
385
- const member_types = [...(schema.members.map((v) => (<NamedTypeNode>v.node.type).name.identifier.text) || [])];
386
- const scopeTypes = new Set<string>([...json_types, ...generic_types, ...member_types]);
387
-
388
- for (const typ of member_types) {
389
- if (typ === "JSON") continue; // JSON.Raw, JSON.Box, JSON.Any, ect...
390
- if (json_types.includes(typ)) continue;
391
- if (generic_types.includes(typ)) continue;
392
- const check = schemas.find((v) => v.name == typ);
393
- if (!check) logError(`Type ${typ} is not a JSON compatible type or does not include the @json flag!`);
394
- }
395
-
396
- for (const member of schema.members) {
397
- const invalidType = checkType(schema, schemas, member.node.type as NamedTypeNode, member, scopeTypes, schema.name);
398
- if (invalidType) logError(`Type ${invalidType.type} in ${invalidType.path} does not implement a JSON compatible type!\n${chalk.dim(` at ${member.node.range.source.normalizedPath.replace("~lib/", "./node_modules/")}`)}`);
399
- }
400
-
401
- return null;
402
- }
403
-
404
- function checkType(
405
- schema: SchemaData,
406
- schemas: SchemaData[],
407
- typ: NamedTypeNode,
408
- member: Property,
409
- scopeTypes: Set<string>,
410
- path: string,
411
- ): {
412
- type: string;
413
- path: string;
414
- } | null {
415
- path += "." + member.name;
416
- if (schemas.find(v => v.node.name.text === typ.name.identifier.text)) scopeTypes.add(typ.name.identifier.text);
417
- if (!scopeTypes.has(typ.name.identifier.text)) return { type: toString(typ), path };
418
-
419
- if (typ.isNullable && isPrimitive(typ)) return { type: toString(typ), path };
420
-
421
- if (typ.typeArguments?.length && typ.typeArguments?.length > 0) {
422
- for (const ty of typ.typeArguments.filter((v) => v instanceof NamedTypeNode)) {
423
- const check = checkType(schema, schemas, ty, member, scopeTypes, path);
424
- if (check) return { type: toString(typ), path };
425
- }
426
- } else {
427
- if (scopeTypes.has(typ.name.identifier.text)) return null;
428
- }
429
-
430
- return null;
431
- }
432
-
433
- function logError(message: string): never {
434
- console.log("\n" + chalk.bold.bgRed(" Error ") + chalk.dim(":") + " " + message + "\n");
435
- process.exit(1);
436
- }
437
-
438
461
  enum PropertyFlags {
439
462
  Null,
440
463
  Omit,
@@ -449,10 +472,12 @@ class Property {
449
472
  public alias: string | null = null;
450
473
  public type: string = "";
451
474
  public value: string | null = null;
452
- public flags: Map<PropertyFlags, string[]> = new Map<PropertyFlags, string[]>();
475
+ public flags: Map<PropertyFlags, string[]> = new Map<
476
+ PropertyFlags,
477
+ string[]
478
+ >();
453
479
 
454
480
  public serialize: string | null = null;
455
- public serialize_pretty: string | null = null;
456
481
  public deserialize: string | null = null;
457
482
  public initialize: string | null = null;
458
483
 
@@ -469,7 +494,7 @@ class Property {
469
494
 
470
495
  if (this.flags.has(PropertyFlags.JSON_Raw)) {
471
496
  if (this.flags.has(PropertyFlags.Null)) {
472
- this.right_s = "(this." + name + ' || "null")';
497
+ this.right_s = "(this." + name + " || \"null\")";
473
498
  this.right_d = "value_start === value_end - 4 && 30399761348886638 === load<u64>(changetype<usize>(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)";
474
499
  } else {
475
500
  this.right_s = "this." + name;
@@ -477,22 +502,38 @@ class Property {
477
502
  }
478
503
  } else {
479
504
  this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")";
480
- this.right_d = "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end))";
505
+ this.right_d =
506
+ "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end))";
481
507
  }
482
508
 
483
509
  if (this.flags.has(PropertyFlags.OmitIf)) {
484
510
  const condition = this.flags.get(PropertyFlags.OmitIf)![0];
485
- if (!condition) throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition");
486
- this.serialize = "${" + condition + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}';
487
- this.serialize_pretty = "${" + condition + ' ? "" : \'' + escapedName + ": ' + " + this.right_s + ' + ","}';
511
+ if (!condition)
512
+ throw new Error(
513
+ "Could not find condition when using decorator @omitif! Provide at least one condition",
514
+ );
515
+ this.serialize =
516
+ "${" +
517
+ condition +
518
+ ' ? "" : \'' +
519
+ escapedName +
520
+ ":' + " +
521
+ this.right_s +
522
+ ' + ","}';
488
523
  this.deserialize = "this." + name + " = " + this.right_d + ";";
489
524
  } else if (this.flags.has(PropertyFlags.OmitNull)) {
490
- this.serialize = "${changetype<usize>(this." + name + ") == <usize>0" + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}';
491
- this.serialize_pretty = "${changetype<usize>(this." + name + ") == <usize>0" + ' ? "" : \'' + escapedName + ": ' + " + this.right_s + ' + ","}';
525
+ this.serialize =
526
+ "${changetype<usize>(this." +
527
+ name +
528
+ ") == <usize>0" +
529
+ ' ? "" : \'' +
530
+ escapedName +
531
+ ":' + " +
532
+ this.right_s +
533
+ ' + ","}';
492
534
  this.deserialize = "this." + name + " = " + this.right_d + ";";
493
535
  } else {
494
536
  this.serialize = escapedName + ":${" + this.right_s + "}";
495
- this.serialize_pretty = escapedName + ": ${" + this.right_s + "}";
496
537
  this.deserialize = "this." + name + " = " + this.right_d + ";";
497
538
  }
498
539
  }
@@ -511,7 +552,9 @@ function charCodeAt32(data: string, offset: number): number {
511
552
 
512
553
  function charCodeAt64(data: string, offset: number): bigint {
513
554
  if (offset + 3 >= data.length) {
514
- throw new Error("The string must have at least 4 characters from the specified offset.");
555
+ throw new Error(
556
+ "The string must have at least 4 characters from the specified offset.",
557
+ );
515
558
  }
516
559
 
517
560
  const firstCharCode = BigInt(data.charCodeAt(offset));
@@ -519,7 +562,11 @@ function charCodeAt64(data: string, offset: number): bigint {
519
562
  const thirdCharCode = BigInt(data.charCodeAt(offset + 2));
520
563
  const fourthCharCode = BigInt(data.charCodeAt(offset + 3));
521
564
 
522
- const u64Value = (fourthCharCode << 48n) | (thirdCharCode << 32n) | (secondCharCode << 16n) | firstCharCode;
565
+ const u64Value =
566
+ (fourthCharCode << 48n) |
567
+ (thirdCharCode << 32n) |
568
+ (secondCharCode << 16n) |
569
+ firstCharCode;
523
570
 
524
571
  return u64Value;
525
572
  }
@@ -563,9 +610,3 @@ function getArgs(args: Expression[] | null): string[] {
563
610
  }
564
611
  return out;
565
612
  }
566
-
567
- function isPrimitive(type: NamedTypeNode): boolean {
568
- const primitives = new Set(["u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean"]);
569
-
570
- return primitives.has(type.name.identifier.text);
571
- }