json-as 1.1.11 → 1.1.12

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,12 +1,13 @@
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";
1
+ import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, CommonFlags, ImportStatement, Node, SourceKind, NamedTypeNode, Range, FunctionExpression, MethodDeclaration, Program, Feature } 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, removeExtension, replaceRef, 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
- import { Property, PropertyFlags, Schema } from "./types.js";
8
- import { getClass, getClasses, getImportedClass } from "./linker.js";
7
+ import { Property, PropertyFlags, Schema, Src } from "./types.js";
8
+ import { getClass, getImportedClass } from "./linkers/classes.js";
9
9
  import { existsSync, writeFileSync } from "fs";
10
+ import { CustomTransform } from "./linkers/custom.js";
10
11
 
11
12
  let indent = " ";
12
13
 
@@ -25,37 +26,6 @@ const DEBUG = rawValue === "true"
25
26
 
26
27
  const STRICT = process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "true";
27
28
 
28
- class CustomTransform extends Visitor {
29
- static SN: CustomTransform = new CustomTransform();
30
-
31
- private modify: boolean = false;
32
- visitCallExpression(node: CallExpression) {
33
- super.visit(node.args, node);
34
- if (node.expression.kind != NodeKind.PropertyAccess || (node.expression as PropertyAccessExpression).property.text != "stringify") return;
35
- if ((node.expression as PropertyAccessExpression).expression.kind != NodeKind.Identifier || ((node.expression as PropertyAccessExpression).expression as IdentifierExpression).text != "JSON") return;
36
-
37
- if (this.modify) {
38
- (node.expression as PropertyAccessExpression).expression = Node.createPropertyAccessExpression(Node.createIdentifierExpression("JSON", node.expression.range), Node.createIdentifierExpression("internal", node.expression.range), node.expression.range);
39
- }
40
- this.modify = true;
41
-
42
- // console.log(toString(node));
43
- // console.log(SimpleParser.parseStatement("JSON.internal.stringify").expression.expression)
44
- }
45
- static visit(node: Node | Node[], ref: Node | null = null): void {
46
- if (!node) return;
47
- CustomTransform.SN.modify = true;
48
- CustomTransform.SN.visit(node, ref);
49
- CustomTransform.SN.modify = false;
50
- }
51
- static hasCall(node: Node | Node[]): boolean {
52
- if (!node) return;
53
- CustomTransform.SN.modify = false;
54
- CustomTransform.SN.visit(node);
55
- return CustomTransform.SN.modify;
56
- }
57
- }
58
-
59
29
  class JSONTransform extends Visitor {
60
30
  static SN: JSONTransform = new JSONTransform();
61
31
 
@@ -64,10 +34,10 @@ class JSONTransform extends Visitor {
64
34
  public parser!: Parser;
65
35
  public schemas: Map<string, Schema[]> = new Map<string, Schema[]>();
66
36
  public schema!: Schema;
67
- public sources = new Set<Source>();
37
+ public src!: Src;
38
+ public sources: Map<string, Src> = new Map<string, Src>();
68
39
  public imports: ImportStatement[] = [];
69
40
 
70
- public topStatements: Statement[] = [];
71
41
  public simdStatements: string[] = [];
72
42
 
73
43
  private visitedClasses: Set<string> = new Set<string>();
@@ -90,11 +60,16 @@ class JSONTransform extends Visitor {
90
60
  const name = (<IdentifierExpression>decorator.name).text;
91
61
  return name === "json" || name === "serializable";
92
62
  })
93
- )
94
- return;
63
+ ) return;
95
64
 
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, []);
65
+ const source = node.range.source;
66
+ if (!this.sources.has(source.internalPath)) {
67
+ this.src = new Src(source);
68
+ this.sources.set(source.internalPath, this.src);
69
+ } else this.src = this.sources.get(source.internalPath);
70
+
71
+ if (this.visitedClasses.has(source.internalPath + node.name.text)) return;
72
+ if (!this.schemas.has(source.internalPath)) this.schemas.set(source.internalPath, []);
98
73
 
99
74
  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
75
  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[];
