json-as 1.1.8 → 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.
- package/CHANGELOG.md +16 -0
- package/README.md +9 -2
- package/assembly/__benches__/large.bench.ts +214 -104
- package/assembly/__tests__/array.spec.ts +8 -5
- package/assembly/__tests__/lib/index.ts +20 -6
- package/assembly/__tests__/struct.spec.ts +2 -0
- package/assembly/__tests__/test.spec.ts +0 -119
- package/assembly/index.ts +4 -2
- package/assembly/test.ts +141 -251
- package/assembly/types.ts +70 -0
- package/index.ts +1 -1
- package/package.json +6 -6
- package/run-bench.as.sh +1 -1
- package/transform/lib/builder.js +3 -0
- package/transform/lib/builder.js.map +1 -1
- package/transform/lib/index.js +463 -224
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linker.js +38 -6
- package/transform/lib/linker.js.map +1 -1
- package/transform/lib/util.js +5 -0
- package/transform/lib/util.js.map +1 -1
- package/transform/src/builder.ts +4 -0
- package/transform/src/index.ts +531 -275
- package/transform/src/linker.ts +48 -7
- package/transform/src/types.ts +1 -1
- package/transform/src/util.ts +11 -16
package/transform/lib/index.js
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
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 {
|
|
8
|
+
import { getClass, getImportedClass } from "./linker.js";
|
|
9
|
+
import { existsSync, writeFileSync } from "fs";
|
|
9
10
|
let indent = " ";
|
|
10
|
-
|
|
11
|
-
const
|
|
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);
|
|
21
|
+
const STRICT = process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "true";
|
|
12
22
|
class CustomTransform extends Visitor {
|
|
13
23
|
static SN = new CustomTransform();
|
|
14
24
|
modify = false;
|
|
@@ -41,14 +51,15 @@ class CustomTransform extends Visitor {
|
|
|
41
51
|
class JSONTransform extends Visitor {
|
|
42
52
|
static SN = new JSONTransform();
|
|
43
53
|
program;
|
|
44
|
-
|
|
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.
|
|
61
|
-
|
|
62
|
-
this.
|
|
63
|
-
|
|
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.
|
|
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<")) {
|
|
@@ -338,7 +414,7 @@ class JSONTransform extends Visitor {
|
|
|
338
414
|
DESERIALIZE += indent + " let keyStart: usize = 0;\n";
|
|
339
415
|
DESERIALIZE += indent + " let keyEnd: usize = 0;\n";
|
|
340
416
|
DESERIALIZE += indent + " let isKey = false;\n";
|
|
341
|
-
if (sortedMembers.object.length || sortedMembers.array.length)
|
|
417
|
+
if (!STRICT || sortedMembers.object.length || sortedMembers.array.length)
|
|
342
418
|
DESERIALIZE += indent + " let depth: i32 = 0;\n";
|
|
343
419
|
DESERIALIZE += indent + " let lastIndex: usize = 0;\n\n";
|
|
344
420
|
DESERIALIZE += indent + " while (srcStart < srcEnd && JSON.Util.isSpace(load<u16>(srcStart))) srcStart += 2;\n";
|
|
@@ -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";
|
|
@@ -376,27 +454,61 @@ class JSONTransform extends Visitor {
|
|
|
376
454
|
groups.get(length).push(member);
|
|
377
455
|
}
|
|
378
456
|
return [...groups.values()]
|
|
379
|
-
.map(group => group.sort((a, b) => {
|
|
457
|
+
.map((group) => group.sort((a, b) => {
|
|
380
458
|
const aLen = (a.alias || a.name).length;
|
|
381
459
|
const bLen = (b.alias || b.name).length;
|
|
382
460
|
return aLen - bLen;
|
|
383
461
|
}))
|
|
384
462
|
.sort((a, b) => b.length - a.length);
|
|
385
463
|
};
|
|
386
|
-
const generateGroups = (members, cb,
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
464
|
+
const generateGroups = (members, cb, type) => {
|
|
465
|
+
if (!members.length) {
|
|
466
|
+
if (STRICT) {
|
|
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';
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
if (type == "string") {
|
|
471
|
+
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
472
|
+
}
|
|
473
|
+
else if (type == "boolean" || type == "null" || type == "number") {
|
|
474
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
475
|
+
}
|
|
476
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
477
|
+
if (type == "string" || type == "object" || type == "array" || type == "number")
|
|
478
|
+
DESERIALIZE += indent + " break;\n";
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
const groups = groupMembers(members);
|
|
483
|
+
DESERIALIZE += " switch (<u32>keyEnd - <u32>keyStart) {\n";
|
|
484
|
+
for (const group of groups) {
|
|
485
|
+
const groupLen = (group[0].alias || group[0].name).length << 1;
|
|
486
|
+
DESERIALIZE += " case " + groupLen + ": {\n";
|
|
487
|
+
cb(group);
|
|
488
|
+
DESERIALIZE += "\n }\n";
|
|
489
|
+
}
|
|
490
|
+
DESERIALIZE += " default: {\n";
|
|
491
|
+
if (STRICT) {
|
|
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';
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
if (type == "string") {
|
|
496
|
+
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
497
|
+
}
|
|
498
|
+
else if (type == "boolean" || type == "null" || type == "number") {
|
|
499
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
500
|
+
}
|
|
501
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
502
|
+
if (type == "string" || type == "object" || type == "array" || type == "number")
|
|
503
|
+
DESERIALIZE += indent + " break;\n";
|
|
504
|
+
}
|
|
505
|
+
DESERIALIZE += " }\n";
|
|
506
|
+
DESERIALIZE += " }\n";
|
|
507
|
+
if (type != "null" && type != "boolean")
|
|
508
|
+
DESERIALIZE += " break;\n";
|
|
509
|
+
}
|
|
398
510
|
};
|
|
399
|
-
const
|
|
511
|
+
const generateConsts = (members) => {
|
|
400
512
|
if (members.some((m) => (m.alias || m.name).length << 1 == 2)) {
|
|
401
513
|
DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
|
|
402
514
|
}
|
|
@@ -412,66 +524,105 @@ class JSONTransform extends Visitor {
|
|
|
412
524
|
if (members.some((m) => (m.alias || m.name).length << 1 > 8)) {
|
|
413
525
|
DESERIALIZE += toMemCDecl(Math.max(...members.map((m) => (m.alias || m.name).length << 1)), " ");
|
|
414
526
|
}
|
|
415
|
-
const complex = isStruct(members[0].type) || members[0].type != "JSON.Obj" || isArray(members[0].type);
|
|
416
|
-
const firstMemberName = members[0].alias || members[0].name;
|
|
417
|
-
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
|
|
418
|
-
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";
|
|
419
|
-
if (isString(members[0].type))
|
|
420
|
-
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
421
|
-
else if (!complex)
|
|
422
|
-
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
423
|
-
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
424
|
-
DESERIALIZE += indent + " break;\n";
|
|
425
|
-
DESERIALIZE += indent + " }";
|
|
426
|
-
for (let i = 1; i < members.length; i++) {
|
|
427
|
-
const member = members[i];
|
|
428
|
-
const memberName = member.alias || member.name;
|
|
429
|
-
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
|
|
430
|
-
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";
|
|
431
|
-
if (isString(member.type))
|
|
432
|
-
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
433
|
-
else if (!complex)
|
|
434
|
-
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
435
|
-
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
436
|
-
DESERIALIZE += indent + " break;\n";
|
|
437
|
-
DESERIALIZE += indent + " }";
|
|
438
|
-
}
|
|
439
|
-
if (STRICT) {
|
|
440
|
-
DESERIALIZE += " else {\n";
|
|
441
|
-
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
442
|
-
DESERIALIZE += indent + " }\n";
|
|
443
|
-
}
|
|
444
527
|
};
|
|
445
528
|
let mbElse = " ";
|
|
446
|
-
if (sortedMembers.string.length) {
|
|
529
|
+
if (!STRICT || sortedMembers.string.length) {
|
|
447
530
|
DESERIALIZE += mbElse + "if (code == 34) {\n";
|
|
448
531
|
DESERIALIZE += " lastIndex = srcStart;\n";
|
|
449
532
|
DESERIALIZE += " srcStart += 2;\n";
|
|
450
533
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
451
534
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
452
535
|
DESERIALIZE += " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
453
|
-
|
|
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");
|
|
454
571
|
DESERIALIZE += " }\n";
|
|
455
572
|
DESERIALIZE += " srcStart += 2;\n";
|
|
456
573
|
DESERIALIZE += " }\n";
|
|
457
574
|
DESERIALIZE += " }\n";
|
|
458
575
|
mbElse = " else ";
|
|
459
576
|
}
|
|
460
|
-
if (sortedMembers.number.length) {
|
|
577
|
+
if (!STRICT || sortedMembers.number.length) {
|
|
461
578
|
DESERIALIZE += mbElse + "if (code - 48 <= 9 || code == 45) {\n";
|
|
462
579
|
DESERIALIZE += " lastIndex = srcStart;\n";
|
|
463
580
|
DESERIALIZE += " srcStart += 2;\n";
|
|
464
581
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
465
582
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
466
583
|
DESERIALIZE += " if (code == 44 || code == 125 || JSON.Util.isSpace(code)) {\n";
|
|
467
|
-
|
|
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");
|
|
468
619
|
DESERIALIZE += " }\n";
|
|
469
620
|
DESERIALIZE += " srcStart += 2;\n";
|
|
470
621
|
DESERIALIZE += " }\n";
|
|
471
622
|
DESERIALIZE += " }";
|
|
472
623
|
mbElse = " else ";
|
|
473
624
|
}
|
|
474
|
-
if (sortedMembers.object.length) {
|
|
625
|
+
if (!STRICT || sortedMembers.object.length) {
|
|
475
626
|
DESERIALIZE += mbElse + "if (code == 123) {\n";
|
|
476
627
|
DESERIALIZE += " lastIndex = srcStart;\n";
|
|
477
628
|
DESERIALIZE += " depth++;\n";
|
|
@@ -484,8 +635,39 @@ class JSONTransform extends Visitor {
|
|
|
484
635
|
DESERIALIZE += " } else if (code == 125) {\n";
|
|
485
636
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
486
637
|
DESERIALIZE += " srcStart += 2;\n";
|
|
638
|
+
if (DEBUG > 1)
|
|
639
|
+
DESERIALIZE += " console.log(\"Value (object, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart));";
|
|
487
640
|
indent = " ";
|
|
488
|
-
generateGroups(sortedMembers.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");
|
|
489
671
|
indent = "";
|
|
490
672
|
DESERIALIZE += " }\n";
|
|
491
673
|
DESERIALIZE += " } else if (code == 123) depth++;\n";
|
|
@@ -494,7 +676,7 @@ class JSONTransform extends Visitor {
|
|
|
494
676
|
DESERIALIZE += " }";
|
|
495
677
|
mbElse = " else ";
|
|
496
678
|
}
|
|
497
|
-
if (sortedMembers.array.length) {
|
|
679
|
+
if (!STRICT || sortedMembers.array.length) {
|
|
498
680
|
DESERIALIZE += mbElse + "if (code == 91) {\n";
|
|
499
681
|
DESERIALIZE += " lastIndex = srcStart;\n";
|
|
500
682
|
DESERIALIZE += " depth++;\n";
|
|
@@ -507,8 +689,39 @@ class JSONTransform extends Visitor {
|
|
|
507
689
|
DESERIALIZE += " } else if (code == 93) {\n";
|
|
508
690
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
509
691
|
DESERIALIZE += " srcStart += 2;\n";
|
|
692
|
+
if (DEBUG > 1)
|
|
693
|
+
DESERIALIZE += " console.log(\"Value (object, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart));";
|
|
510
694
|
indent = " ";
|
|
511
|
-
generateGroups(sortedMembers.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");
|
|
512
725
|
indent = "";
|
|
513
726
|
DESERIALIZE += " }\n";
|
|
514
727
|
DESERIALIZE += " } else if (code == 91) depth++;\n";
|
|
@@ -517,38 +730,27 @@ class JSONTransform extends Visitor {
|
|
|
517
730
|
DESERIALIZE += " }";
|
|
518
731
|
mbElse = " else ";
|
|
519
732
|
}
|
|
520
|
-
if (sortedMembers.boolean.length) {
|
|
733
|
+
if (!STRICT || sortedMembers.boolean.length) {
|
|
521
734
|
DESERIALIZE += mbElse + "if (code == 116) {\n";
|
|
522
735
|
DESERIALIZE += " if (load<u64>(srcStart) == 28429475166421108) {\n";
|
|
523
736
|
DESERIALIZE += " srcStart += 8;\n";
|
|
737
|
+
if (DEBUG > 1)
|
|
738
|
+
DESERIALIZE += " console.log(\"Value (bool, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart - 8));";
|
|
524
739
|
generateGroups(sortedMembers.boolean, (group) => {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
535
|
-
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
536
|
-
}
|
|
537
|
-
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
|
|
538
|
-
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
|
|
539
|
-
}
|
|
540
|
-
const firstMemberName = group[0].alias || group[0].name;
|
|
541
|
-
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
|
|
542
|
-
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
|
|
543
|
-
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
544
|
-
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
545
|
-
DESERIALIZE += indent + " break;\n";
|
|
546
|
-
DESERIALIZE += indent + " }";
|
|
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";
|
|
745
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
746
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
747
|
+
DESERIALIZE += indent + " break;\n";
|
|
748
|
+
DESERIALIZE += indent + " }";
|
|
547
749
|
for (let i = 1; i < group.length; i++) {
|
|
548
|
-
const
|
|
549
|
-
const
|
|
550
|
-
DESERIALIZE += indent + " else if (" + getComparision(
|
|
551
|
-
DESERIALIZE += indent + " store<" +
|
|
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";
|
|
552
754
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
553
755
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
554
756
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -556,42 +758,43 @@ class JSONTransform extends Visitor {
|
|
|
556
758
|
}
|
|
557
759
|
if (STRICT) {
|
|
558
760
|
DESERIALIZE += " else {\n";
|
|
559
|
-
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" +
|
|
761
|
+
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';
|
|
560
762
|
DESERIALIZE += indent + " }\n";
|
|
561
763
|
}
|
|
562
|
-
|
|
764
|
+
else {
|
|
765
|
+
DESERIALIZE += " else { \n";
|
|
766
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
767
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
768
|
+
DESERIALIZE += indent + " break;\n";
|
|
769
|
+
DESERIALIZE += indent + " }\n";
|
|
770
|
+
}
|
|
771
|
+
}, "boolean");
|
|
563
772
|
DESERIALIZE += " }";
|
|
773
|
+
DESERIALIZE += " else {\n";
|
|
774
|
+
DESERIALIZE += " throw new Error(\"Expected to find 'true' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n";
|
|
775
|
+
DESERIALIZE += " }";
|
|
776
|
+
DESERIALIZE += "\n }";
|
|
564
777
|
mbElse = " else ";
|
|
565
|
-
DESERIALIZE +=
|
|
778
|
+
DESERIALIZE += mbElse + "if (code == 102) {\n";
|
|
779
|
+
DESERIALIZE += " if (load<u64>(srcStart, 2) == 28429466576093281) {\n";
|
|
566
780
|
DESERIALIZE += " srcStart += 10;\n";
|
|
781
|
+
if (DEBUG > 1)
|
|
782
|
+
DESERIALIZE += " console.log(\"Value (bool, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart - 10));";
|
|
567
783
|
generateGroups(sortedMembers.boolean, (group) => {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
if (
|
|
572
|
-
|
|
573
|
-
}
|
|
574
|
-
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
|
|
575
|
-
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
|
|
576
|
-
}
|
|
577
|
-
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
578
|
-
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
579
|
-
}
|
|
580
|
-
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
|
|
581
|
-
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
|
|
582
|
-
}
|
|
583
|
-
const firstMemberName = group[0].alias || group[0].name;
|
|
584
|
-
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
|
|
585
|
-
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";
|
|
586
789
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
587
790
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
588
791
|
DESERIALIZE += indent + " break;\n";
|
|
589
792
|
DESERIALIZE += indent + " }";
|
|
590
793
|
for (let i = 1; i < group.length; i++) {
|
|
591
|
-
const
|
|
592
|
-
const
|
|
593
|
-
DESERIALIZE += indent + " else if (" + getComparision(
|
|
594
|
-
DESERIALIZE += indent + " store<" +
|
|
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";
|
|
595
798
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
596
799
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
597
800
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -599,45 +802,45 @@ class JSONTransform extends Visitor {
|
|
|
599
802
|
}
|
|
600
803
|
if (STRICT) {
|
|
601
804
|
DESERIALIZE += " else {\n";
|
|
602
|
-
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" +
|
|
805
|
+
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';
|
|
603
806
|
DESERIALIZE += indent + " }\n";
|
|
604
807
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
808
|
+
else {
|
|
809
|
+
DESERIALIZE += " else { \n";
|
|
810
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
811
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
812
|
+
DESERIALIZE += indent + " break;\n";
|
|
813
|
+
DESERIALIZE += indent + " }\n";
|
|
814
|
+
}
|
|
815
|
+
}, "boolean");
|
|
816
|
+
DESERIALIZE += " }";
|
|
817
|
+
DESERIALIZE += " else {\n";
|
|
818
|
+
DESERIALIZE += " throw new Error(\"Expected to find 'false' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n";
|
|
819
|
+
DESERIALIZE += " }";
|
|
820
|
+
DESERIALIZE += "\n }";
|
|
821
|
+
mbElse = " else ";
|
|
608
822
|
}
|
|
609
|
-
if (sortedMembers.null.length) {
|
|
823
|
+
if (!STRICT || sortedMembers.null.length) {
|
|
610
824
|
DESERIALIZE += mbElse + "if (code == 110) {\n";
|
|
611
825
|
DESERIALIZE += " if (load<u64>(srcStart) == 30399761348886638) {\n";
|
|
612
826
|
DESERIALIZE += " srcStart += 8;\n";
|
|
827
|
+
if (DEBUG > 1)
|
|
828
|
+
DESERIALIZE += " console.log(\"Value (null, " + (++id) + "): \" + JSON.Util.ptrToStr(lastIndex, srcStart - 8));";
|
|
613
829
|
generateGroups(sortedMembers.null, (group) => {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
if (
|
|
618
|
-
|
|
619
|
-
}
|
|
620
|
-
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
|
|
621
|
-
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
|
|
622
|
-
}
|
|
623
|
-
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
624
|
-
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
625
|
-
}
|
|
626
|
-
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
|
|
627
|
-
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
|
|
628
|
-
}
|
|
629
|
-
const firstMemberName = group[0].alias || group[0].name;
|
|
630
|
-
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
|
|
631
|
-
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";
|
|
632
835
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
633
836
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
634
837
|
DESERIALIZE += indent + " break;\n";
|
|
635
838
|
DESERIALIZE += indent + " }";
|
|
636
839
|
for (let i = 1; i < group.length; i++) {
|
|
637
|
-
const
|
|
638
|
-
const
|
|
639
|
-
DESERIALIZE += indent + " else if (" + getComparision(
|
|
640
|
-
DESERIALIZE += indent + " store<" +
|
|
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";
|
|
641
844
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
642
845
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
643
846
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -645,16 +848,24 @@ class JSONTransform extends Visitor {
|
|
|
645
848
|
}
|
|
646
849
|
if (STRICT) {
|
|
647
850
|
DESERIALIZE += " else {\n";
|
|
648
|
-
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" +
|
|
851
|
+
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';
|
|
649
852
|
DESERIALIZE += indent + " }\n";
|
|
650
853
|
}
|
|
651
|
-
|
|
854
|
+
else {
|
|
855
|
+
DESERIALIZE += " else { \n";
|
|
856
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
857
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
858
|
+
DESERIALIZE += indent + " break;\n";
|
|
859
|
+
DESERIALIZE += indent + " }\n";
|
|
860
|
+
}
|
|
861
|
+
}, "null");
|
|
652
862
|
DESERIALIZE += " }";
|
|
653
863
|
DESERIALIZE += "\n }";
|
|
654
864
|
mbElse = " else ";
|
|
655
865
|
}
|
|
656
866
|
DESERIALIZE += " else {\n";
|
|
657
867
|
DESERIALIZE += " srcStart += 2;\n";
|
|
868
|
+
DESERIALIZE += " keyStart = 0;\n";
|
|
658
869
|
DESERIALIZE += "}\n";
|
|
659
870
|
DESERIALIZE += "\n }\n";
|
|
660
871
|
indentDec();
|
|
@@ -669,7 +880,7 @@ class JSONTransform extends Visitor {
|
|
|
669
880
|
SERIALIZE = SERIALIZE.slice(0, 32) + indent + "bs.proposeSize(" + this.schema.byteSize + ");\n" + SERIALIZE.slice(32);
|
|
670
881
|
INITIALIZE += " return this;\n";
|
|
671
882
|
INITIALIZE += "}";
|
|
672
|
-
if (DEBUG) {
|
|
883
|
+
if (DEBUG > 0) {
|
|
673
884
|
console.log(SERIALIZE_CUSTOM || SERIALIZE);
|
|
674
885
|
console.log(INITIALIZE);
|
|
675
886
|
console.log(DESERIALIZE_CUSTOM || DESERIALIZE);
|
|
@@ -685,11 +896,15 @@ class JSONTransform extends Visitor {
|
|
|
685
896
|
node.members.push(DESERIALIZE_METHOD);
|
|
686
897
|
super.visitClassDeclaration(node);
|
|
687
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
|
+
}
|
|
688
903
|
generateEmptyMethods(node) {
|
|
689
904
|
let SERIALIZE_EMPTY = "@inline __SERIALIZE(ptr: usize): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
|
|
690
905
|
let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
|
|
691
906
|
let DESERIALIZE_EMPTY = "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): __JSON_T {\n return this;\n}";
|
|
692
|
-
if (DEBUG) {
|
|
907
|
+
if (DEBUG > 0) {
|
|
693
908
|
console.log(SERIALIZE_EMPTY);
|
|
694
909
|
console.log(INITIALIZE_EMPTY);
|
|
695
910
|
console.log(DESERIALIZE_EMPTY);
|
|
@@ -712,31 +927,57 @@ class JSONTransform extends Visitor {
|
|
|
712
927
|
this.imports = [];
|
|
713
928
|
super.visitSource(node);
|
|
714
929
|
}
|
|
715
|
-
|
|
716
|
-
const
|
|
717
|
-
const
|
|
718
|
-
const
|
|
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);
|
|
719
940
|
const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
|
|
720
941
|
const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
|
|
721
|
-
let
|
|
722
|
-
|
|
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
|
+
}
|
|
723
968
|
if (!bsImport) {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
if (DEBUG)
|
|
730
|
-
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");
|
|
731
974
|
}
|
|
732
975
|
if (!jsonImport) {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
if (DEBUG)
|
|
739
|
-
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");
|
|
740
981
|
}
|
|
741
982
|
}
|
|
742
983
|
getStores(data, simd = false) {
|
|
@@ -769,7 +1010,7 @@ class JSONTransform extends Visitor {
|
|
|
769
1010
|
return out;
|
|
770
1011
|
}
|
|
771
1012
|
isValidType(type, node) {
|
|
772
|
-
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)];
|
|
773
1014
|
const baseTypes = ["Array", "Map", "Set", "JSON.Box", "Box"];
|
|
774
1015
|
if (node && node.isGeneric && node.typeParameters)
|
|
775
1016
|
validTypes.push(...node.typeParameters.map((v) => v.name.text));
|
|
@@ -815,7 +1056,7 @@ export default class Transformer extends Transform {
|
|
|
815
1056
|
return 0;
|
|
816
1057
|
}
|
|
817
1058
|
});
|
|
818
|
-
transformer.
|
|
1059
|
+
transformer.baseCWD = path.join(process.cwd(), this.baseDir);
|
|
819
1060
|
transformer.program = this.program;
|
|
820
1061
|
transformer.parser = parser;
|
|
821
1062
|
for (const source of sources) {
|
|
@@ -831,13 +1072,11 @@ export default class Transformer extends Transform {
|
|
|
831
1072
|
source.statements.unshift(SimpleParser.parseTopLevelStatement(simd));
|
|
832
1073
|
}
|
|
833
1074
|
transformer.simdStatements = [];
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
if (
|
|
838
|
-
|
|
839
|
-
if (!parent)
|
|
840
|
-
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));
|
|
841
1080
|
}
|
|
842
1081
|
}
|
|
843
1082
|
}
|
|
@@ -972,9 +1211,9 @@ function isPrimitive(type) {
|
|
|
972
1211
|
function isBoolean(type) {
|
|
973
1212
|
return type == "bool" || type == "boolean";
|
|
974
1213
|
}
|
|
975
|
-
function isStruct(type) {
|
|
1214
|
+
function isStruct(type, source) {
|
|
976
1215
|
type = stripNull(type);
|
|
977
|
-
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;
|
|
978
1217
|
}
|
|
979
1218
|
function isString(type) {
|
|
980
1219
|
return stripNull(type) == "string" || stripNull(type) == "String";
|