json-as 1.1.9 → 1.1.10

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,13 +1,23 @@
1
1
  import { Node } from "assemblyscript/dist/assemblyscript.js";
2
2
  import { Transform } from "assemblyscript/dist/transform.js";
3
3
  import { Visitor } from "./visitor.js";
4
- import { isStdlib, SimpleParser, toString } from "./util.js";
4
+ import { isStdlib, removeExtension, 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, getImportedClass } from "./linker.js";
9
+ import { existsSync, writeFileSync } from "fs";
9
10
  let indent = " ";
10
- const DEBUG = process.env["JSON_DEBUG"];
11
+ let id = 0;
12
+ const WRITE = process.env["JSON_WRITE"];
13
+ const rawValue = process.env["JSON_DEBUG"];
14
+ const DEBUG = rawValue === "true"
15
+ ? 1
16
+ : rawValue === "false" || rawValue === ""
17
+ ? 0
18
+ : isNaN(Number(rawValue))
19
+ ? 0
20
+ : Number(rawValue);
11
21
  const STRICT = process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "true";
12
22
  class CustomTransform extends Visitor {
13
23
  static SN = new CustomTransform();
@@ -41,14 +51,15 @@ class CustomTransform extends Visitor {
41
51
  class JSONTransform extends Visitor {
42
52
  static SN = new JSONTransform();
43
53
  program;
44
- baseDir;
54
+ baseCWD;
45
55
  parser;
46
- schemas = [];
56
+ schemas = new Map();
47
57
  schema;
48
58
  sources = new Set();
49
59
  imports = [];
50
60
  topStatements = [];
51
61
  simdStatements = [];
62
+ visitedClasses = new Set();
52
63
  visitClassDeclaration(node) {
53
64
  if (!node.decorators?.length)
54
65
  return;
@@ -57,20 +68,127 @@ class JSONTransform extends Visitor {
57
68
  return name === "json" || name === "serializable";
58
69
  }))
59
70
  return;
60
- this.schema = new Schema();
61
- this.schema.node = node;
62
- this.schema.name = node.name.text;
63
- this.schemas.push(this.schema);
71
+ if (this.visitedClasses.has(node.range.source.internalPath + node.name.text))
72
+ return;
73
+ if (!this.schemas.has(node.range.source.internalPath))
74
+ this.schemas.set(node.range.source.internalPath, []);
75
+ const members = [...node.members.filter((v) => v.kind === 54 && v.flags !== 32 && v.flags !== 512 && v.flags !== 1024 && !v.decorators?.some((decorator) => decorator.name.text === "omit"))];
76
+ const serializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "serializer"))];
77
+ const deserializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "deserializer"))];
78
+ const schema = new Schema();
79
+ schema.node = node;
80
+ schema.name = node.name.text;
81
+ if (node.extendsType) {
82
+ const extendsName = node.extendsType?.name.identifier.text;
83
+ if (!schema.parent) {
84
+ const depSearch = schema.deps.find((v) => v.name == extendsName);
85
+ if (depSearch) {
86
+ if (DEBUG > 0)
87
+ console.log("Found " + extendsName + " in dependencies of " + node.range.source.internalPath);
88
+ schema.deps.push(depSearch);
89
+ schema.parent = depSearch;
90
+ }
91
+ else {
92
+ const internalSearch = getClass(extendsName, node.range.source);
93
+ if (internalSearch) {
94
+ if (DEBUG > 0)
95
+ console.log("Found " + extendsName + " internally from " + node.range.source.internalPath);
96
+ this.visitClassDeclaration(internalSearch);
97
+ schema.deps.push(this.schema);
98
+ this.schemas.get(node.range.source.internalPath).push(this.schema);
99
+ schema.parent = this.schema;
100
+ this.schema = schema;
101
+ }
102
+ else {
103
+ const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
104
+ if (externalSearch) {
105
+ if (DEBUG > 0)
106
+ console.log("Found " + externalSearch.name.text + " externally from " + node.range.source.internalPath);
107
+ this.visitClassDeclaration(externalSearch);
108
+ schema.deps.push(this.schema);
109
+ this.schemas.get(node.range.source.internalPath).push(this.schema);
110
+ schema.parent = this.schema;
111
+ this.schema = schema;
112
+ }
113
+ }
114
+ }
115
+ }
116
+ if (schema.parent?.members) {
117
+ for (let i = schema.parent.members.length - 1; i >= 0; i--) {
118
+ const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
119
+ if (!replace) {
120
+ members.unshift(schema.parent?.members[i].node);
121
+ }
122
+ }
123
+ }
124
+ }
125
+ const getUnknownTypes = (type, types = []) => {
126
+ type = stripNull(type);
127
+ if (type.startsWith("Array<")) {
128
+ return getUnknownTypes(type.slice(6, -1));
129
+ }
130
+ else if (type.startsWith("Map<")) {
131
+ const parts = type.slice(4, -1).split(",");
132
+ return getUnknownTypes(parts[0]) || getUnknownTypes(parts[1]);
133
+ }
134
+ else if (isString(type) || isPrimitive(type)) {
135
+ return types;
136
+ }
137
+ else if (["JSON.Box", "JSON.Obj", "JSON.Value", "JSON.Raw"].includes(type)) {
138
+ return types;
139
+ }
140
+ else if (node.isGeneric && node.typeParameters.some((p) => p.name.text == type)) {
141
+ return types;
142
+ }
143
+ else if (type == node.name.text) {
144
+ return types;
145
+ }
146
+ types.push(type);
147
+ return types;
148
+ };
149
+ for (const member of members) {
150
+ const type = toString(member.type);
151
+ const unknown = getUnknownTypes(type);
152
+ for (const unknownType of unknown) {
153
+ const depSearch = schema.deps.find((v) => v.name == unknownType);
154
+ if (depSearch) {
155
+ if (DEBUG > 0)
156
+ console.log("Found " + unknownType + " in dependencies of " + node.range.source.internalPath);
157
+ schema.deps.push(depSearch);
158
+ continue;
159
+ }
160
+ const internalSearch = getClass(unknownType, node.range.source);
161
+ if (internalSearch) {
162
+ if (DEBUG > 0)
163
+ console.log("Found " + unknownType + " internally from " + node.range.source.internalPath);
164
+ this.visitClassDeclaration(internalSearch);
165
+ this.schemas.get(node.range.source.internalPath).push(this.schema);
166
+ schema.deps.push(this.schema);
167
+ this.schema = schema;
168
+ }
169
+ else {
170
+ const externalSearch = getImportedClass(unknownType, node.range.source, this.parser);
171
+ if (externalSearch) {
172
+ if (DEBUG > 0)
173
+ console.log("Found " + externalSearch.name.text + " externally from " + node.range.source.internalPath);
174
+ this.visitClassDeclaration(externalSearch);
175
+ this.schemas.get(node.range.source.internalPath).push(this.schema);
176
+ schema.deps.push(this.schema);
177
+ this.schema = schema;
178
+ }
179
+ }
180
+ }
181
+ }
182
+ this.schemas.get(node.range.source.internalPath).push(schema);
183
+ this.schema = schema;
184
+ this.visitedClasses.add(node.range.source.internalPath + node.name.text);
64
185
  let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
