json-as 1.0.0-alpha.1 → 1.0.0-alpha.3

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.
Files changed (57) hide show
  1. package/.gitmodules +0 -0
  2. package/.prettierignore +6 -0
  3. package/.prettierrc.json +0 -1
  4. package/CHANGELOG +20 -1
  5. package/README.md +4 -3
  6. package/as-test.config.json +1 -1
  7. package/asconfig.json +1 -29
  8. package/assembly/__benches__/misc.bench.ts +0 -19
  9. package/assembly/__tests__/array.spec.ts +67 -0
  10. package/assembly/__tests__/bool.spec.ts +4 -12
  11. package/assembly/__tests__/float.spec.ts +11 -21
  12. package/assembly/__tests__/integer.spec.ts +7 -9
  13. package/assembly/__tests__/null.spec.ts +12 -0
  14. package/assembly/__tests__/obj.spec.ts +137 -3
  15. package/assembly/__tests__/simd/string.spec.ts +21 -21
  16. package/assembly/__tests__/string.spec.ts +6 -4
  17. package/assembly/__tests__/test.spec.ts +120 -191
  18. package/assembly/deserialize/simple/bool.ts +1 -1
  19. package/assembly/deserialize/simple/map.ts +1 -1
  20. package/assembly/deserialize/simple/object.ts +2 -3
  21. package/assembly/deserialize/simple/string.ts +4 -3
  22. package/assembly/globals/tables.ts +74 -416
  23. package/assembly/index.ts +20 -25
  24. package/assembly/serialize/simd/string.ts +11 -11
  25. package/assembly/serialize/simple/array.ts +5 -5
  26. package/assembly/serialize/simple/bool.ts +3 -3
  27. package/assembly/serialize/simple/date.ts +2 -2
  28. package/assembly/serialize/simple/float.ts +2 -2
  29. package/assembly/serialize/simple/integer.ts +2 -2
  30. package/assembly/serialize/simple/map.ts +7 -7
  31. package/assembly/serialize/simple/string.ts +5 -5
  32. package/assembly/test.ts +4 -48
  33. package/assembly/util/bytes.ts +1 -1
  34. package/modules/as-bs/LICENSE +21 -0
  35. package/modules/as-bs/README.md +95 -0
  36. package/modules/as-bs/assembly/index.ts +116 -0
  37. package/modules/as-bs/assembly/tsconfig.json +97 -0
  38. package/modules/as-bs/index.ts +1 -0
  39. package/modules/as-bs/package.json +32 -0
  40. package/modules/test/assembly/index.ts +22 -0
  41. package/package.json +5 -10
  42. package/run-tests.sh +15 -0
  43. package/transform/lib/builder.js +1262 -1340
  44. package/transform/lib/index.js +512 -572
  45. package/transform/lib/index.js.map +1 -1
  46. package/transform/lib/linker.js +10 -12
  47. package/transform/lib/types.js +19 -18
  48. package/transform/lib/types.js.map +1 -1
  49. package/transform/lib/util.js +34 -34
  50. package/transform/lib/visitor.js +526 -529
  51. package/transform/package.json +2 -1
  52. package/transform/src/index.ts +20 -9
  53. package/transform/src/types.ts +1 -0
  54. package/modules/bs/index.ts +0 -167
  55. package/modules/tsconfig.json +0 -8
  56. package/transform/lib/index.old.js +0 -404
  57. package/transform/lib/index.old.js.map +0 -1