@@ -109,13 +84,13 @@ class JSONTransform extends Visitor {
109
84
  if (!schema.parent) {
110
85
  const depSearch = schema.deps.find((v) => v.name == extendsName);
111
86
  if (depSearch) {
112
- if (DEBUG > 0) console.log("Found " + extendsName + " in dependencies of " + node.range.source.internalPath);
87
+ if (DEBUG > 0) console.log("Found " + extendsName + " in dependencies of " + source.internalPath);
113
88
  if (!schema.deps.some(v => v.name == depSearch.name)) schema.deps.push(depSearch);
114
89
  schema.parent = depSearch;
115
90
  } else {
116
- const internalSearch = getClass(extendsName, node.range.source);
91
+ const internalSearch = getClass(extendsName, source);
117
92
  if (internalSearch) {
118
- if (DEBUG > 0) console.log("Found " + extendsName + " internally from " + node.range.source.internalPath);
93
+ if (DEBUG > 0) console.log("Found " + extendsName + " internally from " + source.internalPath);
119
94
  if (!this.visitedClasses.has(internalSearch.range.source.internalPath + internalSearch.name.text)) {
120
95
  this.visitClassDeclarationRef(internalSearch);
121
96
  this.schemas.get(internalSearch.range.source.internalPath).push(this.schema);
@@ -127,9 +102,9 @@ class JSONTransform extends Visitor {
127
102
  schema.deps.push(schem);
128
103
  schema.parent = schem;
129
104
  } else {
130
- const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
105
+ const externalSearch = getImportedClass(extendsName, source, this.parser);
131
106
  if (externalSearch) {
132
- if (DEBUG > 0) console.log("Found " + externalSearch.name.text + " externally from " + node.range.source.internalPath);
107
+ if (DEBUG > 0) console.log("Found " + externalSearch.name.text + " externally from " + source.internalPath);
133
108
  if (!this.visitedClasses.has(externalSearch.range.source.internalPath + externalSearch.name.text)) {
134
109
  this.visitClassDeclarationRef(externalSearch);
135
110
  this.schemas.get(externalSearch.range.source.internalPath).push(this.schema);
@@ -156,6 +131,7 @@ class JSONTransform extends Visitor {
156
131
 
157
132
  const getUnknownTypes = (type: string, types: string[] = []): string[] => {
158
133
  type = stripNull(type);
134
+ type = this.src.aliases.find(v => stripNull(v.name) == type)?.getBaseType() || type;
159
135
  if (type.startsWith("Array<")) {
160
136
  return getUnknownTypes(type.slice(6, -1));
161
137
  } else if (type.startsWith("Map<")) {
@@ -181,12 +157,12 @@ class JSONTransform extends Visitor {
181
157
  for (const unknownType of unknown) {
182
158
  const depSearch = schema.deps.find((v) => v.name == unknownType);
183
159
  if (depSearch) {
184
- if (DEBUG > 0) console.log("Found " + unknownType + " in dependencies of " + node.range.source.internalPath);
160
+ if (DEBUG > 0) console.log("Found " + unknownType + " in dependencies of " + source.internalPath);
185
161
  if (!schema.deps.some(v => v.name == depSearch.name)) schema.deps.push(depSearch);
186
162
  } else {
187
- const internalSearch = getClass(unknownType, node.range.source);
163
+ const internalSearch = getClass(unknownType, source);
188
164
  if (internalSearch) {
189
- if (DEBUG > 0) console.log("Found " + unknownType + " internally from " + node.range.source.internalPath);
165
+ if (DEBUG > 0) console.log("Found " + unknownType + " internally from " + source.internalPath);
190
166
  if (!this.visitedClasses.has(internalSearch.range.source.internalPath + internalSearch.name.text)) {
191
167
  this.visitClassDeclarationRef(internalSearch);
192
168
  this.schemas.get(internalSearch.range.source.internalPath).push(this.schema);
@@ -197,9 +173,9 @@ class JSONTransform extends Visitor {
197
173
  if (!schem) throw new Error("Could not find schema for " + internalSearch.name.text + " in " + internalSearch.range.source.internalPath);
198
174
  schema.deps.push(schem);
199
175
  } else {
200
- const externalSearch = getImportedClass(unknownType, node.range.source, this.parser);
176
+ const externalSearch = getImportedClass(unknownType, source, this.parser);
201
177
  if (externalSearch) {
202
- if (DEBUG > 0) console.log("Found " + externalSearch.name.text + " externally from " + node.range.source.internalPath);
178
+ if (DEBUG > 0) console.log("Found " + externalSearch.name.text + " externally from " + source.internalPath);
203
179
  if (!this.visitedClasses.has(externalSearch.range.source.internalPath + externalSearch.name.text)) {
204
180
  this.visitClassDeclarationRef(externalSearch);
205
181
  this.schemas.get(externalSearch.range.source.internalPath).push(this.schema);
@@ -215,9 +191,9 @@ class JSONTransform extends Visitor {
215
191
  }
216
192
  }
217
193
 
218
- this.schemas.get(node.range.source.internalPath).push(schema);
194
+ this.schemas.get(source.internalPath).push(schema);
219
195
  this.schema = schema;
220
- this.visitedClasses.add(node.range.source.internalPath + node.name.text);
196
+ this.visitedClasses.add(source.internalPath + node.name.text);
221
197
 
222
198
  let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
223
199
  let INITIALIZE = "@inline __INITIALIZE(): this {\n";
@@ -225,7 +201,7 @@ class JSONTransform extends Visitor {
225
201
  let DESERIALIZE_CUSTOM = "";
226
202
  let SERIALIZE_CUSTOM = "";
227
203
 
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 ") : ""));
204
+ if (DEBUG > 0) console.log("Created schema: " + this.schema.name + " in file " + source.normalizedPath + (this.schema.deps.length ? " with dependencies:\n " + this.schema.deps.map((v) => v.name).join("\n ") : ""));
229
205
 
230
206
  if (serializers.length > 1) throwError("Multiple serializers detected for class " + node.name.text + " but schemas can only have one serializer!", serializers[1].range);
231
207
  if (deserializers.length > 1) throwError("Multiple deserializers detected for class " + node.name.text + " but schemas can only have one deserializer!", deserializers[1].range);
@@ -278,7 +254,9 @@ class JSONTransform extends Visitor {
278
254
 
279
255
  for (const member of members) {
280
256
  if (!member.type) throwError("Fields must be strongly typed", node.range);
281
- const type = toString(member.type!);
257
+ let type = toString(member.type!);
258
+ type = this.src.aliases.find(v => stripNull(v.name) == stripNull(type))?.getBaseType() || type;
259
+
282
260
  const name = member.name;
283
261
  const value = member.initializer ? toString(member.initializer!) : null;
284
262
 
@@ -448,16 +426,27 @@ class JSONTransform extends Visitor {
448
426
  };
449
427
 
450
428
  for (const member of this.schema.members) {
451
- if (member.type.endsWith(" | null")) sortedMembers.null.push(member);
452
- if (isString(member.type) || member.type == "JSON.Raw") sortedMembers.string.push(member);
453
- else if (isBoolean(member.type) || member.type.startsWith("JSON.Box<bool")) sortedMembers.boolean.push(member);
454
- else if (isPrimitive(member.type) || member.type.startsWith("JSON.Box<")) sortedMembers.number.push(member);
455
- else if (isArray(member.type)) sortedMembers.array.push(member);
456
- else sortedMembers.object.push(member);
429
+ const type = stripNull(member.type);
430
+ if (node.isGeneric && node.typeParameters.some((p) => stripNull(p.name.text) == type)) {
431
+ member.generic = true;
432
+ sortedMembers.string.push(member);
433
+ sortedMembers.number.push(member);
434
+ sortedMembers.object.push(member);
435
+ sortedMembers.array.push(member);
436
+ sortedMembers.boolean.push(member);
437
+ sortedMembers.null.push(member);
438
+ } else {
439
+ if (member.node.type.isNullable) sortedMembers.null.push(member);
440
+ if (isString(type) || type == "JSON.Raw") sortedMembers.string.push(member);
441
+ else if (isBoolean(type) || type.startsWith("JSON.Box<bool")) sortedMembers.boolean.push(member);
442
+ else if (isPrimitive(type) || type.startsWith("JSON.Box<")) sortedMembers.number.push(member);
443
+ else if (isArray(type)) sortedMembers.array.push(member);
444
+ else if (isStruct(type, source)) sortedMembers.object.push(member);
445
+ else throw new Error("Could not determine type " + type + " for member " + member.name + " in class " + this.schema.name);
446
+ }
457
447
  }
458
448
 
459
449
  indent = "";
460
- let shouldGroup = false;
461
450
 
462
451
  DESERIALIZE += indent + " let keyStart: usize = 0;\n";
463
452
  DESERIALIZE += indent + " let keyEnd: usize = 0;\n";
@@ -634,7 +623,7 @@ class JSONTransform extends Visitor {
634
623
  generateConsts(group);
635
624
  const first = group[0];
636
625
  const fName = first.alias || first.name;
637
- DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
626
+ DESERIALIZE += indent + " if (" + (first.generic ? "isString<" + first.type + ">() && " : "") + getComparision(fName) + ") { // " + fName + "\n";
638
627
  DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart + 2), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
639
628
  DESERIALIZE += indent + " srcStart += 4;\n";
640
629
  DESERIALIZE += indent + " keyStart = 0;\n";
@@ -644,7 +633,7 @@ class JSONTransform extends Visitor {
644
633
  for (let i = 1; i < group.length; i++) {
645
634
  const mem = group[i];
646
635
  const memName = mem.alias || mem.name;
647
- DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
636
+ DESERIALIZE += indent + " else if (" + (mem.generic ? "isString<" + mem.type + ">() && " : "") + getComparision(memName) + ") { // " + memName + "\n";
648
637
  DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart + 2), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
649
638
  DESERIALIZE += indent + " srcStart += 4;\n";
650
639
  DESERIALIZE += indent + " keyStart = 0;\n";
@@ -685,7 +674,7 @@ class JSONTransform extends Visitor {
685
674
  generateConsts(group);
686
675
  const first = group[0];
687
676
  const fName = first.alias || first.name;
688
- DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
677
+ DESERIALIZE += indent + " if (" + (first.generic ? "(isInteger<" + first.type + ">() || isFloat<" + first.type + ">()) && " : "") + getComparision(fName) + ") { // " + fName + "\n";
689
678
  DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
690
679
  DESERIALIZE += indent + " srcStart += 2;\n";
691
680
  DESERIALIZE += indent + " keyStart = 0;\n";
@@ -695,7 +684,7 @@ class JSONTransform extends Visitor {
695
684
  for (let i = 1; i < group.length; i++) {
696
685
  const mem = group[i];
697
686
  const memName = mem.alias || mem.name;
698
- DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
687
+ DESERIALIZE += indent + " else if (" + (mem.generic ? "(isInteger<" + mem.type + ">() || isFloat<" + mem.type + ">()) && " : "") + getComparision(memName) + ") { // " + memName + "\n";
699
688
  DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
700
689
  DESERIALIZE += indent + " srcStart += 2;\n";
701
690
  DESERIALIZE += indent + " keyStart = 0;\n";
@@ -742,7 +731,7 @@ class JSONTransform extends Visitor {
742
731
  generateConsts(group);
743
732
  const first = group[0];
744
733
  const fName = first.alias || first.name;
745
- DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
734
+ DESERIALIZE += indent + " if (" + (first.generic ? "isDefined(out.__DESERIALIZE) &&" : "") + getComparision(fName) + ") { // " + fName + "\n";
746
735
  DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
747
736
  DESERIALIZE += indent + " keyStart = 0;\n";
748
737
  DESERIALIZE += indent + " break;\n";
@@ -751,7 +740,7 @@ class JSONTransform extends Visitor {
751
740
  for (let i = 1; i < group.length; i++) {
752
741
  const mem = group[i];
753
742
  const memName = mem.alias || mem.name;
754
- DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
743
+ DESERIALIZE += indent + " else if (" + (mem.generic ? "isDefined(out.__DESERIALIZE) &&" : "") + getComparision(memName) + ") { // " + memName + "\n";
755
744
  DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
756
745
  DESERIALIZE += indent + " keyStart = 0;\n";
757
746
  DESERIALIZE += indent + " break;\n";
@@ -798,7 +787,7 @@ class JSONTransform extends Visitor {
798
787
  generateConsts(group);
799
788
  const first = group[0];
800
789
  const fName = first.alias || first.name;
801
- DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
790
+ DESERIALIZE += indent + " if (" + (first.generic ? "isArray<" + first.type + ">() && " : "") + getComparision(fName) + ") { // " + fName + "\n";
802
791
  DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
803
792
  DESERIALIZE += indent + " keyStart = 0;\n";
804
793
  DESERIALIZE += indent + " break;\n";
@@ -807,7 +796,7 @@ class JSONTransform extends Visitor {
807
796
  for (let i = 1; i < group.length; i++) {
808
797
  const mem = group[i];
809
798
  const memName = mem.alias || mem.name;
810
- DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
799
+ DESERIALIZE += indent + " else if (" + (mem.generic ? "isArray" + mem.type + ">() && " : "") + getComparision(memName) + ") { // " + memName + "\n";
811
800
  DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
812
801
  DESERIALIZE += indent + " keyStart = 0;\n";
813
802
  DESERIALIZE += indent + " break;\n";
@@ -846,7 +835,7 @@ class JSONTransform extends Visitor {
846
835
  generateConsts(group);
847
836
  const first = group[0];
848
837
  const fName = first.alias || first.name;
849
- DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
838
+ DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparision(fName) + ") { // " + fName + "\n";
850
839
  DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
851
840
  DESERIALIZE += indent + " srcStart += 2;\n";
852
841
  DESERIALIZE += indent + " keyStart = 0;\n";
@@ -856,7 +845,7 @@ class JSONTransform extends Visitor {
856
845
  for (let i = 1; i < group.length; i++) {
857
846
  const mem = group[i];
858
847
  const memName = mem.alias || mem.name;
859
- DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
848
+ DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparision(memName) + ") { // " + memName + "\n";
860
849
  DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
861
850
  DESERIALIZE += indent + " srcStart += 2;\n";
862
851
  DESERIALIZE += indent + " keyStart = 0;\n";
@@ -898,7 +887,7 @@ class JSONTransform extends Visitor {
898
887
 
899
888
  const first = group[0];
900
889
  const fName = first.alias || first.name;
901
- DESERIALIZE += indent + " if (" + getComparision(fName) + ") { // " + fName + "\n";
890
+ DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparision(fName) + ") { // " + fName + "\n";
902
891
  DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
903
892
  DESERIALIZE += indent + " srcStart += 2;\n";
904
893
  DESERIALIZE += indent + " keyStart = 0;\n";
@@ -908,7 +897,7 @@ class JSONTransform extends Visitor {
908
897
  for (let i = 1; i < group.length; i++) {
909
898
  const mem = group[i];
910
899
  const memName = mem.alias || mem.name;
911
- DESERIALIZE += indent + " else if (" + getComparision(memName) + ") { // " + memName + "\n";
900
+ DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparision(memName) + ") { // " + memName + "\n";
912
901
  DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
913
902
  DESERIALIZE += indent + " srcStart += 2;\n";
914
903
  DESERIALIZE += indent + " keyStart = 0;\n";
@@ -951,8 +940,8 @@ class JSONTransform extends Visitor {
951
940
 
952
941
  const first = group[0];
953
942
  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";
943
+ DESERIALIZE += indent + " if (" + (first.generic ? "isNullable<" + first.type + ">() && " : "") + getComparision(fName) + ") { // " + fName + "\n";
944
+ DESERIALIZE += indent + " store<usize>(changetype<usize>(out), 0, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
956
945
  DESERIALIZE += indent + " srcStart += 2;\n";
957
946
  DESERIALIZE += indent + " keyStart = 0;\n";
958
947
  DESERIALIZE += indent + " break;\n";
@@ -961,8 +950,8 @@ class JSONTransform extends Visitor {
961
950
  for (let i = 1; i < group.length; i++) {
962
951
  const mem = group[i];
963
952
  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";
953
+ DESERIALIZE += indent + " else if (" + (mem.generic ? "isNullable<" + mem.type + ">() && " : "") + getComparision(memName) + ") { // " + memName + "\n";
954
+ DESERIALIZE += indent + " store<usize>(changetype<usize>(out), 0, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
966
955
  DESERIALIZE += indent + " srcStart += 2;\n";
967
956
  DESERIALIZE += indent + " keyStart = 0;\n";
968
957
  DESERIALIZE += indent + " break;\n";
@@ -1267,10 +1256,6 @@ export default class Transformer extends Transform {
1267
1256
  transformer.currentSource = source;
1268
1257
  transformer.visit(source);
1269
1258
 
1270
- if (transformer.topStatements.length) {
1271
- source.statements.unshift(...transformer.topStatements);
1272
- transformer.topStatements = [];
1273
- }
1274
1259
  if (transformer.simdStatements.length) {
1275
1260
  for (const simd of transformer.simdStatements) source.statements.unshift(SimpleParser.parseTopLevelStatement(simd));
1276
1261
  }
@@ -0,0 +1,59 @@
1
+ import { Node, Source, TypeDeclaration, TypeNode } from "assemblyscript/dist/assemblyscript.js";
2
+ import { Visitor } from "../visitor.js";
3
+ import { toString } from "../util.js";
4
+
5
+ class AliasFinder extends Visitor {
6
+ visitTypeDeclaration(node: TypeDeclaration, ref?: Node | null): void {
7
+ TypeAlias.add(node.name.text, node.type);
8
+ }
9
+ }
10
+
11
+ export class TypeAlias {
12
+ public name: string;
13
+ public type: TypeAlias | string;
14
+
15
+ constructor(name: string, type: TypeAlias | string) {
16
+ this.name = name;
17
+ this.type = type;
18
+ }
19
+
20
+ getBaseType(type: TypeAlias | string = this.type): string {
21
+ if (typeof type === "string") return type;
22
+ return this.getBaseType(type.type);
23
+ }
24
+
25
+ static foundAliases: Map<string, string> = new Map<string, string>();
26
+ static aliases: Map<string, TypeAlias> = new Map<string, TypeAlias>();
27
+
28
+ static add(name: string, type: TypeNode): void {
29
+ if (!TypeAlias.foundAliases.has(name)) {
30
+ TypeAlias.foundAliases.set(name, toString(type));
31
+ } else {
32
+ const existingType = TypeAlias.foundAliases.get(name);
33
+ if (existingType !== toString(type)) {
34
+ throw new Error(`Type alias conflict for ${name}: "${existingType}" vs "${toString(type)}"`);
35
+ }
36
+ }
37
+ }
38
+
39
+ static getAliases(source: Source): TypeAlias[] {
40
+ this.foundAliases.clear();
41
+ this.aliases.clear();
42
+
43
+ const finder = new AliasFinder();
44
+ finder.visit(source);
45
+
46
+ for (const [name, typeStr] of this.foundAliases) {
47
+ this.aliases.set(name, new TypeAlias(name, typeStr));
48
+ }
49
+
50
+ for (const alias of this.aliases.values()) {
51
+ if (typeof alias.type === "string" && this.aliases.has(alias.type)) {
52
+ alias.type = this.aliases.get(alias.type)!;
53
+ }
54
+ }
55
+
56
+ return [...this.aliases.values()];
57
+ }
58
+
59
+ }
@@ -1,26 +1,6 @@
1
- import { ClassDeclaration, CommonFlags, ImportStatement, NodeKind, Parser, Source } from "assemblyscript/dist/assemblyscript.js";
2
- import { Visitor } from "./visitor.js";
3
- import { Node } from "types:assemblyscript/src/ast";
4
-
5
- class ImportGetter extends Visitor {
6
- static SN: ImportGetter = new ImportGetter();
7
-
8
- private imports: ImportStatement[] = [];
9
-
10
- visitImportStatement(node: ImportStatement, ref?: Node | null): void {
11
- this.imports.push(node);
12
- }
13
-
14
- static getImports(source: Source): ImportStatement[] {
15
- ImportGetter.SN.imports = [];
16
- ImportGetter.SN.visit(source);
17
- return ImportGetter.SN.imports;
18
- }
19
- }
20
-
21
- export function getImports(source: Source): ImportStatement[] {
22
- return ImportGetter.getImports(source);
23
- }
1
+ import { ClassDeclaration, CommonFlags, NodeKind, Parser, Source } from "assemblyscript/dist/assemblyscript.js";
2
+ import { Visitor } from "../visitor.js";
3
+ import { getImports } from "./imports.js";
24
4
 
25
5
  export function getImportedClass(name: string, source: Source, parser: Parser): ClassDeclaration | null {
26
6
  for (const stmt of getImports(source)) {
@@ -0,0 +1,32 @@
1
+ import { CallExpression, IdentifierExpression, Node, NodeKind, PropertyAccessExpression } from "assemblyscript/dist/assemblyscript.js";
2
+ import { Visitor } from "../visitor.js";
3
+
4
+ export class CustomTransform extends Visitor {
5
+ static SN: CustomTransform = new CustomTransform();
6
+ private modify: boolean = false;
7
+ visitCallExpression(node: CallExpression) {
8
+ super.visit(node.args, node);
9
+ if (node.expression.kind != NodeKind.PropertyAccess || (node.expression as PropertyAccessExpression).property.text != "stringify") return;
10
+ if ((node.expression as PropertyAccessExpression).expression.kind != NodeKind.Identifier || ((node.expression as PropertyAccessExpression).expression as IdentifierExpression).text != "JSON") return;
11
+
12
+ if (this.modify) {
13
+ (node.expression as PropertyAccessExpression).expression = Node.createPropertyAccessExpression(Node.createIdentifierExpression("JSON", node.expression.range), Node.createIdentifierExpression("internal", node.expression.range), node.expression.range);
14
+ }
15
+ this.modify = true;
16
+
17
+ // console.log(toString(node));
18
+ // console.log(SimpleParser.parseStatement("JSON.internal.stringify").expression.expression)
19
+ }
20
+ static visit(node: Node | Node[], ref: Node | null = null): void {
21
+ if (!node) return;
22
+ CustomTransform.SN.modify = true;
23
+ CustomTransform.SN.visit(node, ref);
24
+ CustomTransform.SN.modify = false;
25
+ }
26
+ static hasCall(node: Node | Node[]): boolean {
27
+ if (!node) return false;
28
+ CustomTransform.SN.modify = false;
29
+ CustomTransform.SN.visit(node);
30
+ return CustomTransform.SN.modify;
31
+ }
32
+ }
@@ -0,0 +1,22 @@
1
+ import { ImportStatement, Node, Source } from "assemblyscript/dist/assemblyscript.js";
2
+ import { Visitor } from "../visitor.js";
3
+
4
+ class ImportGetter extends Visitor {
5
+ static SN: ImportGetter = new ImportGetter();
6
+
7
+ private imports: ImportStatement[] = [];
8
+
9
+ visitImportStatement(node: ImportStatement, ref?: Node | null): void {
10
+ this.imports.push(node);
11
+ }
12
+
13
+ static getImports(source: Source): ImportStatement[] {
14
+ ImportGetter.SN.imports = [];
15
+ ImportGetter.SN.visit(source);
16
+ return ImportGetter.SN.imports;
17
+ }
18
+ }
19
+
20
+ export function getImports(source: Source): ImportStatement[] {
21
+ return ImportGetter.getImports(source);
22
+ }
@@ -1,4 +1,5 @@
1
- import { ClassDeclaration, Expression, FieldDeclaration } from "assemblyscript/dist/assemblyscript.js";
1
+ import { ClassDeclaration, Expression, FieldDeclaration, Source } from "assemblyscript/dist/assemblyscript.js";
2
+ import { TypeAlias } from "./linkers/alias.js";
2
3
 
3
4
  export enum PropertyFlags {
4
5
  OmitNull,
@@ -15,6 +16,7 @@ export class Property {
15
16
  public flags: Map<PropertyFlags, Expression | null> = new Map<PropertyFlags, Expression | null>();
16
17
  public node!: FieldDeclaration;
17
18
  public byteSize: number = 0;
19
+ public generic: boolean = false;
18
20
  }
19
21
 
20
22
  export class Schema {
@@ -28,3 +30,15 @@ export class Schema {
28
30
  public deps: Schema[] = [];
29
31
  public custom: boolean = false;
30
32
  }
33
+
34
+ export class Src {
35
+ public internalPath: string;
36
+ public schemas: Schema[];
37
+ public aliases: TypeAlias[];
38
+ public imports: Schema[];
39
+ public exports: Schema[];
40
+ constructor(source: Source) {
41
+ this.internalPath = source.internalPath;
42
+ this.aliases = TypeAlias.getAliases(source);
43
+ }
44
+ }
@@ -8,5 +8,5 @@
8
8
  "outDir": "./lib",
9
9
  "sourceMap": true
10
10
  },
11
- "include": ["./src/*.ts"]
11
+ "include": ["./src/**.ts"]
12
12
  }
package/bench/lib/test.ts DELETED
@@ -1,37 +0,0 @@
1
- let currentDescription: string = "";
2
- export function describe(description: string, routine: () => void): void {
3
- currentDescription = description;
4
- routine();
5
- }
6
-
7
- export function it(description: string, routine: () => void): void {
8
- currentDescription = description;
9
- routine();
10
- }
11
-
12
- export function expect<T>(left: T): Expectation {
13
- // @ts-ignore
14
- if (!left.toString) throw new Error("Expected left to have a toString method, but it does not.");
15
- // @ts-ignore
16
- return new Expectation(left == null ? "null" : left.toString());
17
- }
18
-
19
- class Expectation {
20
- public left: string;
21
-
22
- constructor(left: string) {
23
- this.left = left;
24
- }
25
- toBe<T>(right: T): void {
26
- // @ts-ignore
27
- if (!right.toString) throw new Error("Expected right to have a toString method, but it does not.");
28
- // @ts-ignore
29
- if (this.left != (right == null ? "null" : right.toString())) {
30
- console.log(" " + currentDescription + "\n");
31
- // @ts-ignore
32
- console.log(" (expected) -> " + (right == null ? "null" : right.toString()));
33
- console.log(" (received) -> " + this.left);
34
- process.exit(1);
35
- }
36
- }
37
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"linker.js","sourceRoot":"","sources":["../src/linker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,YAAa,SAAQ,OAAO;IAChC,MAAM,CAAC,EAAE,GAAiB,IAAI,YAAY,EAAE,CAAC;IAErC,OAAO,GAAsB,EAAE,CAAC;IAExC,oBAAoB,CAAC,IAAqB,EAAE,GAAiB;QAC3D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,MAAc;QAC9B,YAAY,CAAC,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC;QAC7B,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC;IACjC,CAAC;;AAGH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,MAAc,EAAE,MAAc;IAC3E,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;QACpJ,IAAI,CAAC,cAAc;YAAE,SAAS;QAE9B,MAAM,gBAAgB,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QACpE,IAAI,CAAC,gBAAgB;YAAE,SAAS;QAChC,IAAI,CAAC,CAAC,gBAAgB,CAAC,KAAK,IAAqB,CAAC;YAAE,SAAS;QAC7D,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,WAAY,SAAQ,OAAO;IAC/B,MAAM,CAAC,EAAE,GAAgB,IAAI,WAAW,EAAE,CAAC;IAEnC,OAAO,GAAuB,EAAE,CAAC;IAEzC,qBAAqB,CAAC,IAAsB;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAOD,MAAM,CAAC,QAAQ,CAAC,IAAY,EAAE,MAAc;QAC1C,OAAO,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;IACjF,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,MAAc;QAI9B,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,MAA6B,CAAuB,CAAC;IAC1G,CAAC;;AAGH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,MAAc;IACnD,OAAO,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC"}