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.
- package/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/assembly/__benches__/large.bench.ts +22 -19
- package/assembly/__tests__/generics.spec.ts +40 -0
- package/assembly/__tests__/lib/index.ts +3 -7
- package/assembly/__tests__/types.spec.ts +26 -0
- package/bench/large.bench.ts +104 -215
- package/package.json +2 -3
- package/run-bench.js.sh +1 -1
- package/transform/lib/index.js +70 -80
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linkers/alias.js +49 -0
- package/transform/lib/linkers/alias.js.map +1 -0
- package/transform/lib/{linker.js → linkers/classes.js} +3 -17
- package/transform/lib/linkers/classes.js.map +1 -0
- package/transform/lib/linkers/custom.js +32 -0
- package/transform/lib/linkers/custom.js.map +1 -0
- package/transform/lib/linkers/imports.js +17 -0
- package/transform/lib/linkers/imports.js.map +1 -0
- package/transform/lib/types.js +13 -0
- package/transform/lib/types.js.map +1 -1
- package/transform/src/index.ts +67 -82
- package/transform/src/linkers/alias.ts +59 -0
- package/transform/src/{linker.ts → linkers/classes.ts} +3 -23
- package/transform/src/linkers/custom.ts +32 -0
- package/transform/src/linkers/imports.ts +22 -0
- package/transform/src/types.ts +15 -1
- package/transform/tsconfig.json +1 -1
- package/bench/lib/test.ts +0 -37
- package/transform/lib/linker.js.map +0 -1
package/transform/src/index.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, CommonFlags, ImportStatement, Node,
|
|
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 {
|
|
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,
|
|
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
|
|
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
|
-
|
|
97
|
-
if (!this.
|
|
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 " +
|
|
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,
|
|
91
|
+
const internalSearch = getClass(extendsName, source);
|
|
117
92
|
if (internalSearch) {
|
|
118
|
-
if (DEBUG > 0) console.log("Found " + extendsName + " internally from " +
|
|
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,
|
|
105
|
+
const externalSearch = getImportedClass(extendsName, source, this.parser);
|
|
131
106
|
if (externalSearch) {
|
|
132
|
-
if (DEBUG > 0) console.log("Found " + externalSearch.name.text + " externally from " +
|
|
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 " +
|
|
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,
|
|
163
|
+
const internalSearch = getClass(unknownType, source);
|
|
188
164
|
if (internalSearch) {
|
|
189
|
-
if (DEBUG > 0) console.log("Found " + unknownType + " internally from " +
|
|
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,
|
|
176
|
+
const externalSearch = getImportedClass(unknownType, source, this.parser);
|
|
201
177
|
if (externalSearch) {
|
|
202
|
-
if (DEBUG > 0) console.log("Found " + externalSearch.name.text + " externally from " +
|
|
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(
|
|
194
|
+
this.schemas.get(source.internalPath).push(schema);
|
|
219
195
|
this.schema = schema;
|
|
220
|
-
this.visitedClasses.add(
|
|
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 " +
|
|
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
|
-
|
|
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
|
-
|
|
452
|
-
if (
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
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<
|
|
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<
|
|
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,
|
|
2
|
-
import { Visitor } from "
|
|
3
|
-
import {
|
|
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
|
+
}
|
package/transform/src/types.ts
CHANGED
|
@@ -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
|
+
}
|
package/transform/tsconfig.json
CHANGED
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"}
|