json-as 1.1.9 → 1.1.11

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,15 +1,28 @@
1
1
  import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, CommonFlags, ImportStatement, Node, Tokenizer, SourceKind, NamedTypeNode, Range, FEATURE_SIMD, FunctionExpression, MethodDeclaration, Statement, Program, Feature, CallExpression, PropertyAccessExpression } from "assemblyscript/dist/assemblyscript.js";
2
2
  import { Transform } from "assemblyscript/dist/transform.js";
3
3
  import { Visitor } from "./visitor.js";
4
- import { cloneNode, isStdlib, replaceRef, SimpleParser, toString } from "./util.js";
4
+ import { cloneNode, isStdlib, removeExtension, replaceRef, SimpleParser, toString } from "./util.js";
5
5
  import * as path from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { Property, PropertyFlags, Schema } from "./types.js";
8
- import { getClasses, getImportedClass } from "./linker.js";
8
+ import { getClass, getClasses, getImportedClass } from "./linker.js";
9
+ import { existsSync, writeFileSync } from "fs";
9
10
 
10
11
  let indent = " ";
11
12
 
12
- const DEBUG = process.env["JSON_DEBUG"];
13
+ let id = 0;
14
+
15
+ const WRITE = process.env["JSON_WRITE"];
16
+ const rawValue = process.env["JSON_DEBUG"];
17
+
18
+ const DEBUG = rawValue === "true"
19
+ ? 1
20
+ : rawValue === "false" || rawValue === ""
21
+ ? 0
22
+ : isNaN(Number(rawValue))
23
+ ? 0
24
+ : Number(rawValue);
25
+
13
26
  const STRICT = process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "true";
14
27
 