@@ -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
- 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)
21
- return;
22
- if (!node.decorators.some((decorator) => {
23
- const name = decorator.name.text;
24
- return name === "json" || name === "serializable";
25
- }))
26
- return;
27
- this.schema = new Schema();
28
- this.schema.node = node;
29
- this.schema.name = node.name.text;
30
- this.schemas.push(this.schema);
31
- if (process.env["JSON_DEBUG"])
32
- 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"])
41
- console.log("Found " + extendsName + " internally");
42
- this.visitClassDeclaration(internalSearch);
43
- this.visitClassDeclaration(node);
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.addRequiredImports(node);
69
- for (const member of members) {
70
- if (!member.type)
71
- throwError("Fields must be strongly typed", node.range);
72
- const type = toString(member.type);
73
- const name = member.name;
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
- if (!this.schema.static)
122
- this.schema.members = sortMembers(this.schema.members);
123
- let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
124
- let INITIALIZE = "@inline __INITIALIZE(): this {\n";
125
- let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n switch (keyEnd - keyStart) {\n";
126
- let ALLOCATE = "@inline __ALLOCATE(): void {\n";
127
- indent = " ";
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
- let isPure = this.schema.static;
137
- let isRegular = isPure;
138
- let isFirst = true;
139
- for (let i = 0; i < this.schema.members.length; i++) {
140
- const member = this.schema.members[i];
141
- const aliasName = JSON.stringify(member.alias || member.name);
142
- const realName = member.name;
143
- const isLast = i == this.schema.members.length - 1;
144
- const nonNullType = member.type.replace(" | null", "");
145
- if (member.value) {
146
- INITIALIZE += ` this.${member.name} = ${member.value};\n`;
147
- }
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
- }
151
- else if (member.type.startsWith("Array<") || member.type.startsWith("Map<")) {
152
- INITIALIZE += ` this.${member.name} = [];\n`;
153
- }
154
- else if (member.type == "string" || member.type == "String" || member.type == "JSON.Raw") {
155
- INITIALIZE += ` this.${member.name} = "";\n`;
156
- }
157
- if (!isRegular && !member.flags.has(PropertyFlags.OmitIf) && !member.flags.has(PropertyFlags.OmitNull))
158
- isRegular = true;
159
- if (isRegular && isPure) {
160
- const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
161
- this.schema.byteSize += keyPart.length << 1;
162
- SERIALIZE += this.getStores(keyPart)
163
- .map((v) => indent + v + "\n")
164
- .join("");
165
- SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
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
- else if (isRegular && !isPure) {
170
- const keyPart = (isFirst ? "" : ",") + aliasName + ":";
171
- this.schema.byteSize += keyPart.length << 1;
172
- SERIALIZE += this.getStores(keyPart)
173
- .map((v) => indent + v + "\n")
174
- .join("");
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
- else {
180
- if (member.flags.has(PropertyFlags.OmitNull)) {
181
- SERIALIZE += indent + `if ((block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0) {\n`;
182
- indentInc();
183
- const keyPart = aliasName + ":";
184
- this.schema.byteSize += keyPart.length << 1;
185
- SERIALIZE += this.getStores(keyPart)
186
- .map((v) => indent + v + "\n")
187
- .join("");
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
- let sortedMembers = [];
223
- let len = -1;
224
- this.schema.members
225
- .slice()
226
- .sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length))
227
- .forEach((member) => {
228
- const _nameLength = member.alias?.length || member.name.length;
229
- if (_nameLength === len) {
230
- sortedMembers[sortedMembers.length - 1].push(member);
231
- }
232
- else {
233
- sortedMembers.push([member]);
234
- len = _nameLength;
235
- }
236
- });
237
- sortedMembers = sortedMembers.sort((a, b) => b.length - a.length);
238
- indentInc();
239
- for (const memberGroup of sortedMembers) {
240
- const memberLen = (memberGroup[0].alias || memberGroup[0].name).length << 1;
241
- DESERIALIZE += `${indent}case ${memberLen}: {\n`;
242
- indentInc();
243
- if (memberLen == 2)
244
- DESERIALIZE += `${indent}switch (load<u16>(keyStart)) {\n`;
245
- else if (memberLen == 4)
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
- indentDec();
289
- DESERIALIZE += `${indent}}\n`;
290
- indentDec();
291
- DESERIALIZE += `${indent}}\n`;
292
- indent = " ";
293
- this.schema.byteSize += 2;
294
- SERIALIZE += indent + "store<u16>(bs.offset, 125, 0); // }\n";
295
- SERIALIZE += indent + "bs.offset += 2;\n";
296
- SERIALIZE += "}";
297
- ALLOCATE += indent + "bs.ensureSize(" + this.schema.byteSize + ");\n";
298
- ALLOCATE += "}";
299
- INITIALIZE += " return this;\n";
300
- INITIALIZE += "}";
301
- if (process.env["JSON_DEBUG"]) {
302
- console.log(SERIALIZE);
303
- console.log(INITIALIZE);
304
- console.log(DESERIALIZE);
305
- console.log(ALLOCATE);
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
- const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE, node);
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
- generateEmptyMethods(node) {
322
- let SERIALIZE_RAW_EMPTY = '@inline __SERIALIZE(ptr: usize = changetype<usize>(this)): string {\n return "{}";\n}';
323
- let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE(ptr: usize: bool): void {\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
324
- let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
325
- let DESERIALIZE_EMPTY = "@inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n return false;\n}";
326
- let ALLOCATE_EMPTY = "@inline __ALLOCATE(): void {\n bs.ensureSize(4);\n}";
327
- if (process.env["JSON_DEBUG"]) {
328
- console.log(SERIALIZE_RAW_EMPTY);
329
- console.log(SERIALIZE_BS_EMPTY);
330
- console.log(INITIALIZE_EMPTY);
331
- console.log(DESERIALIZE_EMPTY);
332
- console.log(ALLOCATE_EMPTY);
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
- const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
335
- const SERIALIZE_BS_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_BS_EMPTY, node);
336
- const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
337
- const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
338
- const ALLOCATE_METHOD_EMPTY = SimpleParser.parseClassMember(ALLOCATE_EMPTY, node);
339
- if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
340
- node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
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
- visitImportStatement(node) {
351
- super.visitImportStatement(node);
352
- const source = this.parser.sources.find((src) => src.internalPath == node.internalPath);
353
- if (!source)
354
- return;
355
- if (source.statements.some((stmt) => stmt.kind === 59 && stmt.name.text === "JSON"))
356
- this.imports.push(node);
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.proposeSize(" + 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
- visitSource(node) {
359
- this.imports = [];
360
- super.visitSource(node);
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
- addRequiredImports(node) {
363
- if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "bs"))) {
364
- const __filename = fileURLToPath(import.meta.url);
365
- const __dirname = path.dirname(__filename);
366
- let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../modules/bs/index.ts"));
367
- if (!relativePath.startsWith(".") && !relativePath.startsWith("/"))
368
- relativePath = "./" + relativePath;
369
- const txt = `import { bs } from "${relativePath}";`;
370
- if (!this.jsonImport) {
371
- this.jsonImport = txt;
372
- if (process.env["JSON_DEBUG"])
373
- console.log("Added bs import: " + txt + "\n");
374
- }
375
- }
376
- if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "JSON"))) {
377
- const __filename = fileURLToPath(import.meta.url);
378
- const __dirname = path.dirname(__filename);
379
- let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../assembly/index.ts"));
380
- if (!relativePath.startsWith(".") && !relativePath.startsWith("/"))
381
- relativePath = "./" + relativePath;
382
- const txt = `import { JSON } from "${relativePath}";`;
383
- if (!this.jsonImport) {
384
- this.jsonImport = txt;
385
- if (process.env["JSON_DEBUG"])
386
- console.log("Added json-as import: " + txt + "\n");
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
- getStores(data, simd = true) {
391
- const out = [];
392
- const sizes = strToNum(data, simd);
393
- let offset = 0;
394
- for (const [size, num] of sizes) {
395
- if (size == "v128") {
396
- let index = this.newStmts.simd.findIndex((v) => v.includes(num));
397
- let name = "SIMD_" + (index == -1 ? this.newStmts.simd.length : index);
398
- if (index && !this.newStmts.simd.includes(`const ${name} = ${num};`))
399
- this.newStmts.simd.push(`const ${name} = ${num};`);
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
- afterParse(parser) {
422
- const transformer = new JSONTransform();
423
- const sources = parser.sources.sort((_a, _b) => {
424
- const a = _a.internalPath;
425
- const b = _b.internalPath;
426
- if (a[0] == "~" && b[0] !== "~") {
427
- return -1;
428
- }
429
- else if (a[0] !== "~" && b[0] == "~") {
430
- return 1;
431
- }
432
- else {
433
- return 0;
434
- }
435
- });
436
- transformer.parser = parser;
437
- for (const source of sources) {
438
- transformer.imports = [];
439
- transformer.currentSource = source;
440
- transformer.visit(source);
441
- if (transformer.newStmts.simd) {
442
- const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.newStmts.simd.join("\n")));
443
- parser.currentSource = tokenizer.source;
444
- for (let i = 0; i < transformer.newStmts.simd.length; i++)
445
- source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
446
- parser.currentSource = source;
447
- transformer.newStmts.simd = [];
448
- }
449
- if (transformer.jsonImport) {
450
- const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.jsonImport));
451
- parser.currentSource = tokenizer.source;
452
- source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
453
- parser.currentSource = source;
454
- transformer.jsonImport = null;
455
- }
456
- if (transformer.bsImport) {
457
- const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.bsImport));
458
- parser.currentSource = tokenizer.source;
459
- source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
460
- parser.currentSource = source;
461
- transformer.bsImport = null;
462
- }
463
- }
464
- const schemas = transformer.schemas;
465
- for (const schema of schemas) {
466
- if (schema.parent) {
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
- return members.sort((a, b) => {
476
- const aMove = a.flags.has(PropertyFlags.OmitIf) || a.flags.has(PropertyFlags.OmitNull);
477
- const bMove = b.flags.has(PropertyFlags.OmitIf) || b.flags.has(PropertyFlags.OmitNull);
478
- if (aMove && !bMove) {
479
- return -1;
480
- }
481
- else if (!aMove && bMove) {
482
- return 1;
483
- }
484
- else {
485
- return 0;
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
- if (!args)
491
- return [];
492
- let out = [];
493
- for (const arg of args) {
494
- if (arg instanceof StringLiteralExpression) {
495
- out.push(arg.value);
496
- }
497
- else if (arg instanceof IntegerLiteralExpression) {
498
- out.push(i64_to_string(arg.value));
499
- }
500
- else if (arg instanceof FloatLiteralExpression) {
501
- out.push(arg.value.toString());
502
- }
503
- else if (arg instanceof NullExpression) {
504
- out.push(arg.text);
505
- }
506
- else if (arg instanceof TrueExpression) {
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
- return out;
467
+ }
468
+ return out;
517
469
  }
518
470
  function toU16(data, offset = 0) {
519
- return data.charCodeAt(offset + 0).toString();
471
+ return data.charCodeAt(offset + 0).toString();
520
472
  }
521
473
  function toU32(data, offset = 0) {
522
- return ((data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0)).toString();
474
+ return ((data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0)).toString();
523
475
  }
524
476
  function toU48(data, offset = 0) {
525
- return ((BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0))).toString();
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
- 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();
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
- let out = "";
532
- let offset = 0;
533
- let index = 0;
534
- while (n >= 8) {
535
- out += `${indent}const code${index++} = load<u64>(keyStart, ${offset});\n`;
536
- offset += 8;
537
- n -= 8;
538
- }
539
- while (n >= 4) {
540
- out += `${indent}const code${index++} = load<u32>(keyStart, ${offset});\n`;
541
- offset += 4;
542
- n -= 4;
543
- }
544
- if (n == 1)
545
- out += `${indent}const code${index++} = load<u16>(keyStart, ${offset});\n`;
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
- let n = data.length << 1;
550
- let out = "";
551
- let offset = 0;
552
- let index = 0;
553
- while (n >= 8) {
554
- out += ` && code${index++} == ${toU64(data, offset >> 1)}`;
555
- offset += 8;
556
- n -= 8;
557
- }
558
- while (n >= 4) {
559
- out += ` && code${index++} == ${toU32(data, offset >> 1)}`;
560
- offset += 4;
561
- n -= 4;
562
- }
563
- if (n == 1)
564
- out += ` && code${index++} == ${toU16(data, offset >> 1)}`;
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
- const out = [];
569
- let n = data.length;
570
- while (n >= 8 && simd) {
571
- 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) + ")"]);
572
- offset += 8;
573
- n -= 8;
574
- }
575
- while (n >= 4) {
576
- 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));
577
- out.push(["u64", value.toString()]);
578
- offset += 4;
579
- n -= 4;
580
- }
581
- while (n >= 2) {
582
- const value = (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0);
583
- out.push(["u32", value.toString()]);
584
- offset += 2;
585
- n -= 2;
586
- }
587
- if (n === 1) {
588
- const value = data.charCodeAt(offset + 0);
589
- out.push(["u16", value.toString()]);
590
- }
591
- return out;
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
- const primitiveTypes = ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "f32", "f64", "bool", "boolean"];
595
- return primitiveTypes.some((v) => type.includes(v));
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
- const err = new Error();
599
- err.stack = `${message}\n at ${range.source.normalizedPath}:${range.source.lineAt(range.start)}:${range.source.columnAt()}\n`;
600
- throw err;
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
- indent += " ";
553
+ indent += " ";
604
554
  }
605
555
  function indentDec() {
606
- indent = indent.slice(0, Math.max(0, indent.length - 2));
556
+ indent = indent.slice(0, Math.max(0, indent.length - 2));
607
557
  }
608
558
  function sizeof(type) {
609
- if (type == "u8")
610
- return 6;
611
- else if (type == "i8")
612
- return 8;
613
- else if (type == "u16")
614
- return 10;
615
- else if (type == "i16")
616
- return 12;
617
- else if (type == "u32")
618
- return 20;
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
- return !schema.members.some((p) => p.byteSize == 0);
571
+ return !schema.members.some((p) => p.byteSize == 0);
632
572
  }
633
- //# sourceMappingURL=index.js.map
573
+ //# sourceMappingURL=index.js.map