json-as 1.0.0-alpha.1 → 1.0.0-alpha.2
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/.gitmodules +0 -0
- package/CHANGELOG +11 -0
- package/README.md +3 -2
- package/assembly/__benches__/misc.bench.ts +0 -19
- package/assembly/deserialize/simple/object.ts +2 -3
- package/assembly/index.ts +2 -7
- package/assembly/serialize/simd/string.ts +1 -1
- package/assembly/serialize/simple/array.ts +1 -1
- package/assembly/serialize/simple/bool.ts +1 -1
- package/assembly/serialize/simple/date.ts +1 -1
- package/assembly/serialize/simple/float.ts +1 -1
- package/assembly/serialize/simple/integer.ts +1 -1
- package/assembly/serialize/simple/map.ts +1 -1
- package/assembly/serialize/simple/string.ts +2 -2
- package/assembly/test.ts +8 -13
- package/modules/as-bs/LICENSE +21 -0
- package/modules/as-bs/README.md +95 -0
- package/modules/{bs → as-bs/assembly}/index.ts +11 -12
- package/modules/as-bs/assembly/tsconfig.json +97 -0
- package/modules/as-bs/index.ts +1 -0
- package/modules/as-bs/package.json +32 -0
- package/package.json +4 -5
- package/transform/lib/builder.js +1262 -1340
- package/transform/lib/index.js +512 -572
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linker.js +10 -12
- package/transform/lib/types.js +19 -18
- package/transform/lib/types.js.map +1 -1
- package/transform/lib/util.js +34 -34
- package/transform/lib/visitor.js +526 -529
- package/transform/package.json +2 -1
- package/transform/src/index.ts +19 -8
- package/transform/src/types.ts +1 -0
- package/modules/tsconfig.json +0 -8
- package/transform/lib/index.old.js +0 -404
- package/transform/lib/index.old.js.map +0 -1
package/transform/lib/index.js
CHANGED
|
@@ -8,626 +8,566 @@ import { Property, PropertyFlags, Schema } from "./types.js";
|
|
|
8
8
|
import { getClasses, getImportedClass } from "./linker.js";
|
|
9
9
|
let indent = " ";
|
|
10
10
|
class JSONTransform extends Visitor {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
|
|
47
|
-
if (externalSearch) {
|
|
48
|
-
if (process.env["JSON_DEBUG"])
|
|
49
|
-
console.log("Found " + extendsName + " externally");
|
|
50
|
-
this.visitClassDeclaration(externalSearch);
|
|
51
|
-
this.visitClassDeclaration(node);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (this.schema.parent?.members) {
|
|
56
|
-
for (let i = this.schema.parent.members.length - 1; i >= 0; i--) {
|
|
57
|
-
const replace = this.schema.members.find((v) => v.name == this.schema.parent?.members[i]?.name);
|
|
58
|
-
if (!replace) {
|
|
59
|
-
members.unshift(this.schema.parent?.members[i].node);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (!members.length) {
|
|
65
|
-
this.generateEmptyMethods(node);
|
|
66
|
-
return;
|
|
11
|
+
parser;
|
|
12
|
+
schemas = [];
|
|
13
|
+
schema;
|
|
14
|
+
sources = new Set();
|
|
15
|
+
imports = [];
|
|
16
|
+
jsonImport = null;
|
|
17
|
+
bsImport = null;
|
|
18
|
+
newStmts = { simd: [] };
|
|
19
|
+
visitClassDeclaration(node) {
|
|
20
|
+
if (!node.decorators?.length) return;
|
|
21
|
+
if (
|
|
22
|
+
!node.decorators.some((decorator) => {
|
|
23
|
+
const name = decorator.name.text;
|
|
24
|
+
return name === "json" || name === "serializable";
|
|
25
|
+
})
|
|
26
|
+
)
|
|
27
|
+
return;
|
|
28
|
+
this.schema = new Schema();
|
|
29
|
+
this.schema.node = node;
|
|
30
|
+
this.schema.name = node.name.text;
|
|
31
|
+
this.schemas.push(this.schema);
|
|
32
|
+
if (process.env["JSON_DEBUG"]) console.log("Created schema: " + this.schema.name);
|
|
33
|
+
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"))];
|
|
34
|
+
if (node.extendsType) {
|
|
35
|
+
const extendsName = node.extendsType?.name.identifier.text;
|
|
36
|
+
this.schema.parent = this.schemas.find((v) => v.name == extendsName);
|
|
37
|
+
if (!this.schema.parent) {
|
|
38
|
+
const internalSearch = getClasses(node.range.source).find((v) => v.name.text == extendsName);
|
|
39
|
+
if (internalSearch) {
|
|
40
|
+
if (process.env["JSON_DEBUG"]) console.log("Found " + extendsName + " internally");
|
|
41
|
+
this.visitClassDeclaration(internalSearch);
|
|
42
|
+
this.visitClassDeclaration(node);
|
|
43
|
+
return;
|
|
67
44
|
}
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const value = member.initializer ? toString(member.initializer) : null;
|
|
75
|
-
if (type.startsWith("(") && type.includes("=>"))
|
|
76
|
-
continue;
|
|
77
|
-
const mem = new Property();
|
|
78
|
-
mem.name = name.text;
|
|
79
|
-
mem.type = type;
|
|
80
|
-
mem.value = value;
|
|
81
|
-
mem.node = member;
|
|
82
|
-
mem.byteSize = sizeof(mem.type);
|
|
83
|
-
this.schema.byteSize += mem.byteSize;
|
|
84
|
-
if (type.includes("JSON.Raw"))
|
|
85
|
-
mem.flags.set(PropertyFlags.Raw, null);
|
|
86
|
-
if (member.decorators) {
|
|
87
|
-
for (const decorator of member.decorators) {
|
|
88
|
-
const decoratorName = decorator.name.text.toLowerCase().trim();
|
|
89
|
-
switch (decoratorName) {
|
|
90
|
-
case "alias": {
|
|
91
|
-
const args = getArgs(decorator.args);
|
|
92
|
-
if (!args.length)
|
|
93
|
-
throwError("@alias must have an argument of type string or number", member.range);
|
|
94
|
-
mem.alias = args[0];
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
97
|
-
case "omitif": {
|
|
98
|
-
let arg = decorator.args[0];
|
|
99
|
-
if (!decorator.args?.length)
|
|
100
|
-
throwError("@omitif must have an argument or callback that resolves to type bool", member.range);
|
|
101
|
-
mem.flags.set(PropertyFlags.OmitIf, arg);
|
|
102
|
-
this.schema.static = false;
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
case "omitnull": {
|
|
106
|
-
if (isPrimitive(type)) {
|
|
107
|
-
throwError("@omitnull cannot be used on primitive types!", member.range);
|
|
108
|
-
}
|
|
109
|
-
else if (!member.type.isNullable) {
|
|
110
|
-
throwError("@omitnull cannot be used on non-nullable types!", member.range);
|
|
111
|
-
}
|
|
112
|
-
mem.flags.set(PropertyFlags.OmitNull, null);
|
|
113
|
-
this.schema.static = false;
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
this.schema.members.push(mem);
|
|
45
|
+
const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
|
|
46
|
+
if (externalSearch) {
|
|
47
|
+
if (process.env["JSON_DEBUG"]) console.log("Found " + extendsName + " externally");
|
|
48
|
+
this.visitClassDeclaration(externalSearch);
|
|
49
|
+
this.visitClassDeclaration(node);
|
|
50
|
+
return;
|
|
120
51
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
let
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (this.schema.static == false) {
|
|
129
|
-
if (this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull))) {
|
|
130
|
-
SERIALIZE += indent + "let block: usize = 0;\n";
|
|
131
|
-
}
|
|
132
|
-
this.schema.byteSize += 2;
|
|
133
|
-
SERIALIZE += indent + "store<u16>(bs.offset, 123, 0); // {\n";
|
|
134
|
-
SERIALIZE += indent + "bs.offset += 2;\n";
|
|
52
|
+
}
|
|
53
|
+
if (this.schema.parent?.members) {
|
|
54
|
+
for (let i = this.schema.parent.members.length - 1; i >= 0; i--) {
|
|
55
|
+
const replace = this.schema.members.find((v) => v.name == this.schema.parent?.members[i]?.name);
|
|
56
|
+
if (!replace) {
|
|
57
|
+
members.unshift(this.schema.parent?.members[i].node);
|
|
58
|
+
}
|
|
135
59
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (isFirst)
|
|
167
|
-
isFirst = false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!members.length) {
|
|
63
|
+
this.generateEmptyMethods(node);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.addRequiredImports(node);
|
|
67
|
+
for (const member of members) {
|
|
68
|
+
if (!member.type) throwError("Fields must be strongly typed", node.range);
|
|
69
|
+
const type = toString(member.type);
|
|
70
|
+
const name = member.name;
|
|
71
|
+
const value = member.initializer ? toString(member.initializer) : null;
|
|
72
|
+
if (type.startsWith("(") && type.includes("=>")) continue;
|
|
73
|
+
const mem = new Property();
|
|
74
|
+
mem.name = name.text;
|
|
75
|
+
mem.type = type;
|
|
76
|
+
mem.value = value;
|
|
77
|
+
mem.node = member;
|
|
78
|
+
mem.byteSize = sizeof(mem.type);
|
|
79
|
+
this.schema.byteSize += mem.byteSize;
|
|
80
|
+
if (type.includes("JSON.Raw")) mem.flags.set(PropertyFlags.Raw, null);
|
|
81
|
+
if (member.decorators) {
|
|
82
|
+
for (const decorator of member.decorators) {
|
|
83
|
+
const decoratorName = decorator.name.text.toLowerCase().trim();
|
|
84
|
+
switch (decoratorName) {
|
|
85
|
+
case "alias": {
|
|
86
|
+
const args = getArgs(decorator.args);
|
|
87
|
+
if (!args.length) throwError("@alias must have an argument of type string or number", member.range);
|
|
88
|
+
mem.alias = args[0];
|
|
89
|
+
break;
|
|
168
90
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
176
|
-
if (isFirst)
|
|
177
|
-
isFirst = false;
|
|
91
|
+
case "omitif": {
|
|
92
|
+
let arg = decorator.args[0];
|
|
93
|
+
if (!decorator.args?.length) throwError("@omitif must have an argument or callback that resolves to type bool", member.range);
|
|
94
|
+
mem.flags.set(PropertyFlags.OmitIf, arg);
|
|
95
|
+
this.schema.static = false;
|
|
96
|
+
break;
|
|
178
97
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
189
|
-
if (!isLast) {
|
|
190
|
-
this.schema.byteSize += 2;
|
|
191
|
-
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
|
|
192
|
-
SERIALIZE += indent + `bs.offset += 2;\n`;
|
|
193
|
-
}
|
|
194
|
-
indentDec();
|
|
195
|
-
this.schema.byteSize += 2;
|
|
196
|
-
SERIALIZE += indent + `}\n`;
|
|
197
|
-
}
|
|
198
|
-
else if (member.flags.has(PropertyFlags.OmitIf)) {
|
|
199
|
-
if (member.flags.get(PropertyFlags.OmitIf).kind == 14) {
|
|
200
|
-
const arg = member.flags.get(PropertyFlags.OmitIf);
|
|
201
|
-
arg.declaration.signature.returnType.name = Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name.range);
|
|
202
|
-
SERIALIZE += indent + `if ((${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
SERIALIZE += indent + `if (${toString(member.flags.get(PropertyFlags.OmitIf))}) {\n`;
|
|
206
|
-
}
|
|
207
|
-
indentInc();
|
|
208
|
-
SERIALIZE += this.getStores(aliasName + ":")
|
|
209
|
-
.map((v) => indent + v + "\n")
|
|
210
|
-
.join("");
|
|
211
|
-
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
212
|
-
if (!isLast) {
|
|
213
|
-
this.schema.byteSize += 2;
|
|
214
|
-
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
|
|
215
|
-
SERIALIZE += indent + `bs.offset += 2;\n`;
|
|
216
|
-
}
|
|
217
|
-
indentDec();
|
|
218
|
-
SERIALIZE += indent + `}\n`;
|
|
219
|
-
}
|
|
98
|
+
case "omitnull": {
|
|
99
|
+
if (isPrimitive(type)) {
|
|
100
|
+
throwError("@omitnull cannot be used on primitive types!", member.range);
|
|
101
|
+
} else if (!member.type.isNullable) {
|
|
102
|
+
throwError("@omitnull cannot be used on non-nullable types!", member.range);
|
|
103
|
+
}
|
|
104
|
+
mem.flags.set(PropertyFlags.OmitNull, null);
|
|
105
|
+
this.schema.static = false;
|
|
106
|
+
break;
|
|
220
107
|
}
|
|
108
|
+
}
|
|
221
109
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
DESERIALIZE += `${indent}switch (load<u32>(keyStart)) {\n`;
|
|
247
|
-
else if (memberLen == 6)
|
|
248
|
-
DESERIALIZE += `${indent}let code = (<u64>load<u32>(keyStart) << 16) | <u64>load<u16>(keyStart, 4);\n`;
|
|
249
|
-
else
|
|
250
|
-
DESERIALIZE += toMemCDecl(memberLen, indent);
|
|
251
|
-
for (let i = 0; i < memberGroup.length; i++) {
|
|
252
|
-
const member = memberGroup[i];
|
|
253
|
-
const memberName = member.alias || member.name;
|
|
254
|
-
if (memberLen == 2) {
|
|
255
|
-
DESERIALIZE += `${indent} case ${memberName.charCodeAt(0)}: { // ${memberName}\n`;
|
|
256
|
-
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
257
|
-
DESERIALIZE += `${indent} return;\n`;
|
|
258
|
-
DESERIALIZE += `${indent} }\n`;
|
|
259
|
-
}
|
|
260
|
-
else if (memberLen == 4) {
|
|
261
|
-
DESERIALIZE += `${indent} case ${toU32(memberName)}: { // ${memberName}\n`;
|
|
262
|
-
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
263
|
-
DESERIALIZE += `${indent} return;\n`;
|
|
264
|
-
DESERIALIZE += `${indent} }\n`;
|
|
265
|
-
}
|
|
266
|
-
else if (memberLen == 6) {
|
|
267
|
-
DESERIALIZE += i == 0 ? indent : "";
|
|
268
|
-
DESERIALIZE += `if (code == ${toU48(memberName)}) { // ${memberName}\n`;
|
|
269
|
-
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
270
|
-
DESERIALIZE += `${indent} return;\n`;
|
|
271
|
-
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
DESERIALIZE += i == 0 ? indent : "";
|
|
275
|
-
DESERIALIZE += `if (${toMemCCheck(memberName)}) { // ${memberName}\n`;
|
|
276
|
-
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
277
|
-
DESERIALIZE += `${indent} return;\n`;
|
|
278
|
-
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
if (memberLen < 6) {
|
|
282
|
-
DESERIALIZE += `${indent}}\n`;
|
|
283
|
-
}
|
|
284
|
-
indentDec();
|
|
285
|
-
DESERIALIZE += `${indent} return;\n`;
|
|
286
|
-
DESERIALIZE += `${indent}}\n`;
|
|
110
|
+
}
|
|
111
|
+
this.schema.members.push(mem);
|
|
112
|
+
}
|
|
113
|
+
if (!this.schema.static) this.schema.members = sortMembers(this.schema.members);
|
|
114
|
+
let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
|
|
115
|
+
let INITIALIZE = "@inline __INITIALIZE(): this {\n";
|
|
116
|
+
let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n switch (<u32>keyEnd - <u32>keyStart) {\n";
|
|
117
|
+
let ALLOCATE = "@inline __ALLOCATE(): void {\n";
|
|
118
|
+
indent = " ";
|
|
119
|
+
if (this.schema.static == false) {
|
|
120
|
+
if (this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull))) {
|
|
121
|
+
SERIALIZE += indent + "let block: usize = 0;\n";
|
|
122
|
+
}
|
|
123
|
+
this.schema.byteSize += 2;
|
|
124
|
+
SERIALIZE += indent + "store<u16>(bs.offset, 123, 0); // {\n";
|
|
125
|
+
SERIALIZE += indent + "bs.offset += 2;\n";
|
|
126
|
+
}
|
|
127
|
+
for (const member of this.schema.members) {
|
|
128
|
+
const nonNullType = member.type.replace(" | null", "");
|
|
129
|
+
if (!isPrimitive(nonNullType)) {
|
|
130
|
+
const schema = this.schemas.find((v) => v.name == nonNullType);
|
|
131
|
+
if (schema && !this.schema.deps.includes(schema)) {
|
|
132
|
+
this.schema.deps.push(schema);
|
|
133
|
+
this.schema.byteSize += schema.byteSize;
|
|
287
134
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
INITIALIZE +=
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
let isPure = this.schema.static;
|
|
138
|
+
let isRegular = isPure;
|
|
139
|
+
let isFirst = true;
|
|
140
|
+
for (let i = 0; i < this.schema.members.length; i++) {
|
|
141
|
+
const member = this.schema.members[i];
|
|
142
|
+
const aliasName = JSON.stringify(member.alias || member.name);
|
|
143
|
+
const realName = member.name;
|
|
144
|
+
const isLast = i == this.schema.members.length - 1;
|
|
145
|
+
const nonNullType = member.type.replace(" | null", "");
|
|
146
|
+
if (member.value) {
|
|
147
|
+
INITIALIZE += ` this.${member.name} = ${member.value};\n`;
|
|
148
|
+
} else if (this.schemas.find((v) => nonNullType == v.name)) {
|
|
149
|
+
INITIALIZE += ` this.${member.name} = changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE();\n`;
|
|
150
|
+
} else if (member.type.startsWith("Array<") || member.type.startsWith("Map<")) {
|
|
151
|
+
INITIALIZE += ` this.${member.name} = [];\n`;
|
|
152
|
+
} else if (member.type == "string" || member.type == "String" || member.type == "JSON.Raw") {
|
|
153
|
+
INITIALIZE += ` this.${member.name} = "";\n`;
|
|
154
|
+
}
|
|
155
|
+
if (!isRegular && !member.flags.has(PropertyFlags.OmitIf) && !member.flags.has(PropertyFlags.OmitNull)) isRegular = true;
|
|
156
|
+
if (isRegular && isPure) {
|
|
157
|
+
const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
|
|
158
|
+
this.schema.byteSize += keyPart.length << 1;
|
|
159
|
+
SERIALIZE += this.getStores(keyPart)
|
|
160
|
+
.map((v) => indent + v + "\n")
|
|
161
|
+
.join("");
|
|
162
|
+
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
163
|
+
if (isFirst) isFirst = false;
|
|
164
|
+
} else if (isRegular && !isPure) {
|
|
165
|
+
const keyPart = (isFirst ? "" : ",") + aliasName + ":";
|
|
166
|
+
this.schema.byteSize += keyPart.length << 1;
|
|
167
|
+
SERIALIZE += this.getStores(keyPart)
|
|
168
|
+
.map((v) => indent + v + "\n")
|
|
169
|
+
.join("");
|
|
170
|
+
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
171
|
+
if (isFirst) isFirst = false;
|
|
172
|
+
} else {
|
|
173
|
+
if (member.flags.has(PropertyFlags.OmitNull)) {
|
|
174
|
+
SERIALIZE += indent + `if ((block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0) {\n`;
|
|
175
|
+
indentInc();
|
|
176
|
+
const keyPart = aliasName + ":";
|
|
177
|
+
this.schema.byteSize += keyPart.length << 1;
|
|
178
|
+
SERIALIZE += this.getStores(keyPart)
|
|
179
|
+
.map((v) => indent + v + "\n")
|
|
180
|
+
.join("");
|
|
181
|
+
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
182
|
+
if (!isLast) {
|
|
183
|
+
this.schema.byteSize += 2;
|
|
184
|
+
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
|
|
185
|
+
SERIALIZE += indent + `bs.offset += 2;\n`;
|
|
186
|
+
}
|
|
187
|
+
indentDec();
|
|
188
|
+
this.schema.byteSize += 2;
|
|
189
|
+
SERIALIZE += indent + `}\n`;
|
|
190
|
+
} else if (member.flags.has(PropertyFlags.OmitIf)) {
|
|
191
|
+
if (member.flags.get(PropertyFlags.OmitIf).kind == 14) {
|
|
192
|
+
const arg = member.flags.get(PropertyFlags.OmitIf);
|
|
193
|
+
arg.declaration.signature.returnType.name = Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name.range);
|
|
194
|
+
SERIALIZE += indent + `if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
|
|
195
|
+
} else {
|
|
196
|
+
SERIALIZE += indent + `if (${toString(member.flags.get(PropertyFlags.OmitIf))}) {\n`;
|
|
197
|
+
}
|
|
198
|
+
indentInc();
|
|
199
|
+
SERIALIZE += this.getStores(aliasName + ":")
|
|
200
|
+
.map((v) => indent + v + "\n")
|
|
201
|
+
.join("");
|
|
202
|
+
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
203
|
+
if (!isLast) {
|
|
204
|
+
this.schema.byteSize += 2;
|
|
205
|
+
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
|
|
206
|
+
SERIALIZE += indent + `bs.offset += 2;\n`;
|
|
207
|
+
}
|
|
208
|
+
indentDec();
|
|
209
|
+
SERIALIZE += indent + `}\n`;
|
|
306
210
|
}
|
|
307
|
-
|
|
308
|
-
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
309
|
-
const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
|
|
310
|
-
const ALLOCATE_METHOD = SimpleParser.parseClassMember(ALLOCATE, node);
|
|
311
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
312
|
-
node.members.push(SERIALIZE_METHOD);
|
|
313
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
314
|
-
node.members.push(INITIALIZE_METHOD);
|
|
315
|
-
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
316
|
-
node.members.push(DESERIALIZE_METHOD);
|
|
317
|
-
if (!node.members.find((v) => v.name.text == "__ALLOCATE"))
|
|
318
|
-
node.members.push(ALLOCATE_METHOD);
|
|
319
|
-
super.visitClassDeclaration(node);
|
|
211
|
+
}
|
|
320
212
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
213
|
+
let sortedMembers = [];
|
|
214
|
+
let len = -1;
|
|
215
|
+
this.schema.members
|
|
216
|
+
.slice()
|
|
217
|
+
.sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length))
|
|
218
|
+
.forEach((member) => {
|
|
219
|
+
const _nameLength = member.alias?.length || member.name.length;
|
|
220
|
+
if (_nameLength === len) {
|
|
221
|
+
sortedMembers[sortedMembers.length - 1].push(member);
|
|
222
|
+
} else {
|
|
223
|
+
sortedMembers.push([member]);
|
|
224
|
+
len = _nameLength;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
sortedMembers = sortedMembers.sort((a, b) => b.length - a.length);
|
|
228
|
+
indentInc();
|
|
229
|
+
for (const memberGroup of sortedMembers) {
|
|
230
|
+
const memberLen = (memberGroup[0].alias || memberGroup[0].name).length << 1;
|
|
231
|
+
DESERIALIZE += `${indent}case ${memberLen}: {\n`;
|
|
232
|
+
indentInc();
|
|
233
|
+
if (memberLen == 2) DESERIALIZE += `${indent}switch (load<u16>(keyStart)) {\n`;
|
|
234
|
+
else if (memberLen == 4) DESERIALIZE += `${indent}switch (load<u32>(keyStart)) {\n`;
|
|
235
|
+
else if (memberLen == 6) DESERIALIZE += `${indent}let code = (<u64>load<u32>(keyStart) << 16) | <u64>load<u16>(keyStart, 4);\n`;
|
|
236
|
+
else DESERIALIZE += toMemCDecl(memberLen, indent);
|
|
237
|
+
for (let i = 0; i < memberGroup.length; i++) {
|
|
238
|
+
const member = memberGroup[i];
|
|
239
|
+
const memberName = member.alias || member.name;
|
|
240
|
+
if (memberLen == 2) {
|
|
241
|
+
DESERIALIZE += `${indent} case ${memberName.charCodeAt(0)}: { // ${memberName}\n`;
|
|
242
|
+
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
243
|
+
DESERIALIZE += `${indent} return;\n`;
|
|
244
|
+
DESERIALIZE += `${indent} }\n`;
|
|
245
|
+
} else if (memberLen == 4) {
|
|
246
|
+
DESERIALIZE += `${indent} case ${toU32(memberName)}: { // ${memberName}\n`;
|
|
247
|
+
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
248
|
+
DESERIALIZE += `${indent} return;\n`;
|
|
249
|
+
DESERIALIZE += `${indent} }\n`;
|
|
250
|
+
} else if (memberLen == 6) {
|
|
251
|
+
DESERIALIZE += i == 0 ? indent : "";
|
|
252
|
+
DESERIALIZE += `if (code == ${toU48(memberName)}) { // ${memberName}\n`;
|
|
253
|
+
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
254
|
+
DESERIALIZE += `${indent} return;\n`;
|
|
255
|
+
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
|
|
256
|
+
} else {
|
|
257
|
+
DESERIALIZE += i == 0 ? indent : "";
|
|
258
|
+
DESERIALIZE += `if (${toMemCCheck(memberName)}) { // ${memberName}\n`;
|
|
259
|
+
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
260
|
+
DESERIALIZE += `${indent} return;\n`;
|
|
261
|
+
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
|
|
333
262
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
342
|
-
node.members.push(SERIALIZE_BS_METHOD_EMPTY);
|
|
343
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
344
|
-
node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
345
|
-
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
346
|
-
node.members.push(DESERIALIZE_METHOD_EMPTY);
|
|
347
|
-
if (!node.members.find((v) => v.name.text == "__ALLOCATE"))
|
|
348
|
-
node.members.push(ALLOCATE_METHOD_EMPTY);
|
|
263
|
+
}
|
|
264
|
+
if (memberLen < 6) {
|
|
265
|
+
DESERIALIZE += `${indent}}\n`;
|
|
266
|
+
}
|
|
267
|
+
indentDec();
|
|
268
|
+
DESERIALIZE += `${indent} return;\n`;
|
|
269
|
+
DESERIALIZE += `${indent}}\n`;
|
|
349
270
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
271
|
+
indentDec();
|
|
272
|
+
DESERIALIZE += `${indent}}\n`;
|
|
273
|
+
indentDec();
|
|
274
|
+
DESERIALIZE += `${indent}}\n`;
|
|
275
|
+
indent = " ";
|
|
276
|
+
this.schema.byteSize += 2;
|
|
277
|
+
SERIALIZE += indent + "store<u16>(bs.offset, 125, 0); // }\n";
|
|
278
|
+
SERIALIZE += indent + "bs.offset += 2;\n";
|
|
279
|
+
SERIALIZE += "}";
|
|
280
|
+
ALLOCATE += indent + "bs.ensureSize(" + this.schema.byteSize + ");\n";
|
|
281
|
+
ALLOCATE += "}";
|
|
282
|
+
INITIALIZE += " return this;\n";
|
|
283
|
+
INITIALIZE += "}";
|
|
284
|
+
if (process.env["JSON_DEBUG"]) {
|
|
285
|
+
console.log(SERIALIZE);
|
|
286
|
+
console.log(INITIALIZE);
|
|
287
|
+
console.log(DESERIALIZE);
|
|
288
|
+
console.log(ALLOCATE);
|
|
357
289
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
290
|
+
const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE, node);
|
|
291
|
+
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
292
|
+
const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
|
|
293
|
+
const ALLOCATE_METHOD = SimpleParser.parseClassMember(ALLOCATE, node);
|
|
294
|
+
if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_METHOD);
|
|
295
|
+
if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD);
|
|
296
|
+
if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD);
|
|
297
|
+
if (!node.members.find((v) => v.name.text == "__ALLOCATE")) node.members.push(ALLOCATE_METHOD);
|
|
298
|
+
super.visitClassDeclaration(node);
|
|
299
|
+
}
|
|
300
|
+
generateEmptyMethods(node) {
|
|
301
|
+
let SERIALIZE_RAW_EMPTY = '@inline __SERIALIZE(ptr: usize = changetype<usize>(this)): string {\n return "{}";\n}';
|
|
302
|
+
let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE(ptr: usize: bool): void {\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
|
|
303
|
+
let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
|
|
304
|
+
let DESERIALIZE_EMPTY = "@inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n return false;\n}";
|
|
305
|
+
let ALLOCATE_EMPTY = "@inline __ALLOCATE(): void {\n bs.ensureSize(4);\n}";
|
|
306
|
+
if (process.env["JSON_DEBUG"]) {
|
|
307
|
+
console.log(SERIALIZE_RAW_EMPTY);
|
|
308
|
+
console.log(SERIALIZE_BS_EMPTY);
|
|
309
|
+
console.log(INITIALIZE_EMPTY);
|
|
310
|
+
console.log(DESERIALIZE_EMPTY);
|
|
311
|
+
console.log(ALLOCATE_EMPTY);
|
|
361
312
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
313
|
+
const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
|
|
314
|
+
const SERIALIZE_BS_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_BS_EMPTY, node);
|
|
315
|
+
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
|
|
316
|
+
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
|
|
317
|
+
const ALLOCATE_METHOD_EMPTY = SimpleParser.parseClassMember(ALLOCATE_EMPTY, node);
|
|
318
|
+
if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
|
|
319
|
+
if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_BS_METHOD_EMPTY);
|
|
320
|
+
if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
321
|
+
if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD_EMPTY);
|
|
322
|
+
if (!node.members.find((v) => v.name.text == "__ALLOCATE")) node.members.push(ALLOCATE_METHOD_EMPTY);
|
|
323
|
+
}
|
|
324
|
+
visitImportStatement(node) {
|
|
325
|
+
super.visitImportStatement(node);
|
|
326
|
+
const source = this.parser.sources.find((src) => src.internalPath == node.internalPath);
|
|
327
|
+
if (!source) return;
|
|
328
|
+
if (source.statements.some((stmt) => stmt.kind === 59 && stmt.name.text === "JSON")) this.imports.push(node);
|
|
329
|
+
}
|
|
330
|
+
visitSource(node) {
|
|
331
|
+
this.imports = [];
|
|
332
|
+
super.visitSource(node);
|
|
333
|
+
}
|
|
334
|
+
addRequiredImports(node) {
|
|
335
|
+
if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "bs"))) {
|
|
336
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
337
|
+
const __dirname = path.dirname(__filename);
|
|
338
|
+
let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../modules/as-bs/"));
|
|
339
|
+
if (!relativePath.startsWith(".") && !relativePath.startsWith("/")) relativePath = "./" + relativePath;
|
|
340
|
+
const txt = `import { bs } from "${relativePath}";`;
|
|
341
|
+
if (!this.bsImport) {
|
|
342
|
+
this.bsImport = txt;
|
|
343
|
+
if (process.env["JSON_DEBUG"]) console.log("Added as-bs import: " + txt + "\n");
|
|
344
|
+
}
|
|
389
345
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
out.push("store<v128>(bs.offset, " + name + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 8));
|
|
401
|
-
offset += 16;
|
|
402
|
-
}
|
|
403
|
-
if (size == "u64") {
|
|
404
|
-
out.push("store<u64>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 4));
|
|
405
|
-
offset += 8;
|
|
406
|
-
}
|
|
407
|
-
else if (size == "u32") {
|
|
408
|
-
out.push("store<u32>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 2));
|
|
409
|
-
offset += 4;
|
|
410
|
-
}
|
|
411
|
-
else if (size == "u16") {
|
|
412
|
-
out.push("store<u16>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 1));
|
|
413
|
-
offset += 2;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
out.push("bs.offset += " + offset + ";");
|
|
417
|
-
return out;
|
|
346
|
+
if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "JSON"))) {
|
|
347
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
348
|
+
const __dirname = path.dirname(__filename);
|
|
349
|
+
let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../assembly/index.ts"));
|
|
350
|
+
if (!relativePath.startsWith(".") && !relativePath.startsWith("/")) relativePath = "./" + relativePath;
|
|
351
|
+
const txt = `import { JSON } from "${relativePath}";`;
|
|
352
|
+
if (!this.jsonImport) {
|
|
353
|
+
this.jsonImport = txt;
|
|
354
|
+
if (process.env["JSON_DEBUG"]) console.log("Added json-as import: " + txt + "\n");
|
|
355
|
+
}
|
|
418
356
|
}
|
|
357
|
+
}
|
|
358
|
+
getStores(data, simd = false) {
|
|
359
|
+
const out = [];
|
|
360
|
+
const sizes = strToNum(data, simd);
|
|
361
|
+
let offset = 0;
|
|
362
|
+
for (const [size, num] of sizes) {
|
|
363
|
+
if (size == "v128") {
|
|
364
|
+
let index = this.newStmts.simd.findIndex((v) => v.includes(num));
|
|
365
|
+
let name = "SIMD_" + (index == -1 ? this.newStmts.simd.length : index);
|
|
366
|
+
if (index && !this.newStmts.simd.includes(`const ${name} = ${num};`)) this.newStmts.simd.push(`const ${name} = ${num};`);
|
|
367
|
+
out.push("store<v128>(bs.offset, " + name + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 8));
|
|
368
|
+
offset += 16;
|
|
369
|
+
}
|
|
370
|
+
if (size == "u64") {
|
|
371
|
+
out.push("store<u64>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 4));
|
|
372
|
+
offset += 8;
|
|
373
|
+
} else if (size == "u32") {
|
|
374
|
+
out.push("store<u32>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 2));
|
|
375
|
+
offset += 4;
|
|
376
|
+
} else if (size == "u16") {
|
|
377
|
+
out.push("store<u16>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 1));
|
|
378
|
+
offset += 2;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
out.push("bs.offset += " + offset + ";");
|
|
382
|
+
return out;
|
|
383
|
+
}
|
|
419
384
|
}
|
|
420
385
|
export default class Transformer extends Transform {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
const parent = schemas.find((v) => v.name == schema.parent?.name);
|
|
468
|
-
if (!parent)
|
|
469
|
-
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);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
386
|
+
afterParse(parser) {
|
|
387
|
+
const transformer = new JSONTransform();
|
|
388
|
+
const sources = parser.sources.sort((_a, _b) => {
|
|
389
|
+
const a = _a.internalPath;
|
|
390
|
+
const b = _b.internalPath;
|
|
391
|
+
if (a[0] == "~" && b[0] !== "~") {
|
|
392
|
+
return -1;
|
|
393
|
+
} else if (a[0] !== "~" && b[0] == "~") {
|
|
394
|
+
return 1;
|
|
395
|
+
} else {
|
|
396
|
+
return 0;
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
transformer.parser = parser;
|
|
400
|
+
for (const source of sources) {
|
|
401
|
+
transformer.imports = [];
|
|
402
|
+
transformer.currentSource = source;
|
|
403
|
+
transformer.visit(source);
|
|
404
|
+
if (transformer.newStmts.simd) {
|
|
405
|
+
const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.newStmts.simd.join("\n")));
|
|
406
|
+
parser.currentSource = tokenizer.source;
|
|
407
|
+
for (let i = 0; i < transformer.newStmts.simd.length; i++) source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
|
|
408
|
+
parser.currentSource = source;
|
|
409
|
+
transformer.newStmts.simd = [];
|
|
410
|
+
}
|
|
411
|
+
if (transformer.jsonImport) {
|
|
412
|
+
const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.jsonImport));
|
|
413
|
+
parser.currentSource = tokenizer.source;
|
|
414
|
+
source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
|
|
415
|
+
parser.currentSource = source;
|
|
416
|
+
transformer.jsonImport = null;
|
|
417
|
+
}
|
|
418
|
+
if (transformer.bsImport) {
|
|
419
|
+
const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.bsImport));
|
|
420
|
+
parser.currentSource = tokenizer.source;
|
|
421
|
+
source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
|
|
422
|
+
parser.currentSource = source;
|
|
423
|
+
transformer.bsImport = null;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
const schemas = transformer.schemas;
|
|
427
|
+
for (const schema of schemas) {
|
|
428
|
+
if (schema.parent) {
|
|
429
|
+
const parent = schemas.find((v) => v.name == schema.parent?.name);
|
|
430
|
+
if (!parent) 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);
|
|
431
|
+
}
|
|
472
432
|
}
|
|
433
|
+
}
|
|
473
434
|
}
|
|
474
435
|
function sortMembers(members) {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
487
|
-
});
|
|
436
|
+
return members.sort((a, b) => {
|
|
437
|
+
const aMove = a.flags.has(PropertyFlags.OmitIf) || a.flags.has(PropertyFlags.OmitNull);
|
|
438
|
+
const bMove = b.flags.has(PropertyFlags.OmitIf) || b.flags.has(PropertyFlags.OmitNull);
|
|
439
|
+
if (aMove && !bMove) {
|
|
440
|
+
return -1;
|
|
441
|
+
} else if (!aMove && bMove) {
|
|
442
|
+
return 1;
|
|
443
|
+
} else {
|
|
444
|
+
return 0;
|
|
445
|
+
}
|
|
446
|
+
});
|
|
488
447
|
}
|
|
489
448
|
function getArgs(args) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
out.push(arg.text);
|
|
508
|
-
}
|
|
509
|
-
else if (arg instanceof FalseExpression) {
|
|
510
|
-
out.push(arg.text);
|
|
511
|
-
}
|
|
512
|
-
else if (arg instanceof IdentifierExpression) {
|
|
513
|
-
out.push(arg.text);
|
|
514
|
-
}
|
|
449
|
+
if (!args) return [];
|
|
450
|
+
let out = [];
|
|
451
|
+
for (const arg of args) {
|
|
452
|
+
if (arg instanceof StringLiteralExpression) {
|
|
453
|
+
out.push(arg.value);
|
|
454
|
+
} else if (arg instanceof IntegerLiteralExpression) {
|
|
455
|
+
out.push(i64_to_string(arg.value));
|
|
456
|
+
} else if (arg instanceof FloatLiteralExpression) {
|
|
457
|
+
out.push(arg.value.toString());
|
|
458
|
+
} else if (arg instanceof NullExpression) {
|
|
459
|
+
out.push(arg.text);
|
|
460
|
+
} else if (arg instanceof TrueExpression) {
|
|
461
|
+
out.push(arg.text);
|
|
462
|
+
} else if (arg instanceof FalseExpression) {
|
|
463
|
+
out.push(arg.text);
|
|
464
|
+
} else if (arg instanceof IdentifierExpression) {
|
|
465
|
+
out.push(arg.text);
|
|
515
466
|
}
|
|
516
|
-
|
|
467
|
+
}
|
|
468
|
+
return out;
|
|
517
469
|
}
|
|
518
470
|
function toU16(data, offset = 0) {
|
|
519
|
-
|
|
471
|
+
return data.charCodeAt(offset + 0).toString();
|
|
520
472
|
}
|
|
521
473
|
function toU32(data, offset = 0) {
|
|
522
|
-
|
|
474
|
+
return ((data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0)).toString();
|
|
523
475
|
}
|
|
524
476
|
function toU48(data, offset = 0) {
|
|
525
|
-
|
|
477
|
+
return ((BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0))).toString();
|
|
526
478
|
}
|
|
527
479
|
function toU64(data, offset = 0) {
|
|
528
|
-
|
|
480
|
+
return ((BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0))).toString();
|
|
529
481
|
}
|
|
530
482
|
function toMemCDecl(n, indent) {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
return out;
|
|
483
|
+
let out = "";
|
|
484
|
+
let offset = 0;
|
|
485
|
+
let index = 0;
|
|
486
|
+
while (n >= 8) {
|
|
487
|
+
out += `${indent}const code${index++} = load<u64>(keyStart, ${offset});\n`;
|
|
488
|
+
offset += 8;
|
|
489
|
+
n -= 8;
|
|
490
|
+
}
|
|
491
|
+
while (n >= 4) {
|
|
492
|
+
out += `${indent}const code${index++} = load<u32>(keyStart, ${offset});\n`;
|
|
493
|
+
offset += 4;
|
|
494
|
+
n -= 4;
|
|
495
|
+
}
|
|
496
|
+
if (n == 1) out += `${indent}const code${index++} = load<u16>(keyStart, ${offset});\n`;
|
|
497
|
+
return out;
|
|
547
498
|
}
|
|
548
499
|
function toMemCCheck(data) {
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
return out.slice(4);
|
|
500
|
+
let n = data.length << 1;
|
|
501
|
+
let out = "";
|
|
502
|
+
let offset = 0;
|
|
503
|
+
let index = 0;
|
|
504
|
+
while (n >= 8) {
|
|
505
|
+
out += ` && code${index++} == ${toU64(data, offset >> 1)}`;
|
|
506
|
+
offset += 8;
|
|
507
|
+
n -= 8;
|
|
508
|
+
}
|
|
509
|
+
while (n >= 4) {
|
|
510
|
+
out += ` && code${index++} == ${toU32(data, offset >> 1)}`;
|
|
511
|
+
offset += 4;
|
|
512
|
+
n -= 4;
|
|
513
|
+
}
|
|
514
|
+
if (n == 1) out += ` && code${index++} == ${toU16(data, offset >> 1)}`;
|
|
515
|
+
return out.slice(4);
|
|
566
516
|
}
|
|
567
517
|
function strToNum(data, simd = false, offset = 0) {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
518
|
+
const out = [];
|
|
519
|
+
let n = data.length;
|
|
520
|
+
while (n >= 8 && simd) {
|
|
521
|
+
out.push(["v128", "i16x8(" + data.charCodeAt(offset + 0) + ", " + data.charCodeAt(offset + 1) + ", " + data.charCodeAt(offset + 2) + ", " + data.charCodeAt(offset + 3) + ", " + data.charCodeAt(offset + 4) + ", " + data.charCodeAt(offset + 5) + ", " + data.charCodeAt(offset + 6) + ", " + data.charCodeAt(offset + 7) + ")"]);
|
|
522
|
+
offset += 8;
|
|
523
|
+
n -= 8;
|
|
524
|
+
}
|
|
525
|
+
while (n >= 4) {
|
|
526
|
+
const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0));
|
|
527
|
+
out.push(["u64", value.toString()]);
|
|
528
|
+
offset += 4;
|
|
529
|
+
n -= 4;
|
|
530
|
+
}
|
|
531
|
+
while (n >= 2) {
|
|
532
|
+
const value = (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0);
|
|
533
|
+
out.push(["u32", value.toString()]);
|
|
534
|
+
offset += 2;
|
|
535
|
+
n -= 2;
|
|
536
|
+
}
|
|
537
|
+
if (n === 1) {
|
|
538
|
+
const value = data.charCodeAt(offset + 0);
|
|
539
|
+
out.push(["u16", value.toString()]);
|
|
540
|
+
}
|
|
541
|
+
return out;
|
|
592
542
|
}
|
|
593
543
|
function isPrimitive(type) {
|
|
594
|
-
|
|
595
|
-
|
|
544
|
+
const primitiveTypes = ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "f32", "f64", "bool", "boolean"];
|
|
545
|
+
return primitiveTypes.some((v) => type.includes(v));
|
|
596
546
|
}
|
|
597
547
|
function throwError(message, range) {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
548
|
+
const err = new Error();
|
|
549
|
+
err.stack = `${message}\n at ${range.source.normalizedPath}:${range.source.lineAt(range.start)}:${range.source.columnAt()}\n`;
|
|
550
|
+
throw err;
|
|
601
551
|
}
|
|
602
552
|
function indentInc() {
|
|
603
|
-
|
|
553
|
+
indent += " ";
|
|
604
554
|
}
|
|
605
555
|
function indentDec() {
|
|
606
|
-
|
|
556
|
+
indent = indent.slice(0, Math.max(0, indent.length - 2));
|
|
607
557
|
}
|
|
608
558
|
function sizeof(type) {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
else if (type == "i32")
|
|
620
|
-
return 22;
|
|
621
|
-
else if (type == "u64")
|
|
622
|
-
return 40;
|
|
623
|
-
else if (type == "i64")
|
|
624
|
-
return 40;
|
|
625
|
-
else if (type == "bool" || type == "boolean")
|
|
626
|
-
return 10;
|
|
627
|
-
else
|
|
628
|
-
return 0;
|
|
559
|
+
if (type == "u8") return 6;
|
|
560
|
+
else if (type == "i8") return 8;
|
|
561
|
+
else if (type == "u16") return 10;
|
|
562
|
+
else if (type == "i16") return 12;
|
|
563
|
+
else if (type == "u32") return 20;
|
|
564
|
+
else if (type == "i32") return 22;
|
|
565
|
+
else if (type == "u64") return 40;
|
|
566
|
+
else if (type == "i64") return 40;
|
|
567
|
+
else if (type == "bool" || type == "boolean") return 10;
|
|
568
|
+
else return 0;
|
|
629
569
|
}
|
|
630
570
|
function allPrimitive(schema) {
|
|
631
|
-
|
|
571
|
+
return !schema.members.some((p) => p.byteSize == 0);
|
|
632
572
|
}
|
|
633
|
-
//# sourceMappingURL=index.js.map
|
|
573
|
+
//# sourceMappingURL=index.js.map
|