65
186
  let INITIALIZE = "@inline __INITIALIZE(): this {\n";
66
187
  let DESERIALIZE = "__DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): __JSON_T {\n";
67
188
  let DESERIALIZE_CUSTOM = "";
68
189
  let SERIALIZE_CUSTOM = "";
69
- if (DEBUG)
70
- console.log("Created schema: " + this.schema.name + " in file " + node.range.source.normalizedPath);
71
- const members = [...node.members.filter((v) => v.kind === 54 && v.flags !== 32 && v.flags !== 512 && v.flags !== 1024 && !v.decorators?.some((decorator) => decorator.name.text === "omit"))];
72
- const serializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "serializer"))];
73
- const deserializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "deserializer"))];
190
+ if (DEBUG > 0)
191
+ 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 ") : ""));
74
192
  if (serializers.length > 1)
75
193
  throwError("Multiple serializers detected for class " + node.name.text + " but schemas can only have one serializer!", serializers[1].range);
76
194
  if (deserializers.length > 1)
@@ -116,41 +234,10 @@ class JSONTransform extends Visitor {
116
234
  DESERIALIZE_CUSTOM += " return inline.always(this." + deserializer.name.text + "(changetype<string>(srcStart)));\n";
117
235
  DESERIALIZE_CUSTOM += " }\n";
118
236
  }
119
- if (node.extendsType) {
120
- const extendsName = node.extendsType?.name.identifier.text;
121
- this.schema.parent = this.schemas.find((v) => v.name == extendsName);
122
- if (!this.schema.parent) {
123
- const internalSearch = getClasses(node.range.source).find((v) => v.name.text == extendsName);
124
- if (internalSearch) {
125
- if (DEBUG)
126
- console.log("Found " + extendsName + " internally");
127
- this.visitClassDeclaration(internalSearch);
128
- this.visitClassDeclaration(node);
129
- return;
130
- }
131
- const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
132
- if (externalSearch) {
133
- if (DEBUG)
134
- console.log("Found " + extendsName + " externally");
135
- this.visitClassDeclaration(externalSearch);
136
- this.visitClassDeclaration(node);
137
- return;
138
- }
139
- }
140
- if (this.schema.parent?.members) {
141
- for (let i = this.schema.parent.members.length - 1; i >= 0; i--) {
142
- const replace = this.schema.members.find((v) => v.name == this.schema.parent?.members[i]?.name);
143
- if (!replace) {
144
- members.unshift(this.schema.parent?.members[i].node);
145
- }
146
- }
147
- }
148
- }
149
237
  if (!members.length) {
150
238
  this.generateEmptyMethods(node);
151
239
  return;
152
240
  }
