json-as 0.9.28 → 1.0.0-alpha.1
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/.github/workflows/nodejs.yml +0 -3
- package/.prettierrc.json +4 -1
- package/CHANGELOG +13 -0
- package/LICENSE +1 -1
- package/README.md +22 -7
- package/as-test.config.json +1 -1
- package/asconfig.json +2 -2
- package/assembly/__benches__/misc.bench.ts +17 -31
- package/assembly/__tests__/bool.spec.ts +1 -1
- package/assembly/__tests__/simd/string.spec.ts +32 -0
- package/assembly/__tests__/types.ts +17 -0
- package/assembly/custom/chars.ts +2 -2
- package/assembly/custom/memory.ts +25 -0
- package/assembly/custom/types.ts +1 -0
- package/assembly/custom/util.ts +59 -140
- package/assembly/deserialize/simd/string.ts +103 -0
- package/assembly/deserialize/simple/arbitrary.ts +17 -0
- package/assembly/deserialize/simple/array/arbitrary.ts +113 -0
- package/assembly/deserialize/simple/array/array.ts +18 -0
- package/assembly/deserialize/simple/array/bool.ts +17 -0
- package/assembly/deserialize/simple/array/float.ts +28 -0
- package/assembly/deserialize/simple/array/integer.ts +27 -0
- package/assembly/deserialize/simple/array/map.ts +18 -0
- package/assembly/deserialize/simple/array/object.ts +18 -0
- package/assembly/deserialize/simple/array/string.ts +22 -0
- package/assembly/deserialize/simple/array.ts +48 -0
- package/assembly/deserialize/simple/bool.ts +9 -0
- package/assembly/deserialize/simple/date.ts +11 -0
- package/assembly/deserialize/simple/float.ts +10 -0
- package/assembly/deserialize/simple/integer.ts +5 -0
- package/assembly/deserialize/simple/map.ts +154 -0
- package/assembly/deserialize/simple/object.ts +159 -0
- package/assembly/deserialize/simple/string.ts +48 -0
- package/assembly/globals/tables.ts +417 -0
- package/assembly/index.d.ts +9 -13
- package/assembly/index.ts +282 -158
- package/assembly/serialize/simd/string.ts +176 -0
- package/assembly/serialize/simple/arbitrary.ts +36 -0
- package/assembly/serialize/simple/array.ts +32 -0
- package/assembly/serialize/simple/bool.ts +19 -0
- package/assembly/serialize/simple/date.ts +13 -0
- package/assembly/serialize/simple/float.ts +7 -0
- package/assembly/serialize/simple/integer.ts +7 -0
- package/assembly/serialize/simple/map.ts +43 -0
- package/assembly/serialize/simple/object.ts +7 -0
- package/assembly/serialize/simple/string.ts +48 -0
- package/assembly/test.ts +43 -28
- package/assembly/tsconfig.json +2 -91
- package/assembly/types.ts +0 -0
- package/assembly/util/atoi.ts +35 -0
- package/assembly/util/bytes.ts +12 -0
- package/assembly/util/concat.ts +9 -0
- package/assembly/util/getArrayDepth.ts +17 -0
- package/assembly/util/index.ts +5 -0
- package/assembly/util/isSpace.ts +4 -0
- package/assembly/util/nextPowerOf2.ts +4 -0
- package/assembly/util/ptrToStr.ts +7 -0
- package/assembly/util/snp.ts +69 -0
- package/bench.js +5 -5
- package/modules/bs/index.ts +167 -0
- package/modules/tsconfig.json +8 -0
- package/package.json +42 -47
- package/transform/lib/builder.js +1353 -0
- package/transform/lib/builder.js.map +1 -0
- package/transform/lib/index.js +497 -395
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/index.old.js +404 -0
- package/transform/lib/index.old.js.map +1 -0
- package/transform/lib/linker.js +18 -0
- package/transform/lib/linker.js.map +1 -0
- package/transform/lib/types.js +25 -0
- package/transform/lib/types.js.map +1 -0
- package/transform/lib/util.js +47 -0
- package/transform/lib/util.js.map +1 -0
- package/transform/lib/visitor.js +529 -446
- package/transform/lib/visitor.js.map +1 -0
- package/transform/package.json +1 -34
- package/transform/src/builder.ts +1371 -0
- package/transform/src/index.ts +571 -481
- package/transform/src/linker.ts +21 -0
- package/transform/src/types.ts +27 -0
- package/transform/src/util.ts +56 -0
- package/transform/src/visitor.ts +531 -0
- package/transform/tsconfig.json +3 -1
- package/assembly/__benches__/as-tral.d.ts +0 -1
- package/assembly/custom/bs.ts +0 -211
- package/assembly/deserialize/array/array.ts +0 -31
- package/assembly/deserialize/array/bool.ts +0 -19
- package/assembly/deserialize/array/float.ts +0 -24
- package/assembly/deserialize/array/integer.ts +0 -24
- package/assembly/deserialize/array/map.ts +0 -27
- package/assembly/deserialize/array/object.ts +0 -27
- package/assembly/deserialize/array/string.ts +0 -29
- package/assembly/deserialize/array.ts +0 -46
- package/assembly/deserialize/bool.ts +0 -34
- package/assembly/deserialize/date.ts +0 -19
- package/assembly/deserialize/float.ts +0 -21
- package/assembly/deserialize/integer.ts +0 -16
- package/assembly/deserialize/map.ts +0 -189
- package/assembly/deserialize/object.ts +0 -271
- package/assembly/deserialize/string.ts +0 -164
- package/assembly/serialize/array.ts +0 -51
- package/assembly/serialize/bool.ts +0 -10
- package/assembly/serialize/date.ts +0 -4
- package/assembly/serialize/float.ts +0 -4
- package/assembly/serialize/integer.ts +0 -5
- package/assembly/serialize/map.ts +0 -24
- package/assembly/serialize/object.ts +0 -13
- package/assembly/serialize/string.ts +0 -287
- package/logs/test.log.json +0 -1049
package/transform/lib/index.js
CHANGED
|
@@ -1,503 +1,490 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
3
|
-
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
1
|
+
import { IdentifierExpression, Source, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, Node, Tokenizer } from "assemblyscript/dist/assemblyscript.js";
|
|
4
2
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import { Visitor } from "./visitor.js";
|
|
4
|
+
import { SimpleParser, toString } from "./util.js";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { Property, PropertyFlags, Schema } from "./types.js";
|
|
8
|
+
import { getClasses, getImportedClass } from "./linker.js";
|
|
9
|
+
let indent = " ";
|
|
10
|
+
class JSONTransform extends Visitor {
|
|
11
|
+
parser;
|
|
12
|
+
schemas = [];
|
|
13
|
+
schema;
|
|
8
14
|
sources = new Set();
|
|
9
|
-
|
|
15
|
+
imports = [];
|
|
16
|
+
jsonImport = null;
|
|
17
|
+
bsImport = null;
|
|
18
|
+
newStmts = { simd: [] };
|
|
10
19
|
visitClassDeclaration(node) {
|
|
11
20
|
if (!node.decorators?.length)
|
|
12
21
|
return;
|
|
13
|
-
|
|
14
|
-
for (const decorator of node.decorators) {
|
|
22
|
+
if (!node.decorators.some((decorator) => {
|
|
15
23
|
const name = decorator.name.text;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
break;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
if (!found)
|
|
24
|
+
return name === "json" || name === "serializable";
|
|
25
|
+
}))
|
|
22
26
|
return;
|
|
23
|
-
|
|
24
|
-
schema.node = node;
|
|
25
|
-
schema.name = node.name.text;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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"))];
|
|
29
34
|
if (node.extendsType) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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);
|
|
34
58
|
if (!replace) {
|
|
35
|
-
members.unshift(schema.parent?.members[i].node);
|
|
59
|
+
members.unshift(this.schema.parent?.members[i].node);
|
|
36
60
|
}
|
|
37
61
|
}
|
|
38
62
|
}
|
|
39
63
|
}
|
|
40
64
|
if (!members.length) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
|
|
44
|
-
if (process.env["JSON_DEBUG"]) {
|
|
45
|
-
console.log(SERIALIZE_RAW_EMPTY);
|
|
46
|
-
console.log(INITIALIZE_EMPTY);
|
|
47
|
-
console.log(DESERIALIZE_EMPTY);
|
|
48
|
-
}
|
|
49
|
-
const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
|
|
50
|
-
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
|
|
51
|
-
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
|
|
52
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
53
|
-
node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
|
|
54
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
55
|
-
node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
56
|
-
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
57
|
-
node.members.push(DESERIALIZE_METHOD_EMPTY);
|
|
58
|
-
this.schemasList.push(schema);
|
|
65
|
+
this.generateEmptyMethods(node);
|
|
66
|
+
return;
|
|
59
67
|
}
|
|
68
|
+
this.addRequiredImports(node);
|
|
60
69
|
for (const member of members) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
continue;
|
|
64
|
-
if (!member.type) {
|
|
65
|
-
throw new Error("Fields must be strongly typed! Found " +
|
|
66
|
-
toString(member) +
|
|
67
|
-
" at " +
|
|
68
|
-
node.range.source.normalizedPath);
|
|
69
|
-
}
|
|
70
|
+
if (!member.type)
|
|
71
|
+
throwError("Fields must be strongly typed", node.range);
|
|
70
72
|
const type = toString(member.type);
|
|
71
|
-
|
|
72
|
-
continue;
|
|
73
|
+
const name = member.name;
|
|
73
74
|
const value = member.initializer ? toString(member.initializer) : null;
|
|
74
|
-
if (
|
|
75
|
-
continue;
|
|
76
|
-
if (member.flags === 512)
|
|
77
|
-
continue;
|
|
78
|
-
if (member.flags === 1024)
|
|
75
|
+
if (type.startsWith("(") && type.includes("=>"))
|
|
79
76
|
continue;
|
|
80
77
|
const mem = new Property();
|
|
81
78
|
mem.name = name.text;
|
|
82
79
|
mem.type = type;
|
|
83
80
|
mem.value = value;
|
|
84
81
|
mem.node = member;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
mem.flags.set(PropertyFlags.Null, []);
|
|
90
|
-
}
|
|
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);
|
|
91
86
|
if (member.decorators) {
|
|
92
87
|
for (const decorator of member.decorators) {
|
|
93
|
-
const decoratorName = decorator.name.text;
|
|
94
|
-
const args = getArgs(decorator.args);
|
|
88
|
+
const decoratorName = decorator.name.text.toLowerCase().trim();
|
|
95
89
|
switch (decoratorName) {
|
|
96
90
|
case "alias": {
|
|
91
|
+
const args = getArgs(decorator.args);
|
|
97
92
|
if (!args.length)
|
|
98
|
-
|
|
99
|
-
node.range.source.normalizedPath);
|
|
93
|
+
throwError("@alias must have an argument of type string or number", member.range);
|
|
100
94
|
mem.alias = args[0];
|
|
101
|
-
mem.flags.set(PropertyFlags.Alias, args);
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
case "omit": {
|
|
105
|
-
mem.flags.set(PropertyFlags.Omit, args);
|
|
106
95
|
break;
|
|
107
96
|
}
|
|
108
97
|
case "omitif": {
|
|
98
|
+
let arg = decorator.args[0];
|
|
109
99
|
if (!decorator.args?.length)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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;
|
|
113
103
|
break;
|
|
114
104
|
}
|
|
115
105
|
case "omitnull": {
|
|
116
|
-
|
|
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;
|
|
117
114
|
break;
|
|
118
115
|
}
|
|
119
116
|
}
|
|
120
117
|
}
|
|
121
118
|
}
|
|
122
|
-
|
|
123
|
-
if (this.schemasList.find((v) => v.name == type)) {
|
|
124
|
-
mem.initialize =
|
|
125
|
-
"this." +
|
|
126
|
-
name.text +
|
|
127
|
-
" = changetype<nonnull<" +
|
|
128
|
-
mem.type +
|
|
129
|
-
">>(__new(offsetof<nonnull<" +
|
|
130
|
-
mem.type +
|
|
131
|
-
">>(), idof<nonnull<" +
|
|
132
|
-
mem.type +
|
|
133
|
-
">>()));\n changetype<nonnull<" +
|
|
134
|
-
mem.type +
|
|
135
|
-
">>(this." +
|
|
136
|
-
name.text +
|
|
137
|
-
").__INITIALIZE()";
|
|
138
|
-
}
|
|
139
|
-
else if (mem.value) {
|
|
140
|
-
mem.initialize = "this." + name.text + " = " + mem.value;
|
|
141
|
-
}
|
|
142
|
-
else if (type === "Map") {
|
|
143
|
-
mem.initialize = "this." + name.text + " = new " + mem.type + "()";
|
|
144
|
-
}
|
|
145
|
-
else if (type === "string") {
|
|
146
|
-
mem.initialize = "this." + name.text + ' = ""';
|
|
147
|
-
}
|
|
148
|
-
else if (type === "Array") {
|
|
149
|
-
mem.initialize =
|
|
150
|
-
"this." + name.text + " = instantiate<" + mem.type + ">()";
|
|
151
|
-
}
|
|
152
|
-
else if (type === "bool" || type === "boolean") {
|
|
153
|
-
mem.initialize = "this." + name.text + " = false";
|
|
154
|
-
}
|
|
155
|
-
else if (type === "JSON.Raw") {
|
|
156
|
-
mem.initialize = "this." + name.text + ' = ""';
|
|
157
|
-
}
|
|
158
|
-
else if (type === "u8" ||
|
|
159
|
-
type === "u16" ||
|
|
160
|
-
type === "u32" ||
|
|
161
|
-
type === "u64" ||
|
|
162
|
-
type === "i8" ||
|
|
163
|
-
type === "i16" ||
|
|
164
|
-
type === "i32" ||
|
|
165
|
-
type === "i64") {
|
|
166
|
-
mem.initialize = "this." + name.text + " = 0";
|
|
167
|
-
}
|
|
168
|
-
else if (type === "f32" || type === "f64") {
|
|
169
|
-
mem.initialize = "this." + name.text + " = 0.0";
|
|
170
|
-
}
|
|
171
|
-
schema.members.push(mem);
|
|
172
|
-
}
|
|
173
|
-
let SERIALIZE_RAW = "__SERIALIZE(): string {\n let out = `{";
|
|
174
|
-
let SERIALIZE_PRETTY = "__SERIALIZE_PRETTY(): string {\n let out = `{";
|
|
175
|
-
let INITIALIZE = "__INITIALIZE(): this {\n";
|
|
176
|
-
let DESERIALIZE = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n";
|
|
177
|
-
let indent = " ";
|
|
178
|
-
if (!schema.members.length)
|
|
179
|
-
return;
|
|
180
|
-
found = false;
|
|
181
|
-
if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) ||
|
|
182
|
-
schema.members[0]?.flags.has(PropertyFlags.OmitIf)) {
|
|
183
|
-
SERIALIZE_RAW += schema.members[0]?.serialize;
|
|
184
|
-
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
|
|
119
|
+
this.schema.members.push(mem);
|
|
185
120
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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";
|
|
190
135
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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;
|
|
168
|
+
}
|
|
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;
|
|
201
178
|
}
|
|
202
179
|
else {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
+
}
|
|
206
220
|
}
|
|
207
221
|
}
|
|
208
|
-
|
|
209
|
-
SERIALIZE_RAW +=
|
|
210
|
-
"`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
|
|
211
|
-
SERIALIZE_PRETTY +=
|
|
212
|
-
"`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
SERIALIZE_RAW += "}`;\n return out;\n}";
|
|
216
|
-
SERIALIZE_PRETTY += "}`;\n return out;\n}";
|
|
217
|
-
}
|
|
218
|
-
INITIALIZE += " return this;\n}";
|
|
219
|
-
const sortedMembers = [];
|
|
220
|
-
const _sorted = schema.members.sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length));
|
|
222
|
+
let sortedMembers = [];
|
|
221
223
|
let len = -1;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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);
|
|
228
231
|
}
|
|
229
232
|
else {
|
|
230
233
|
sortedMembers.push([member]);
|
|
231
|
-
len =
|
|
232
|
-
offset++;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
let first = true;
|
|
236
|
-
for (const memberSet of sortedMembers) {
|
|
237
|
-
const firstMember = memberSet[0];
|
|
238
|
-
const _name = encodeKey(firstMember.alias || firstMember.name);
|
|
239
|
-
if (_name.length === 1) {
|
|
240
|
-
if (first) {
|
|
241
|
-
DESERIALIZE +=
|
|
242
|
-
" if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
243
|
-
first = false;
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
DESERIALIZE +=
|
|
247
|
-
"else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
248
|
-
}
|
|
234
|
+
len = _nameLength;
|
|
249
235
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
else if (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (first) {
|
|
274
|
-
DESERIALIZE += " if (" + _name.length + " === len) {\n";
|
|
275
|
-
first = false;
|
|
276
|
-
}
|
|
277
|
-
else {
|
|
278
|
-
DESERIALIZE += "else if (" + _name.length + " === len) {\n";
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
let f = true;
|
|
282
|
-
for (let i = 0; i < memberSet.length; i++) {
|
|
283
|
-
const member = memberSet[i];
|
|
284
|
-
if (!member.deserialize)
|
|
285
|
-
continue;
|
|
286
|
-
const _name = encodeKey(member.alias || member.name);
|
|
287
|
-
if (_name.length === 1) {
|
|
288
|
-
DESERIALIZE += ` case ${_name.charCodeAt(0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
|
|
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`;
|
|
289
259
|
}
|
|
290
|
-
else if (
|
|
291
|
-
DESERIALIZE +=
|
|
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`;
|
|
292
265
|
}
|
|
293
|
-
else if (
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
else
|
|
299
|
-
DESERIALIZE =
|
|
300
|
-
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
301
|
-
`else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
|
|
302
|
-
}
|
|
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"}`;
|
|
303
272
|
}
|
|
304
273
|
else {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
else
|
|
310
|
-
DESERIALIZE =
|
|
311
|
-
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
312
|
-
` else if (0 === memory.compare(changetype<usize>("${escapeQuote(escapeSlash(_name))}"), changetype<usize>(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
|
|
313
|
-
}
|
|
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"}`;
|
|
314
279
|
}
|
|
315
280
|
}
|
|
316
|
-
if (
|
|
317
|
-
DESERIALIZE +=
|
|
281
|
+
if (memberLen < 6) {
|
|
282
|
+
DESERIALIZE += `${indent}}\n`;
|
|
318
283
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
` else {\n return false;\n }\n`;
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
DESERIALIZE =
|
|
326
|
-
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
327
|
-
` else {\n return false;\n }\n`;
|
|
328
|
-
}
|
|
329
|
-
DESERIALIZE += " } ";
|
|
284
|
+
indentDec();
|
|
285
|
+
DESERIALIZE += `${indent} return;\n`;
|
|
286
|
+
DESERIALIZE += `${indent}}\n`;
|
|
330
287
|
}
|
|
331
|
-
|
|
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 += "}";
|
|
332
301
|
if (process.env["JSON_DEBUG"]) {
|
|
333
|
-
console.log(
|
|
302
|
+
console.log(SERIALIZE);
|
|
334
303
|
console.log(INITIALIZE);
|
|
335
304
|
console.log(DESERIALIZE);
|
|
305
|
+
console.log(ALLOCATE);
|
|
336
306
|
}
|
|
337
|
-
const
|
|
338
|
-
const DESERIALIZE_SAFE = DESERIALIZE.replaceAll("__DESERIALIZE", "__DESERIALIZE_SAFE");
|
|
307
|
+
const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE, node);
|
|
339
308
|
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
340
309
|
const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
|
|
341
|
-
const
|
|
310
|
+
const ALLOCATE_METHOD = SimpleParser.parseClassMember(ALLOCATE, node);
|
|
342
311
|
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
343
|
-
node.members.push(
|
|
312
|
+
node.members.push(SERIALIZE_METHOD);
|
|
344
313
|
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
345
314
|
node.members.push(INITIALIZE_METHOD);
|
|
346
315
|
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
347
316
|
node.members.push(DESERIALIZE_METHOD);
|
|
348
|
-
if (!node.members.find((v) => v.name.text == "
|
|
349
|
-
node.members.push(
|
|
350
|
-
|
|
317
|
+
if (!node.members.find((v) => v.name.text == "__ALLOCATE"))
|
|
318
|
+
node.members.push(ALLOCATE_METHOD);
|
|
319
|
+
super.visitClassDeclaration(node);
|
|
320
|
+
}
|
|
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);
|
|
333
|
+
}
|
|
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);
|
|
349
|
+
}
|
|
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);
|
|
351
357
|
}
|
|
352
358
|
visitSource(node) {
|
|
359
|
+
this.imports = [];
|
|
353
360
|
super.visitSource(node);
|
|
354
|
-
|
|
355
|
-
|
|
361
|
+
}
|
|
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
|
+
}
|
|
389
|
+
}
|
|
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
|
+
}
|
|
356
415
|
}
|
|
416
|
+
out.push("bs.offset += " + offset + ";");
|
|
417
|
+
return out;
|
|
357
418
|
}
|
|
358
419
|
}
|
|
359
420
|
export default class Transformer extends Transform {
|
|
360
421
|
afterParse(parser) {
|
|
361
422
|
const transformer = new JSONTransform();
|
|
362
|
-
const sources = parser.sources
|
|
363
|
-
.filter((source) => !isStdlib(source))
|
|
364
|
-
.sort((_a, _b) => {
|
|
423
|
+
const sources = parser.sources.sort((_a, _b) => {
|
|
365
424
|
const a = _a.internalPath;
|
|
366
425
|
const b = _b.internalPath;
|
|
367
|
-
if (a[0]
|
|
426
|
+
if (a[0] == "~" && b[0] !== "~") {
|
|
368
427
|
return -1;
|
|
369
428
|
}
|
|
370
|
-
else if (a[0] !== "~" && b[0]
|
|
429
|
+
else if (a[0] !== "~" && b[0] == "~") {
|
|
371
430
|
return 1;
|
|
372
431
|
}
|
|
373
432
|
else {
|
|
374
433
|
return 0;
|
|
375
434
|
}
|
|
376
435
|
});
|
|
436
|
+
transformer.parser = parser;
|
|
377
437
|
for (const source of sources) {
|
|
378
|
-
|
|
379
|
-
|
|
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;
|
|
380
462
|
}
|
|
381
463
|
}
|
|
382
|
-
const schemas = transformer.
|
|
464
|
+
const schemas = transformer.schemas;
|
|
383
465
|
for (const schema of schemas) {
|
|
384
466
|
if (schema.parent) {
|
|
385
|
-
const parent = schemas.find((v) => v.name
|
|
467
|
+
const parent = schemas.find((v) => v.name == schema.parent?.name);
|
|
386
468
|
if (!parent)
|
|
387
|
-
|
|
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);
|
|
388
470
|
}
|
|
389
471
|
}
|
|
390
472
|
}
|
|
391
473
|
}
|
|
392
|
-
|
|
393
|
-
(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
PropertyFlags[PropertyFlags["Alias"] = 4] = "Alias";
|
|
399
|
-
PropertyFlags[PropertyFlags["JSON_Raw"] = 5] = "JSON_Raw";
|
|
400
|
-
})(PropertyFlags || (PropertyFlags = {}));
|
|
401
|
-
class Property {
|
|
402
|
-
name = "";
|
|
403
|
-
alias = null;
|
|
404
|
-
type = "";
|
|
405
|
-
value = null;
|
|
406
|
-
flags = new Map();
|
|
407
|
-
serialize = null;
|
|
408
|
-
deserialize = null;
|
|
409
|
-
initialize = null;
|
|
410
|
-
node;
|
|
411
|
-
right_s = "";
|
|
412
|
-
right_d = "";
|
|
413
|
-
generate(safe) {
|
|
414
|
-
const name = this.name;
|
|
415
|
-
const escapedName = escapeString(JSON.stringify(this.alias || this.name));
|
|
416
|
-
const type = this.type;
|
|
417
|
-
if (this.flags.has(PropertyFlags.Omit))
|
|
418
|
-
return;
|
|
419
|
-
if (this.flags.has(PropertyFlags.JSON_Raw)) {
|
|
420
|
-
if (this.flags.has(PropertyFlags.Null)) {
|
|
421
|
-
this.right_s = "(this." + name + " || \"null\")";
|
|
422
|
-
this.right_d = "value_start === value_end - 4 && 30399761348886638 === load<u64>(changetype<usize>(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)";
|
|
423
|
-
}
|
|
424
|
-
else {
|
|
425
|
-
this.right_s = "this." + name;
|
|
426
|
-
this.right_d = "data.substring(value_start, value_end);";
|
|
427
|
-
}
|
|
474
|
+
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;
|
|
428
480
|
}
|
|
429
|
-
else {
|
|
430
|
-
|
|
431
|
-
this.right_d =
|
|
432
|
-
(safe ? "__DESERIALIZE_SAFE" : "__DESERIALIZE") + "<" + type + ">(data.substring(value_start, value_end))";
|
|
433
|
-
}
|
|
434
|
-
if (this.flags.has(PropertyFlags.OmitIf)) {
|
|
435
|
-
const condition = this.flags.get(PropertyFlags.OmitIf)[0];
|
|
436
|
-
if (!condition)
|
|
437
|
-
throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition");
|
|
438
|
-
this.serialize =
|
|
439
|
-
"${" +
|
|
440
|
-
condition +
|
|
441
|
-
' ? "" : \'' +
|
|
442
|
-
escapedName +
|
|
443
|
-
":' + " +
|
|
444
|
-
this.right_s +
|
|
445
|
-
' + ","}';
|
|
446
|
-
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
447
|
-
}
|
|
448
|
-
else if (this.flags.has(PropertyFlags.OmitNull)) {
|
|
449
|
-
this.serialize =
|
|
450
|
-
"${changetype<usize>(this." +
|
|
451
|
-
name +
|
|
452
|
-
") == <usize>0" +
|
|
453
|
-
' ? "" : \'' +
|
|
454
|
-
escapedName +
|
|
455
|
-
":' + " +
|
|
456
|
-
this.right_s +
|
|
457
|
-
' + ","}';
|
|
458
|
-
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
481
|
+
else if (!aMove && bMove) {
|
|
482
|
+
return 1;
|
|
459
483
|
}
|
|
460
484
|
else {
|
|
461
|
-
|
|
462
|
-
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
485
|
+
return 0;
|
|
463
486
|
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
class SchemaData {
|
|
467
|
-
name = "";
|
|
468
|
-
members = [];
|
|
469
|
-
parent = null;
|
|
470
|
-
node;
|
|
471
|
-
}
|
|
472
|
-
function charCodeAt32(data, offset) {
|
|
473
|
-
return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset);
|
|
474
|
-
}
|
|
475
|
-
function charCodeAt64(data, offset) {
|
|
476
|
-
if (offset + 3 >= data.length) {
|
|
477
|
-
throw new Error("The string must have at least 4 characters from the specified offset.");
|
|
478
|
-
}
|
|
479
|
-
const firstCharCode = BigInt(data.charCodeAt(offset));
|
|
480
|
-
const secondCharCode = BigInt(data.charCodeAt(offset + 1));
|
|
481
|
-
const thirdCharCode = BigInt(data.charCodeAt(offset + 2));
|
|
482
|
-
const fourthCharCode = BigInt(data.charCodeAt(offset + 3));
|
|
483
|
-
const u64Value = (fourthCharCode << 48n) |
|
|
484
|
-
(thirdCharCode << 32n) |
|
|
485
|
-
(secondCharCode << 16n) |
|
|
486
|
-
firstCharCode;
|
|
487
|
-
return u64Value;
|
|
488
|
-
}
|
|
489
|
-
function encodeKey(key) {
|
|
490
|
-
const data = JSON.stringify(key);
|
|
491
|
-
return data.slice(1, data.length - 1);
|
|
492
|
-
}
|
|
493
|
-
function escapeString(data) {
|
|
494
|
-
return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`");
|
|
495
|
-
}
|
|
496
|
-
function escapeSlash(data) {
|
|
497
|
-
return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`");
|
|
498
|
-
}
|
|
499
|
-
function escapeQuote(data) {
|
|
500
|
-
return data.replace(/\"/g, '\\"');
|
|
487
|
+
});
|
|
501
488
|
}
|
|
502
489
|
function getArgs(args) {
|
|
503
490
|
if (!args)
|
|
@@ -528,4 +515,119 @@ function getArgs(args) {
|
|
|
528
515
|
}
|
|
529
516
|
return out;
|
|
530
517
|
}
|
|
518
|
+
function toU16(data, offset = 0) {
|
|
519
|
+
return data.charCodeAt(offset + 0).toString();
|
|
520
|
+
}
|
|
521
|
+
function toU32(data, offset = 0) {
|
|
522
|
+
return ((data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0)).toString();
|
|
523
|
+
}
|
|
524
|
+
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();
|
|
526
|
+
}
|
|
527
|
+
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();
|
|
529
|
+
}
|
|
530
|
+
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;
|
|
547
|
+
}
|
|
548
|
+
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);
|
|
566
|
+
}
|
|
567
|
+
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;
|
|
592
|
+
}
|
|
593
|
+
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));
|
|
596
|
+
}
|
|
597
|
+
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;
|
|
601
|
+
}
|
|
602
|
+
function indentInc() {
|
|
603
|
+
indent += " ";
|
|
604
|
+
}
|
|
605
|
+
function indentDec() {
|
|
606
|
+
indent = indent.slice(0, Math.max(0, indent.length - 2));
|
|
607
|
+
}
|
|
608
|
+
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;
|
|
629
|
+
}
|
|
630
|
+
function allPrimitive(schema) {
|
|
631
|
+
return !schema.members.some((p) => p.byteSize == 0);
|
|
632
|
+
}
|
|
531
633
|
//# sourceMappingURL=index.js.map
|