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