15
28
  class CustomTransform extends Visitor {
@@ -47,9 +60,9 @@ class JSONTransform extends Visitor {
47
60
  static SN: JSONTransform = new JSONTransform();
48
61
 
49
62
  public program!: Program;
50
- public baseDir!: string;
63
+ public baseCWD!: string;
51
64
  public parser!: Parser;
52
- public schemas: Schema[] = [];
65
+ public schemas: Map<string, Schema[]> = new Map<string, Schema[]>();
53
66
  public schema!: Schema;
54
67
  public sources = new Set<Source>();
55
68
  public imports: ImportStatement[] = [];
@@ -57,6 +70,18 @@ class JSONTransform extends Visitor {
57
70
  public topStatements: Statement[] = [];
58
71
  public simdStatements: string[] = [];
59
72
 
73
+ private visitedClasses: Set<string> = new Set<string>();
74
+
75
+ visitClassDeclarationRef(node: ClassDeclaration): void {
76
+ if (
77
+ !node.decorators?.length ||
78
+ !node.decorators.some((decorator) => {
79
+ const name = (<IdentifierExpression>decorator.name).text;
80
+ return name === "json" || name === "serializable";
81
+ })
82
+ ) throw new Error("Class " + node.name.text + " is missing an @json or @serializable decorator in " + node.range.source.internalPath);
83
+ this.visitClassDeclaration(node);
84
+ }
60
85
  visitClassDeclaration(node: ClassDeclaration): void {
61
86
  if (!node.decorators?.length) return;
62
87
 
@@ -68,11 +93,131 @@ class JSONTransform extends Visitor {
68
93
  )
69
94
  return;
70
95
 
71
- this.schema = new Schema();
72
- this.schema.node = node;
73
- this.schema.name = node.name.text;
96
+ if (this.visitedClasses.has(node.range.source.internalPath + node.name.text)) return;
97
+ if (!this.schemas.has(node.range.source.internalPath)) this.schemas.set(node.range.source.internalPath, []);
74
98
 
75
- this.schemas.push(this.schema);
99
+ const members: FieldDeclaration[] = [...(node.members.filter((v) => v.kind === NodeKind.FieldDeclaration && v.flags !== CommonFlags.Static && v.flags !== CommonFlags.Private && v.flags !== CommonFlags.Protected && !v.decorators?.some((decorator) => (<IdentifierExpression>decorator.name).text === "omit")) as FieldDeclaration[])];
100
+ const serializers: MethodDeclaration[] = [...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "serializer"))] as MethodDeclaration[];
101
+ const deserializers: MethodDeclaration[] = [...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "deserializer"))] as MethodDeclaration[];
102
+
103
+ const schema = new Schema();
104
+ schema.node = node;
105
+ schema.name = node.name.text;
106
+
107
+ if (node.extendsType) {
108
+ const extendsName = node.extendsType?.name.identifier.text;
109
+ if (!schema.parent) {
110
+ const depSearch = schema.deps.find((v) => v.name == extendsName);
111
+ if (depSearch) {
112
+ if (DEBUG > 0) console.log("Found " + extendsName + " in dependencies of " + node.range.source.internalPath);
113
+ if (!schema.deps.some(v => v.name == depSearch.name)) schema.deps.push(depSearch);
114
+ schema.parent = depSearch;
115
+ } else {
116
+ const internalSearch = getClass(extendsName, node.range.source);
117
+ if (internalSearch) {
118
+ if (DEBUG > 0) console.log("Found " + extendsName + " internally from " + node.range.source.internalPath);
119
+ if (!this.visitedClasses.has(internalSearch.range.source.internalPath + internalSearch.name.text)) {
120
+ this.visitClassDeclarationRef(internalSearch);
121
+ this.schemas.get(internalSearch.range.source.internalPath).push(this.schema);
122
+ this.visitClassDeclaration(node);
123
+ return;
124
+ }
125
+ const schem = this.schemas.get(internalSearch.range.source.internalPath)?.find(s => s.name == internalSearch.name.text);
126
+ if (!schem) throw new Error("Could not find schema for " + internalSearch.name.text + " in " + internalSearch.range.source.internalPath);
127
+ schema.deps.push(schem);
128
+ schema.parent = schem;
129
+ } else {
130
+ const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
131
+ if (externalSearch) {
132
+ if (DEBUG > 0) console.log("Found " + externalSearch.name.text + " externally from " + node.range.source.internalPath);
133
+ if (!this.visitedClasses.has(externalSearch.range.source.internalPath + externalSearch.name.text)) {
134
+ this.visitClassDeclarationRef(externalSearch);
135
+ this.schemas.get(externalSearch.range.source.internalPath).push(this.schema);
136
+ this.visitClassDeclaration(node);
137
+ return;
138
+ }
139
+ const schem = this.schemas.get(externalSearch.range.source.internalPath)?.find(s => s.name == externalSearch.name.text);
140
+ if (!schem) throw new Error("Could not find schema for " + externalSearch.name.text + " in " + externalSearch.range.source.internalPath);
141
+ schema.deps.push(schem);
142
+ schema.parent = schem;
143
+ }
144
+ }
145
+ }
146
+ }
147
+ if (schema.parent?.members) {
148
+ for (let i = schema.parent.members.length - 1; i >= 0; i--) {
149
+ const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
150
+ if (!replace) {
151
+ members.unshift(schema.parent?.members[i]!.node);
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ const getUnknownTypes = (type: string, types: string[] = []): string[] => {
158
+ type = stripNull(type);
159
+ if (type.startsWith("Array<")) {
160
+ return getUnknownTypes(type.slice(6, -1));
161
+ } else if (type.startsWith("Map<")) {
162
+ const parts = type.slice(4, -1).split(",");
163
+ return getUnknownTypes(parts[0]) || getUnknownTypes(parts[1]);
164
+ } else if (isString(type) || isPrimitive(type)) {
165
+ return types;
166
+ } else if (["JSON.Box", "JSON.Obj", "JSON.Value", "JSON.Raw"].includes(type)) {
167
+ return types;
168
+ } else if (node.isGeneric && node.typeParameters.some((p) => p.name.text == type)) {
169
+ return types;
170
+ } else if (type == node.name.text) {
171
+ return types;
172
+ }
173
+ types.push(type);
174
+ return types;
175
+ }
176
+
177
+ for (const member of members) {
178
+ const type = toString(member.type);
179
+ const unknown = getUnknownTypes(type);
180
+
181
+ for (const unknownType of unknown) {
182
+ const depSearch = schema.deps.find((v) => v.name == unknownType);
183
+ if (depSearch) {
184
+ if (DEBUG > 0) console.log("Found " + unknownType + " in dependencies of " + node.range.source.internalPath);
185
+ if (!schema.deps.some(v => v.name == depSearch.name)) schema.deps.push(depSearch);
186
+ } else {
187
+ const internalSearch = getClass(unknownType, node.range.source);
188
+ if (internalSearch) {
189
+ if (DEBUG > 0) console.log("Found " + unknownType + " internally from " + node.range.source.internalPath);
190
+ if (!this.visitedClasses.has(internalSearch.range.source.internalPath + internalSearch.name.text)) {
191
+ this.visitClassDeclarationRef(internalSearch);
192
+ this.schemas.get(internalSearch.range.source.internalPath).push(this.schema);
193
+ this.visitClassDeclaration(node);
194
+ return;
195
+ }
196
+ const schem = this.schemas.get(internalSearch.range.source.internalPath)?.find(s => s.name == internalSearch.name.text);
197
+ if (!schem) throw new Error("Could not find schema for " + internalSearch.name.text + " in " + internalSearch.range.source.internalPath);
198
+ schema.deps.push(schem);
199
+ } else {
200
+ const externalSearch = getImportedClass(unknownType, node.range.source, this.parser);
201
+ if (externalSearch) {
202
+ if (DEBUG > 0) console.log("Found " + externalSearch.name.text + " externally from " + node.range.source.internalPath);
203
+ if (!this.visitedClasses.has(externalSearch.range.source.internalPath + externalSearch.name.text)) {
204
+ this.visitClassDeclarationRef(externalSearch);
205
+ this.schemas.get(externalSearch.range.source.internalPath).push(this.schema);
206
+ this.visitClassDeclaration(node);
207
+ return;
208
+ }
209
+ const schem = this.schemas.get(externalSearch.range.source.internalPath)?.find(s => s.name == externalSearch.name.text);
210
+ if (!schem) throw new Error("Could not find schema for " + externalSearch.name.text + " in " + externalSearch.range.source.internalPath);
211
+ schema.deps.push(schem);
212
+ }
213
+ }
214
+ }
215
+ }
216
+ }
217
+
218
+ this.schemas.get(node.range.source.internalPath).push(schema);
219
+ this.schema = schema;
220
+ this.visitedClasses.add(node.range.source.internalPath + node.name.text);
76
221
 
77
222
  let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
78
223
  let INITIALIZE = "@inline __INITIALIZE(): this {\n";
@@ -80,11 +225,7 @@ class JSONTransform extends Visitor {
80
225
  let DESERIALIZE_CUSTOM = "";
81
226
  let SERIALIZE_CUSTOM = "";
82
227
 
83
- if (DEBUG) console.log("Created schema: " + this.schema.name + " in file " + node.range.source.normalizedPath);
84
-
85
- const members: FieldDeclaration[] = [...(node.members.filter((v) => v.kind === NodeKind.FieldDeclaration && v.flags !== CommonFlags.Static && v.flags !== CommonFlags.Private && v.flags !== CommonFlags.Protected && !v.decorators?.some((decorator) => (<IdentifierExpression>decorator.name).text === "omit")) as FieldDeclaration[])];
86
- const serializers: MethodDeclaration[] = [...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "serializer"))] as MethodDeclaration[];
87
- const deserializers: MethodDeclaration[] = [...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "deserializer"))] as MethodDeclaration[];
228
+ if (DEBUG > 0) console.log("Created schema: " + this.schema.name + " in file " + node.range.source.normalizedPath + (this.schema.deps.length ? " with dependencies:\n " + this.schema.deps.map((v) => v.name).join("\n ") : ""));
88
229
 
89
230
  if (serializers.length > 1) throwError("Multiple serializers detected for class " + node.name.text + " but schemas can only have one serializer!", serializers[1].range);
90
231
  if (deserializers.length > 1) throwError("Multiple deserializers detected for class " + node.name.text + " but schemas can only have one deserializer!", deserializers[1].range);
@@ -130,43 +271,11 @@ class JSONTransform extends Visitor {
130
271
  DESERIALIZE_CUSTOM += " }\n";
131
272
  }
132
273
 
133
- if (node.extendsType) {
134
- const extendsName = node.extendsType?.name.identifier.text;
135
- this.schema.parent = this.schemas.find((v) => v.name == extendsName) as Schema | null;
136
- if (!this.schema.parent) {
137
- const internalSearch = getClasses(node.range.source).find((v) => v.name.text == extendsName);
138
- if (internalSearch) {
139
- if (DEBUG) console.log("Found " + extendsName + " internally");
140
- this.visitClassDeclaration(internalSearch);
141
- this.visitClassDeclaration(node);
142
- return;
143
- }
144
-
145
- const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
146
- if (externalSearch) {
147
- if (DEBUG) console.log("Found " + extendsName + " externally");
148
- this.visitClassDeclaration(externalSearch);
149
- this.visitClassDeclaration(node);
150
- return;
151
- }
152
- }
153
- if (this.schema.parent?.members) {
154
- for (let i = this.schema.parent.members.length - 1; i >= 0; i--) {
155
- const replace = this.schema.members.find((v) => v.name == this.schema.parent?.members[i]?.name);
156
- if (!replace) {
157
- members.unshift(this.schema.parent?.members[i]!.node);
158
- }
159
- }
160
- }
161
- }
162
-
163
274
  if (!members.length) {
164
275
  this.generateEmptyMethods(node);
165
276
  return;
166
277
  }
167
278
 
168
- this.addRequiredImports(node.range.source);
169
-
170
279
  for (const member of members) {
171
280
  if (!member.type) throwError("Fields must be strongly typed", node.range);
172
281
  const type = toString(member.type!);
@@ -234,22 +343,6 @@ class JSONTransform extends Visitor {
234
343
  SERIALIZE += indent + "bs.offset += 2;\n";
235
344
  }
236
345
 
237
- for (const member of this.schema.members) {
238
- if (isStruct(member.type)) {
239
- const schema = this.schemas.find((v) => v.name == stripNull(member.type));
240
- if (!schema) continue;
241
-
242
- if (!this.schema.deps.includes(schema)) {
243
- this.schema.deps.push(schema);
244
- this.schema.byteSize += schema.byteSize;
245
- }
246
-
247
- // if (schema.custom) {
248
- // member.flags.set(PropertyFlags.Custom, null);
249
- // }
250
- }
251
- }
252
-
253
346
  let isPure = this.schema.static;
254
347
  let isRegular = isPure;
255
348
  let isFirst = true;
@@ -263,7 +356,7 @@ class JSONTransform extends Visitor {
263
356
 
264
357
  if (member.value) {
265
358
  INITIALIZE += ` this.${member.name} = ${member.value};\n`;
266
- } else if (this.schemas.find((v) => nonNullType == v.name)) {
359
+ } else if (this.getSchema(nonNullType)) {
267
360
  INITIALIZE += ` this.${member.name} = changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE();\n`;
268
361
  } else if (member.type.startsWith("Array<") || member.type.startsWith("Map<")) {
269
362
  INITIALIZE += ` this.${member.name} = [];\n`;
@@ -366,7 +459,6 @@ class JSONTransform extends Visitor {
366
459
  indent = "";
367
460
  let shouldGroup = false;
368
461
 
369
- // DESERIALIZE += indent + " console.log(\"data: \" + JSON.Util.ptrToStr(srcStart,srcEnd))\n";
370
462
  DESERIALIZE += indent + " let keyStart: usize = 0;\n";
371
463
  DESERIALIZE += indent + " let keyEnd: usize = 0;\n";
372
464
  DESERIALIZE += indent + " let isKey = false;\n";
@@ -388,6 +480,7 @@ class JSONTransform extends Visitor {
388
480
  DESERIALIZE += indent + " if (isKey) {\n";
389
481
  DESERIALIZE += indent + " keyStart = lastIndex;\n";
390
482
  DESERIALIZE += indent + " keyEnd = srcStart;\n";
483
+ if (DEBUG > 1) DESERIALIZE += indent + " console.log(\"Key: \" + JSON.Util.ptrToStr(keyStart, keyEnd));\n";
391
484
  DESERIALIZE += indent + " while (JSON.Util.isSpace((code = load<u16>((srcStart += 2))))) {}\n";
392
485
  DESERIALIZE += indent + " if (code !== 58) throw new Error(\"Expected ':' after key at position \" + (srcEnd - srcStart).toString());\n";
393
486
  DESERIALIZE += indent + " isKey = false;\n";
@@ -471,10 +564,14 @@ class JSONTransform extends Visitor {
471
564
  if (STRICT) {
472
565
  DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
473
566
  } else {
474
- if (type == "string") DESERIALIZE += indent + " srcStart += 4;\n";
475
- else DESERIALIZE += indent + " srcStart += 2;\n";
567
+ if (type == "string") {
568
+ DESERIALIZE += indent + " srcStart += 4;\n";
569
+ } else if (type == "boolean" || type == "null" || type == "number") {
570
+ DESERIALIZE += indent + " srcStart += 2;\n";
571
+ }
572
+
476
573
  DESERIALIZE += indent + " keyStart = 0;\n";
477
- if (type != "boolean" && type != "null") DESERIALIZE += indent + " break;\n";
574
+ if (type == "string" || type == "object" || type == "array" || type == "number") DESERIALIZE += indent + " break;\n";
478
575
  }
479
576
  } else {
480
577
  const groups = groupMembers(members);
@@ -491,17 +588,21 @@ class JSONTransform extends Visitor {
491
588
  if (STRICT) {
492
589
  DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
493
590
  } else {
494
- if (type == "string") DESERIALIZE += indent + " srcStart += 4;\n";
495
- else DESERIALIZE += indent + " srcStart += 2;\n";
591
+ if (type == "string") {
592
+ DESERIALIZE += indent + " srcStart += 4;\n";
593
+ } else if (type == "boolean" || type == "null" || type == "number") {
594
+ DESERIALIZE += indent + " srcStart += 2;\n";
595
+ }
496
596
  DESERIALIZE += indent + " keyStart = 0;\n";
597
+ if (type == "string" || type == "object" || type == "array" || type == "number") DESERIALIZE += indent + " break;\n";
497
598
  }
498
599
  DESERIALIZE += " }\n";
499
600
  DESERIALIZE += " }\n";
500
- if (!members[0].node.type.isNullable && !isBoolean(members[0].type)) DESERIALIZE += " break;\n";
601
+ if (type != "null" && type != "boolean") DESERIALIZE += " break;\n";
501
602
  }
502
603
  };
503
604
 
504
- const generateComparisions = (members: Property[]) => {
605
+ const generateConsts = (members: Property[]): void => {
505
606
  if (members.some((m) => (m.alias || m.name).length << 1 == 2)) {
506
607
  DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
507
608
  }
@@ -517,42 +618,7 @@ class JSONTransform extends Visitor {
517
618
  if (members.some((m) => (m.alias || m.name).length << 1 > 8)) {
518
619
  DESERIALIZE += toMemCDecl(Math.max(...members.map((m) => (m.alias || m.name).length << 1)), " ");
519
620
  }
520
-
521
- const complex = isStruct(members[0].type) || members[0].type != "JSON.Obj" || isArray(members[0].type);
522
- const firstMemberName = members[0].alias || members[0].name;
523
- DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
524
- DESERIALIZE += indent + " store<" + members[0].type + ">(changetype<usize>(out), JSON.__deserialize<" + members[0].type + ">(lastIndex, srcStart" + (isString(members[0].type) ? " + 2" : "") + "), offsetof<this>(" + JSON.stringify(members[0].name) + "));\n";
525
- if (isString(members[0].type)) DESERIALIZE += indent + " srcStart += 4;\n";
526
- else if (!complex) DESERIALIZE += indent + " srcStart += 2;\n";
527
- DESERIALIZE += indent + " keyStart = 0;\n";
528
- DESERIALIZE += indent + " break;\n";
529
- DESERIALIZE += indent + " }";
530
-
531
- for (let i = 1; i < members.length; i++) {
532
- const member = members[i];
533
- const memberName = member.alias || member.name;
534
- DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
535
- DESERIALIZE += indent + " store<" + member.type + ">(changetype<usize>(out), JSON.__deserialize<" + member.type + ">(lastIndex, srcStart" + (isString(member.type) ? " + 2" : "") + "), offsetof<this>(" + JSON.stringify(member.name) + "));\n";
536
- if (isString(member.type)) DESERIALIZE += indent + " srcStart += 4;\n";
537
- else if (!complex) DESERIALIZE += indent + " srcStart += 2;\n";
538
- DESERIALIZE += indent + " keyStart = 0;\n";
539
- DESERIALIZE += indent + " break;\n";
540
- DESERIALIZE += indent + " }";
541
- }
542
-
543
- if (STRICT) {
544
- DESERIALIZE += " else {\n";
545
- DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
546
- DESERIALIZE += indent + " }\n";
547
- } else {
548
- DESERIALIZE += " else {\n";
549
- if (isString(members[0].type)) DESERIALIZE += indent + " srcStart += 4;\n";
550
- else if (!complex) DESERIALIZE += indent + " srcStart += 2;\n";
551
- DESERIALIZE += indent + " keyStart = 0;\n";
552
- DESERIALIZE += indent + " break;\n";
553
- DESERIALIZE += indent + " }\n";
554
- }
555
- };
621
+ }
556
622
 
557
623
  let mbElse = " ";
558
624
  if (!STRICT || sortedMembers.string.length) {
@@ -563,8 +629,41 @@ class JSONTransform extends Visitor {
563
629
  DESERIALIZE += " while (srcStart < srcEnd) {\n";
564
630
  DESERIALIZE += " const code = load<u16>(srcStart);\n";
565
631
  DESERIALIZE += " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
566
- // DESERIALIZE += " console.log(JSON.Util.ptrToStr(keyStart,keyEnd) + \" = \" + load<u16>(keyStart).toString() + \" val \" + JSON.Util.ptrToStr(lastIndex, srcStart));\n";
567
- generateGroups(sortedMembers.string, generateComparisions, "string");
632
+ if (DEBUG > 1) DESERIALIZE += " console.log(\"Value (string, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart + 2));";
633
+ generateGroups(sortedMembers.string, (group) => {
634
+ generateConsts(group);
635
+ const first = group[0];
636
+ const fName = first.alias || first.name;
637
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
638
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart + 2), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
639
+ DESERIALIZE += indent + " srcStart += 4;\n";
640
+ DESERIALIZE += indent + " keyStart = 0;\n";
641
+ DESERIALIZE += indent + " break;\n";
642
+ DESERIALIZE += indent + " }";
643
+
644
+ for (let i = 1; i < group.length; i++) {
645
+ const mem = group[i];
646
+ const memName = mem.alias || mem.name;
647
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
648
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart + 2), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
649
+ DESERIALIZE += indent + " srcStart += 4;\n";
650
+ DESERIALIZE += indent + " keyStart = 0;\n";
651
+ DESERIALIZE += indent + " break;\n";
652
+ DESERIALIZE += indent + " }";
653
+ }
654
+
655
+ if (STRICT) {
656
+ DESERIALIZE += " else {\n";
657
+ DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
658
+ DESERIALIZE += indent + " }\n";
659
+ } else {
660
+ DESERIALIZE += " else {\n";
661
+ DESERIALIZE += indent + " srcStart += 4;\n";
662
+ DESERIALIZE += indent + " keyStart = 0;\n";
663
+ DESERIALIZE += indent + " break;\n";
664
+ DESERIALIZE += indent + " }\n";
665
+ }
666
+ }, "string");
568
667
  DESERIALIZE += " }\n"; // Close break char check
569
668
  DESERIALIZE += " srcStart += 2;\n";
570
669
  DESERIALIZE += " }\n"; // Close char scan loop
@@ -579,9 +678,43 @@ class JSONTransform extends Visitor {
579
678
  DESERIALIZE += " while (srcStart < srcEnd) {\n";
580
679
  DESERIALIZE += " const code = load<u16>(srcStart);\n";
581
680
  DESERIALIZE += " if (code == 44 || code == 125 || JSON.Util.isSpace(code)) {\n";
681
+ if (DEBUG > 1) DESERIALIZE += " console.log(\"Value (number, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart));";
582
682
  // DESERIALIZE += " console.log(JSON.Util.ptrToStr(keyStart,keyEnd) + \" = \" + load<u16>(keyStart).toString() + \" val \" + JSON.Util.ptrToStr(lastIndex, srcStart));\n";
583
683
 
584
- generateGroups(sortedMembers.number, generateComparisions, "number");
684
+ generateGroups(sortedMembers.number, (group) => {
685
+ generateConsts(group);
686
+ const first = group[0];
687
+ const fName = first.alias || first.name;
688
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
689
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
690
+ DESERIALIZE += indent + " srcStart += 2;\n";
691
+ DESERIALIZE += indent + " keyStart = 0;\n";
692
+ DESERIALIZE += indent + " break;\n";
693
+ DESERIALIZE += indent + " }";
694
+
695
+ for (let i = 1; i < group.length; i++) {
696
+ const mem = group[i];
697
+ const memName = mem.alias || mem.name;
698
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
699
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
700
+ DESERIALIZE += indent + " srcStart += 2;\n";
701
+ DESERIALIZE += indent + " keyStart = 0;\n";
702
+ DESERIALIZE += indent + " break;\n";
703
+ DESERIALIZE += indent + " }";
704
+ }
705
+
706
+ if (STRICT) {
707
+ DESERIALIZE += " else {\n";
708
+ DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
709
+ DESERIALIZE += indent + " }\n";
710
+ } else {
711
+ DESERIALIZE += " else {\n";
712
+ DESERIALIZE += indent + " srcStart += 2;\n";
713
+ DESERIALIZE += indent + " keyStart = 0;\n";
714
+ DESERIALIZE += indent + " break;\n";
715
+ DESERIALIZE += indent + " }\n";
716
+ }
717
+ }, "number");
585
718
  DESERIALIZE += " }\n"; // Close break char check
586
719
  DESERIALIZE += " srcStart += 2;\n";
587
720
  DESERIALIZE += " }\n"; // Close char scan loop
@@ -602,9 +735,40 @@ class JSONTransform extends Visitor {
602
735
  DESERIALIZE += " } else if (code == 125) {\n";
603
736
  DESERIALIZE += " if (--depth == 0) {\n";
604
737
  DESERIALIZE += " srcStart += 2;\n";
738
+ if (DEBUG > 1) DESERIALIZE += " console.log(\"Value (object, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart));";
605
739
 
606
740
  indent = " ";
607
- generateGroups(sortedMembers.object, generateComparisions, "object");
741
+ generateGroups(sortedMembers.object, (group) => {
742
+ generateConsts(group);
743
+ const first = group[0];
744
+ const fName = first.alias || first.name;
745
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
746
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
747
+ DESERIALIZE += indent + " keyStart = 0;\n";
748
+ DESERIALIZE += indent + " break;\n";
749
+ DESERIALIZE += indent + " }";
750
+
751
+ for (let i = 1; i < group.length; i++) {
752
+ const mem = group[i];
753
+ const memName = mem.alias || mem.name;
754
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
755
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
756
+ DESERIALIZE += indent + " keyStart = 0;\n";
757
+ DESERIALIZE += indent + " break;\n";
758
+ DESERIALIZE += indent + " }";
759
+ }
760
+
761
+ if (STRICT) {
762
+ DESERIALIZE += " else {\n";
763
+ DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
764
+ DESERIALIZE += indent + " }\n";
765
+ } else {
766
+ DESERIALIZE += " else {\n";
767
+ DESERIALIZE += indent + " keyStart = 0;\n";
768
+ DESERIALIZE += indent + " break;\n";
769
+ DESERIALIZE += indent + " }\n";
770
+ }
771
+ }, "object");
608
772
  indent = "";
609
773
 
610
774
  DESERIALIZE += " }\n"; // Close break char check
@@ -627,10 +791,40 @@ class JSONTransform extends Visitor {
627
791
  DESERIALIZE += " } else if (code == 93) {\n";
628
792
  DESERIALIZE += " if (--depth == 0) {\n";
629
793
  DESERIALIZE += " srcStart += 2;\n";
630
- // DESERIALIZE += " console.log(ptrToStr(keyStart,keyEnd) + \" = \" + (load<u64>(keyStart) & 0x0000FFFFFFFFFFFF) .toString());\n";
794
+ if (DEBUG > 1) DESERIALIZE += " console.log(\"Value (object, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart));";
631
795
 
632
796
  indent = " ";
633
- generateGroups(sortedMembers.array, generateComparisions, "array");
797
+ generateGroups(sortedMembers.array, (group) => {
798
+ generateConsts(group);
799
+ const first = group[0];
800
+ const fName = first.alias || first.name;
801
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
802
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
803
+ DESERIALIZE += indent + " keyStart = 0;\n";
804
+ DESERIALIZE += indent + " break;\n";
805
+ DESERIALIZE += indent + " }";
806
+
807
+ for (let i = 1; i < group.length; i++) {
808
+ const mem = group[i];
809
+ const memName = mem.alias || mem.name;
810
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
811
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
812
+ DESERIALIZE += indent + " keyStart = 0;\n";
813
+ DESERIALIZE += indent + " break;\n";
814
+ DESERIALIZE += indent + " }";
815
+ }
816
+
817
+ if (STRICT) {
818
+ DESERIALIZE += " else {\n";
819
+ DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
820
+ DESERIALIZE += indent + " }\n";
821
+ } else {
822
+ DESERIALIZE += " else {\n";
823
+ DESERIALIZE += indent + " keyStart = 0;\n";
824
+ DESERIALIZE += indent + " break;\n";
825
+ DESERIALIZE += indent + " }\n";
826
+ }
827
+ }, "array");
634
828
  indent = "";
635
829
 
636
830
  DESERIALIZE += " }\n"; // Close break char check
@@ -647,56 +841,41 @@ class JSONTransform extends Visitor {
647
841
 
648
842
  DESERIALIZE += " if (load<u64>(srcStart) == 28429475166421108) {\n";
649
843
  DESERIALIZE += " srcStart += 8;\n";
650
- generateGroups(
651
- sortedMembers.boolean,
652
- (group) => {
653
- if (group.some((m) => (m.alias || m.name).length << 1 == 2)) {
654
- DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
655
- }
656
- if (group.some((m) => (m.alias || m.name).length << 1 == 4)) {
657
- DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
658
- }
659
- if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
660
- DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
661
- }
662
- if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
663
- DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
664
- }
665
- if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
666
- DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
667
- }
668
-
669
- const firstMemberName = group[0].alias || group[0].name;
670
- DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
671
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
844
+ if (DEBUG > 1) DESERIALIZE += " console.log(\"Value (bool, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart - 8));";
845
+ generateGroups(sortedMembers.boolean, (group) => {
846
+ generateConsts(group);
847
+ const first = group[0];
848
+ const fName = first.alias || first.name;
849
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
850
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
851
+ DESERIALIZE += indent + " srcStart += 2;\n";
852
+ DESERIALIZE += indent + " keyStart = 0;\n";
853
+ DESERIALIZE += indent + " break;\n";
854
+ DESERIALIZE += indent + " }";
855
+
856
+ for (let i = 1; i < group.length; i++) {
857
+ const mem = group[i];
858
+ const memName = mem.alias || mem.name;
859
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
860
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
672
861
  DESERIALIZE += indent + " srcStart += 2;\n";
673
862
  DESERIALIZE += indent + " keyStart = 0;\n";
674
863
  DESERIALIZE += indent + " break;\n";
675
864
  DESERIALIZE += indent + " }";
865
+ }
676
866
 
677
- for (let i = 1; i < group.length; i++) {
678
- const member = group[i];
679
- const memberName = member.alias || member.name;
680
- DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
681
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(member.name) + "));\n";
682
- DESERIALIZE += indent + " srcStart += 2;\n";
683
- DESERIALIZE += indent + " keyStart = 0;\n";
684
- DESERIALIZE += indent + " break;\n";
685
- DESERIALIZE += indent + " }";
686
- }
687
-
688
- if (STRICT) {
689
- DESERIALIZE += " else {\n";
690
- DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
691
- DESERIALIZE += indent + " }\n";
692
- } else {
693
- DESERIALIZE += " else { \n";
694
- DESERIALIZE += indent + " srcStart += 2;\n";
695
- DESERIALIZE += indent + " keyStart = 0;\n";
696
- DESERIALIZE += indent + " break;\n";
697
- DESERIALIZE += indent + " }\n";
698
- }
699
- },
867
+ if (STRICT) {
868
+ DESERIALIZE += " else {\n";
869
+ DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
870
+ DESERIALIZE += indent + " }\n";
871
+ } else {
872
+ DESERIALIZE += " else { \n";
873
+ DESERIALIZE += indent + " srcStart += 2;\n";
874
+ DESERIALIZE += indent + " keyStart = 0;\n";
875
+ DESERIALIZE += indent + " break;\n";
876
+ DESERIALIZE += indent + " }\n";
877
+ }
878
+ },
700
879
  "boolean",
701
880
  );
702
881
 
@@ -713,56 +892,42 @@ class JSONTransform extends Visitor {
713
892
 
714
893
  DESERIALIZE += " if (load<u64>(srcStart, 2) == 28429466576093281) {\n";
715
894
  DESERIALIZE += " srcStart += 10;\n";
716
- generateGroups(
717
- sortedMembers.boolean,
718
- (group) => {
719
- if (group.some((m) => (m.alias || m.name).length << 1 == 2)) {
720
- DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
721
- }
722
- if (group.some((m) => (m.alias || m.name).length << 1 == 4)) {
723
- DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
724
- }
725
- if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
726
- DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
727
- }
728
- if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
729
- DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
730
- }
731
- if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
732
- DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
733
- }
734
-
735
- const firstMemberName = group[0].alias || group[0].name;
736
- DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
737
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
895
+ if (DEBUG > 1) DESERIALIZE += " console.log(\"Value (bool, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart - 10));";
896
+ generateGroups(sortedMembers.boolean, (group) => {
897
+ generateConsts(group);
898
+
899
+ const first = group[0];
900
+ const fName = first.alias || first.name;
901
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
902
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
903
+ DESERIALIZE += indent + " srcStart += 2;\n";
904
+ DESERIALIZE += indent + " keyStart = 0;\n";
905
+ DESERIALIZE += indent + " break;\n";
906
+ DESERIALIZE += indent + " }";
907
+
908
+ for (let i = 1; i < group.length; i++) {
909
+ const mem = group[i];
910
+ const memName = mem.alias || mem.name;
911
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
912
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
738
913
  DESERIALIZE += indent + " srcStart += 2;\n";
739
914
  DESERIALIZE += indent + " keyStart = 0;\n";
740
915
  DESERIALIZE += indent + " break;\n";
741
916
  DESERIALIZE += indent + " }";
917
+ }
742
918
 
743
- for (let i = 1; i < group.length; i++) {
744
- const member = group[i];
745
- const memberName = member.alias || member.name;
746
- DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
747
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(member.name) + "));\n";
748
- DESERIALIZE += indent + " srcStart += 2;\n";
749
- DESERIALIZE += indent + " keyStart = 0;\n";
750
- DESERIALIZE += indent + " break;\n";
751
- DESERIALIZE += indent + " }";
752
- }
753
-
754
- if (STRICT) {
755
- DESERIALIZE += " else {\n";
756
- DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
757
- DESERIALIZE += indent + " }\n";
758
- } else {
759
- DESERIALIZE += " else { \n";
760
- DESERIALIZE += indent + " srcStart += 2;\n";
761
- DESERIALIZE += indent + " keyStart = 0;\n";
762
- DESERIALIZE += indent + " break;\n";
763
- DESERIALIZE += indent + " }\n";
764
- }
765
- },
919
+ if (STRICT) {
920
+ DESERIALIZE += " else {\n";
921
+ DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
922
+ DESERIALIZE += indent + " }\n";
923
+ } else {
924
+ DESERIALIZE += " else { \n";
925
+ DESERIALIZE += indent + " srcStart += 2;\n";
926
+ DESERIALIZE += indent + " keyStart = 0;\n";
927
+ DESERIALIZE += indent + " break;\n";
928
+ DESERIALIZE += indent + " }\n";
929
+ }
930
+ },
766
931
  "boolean",
767
932
  );
768
933
 
@@ -780,56 +945,42 @@ class JSONTransform extends Visitor {
780
945
 
781
946
  DESERIALIZE += " if (load<u64>(srcStart) == 30399761348886638) {\n";
782
947
  DESERIALIZE += " srcStart += 8;\n";
783
- generateGroups(
784
- sortedMembers.null,
785
- (group) => {
786
- if (group.some((m) => (m.alias || m.name).length << 1 == 2)) {
787
- DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
788
- }
789
- if (group.some((m) => (m.alias || m.name).length << 1 == 4)) {
790
- DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
791
- }
792
- if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
793
- DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
794
- }
795
- if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
796
- DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
797
- }
798
- if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
799
- DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
800
- }
801
-
802
- const firstMemberName = group[0].alias || group[0].name;
803
- DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
804
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
948
+ if (DEBUG > 1) DESERIALIZE += " console.log(\"Value (null, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart - 8));";
949
+ generateGroups(sortedMembers.null, (group) => {
950
+ generateConsts(group);
951
+
952
+ const first = group[0];
953
+ const fName = first.alias || first.name;
954
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
955
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
956
+ DESERIALIZE += indent + " srcStart += 2;\n";
957
+ DESERIALIZE += indent + " keyStart = 0;\n";
958
+ DESERIALIZE += indent + " break;\n";
959
+ DESERIALIZE += indent + " }";
960
+
961
+ for (let i = 1; i < group.length; i++) {
962
+ const mem = group[i];
963
+ const memName = mem.alias || mem.name;
964
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
965
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
805
966
  DESERIALIZE += indent + " srcStart += 2;\n";
806
967
  DESERIALIZE += indent + " keyStart = 0;\n";
807
968
  DESERIALIZE += indent + " break;\n";
808
969
  DESERIALIZE += indent + " }";
970
+ }
809
971
 
810
- for (let i = 1; i < group.length; i++) {
811
- const member = group[i];
812
- const memberName = member.alias || member.name;
813
- DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
814
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(member.name) + "));\n";
815
- DESERIALIZE += indent + " srcStart += 2;\n";
816
- DESERIALIZE += indent + " keyStart = 0;\n";
817
- DESERIALIZE += indent + " break;\n";
818
- DESERIALIZE += indent + " }";
819
- }
820
-
821
- if (STRICT) {
822
- DESERIALIZE += " else {\n";
823
- DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
824
- DESERIALIZE += indent + " }\n";
825
- } else {
826
- DESERIALIZE += " else { \n";
827
- DESERIALIZE += indent + " srcStart += 2;\n";
828
- DESERIALIZE += indent + " keyStart = 0;\n";
829
- DESERIALIZE += indent + " break;\n";
830
- DESERIALIZE += indent + " }\n";
831
- }
832
- },
972
+ if (STRICT) {
973
+ DESERIALIZE += " else {\n";
974
+ DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
975
+ DESERIALIZE += indent + " }\n";
976
+ } else {
977
+ DESERIALIZE += " else { \n";
978
+ DESERIALIZE += indent + " srcStart += 2;\n";
979
+ DESERIALIZE += indent + " keyStart = 0;\n";
980
+ DESERIALIZE += indent + " break;\n";
981
+ DESERIALIZE += indent + " }\n";
982
+ }
983
+ },
833
984
  "null",
834
985
  );
835
986
 
@@ -865,7 +1016,7 @@ class JSONTransform extends Visitor {
865
1016
  // if (DESERIALIZE_CUSTOM) {
866
1017
  // DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): usize {\n if (isDefined(this.__DESERIALIZE_CUSTOM) return changetype<usize>(this." + deserializers[0].name + "(changetype<switch (<u32>keyEnd - <u32>keyStart) {\n"
867
1018
  // }
868
- if (DEBUG) {
1019
+ if (DEBUG > 0) {
869
1020
  console.log(SERIALIZE_CUSTOM || SERIALIZE);
870
1021
  console.log(INITIALIZE);
871
1022
  console.log(DESERIALIZE_CUSTOM || DESERIALIZE);
@@ -880,12 +1031,16 @@ class JSONTransform extends Visitor {
880
1031
  if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD);
881
1032
  super.visitClassDeclaration(node);
882
1033
  }
1034
+ getSchema(name: string): Schema | null {
1035
+ name = stripNull(name);
1036
+ return this.schemas.get(this.schema.node.range.source.internalPath).find((s) => s.name == name) || null;
1037
+ }
883
1038
  generateEmptyMethods(node: ClassDeclaration): void {
884
1039
  let SERIALIZE_EMPTY = "@inline __SERIALIZE(ptr: usize): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
885
1040
  let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
886
1041
  let DESERIALIZE_EMPTY = "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): __JSON_T {\n return this;\n}";
887
1042
 
888
- if (DEBUG) {
1043
+ if (DEBUG > 0) {
889
1044
  console.log(SERIALIZE_EMPTY);
890
1045
  console.log(INITIALIZE_EMPTY);
891
1046
  console.log(DESERIALIZE_EMPTY);
@@ -932,39 +1087,104 @@ class JSONTransform extends Visitor {
932
1087
  this.imports = [];
933
1088
  super.visitSource(node);
934
1089
  }
935
- addRequiredImports(node: Source): void {
936
- const filePath = fileURLToPath(import.meta.url);
937
- const baseDir = path.resolve(filePath, "..", "..", "..");
938
- const nodePath = path.resolve(this.baseDir, node.range.source.normalizedPath);
1090
+ addImports(node: Source): void {
1091
+ const baseDir = path.resolve(
1092
+ fileURLToPath(import.meta.url),
1093
+ "..",
1094
+ "..",
1095
+ "..",
1096
+ );
1097
+ const pkgPath = path.join(this.baseCWD, "node_modules");
1098
+ const isLibrary = existsSync(path.join(pkgPath, "json-as"));
1099
+ let fromPath = node.range.source.normalizedPath;
1100
+
1101
+ fromPath = fromPath.startsWith("~lib/")
1102
+ ? existsSync(
1103
+ path.join(pkgPath, fromPath.slice(5, fromPath.indexOf("/", 5))),
1104
+ )
1105
+ ? path.join(pkgPath, fromPath.slice(5))
1106
+ : fromPath
1107
+ : path.join(this.baseCWD, fromPath);
939
1108
 
940
1109
  const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
941
1110
  const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
942
1111
 
943
- let bsPath = path.posix.join(...path.relative(path.dirname(nodePath), path.join(baseDir, "lib", "as-bs")).split(path.sep)).replace(/^.*node_modules\/json-as/, "json-as");
1112
+ let bsRel = removeExtension(
1113
+ path.posix.join(
1114
+ ...path
1115
+ .relative(path.dirname(fromPath), path.join(baseDir, "lib", "as-bs"))
1116
+ .split(path.sep),
1117
+ ),
1118
+ );
1119
+
1120
+ let jsRel = removeExtension(
1121
+ path.posix.join(
1122
+ ...path
1123
+ .relative(path.dirname(fromPath), path.join(baseDir, "assembly", "index"))
1124
+ .split(path.sep),
1125
+ ),
1126
+ );
1127
+
1128
+ if (bsRel.includes("node_modules" + path.sep + "json-as")) {
1129
+ bsRel =
1130
+ "json-as" +
1131
+ bsRel.slice(
1132
+ bsRel.indexOf("node_modules" + path.sep + "json-as") + 20,
1133
+ )
1134
+ } else if (
1135
+ !bsRel.startsWith(".") &&
1136
+ !bsRel.startsWith("/") &&
1137
+ !bsRel.startsWith("json-as")
1138
+ ) {
1139
+ bsRel = "./" + bsRel;
1140
+ }
944
1141
 
945
- let jsonPath = path.posix.join(...path.relative(path.dirname(nodePath), path.join(baseDir, "assembly", "index.ts")).split(path.sep)).replace(/^.*node_modules\/json-as/, "json-as");
1142
+ if (jsRel.includes("node_modules" + path.sep + "json-as")) {
1143
+ jsRel =
1144
+ "json-as" +
1145
+ jsRel.slice(
1146
+ jsRel.indexOf("node_modules" + path.sep + "json-as") + 20,
1147
+ );
1148
+ } else if (
1149
+ !jsRel.startsWith(".") &&
1150
+ !jsRel.startsWith("/") &&
1151
+ !jsRel.startsWith("json-as")
1152
+ ) {
1153
+ jsRel = "./" + jsRel;
1154
+ }
946
1155
 
947
1156
  if (!bsImport) {
948
- if (node.normalizedPath.startsWith("~")) {
949
- bsPath = "json-as/lib/as-bs";
950
- }
951
-
952
- const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range)], Node.createStringLiteralExpression(bsPath, node.range), node.range);
953
- this.topStatements.push(replaceNode);
954
- if (DEBUG) console.log("Added as-bs import: " + toString(replaceNode) + "\n");
1157
+ const replaceNode = Node.createImportStatement(
1158
+ [Node.createImportDeclaration(
1159
+ Node.createIdentifierExpression("bs", node.range, false),
1160
+ null,
1161
+ node.range
1162
+ )
1163
+ ],
1164
+ Node.createStringLiteralExpression(bsRel, node.range),
1165
+ node.range
1166
+ );
1167
+ node.range.source.statements.unshift(replaceNode);
1168
+ if (DEBUG > 0) console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
955
1169
  }
956
1170
 
957
1171
  if (!jsonImport) {
958
- if (node.normalizedPath.startsWith("~")) {
959
- jsonPath = "json-as/assembly/index.ts";
960
- }
961
1172
  const replaceNode = Node.createImportStatement(
962
- [Node.createImportDeclaration(Node.createIdentifierExpression("JSON", node.range, false), null, node.range)],
963
- Node.createStringLiteralExpression(jsonPath, node.range), // Ensure POSIX-style path for 'assembly'
1173
+ [Node.createImportDeclaration(
1174
+ Node.createIdentifierExpression(
1175
+ "JSON",
1176
+ node.range,
1177
+ false
1178
+ ),
1179
+ null,
1180
+ node.range
1181
+ )
1182
+ ],
1183
+ Node.createStringLiteralExpression(jsRel, node.range), // Ensure POSIX-style path for 'assembly'
964
1184
  node.range,
965
1185
  );
966
- this.topStatements.push(replaceNode);
967
- if (DEBUG) console.log("Added json-as import: " + toString(replaceNode) + "\n");
1186
+ node.range.source.statements.unshift(replaceNode);
1187
+ if (DEBUG > 0) console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
968
1188
  }
969
1189
  }
970
1190
 
@@ -996,7 +1216,7 @@ class JSONTransform extends Visitor {
996
1216
  return out;
997
1217
  }
998
1218
  isValidType(type: string, node: ClassDeclaration): boolean {
999
- const validTypes = ["string", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean", "Date", "JSON.Value", "JSON.Obj", "JSON.Raw", "Value", "Obj", "Raw", ...this.schemas.map((v) => v.name)];
1219
+ const validTypes = ["string", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean", "Date", "JSON.Value", "JSON.Obj", "JSON.Raw", "Value", "Obj", "Raw", ...this.schemas.get(this.schema.node.range.source.internalPath).map((v) => v.name)];
1000
1220
 
1001
1221
  const baseTypes = ["Array", "Map", "Set", "JSON.Box", "Box"];
1002
1222
 
@@ -1039,7 +1259,7 @@ export default class Transformer extends Transform {
1039
1259
  }
1040
1260
  });
1041
1261
 
1042
- transformer.baseDir = path.join(process.cwd(), this.baseDir);
1262
+ transformer.baseCWD = path.join(process.cwd(), this.baseDir);
1043
1263
  transformer.program = this.program;
1044
1264
  transformer.parser = parser;
1045
1265
  for (const source of sources) {
@@ -1055,13 +1275,12 @@ export default class Transformer extends Transform {
1055
1275
  for (const simd of transformer.simdStatements) source.statements.unshift(SimpleParser.parseTopLevelStatement(simd));
1056
1276
  }
1057
1277
  transformer.simdStatements = [];
1058
- }
1059
1278
 
1060
- const schemas = transformer.schemas;
1061
- for (const schema of schemas) {
1062
- if (schema.parent) {
1063
- const parent = schemas.find((v) => v.name == schema.parent?.name);
1064
- if (!parent) throwError(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator!`, schema.parent.node.range);
1279
+ if (transformer.schemas.has(source.internalPath)) {
1280
+ transformer.addImports(source);
1281
+ }
1282
+ if (source.normalizedPath == WRITE) {
1283
+ writeFileSync(path.join(process.cwd(), this.baseDir, removeExtension(source.normalizedPath) + ".json.ts"), toString(source));
1065
1284
  }
1066
1285
  }
1067
1286
  }
@@ -1217,9 +1436,9 @@ function isBoolean(type: string): boolean {
1217
1436
  return type == "bool" || type == "boolean";
1218
1437
  }
1219
1438
 
1220
- function isStruct(type: string): boolean {
1439
+ function isStruct(type: string, source: Source): boolean {
1221
1440
  type = stripNull(type);
1222
- return JSONTransform.SN.schemas.some((v) => v.name == type) || JSONTransform.SN.schema.name == type;
1441
+ return JSONTransform.SN.schemas.get(source.internalPath).some((v) => v.name == type) || JSONTransform.SN.schema.name == type;
1223
1442
  }
1224
1443
 
1225
1444
  function isString(type: string) {