153
- this.addRequiredImports(node.range.source);
154
241
  for (const member of members) {
155
242
  if (!member.type)
156
243
  throwError("Fields must be strongly typed", node.range);
@@ -212,17 +299,6 @@ class JSONTransform extends Visitor {
212
299
  SERIALIZE += indent + "store<u16>(bs.offset, 123, 0); // {\n";
213
300
  SERIALIZE += indent + "bs.offset += 2;\n";
214
301
  }
215
- for (const member of this.schema.members) {
216
- if (isStruct(member.type)) {
217
- const schema = this.schemas.find((v) => v.name == stripNull(member.type));
218
- if (!schema)
219
- continue;
220
- if (!this.schema.deps.includes(schema)) {
221
- this.schema.deps.push(schema);
222
- this.schema.byteSize += schema.byteSize;
223
- }
224
- }
225
- }
226
302
  let isPure = this.schema.static;
227
303
  let isRegular = isPure;
228
304
  let isFirst = true;
@@ -235,7 +311,7 @@ class JSONTransform extends Visitor {
235
311
  if (member.value) {
236
312
  INITIALIZE += ` this.${member.name} = ${member.value};\n`;
237
313
  }
238
- else if (this.schemas.find((v) => nonNullType == v.name)) {
314
+ else if (this.getSchema(nonNullType)) {
239
315
  INITIALIZE += ` this.${member.name} = changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE();\n`;
240
316
  }
241
317
  else if (member.type.startsWith("Array<") || member.type.startsWith("Map<")) {
@@ -355,6 +431,8 @@ class JSONTransform extends Visitor {
355
431
  DESERIALIZE += indent + " if (isKey) {\n";
356
432
  DESERIALIZE += indent + " keyStart = lastIndex;\n";
357
433
  DESERIALIZE += indent + " keyEnd = srcStart;\n";
434
+ if (DEBUG > 1)
435
+ DESERIALIZE += indent + " console.log(\"Key: \" + JSON.Util.ptrToStr(keyStart, keyEnd));\n";
358
436
  DESERIALIZE += indent + " while (JSON.Util.isSpace((code = load<u16>((srcStart += 2))))) {}\n";
359
437
  DESERIALIZE += indent + " if (code !== 58) throw new Error(\"Expected ':' after key at position \" + (srcEnd - srcStart).toString());\n";
360
438
  DESERIALIZE += indent + " isKey = false;\n";
@@ -389,12 +467,14 @@ class JSONTransform extends Visitor {
389
467
  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';
390
468
  }
391
469
  else {
392
- if (type == "string")
470
+ if (type == "string") {
393
471
  DESERIALIZE += indent + " srcStart += 4;\n";
394
- else
472
+ }
473
+ else if (type == "boolean" || type == "null" || type == "number") {
395
474
  DESERIALIZE += indent + " srcStart += 2;\n";
475
+ }
396
476
  DESERIALIZE += indent + " keyStart = 0;\n";
397
- if (type != "boolean" && type != "null")
477
+ if (type == "string" || type == "object" || type == "array" || type == "number")
398
478
  DESERIALIZE += indent + " break;\n";
399
479
  }
400
480
  }
@@ -412,19 +492,23 @@ class JSONTransform extends Visitor {
412
492
  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';
413
493
  }
414
494
  else {
415
- if (type == "string")
495
+ if (type == "string") {
416
496
  DESERIALIZE += indent + " srcStart += 4;\n";
417
- else
497
+ }
498
+ else if (type == "boolean" || type == "null" || type == "number") {
418
499
  DESERIALIZE += indent + " srcStart += 2;\n";
500
+ }
419
501
  DESERIALIZE += indent + " keyStart = 0;\n";
502
+ if (type == "string" || type == "object" || type == "array" || type == "number")
503
+ DESERIALIZE += indent + " break;\n";
420
504
  }
421
505
  DESERIALIZE += " }\n";
422
506
  DESERIALIZE += " }\n";
423
- if (!members[0].node.type.isNullable && !isBoolean(members[0].type))
507
+ if (type != "null" && type != "boolean")
424
508
  DESERIALIZE += " break;\n";
425
509
  }
426
510
  };
427
- const generateComparisions = (members) => {
511
+ const generateConsts = (members) => {
428
512
  if (members.some((m) => (m.alias || m.name).length << 1 == 2)) {
429
513
  DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
430
514
  }
@@ -440,45 +524,6 @@ class JSONTransform extends Visitor {
440
524
  if (members.some((m) => (m.alias || m.name).length << 1 > 8)) {
441
525
  DESERIALIZE += toMemCDecl(Math.max(...members.map((m) => (m.alias || m.name).length << 1)), " ");
442
526
  }
443
- const complex = isStruct(members[0].type) || members[0].type != "JSON.Obj" || isArray(members[0].type);
444
- const firstMemberName = members[0].alias || members[0].name;
445
- DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
446
- 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";
447
- if (isString(members[0].type))
448
- DESERIALIZE += indent + " srcStart += 4;\n";
449
- else if (!complex)
450
- DESERIALIZE += indent + " srcStart += 2;\n";
451
- DESERIALIZE += indent + " keyStart = 0;\n";
452
- DESERIALIZE += indent + " break;\n";
453
- DESERIALIZE += indent + " }";
454
- for (let i = 1; i < members.length; i++) {
455
- const member = members[i];
456
- const memberName = member.alias || member.name;
457
- DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
458
- 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";
459
- if (isString(member.type))
460
- DESERIALIZE += indent + " srcStart += 4;\n";
461
- else if (!complex)
462
- DESERIALIZE += indent + " srcStart += 2;\n";
463
- DESERIALIZE += indent + " keyStart = 0;\n";
464
- DESERIALIZE += indent + " break;\n";
465
- DESERIALIZE += indent + " }";
466
- }
467
- if (STRICT) {
468
- DESERIALIZE += " else {\n";
469
- 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';
470
- DESERIALIZE += indent + " }\n";
471
- }
472
- else {
473
- DESERIALIZE += " else {\n";
474
- if (isString(members[0].type))
475
- DESERIALIZE += indent + " srcStart += 4;\n";
476
- else if (!complex)
477
- DESERIALIZE += indent + " srcStart += 2;\n";
478
- DESERIALIZE += indent + " keyStart = 0;\n";
479
- DESERIALIZE += indent + " break;\n";
480
- DESERIALIZE += indent + " }\n";
481
- }
482
527
  };
483
528
  let mbElse = " ";
484
529
  if (!STRICT || sortedMembers.string.length) {
@@ -488,7 +533,41 @@ class JSONTransform extends Visitor {
488
533
  DESERIALIZE += " while (srcStart < srcEnd) {\n";
489
534
  DESERIALIZE += " const code = load<u16>(srcStart);\n";
490
535
  DESERIALIZE += " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
491
- generateGroups(sortedMembers.string, generateComparisions, "string");
536
+ if (DEBUG > 1)
537
+ DESERIALIZE += " console.log(\"Value (string, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart + 2));";
538
+ generateGroups(sortedMembers.string, (group) => {
539
+ generateConsts(group);
540
+ const first = group[0];
541
+ const fName = first.alias || first.name;
542
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
543
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart + 2), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
544
+ DESERIALIZE += indent + " srcStart += 4;\n";
545
+ DESERIALIZE += indent + " keyStart = 0;\n";
546
+ DESERIALIZE += indent + " break;\n";
547
+ DESERIALIZE += indent + " }";
548
+ for (let i = 1; i < group.length; i++) {
549
+ const mem = group[i];
550
+ const memName = mem.alias || mem.name;
551
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
552
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart + 2), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
553
+ DESERIALIZE += indent + " srcStart += 4;\n";
554
+ DESERIALIZE += indent + " keyStart = 0;\n";
555
+ DESERIALIZE += indent + " break;\n";
556
+ DESERIALIZE += indent + " }";
557
+ }
558
+ if (STRICT) {
559
+ DESERIALIZE += " else {\n";
560
+ 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';
561
+ DESERIALIZE += indent + " }\n";
562
+ }
563
+ else {
564
+ DESERIALIZE += " else {\n";
565
+ DESERIALIZE += indent + " srcStart += 4;\n";
566
+ DESERIALIZE += indent + " keyStart = 0;\n";
567
+ DESERIALIZE += indent + " break;\n";
568
+ DESERIALIZE += indent + " }\n";
569
+ }
570
+ }, "string");
492
571
  DESERIALIZE += " }\n";
493
572
  DESERIALIZE += " srcStart += 2;\n";
494
573
  DESERIALIZE += " }\n";
@@ -502,7 +581,41 @@ class JSONTransform extends Visitor {
502
581
  DESERIALIZE += " while (srcStart < srcEnd) {\n";
503
582
  DESERIALIZE += " const code = load<u16>(srcStart);\n";
504
583
  DESERIALIZE += " if (code == 44 || code == 125 || JSON.Util.isSpace(code)) {\n";
505
- generateGroups(sortedMembers.number, generateComparisions, "number");
584
+ if (DEBUG > 1)
585
+ DESERIALIZE += " console.log(\"Value (number, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart));";
586
+ generateGroups(sortedMembers.number, (group) => {
587
+ generateConsts(group);
588
+ const first = group[0];
589
+ const fName = first.alias || first.name;
590
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
591
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
592
+ DESERIALIZE += indent + " srcStart += 2;\n";
593
+ DESERIALIZE += indent + " keyStart = 0;\n";
594
+ DESERIALIZE += indent + " break;\n";
595
+ DESERIALIZE += indent + " }";
596
+ for (let i = 1; i < group.length; i++) {
597
+ const mem = group[i];
598
+ const memName = mem.alias || mem.name;
599
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
600
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
601
+ DESERIALIZE += indent + " srcStart += 2;\n";
602
+ DESERIALIZE += indent + " keyStart = 0;\n";
603
+ DESERIALIZE += indent + " break;\n";
604
+ DESERIALIZE += indent + " }";
605
+ }
606
+ if (STRICT) {
607
+ DESERIALIZE += " else {\n";
608
+ 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';
609
+ DESERIALIZE += indent + " }\n";
610
+ }
611
+ else {
612
+ DESERIALIZE += " else {\n";
613
+ DESERIALIZE += indent + " srcStart += 2;\n";
614
+ DESERIALIZE += indent + " keyStart = 0;\n";
615
+ DESERIALIZE += indent + " break;\n";
616
+ DESERIALIZE += indent + " }\n";
617
+ }
618
+ }, "number");
506
619
  DESERIALIZE += " }\n";
507
620
  DESERIALIZE += " srcStart += 2;\n";
508
621
  DESERIALIZE += " }\n";
@@ -522,8 +635,39 @@ class JSONTransform extends Visitor {
522
635
  DESERIALIZE += " } else if (code == 125) {\n";
523
636
  DESERIALIZE += " if (--depth == 0) {\n";
524
637
  DESERIALIZE += " srcStart += 2;\n";
638
+ if (DEBUG > 1)
639
+ DESERIALIZE += " console.log(\"Value (object, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart));";
525
640
  indent = " ";
526
- generateGroups(sortedMembers.object, generateComparisions, "object");
641
+ generateGroups(sortedMembers.object, (group) => {
642
+ generateConsts(group);
643
+ const first = group[0];
644
+ const fName = first.alias || first.name;
645
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
646
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
647
+ DESERIALIZE += indent + " keyStart = 0;\n";
648
+ DESERIALIZE += indent + " break;\n";
649
+ DESERIALIZE += indent + " }";
650
+ for (let i = 1; i < group.length; i++) {
651
+ const mem = group[i];
652
+ const memName = mem.alias || mem.name;
653
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
654
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
655
+ DESERIALIZE += indent + " keyStart = 0;\n";
656
+ DESERIALIZE += indent + " break;\n";
657
+ DESERIALIZE += indent + " }";
658
+ }
659
+ if (STRICT) {
660
+ DESERIALIZE += " else {\n";
661
+ 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';
662
+ DESERIALIZE += indent + " }\n";
663
+ }
664
+ else {
665
+ DESERIALIZE += " else {\n";
666
+ DESERIALIZE += indent + " keyStart = 0;\n";
667
+ DESERIALIZE += indent + " break;\n";
668
+ DESERIALIZE += indent + " }\n";
669
+ }
670
+ }, "object");
527
671
  indent = "";
528
672
  DESERIALIZE += " }\n";
529
673
  DESERIALIZE += " } else if (code == 123) depth++;\n";
@@ -545,8 +689,39 @@ class JSONTransform extends Visitor {
545
689
  DESERIALIZE += " } else if (code == 93) {\n";
546
690
  DESERIALIZE += " if (--depth == 0) {\n";
547
691
  DESERIALIZE += " srcStart += 2;\n";
692
+ if (DEBUG > 1)
693
+ DESERIALIZE += " console.log(\"Value (object, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart));";
548
694
  indent = " ";
549
- generateGroups(sortedMembers.array, generateComparisions, "array");
695
+ generateGroups(sortedMembers.array, (group) => {
696
+ generateConsts(group);
697
+ const first = group[0];
698
+ const fName = first.alias || first.name;
699
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
700
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
701
+ DESERIALIZE += indent + " keyStart = 0;\n";
702
+ DESERIALIZE += indent + " break;\n";
703
+ DESERIALIZE += indent + " }";
704
+ for (let i = 1; i < group.length; i++) {
705
+ const mem = group[i];
706
+ const memName = mem.alias || mem.name;
707
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
708
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
709
+ DESERIALIZE += indent + " keyStart = 0;\n";
710
+ DESERIALIZE += indent + " break;\n";
711
+ DESERIALIZE += indent + " }";
712
+ }
713
+ if (STRICT) {
714
+ DESERIALIZE += " else {\n";
715
+ 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';
716
+ DESERIALIZE += indent + " }\n";
717
+ }
718
+ else {
719
+ DESERIALIZE += " else {\n";
720
+ DESERIALIZE += indent + " keyStart = 0;\n";
721
+ DESERIALIZE += indent + " break;\n";
722
+ DESERIALIZE += indent + " }\n";
723
+ }
724
+ }, "array");
550
725
  indent = "";
551
726
  DESERIALIZE += " }\n";
552
727
  DESERIALIZE += " } else if (code == 91) depth++;\n";
@@ -559,34 +734,23 @@ class JSONTransform extends Visitor {
559
734
  DESERIALIZE += mbElse + "if (code == 116) {\n";
560
735
  DESERIALIZE += " if (load<u64>(srcStart) == 28429475166421108) {\n";
561
736
  DESERIALIZE += " srcStart += 8;\n";
737
+ if (DEBUG > 1)
738
+ DESERIALIZE += " console.log(\"Value (bool, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart - 8));";
562
739
  generateGroups(sortedMembers.boolean, (group) => {
563
- if (group.some((m) => (m.alias || m.name).length << 1 == 2)) {
564
- DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
565
- }
566
- if (group.some((m) => (m.alias || m.name).length << 1 == 4)) {
567
- DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
568
- }
569
- if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
570
- DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
571
- }
572
- if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
573
- DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
574
- }
575
- if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
576
- DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
577
- }
578
- const firstMemberName = group[0].alias || group[0].name;
579
- DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
580
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
740
+ generateConsts(group);
741
+ const first = group[0];
742
+ const fName = first.alias || first.name;
743
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
744
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
581
745
  DESERIALIZE += indent + " srcStart += 2;\n";
582
746
  DESERIALIZE += indent + " keyStart = 0;\n";
583
747
  DESERIALIZE += indent + " break;\n";
584
748
  DESERIALIZE += indent + " }";
585
749
  for (let i = 1; i < group.length; i++) {
586
- const member = group[i];
587
- const memberName = member.alias || member.name;
588
- DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
589
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(member.name) + "));\n";
750
+ const mem = group[i];
751
+ const memName = mem.alias || mem.name;
752
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
753
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
590
754
  DESERIALIZE += indent + " srcStart += 2;\n";
591
755
  DESERIALIZE += indent + " keyStart = 0;\n";
592
756
  DESERIALIZE += indent + " break;\n";
@@ -614,34 +778,23 @@ class JSONTransform extends Visitor {
614
778
  DESERIALIZE += mbElse + "if (code == 102) {\n";
615
779
  DESERIALIZE += " if (load<u64>(srcStart, 2) == 28429466576093281) {\n";
616
780
  DESERIALIZE += " srcStart += 10;\n";
781
+ if (DEBUG > 1)
782
+ DESERIALIZE += " console.log(\"Value (bool, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart - 10));";
617
783
  generateGroups(sortedMembers.boolean, (group) => {
618
- if (group.some((m) => (m.alias || m.name).length << 1 == 2)) {
619
- DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
620
- }
621
- if (group.some((m) => (m.alias || m.name).length << 1 == 4)) {
622
- DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
623
- }
624
- if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
625
- DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
626
- }
627
- if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
628
- DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
629
- }
630
- if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
631
- DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
632
- }
633
- const firstMemberName = group[0].alias || group[0].name;
634
- DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
635
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
784
+ generateConsts(group);
785
+ const first = group[0];
786
+ const fName = first.alias || first.name;
787
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
788
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
636
789
  DESERIALIZE += indent + " srcStart += 2;\n";
637
790
  DESERIALIZE += indent + " keyStart = 0;\n";
638
791
  DESERIALIZE += indent + " break;\n";
639
792
  DESERIALIZE += indent + " }";
640
793
  for (let i = 1; i < group.length; i++) {
641
- const member = group[i];
642
- const memberName = member.alias || member.name;
643
- DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
644
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(member.name) + "));\n";
794
+ const mem = group[i];
795
+ const memName = mem.alias || mem.name;
796
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
797
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
645
798
  DESERIALIZE += indent + " srcStart += 2;\n";
646
799
  DESERIALIZE += indent + " keyStart = 0;\n";
647
800
  DESERIALIZE += indent + " break;\n";
@@ -671,34 +824,23 @@ class JSONTransform extends Visitor {
671
824
  DESERIALIZE += mbElse + "if (code == 110) {\n";
672
825
  DESERIALIZE += " if (load<u64>(srcStart) == 30399761348886638) {\n";
673
826
  DESERIALIZE += " srcStart += 8;\n";
827
+ if (DEBUG > 1)
828
+ DESERIALIZE += " console.log(\"Value (null, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart - 8));";
674
829
  generateGroups(sortedMembers.null, (group) => {
675
- if (group.some((m) => (m.alias || m.name).length << 1 == 2)) {
676
- DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
677
- }
678
- if (group.some((m) => (m.alias || m.name).length << 1 == 4)) {
679
- DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
680
- }
681
- if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
682
- DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
683
- }
684
- if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
685
- DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
686
- }
687
- if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
688
- DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
689
- }
690
- const firstMemberName = group[0].alias || group[0].name;
691
- DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
692
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
830
+ generateConsts(group);
831
+ const first = group[0];
832
+ const fName = first.alias || first.name;
833
+ DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
834
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
693
835
  DESERIALIZE += indent + " srcStart += 2;\n";
694
836
  DESERIALIZE += indent + " keyStart = 0;\n";
695
837
  DESERIALIZE += indent + " break;\n";
696
838
  DESERIALIZE += indent + " }";
697
839
  for (let i = 1; i < group.length; i++) {
698
- const member = group[i];
699
- const memberName = member.alias || member.name;
700
- DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
701
- DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(member.name) + "));\n";
840
+ const mem = group[i];
841
+ const memName = mem.alias || mem.name;
842
+ DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
843
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
702
844
  DESERIALIZE += indent + " srcStart += 2;\n";
703
845
  DESERIALIZE += indent + " keyStart = 0;\n";
704
846
  DESERIALIZE += indent + " break;\n";
@@ -738,7 +880,7 @@ class JSONTransform extends Visitor {
738
880
  SERIALIZE = SERIALIZE.slice(0, 32) + indent + "bs.proposeSize(" + this.schema.byteSize + ");\n" + SERIALIZE.slice(32);
739
881
  INITIALIZE += " return this;\n";
740
882
  INITIALIZE += "}";
741
- if (DEBUG) {
883
+ if (DEBUG > 0) {
742
884
  console.log(SERIALIZE_CUSTOM || SERIALIZE);
743
885
  console.log(INITIALIZE);
744
886
  console.log(DESERIALIZE_CUSTOM || DESERIALIZE);
@@ -754,11 +896,15 @@ class JSONTransform extends Visitor {
754
896
  node.members.push(DESERIALIZE_METHOD);
755
897
  super.visitClassDeclaration(node);
756
898
  }
899
+ getSchema(name) {
900
+ name = stripNull(name);
901
+ return this.schemas.get(this.schema.node.range.source.internalPath).find((s) => s.name == name) || null;
902
+ }
757
903
  generateEmptyMethods(node) {
758
904
  let SERIALIZE_EMPTY = "@inline __SERIALIZE(ptr: usize): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
759
905
  let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
760
906
  let DESERIALIZE_EMPTY = "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): __JSON_T {\n return this;\n}";
761
- if (DEBUG) {
907
+ if (DEBUG > 0) {
762
908
  console.log(SERIALIZE_EMPTY);
763
909
  console.log(INITIALIZE_EMPTY);
764
910
  console.log(DESERIALIZE_EMPTY);
@@ -781,31 +927,57 @@ class JSONTransform extends Visitor {
781
927
  this.imports = [];
782
928
  super.visitSource(node);
783
929
  }
784
- addRequiredImports(node) {
785
- const filePath = fileURLToPath(import.meta.url);
786
- const baseDir = path.resolve(filePath, "..", "..", "..");
787
- const nodePath = path.resolve(this.baseDir, node.range.source.normalizedPath);
930
+ addImports(node) {
931
+ const baseDir = path.resolve(fileURLToPath(import.meta.url), "..", "..", "..");
932
+ const pkgPath = path.join(this.baseCWD, "node_modules");
933
+ const isLibrary = existsSync(path.join(pkgPath, "json-as"));
934
+ let fromPath = node.range.source.normalizedPath;
935
+ fromPath = fromPath.startsWith("~lib/")
936
+ ? existsSync(path.join(pkgPath, fromPath.slice(5, fromPath.indexOf("/", 5))))
937
+ ? path.join(pkgPath, fromPath.slice(5))
938
+ : fromPath
939
+ : path.join(baseDir, fromPath);
788
940
  const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
789
941
  const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
790
- 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");
791
- 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");
942
+ let bsRel = removeExtension(path.posix.join(...path
943
+ .relative(path.dirname(fromPath), path.join(baseDir, "lib", "as-bs"))
944
+ .split(path.sep)));
945
+ let jsRel = removeExtension(path.posix.join(...path
946
+ .relative(path.dirname(fromPath), path.join(baseDir, "assembly", "index"))
947
+ .split(path.sep)));
948
+ if (bsRel.includes("node_modules" + path.sep + "json-as")) {
949
+ bsRel =
950
+ "json-as" +
951
+ bsRel.slice(bsRel.indexOf("node_modules" + path.sep + "json-as") + 20);
952
+ }
953
+ else if (!bsRel.startsWith(".") &&
954
+ !bsRel.startsWith("/") &&
955
+ !bsRel.startsWith("json-as")) {
956
+ bsRel = "./" + bsRel;
957
+ }
958
+ if (jsRel.includes("node_modules" + path.sep + "json-as")) {
959
+ jsRel =
960
+ "json-as" +
961
+ jsRel.slice(jsRel.indexOf("node_modules" + path.sep + "json-as") + 20);
962
+ }
963
+ else if (!jsRel.startsWith(".") &&
964
+ !jsRel.startsWith("/") &&
965
+ !jsRel.startsWith("json-as")) {
966
+ jsRel = "./" + jsRel;
967
+ }
792
968
  if (!bsImport) {
793
- if (node.normalizedPath.startsWith("~")) {
794
- bsPath = "json-as/lib/as-bs";
795
- }
796
- const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range)], Node.createStringLiteralExpression(bsPath, node.range), node.range);
797
- this.topStatements.push(replaceNode);
798
- if (DEBUG)
799
- console.log("Added as-bs import: " + toString(replaceNode) + "\n");
969
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range)
970
+ ], Node.createStringLiteralExpression(bsRel, node.range), node.range);
971
+ node.range.source.statements.unshift(replaceNode);
972
+ if (DEBUG > 0)
973
+ console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
800
974
  }
801
975
  if (!jsonImport) {
802
- if (node.normalizedPath.startsWith("~")) {
803
- jsonPath = "json-as/assembly/index.ts";
804
- }
805
- const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("JSON", node.range, false), null, node.range)], Node.createStringLiteralExpression(jsonPath, node.range), node.range);
806
- this.topStatements.push(replaceNode);
807
- if (DEBUG)
808
- console.log("Added json-as import: " + toString(replaceNode) + "\n");
976
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("JSON", node.range, false), null, node.range)
977
+ ], Node.createStringLiteralExpression(jsRel, node.range), node.range);
978
+ node.range.source.statements.unshift(replaceNode);
979
+ if (DEBUG > 0)
980
+ console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
809
981
  }
810
982
  }
811
983
  getStores(data, simd = false) {
@@ -838,7 +1010,7 @@ class JSONTransform extends Visitor {
838
1010
  return out;
839
1011
  }
840
1012
  isValidType(type, node) {
841
- 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)];
1013
+ 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)];
842
1014
  const baseTypes = ["Array", "Map", "Set", "JSON.Box", "Box"];
843
1015
  if (node && node.isGeneric && node.typeParameters)
844
1016
  validTypes.push(...node.typeParameters.map((v) => v.name.text));
@@ -884,7 +1056,7 @@ export default class Transformer extends Transform {
884
1056
  return 0;
885
1057
  }
886
1058
  });
887
- transformer.baseDir = path.join(process.cwd(), this.baseDir);
1059
+ transformer.baseCWD = path.join(process.cwd(), this.baseDir);
888
1060
  transformer.program = this.program;
889
1061
  transformer.parser = parser;
890
1062
  for (const source of sources) {
@@ -900,13 +1072,11 @@ export default class Transformer extends Transform {
900
1072
  source.statements.unshift(SimpleParser.parseTopLevelStatement(simd));
901
1073
  }
902
1074
  transformer.simdStatements = [];
903
- }
904
- const schemas = transformer.schemas;
905
- for (const schema of schemas) {
906
- if (schema.parent) {
907
- const parent = schemas.find((v) => v.name == schema.parent?.name);
908
- if (!parent)
909
- 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);
1075
+ if (transformer.schemas.has(source.internalPath)) {
1076
+ transformer.addImports(source);
1077
+ }
1078
+ if (source.normalizedPath == WRITE) {
1079
+ writeFileSync(path.join(process.cwd(), this.baseDir, removeExtension(source.normalizedPath) + ".json.ts"), toString(source));
910
1080
  }
911
1081
  }
912
1082
  }
@@ -1041,9 +1211,9 @@ function isPrimitive(type) {
1041
1211
  function isBoolean(type) {
1042
1212
  return type == "bool" || type == "boolean";
1043
1213
  }
1044
- function isStruct(type) {
1214
+ function isStruct(type, source) {
1045
1215
  type = stripNull(type);
1046
- return JSONTransform.SN.schemas.some((v) => v.name == type) || JSONTransform.SN.schema.name == type;
1216
+ return JSONTransform.SN.schemas.get(source.internalPath).some((v) => v.name == type) || JSONTransform.SN.schema.name == type;
1047
1217
  }
1048
1218
  function isString(type) {
1049
1219
  return stripNull(type) == "string" || stripNull(type) == "String";