json-as 0.9.19 → 0.9.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +2 -0
- package/README.md +7 -16
- package/assembly/__tests__/bool.spec.ts +20 -0
- package/assembly/__tests__/float.spec.ts +52 -0
- package/assembly/__tests__/integer.spec.ts +28 -0
- package/assembly/__tests__/obj.spec.ts +5 -0
- package/assembly/__tests__/string.spec.ts +48 -0
- package/assembly/__tests__/test.spec.ts +0 -133
- package/assembly/index.ts +173 -0
- package/assembly/test.ts +8 -23
- package/package.json +1 -1
- package/transform/lib/index.js +501 -470
- package/transform/package.json +1 -1
- package/transform/src/index.ts +69 -40
package/transform/lib/index.js
CHANGED
|
@@ -1,512 +1,543 @@
|
|
|
1
|
-
import { FieldDeclaration } from "assemblyscript/dist/assemblyscript.js";
|
|
1
|
+
import { FieldDeclaration, IdentifierExpression, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, } from "assemblyscript/dist/assemblyscript.js";
|
|
2
2
|
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
3
3
|
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
4
4
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
5
5
|
class JSONTransform extends BaseVisitor {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
visitMethodDeclaration() {}
|
|
12
|
-
visitClassDeclaration(node) {
|
|
13
|
-
if (!node.decorators?.length) return;
|
|
14
|
-
let found = false;
|
|
15
|
-
for (const decorator of node.decorators) {
|
|
16
|
-
const name = decorator.name.text;
|
|
17
|
-
if (name === "json" || name === "serializable") {
|
|
18
|
-
found = true;
|
|
19
|
-
break;
|
|
20
|
-
}
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.schemasList = [];
|
|
9
|
+
this.sources = new Set();
|
|
21
10
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
(v) => v.name == node.extendsType?.name.identifier.text,
|
|
34
|
-
);
|
|
35
|
-
if (schema.parent?.members) {
|
|
36
|
-
for (let i = schema.parent.members.length - 1; i >= 0; i--) {
|
|
37
|
-
const replace = schema.members.find(
|
|
38
|
-
(v) => v.name == schema.parent?.members[i]?.name,
|
|
39
|
-
);
|
|
40
|
-
if (!replace) {
|
|
41
|
-
members.unshift(schema.parent?.members[i].node);
|
|
42
|
-
}
|
|
11
|
+
visitMethodDeclaration() { }
|
|
12
|
+
visitClassDeclaration(node) {
|
|
13
|
+
if (!node.decorators?.length)
|
|
14
|
+
return;
|
|
15
|
+
let found = false;
|
|
16
|
+
for (const decorator of node.decorators) {
|
|
17
|
+
const name = decorator.name.text;
|
|
18
|
+
if (name === "json" || name === "serializable") {
|
|
19
|
+
found = true;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
43
22
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
//const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
|
|
63
|
-
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(
|
|
64
|
-
INITIALIZE_EMPTY,
|
|
65
|
-
node,
|
|
66
|
-
);
|
|
67
|
-
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(
|
|
68
|
-
DESERIALIZE_EMPTY,
|
|
69
|
-
node,
|
|
70
|
-
);
|
|
71
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
72
|
-
node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
|
|
73
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
74
|
-
node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
75
|
-
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
76
|
-
node.members.push(DESERIALIZE_METHOD_EMPTY);
|
|
77
|
-
this.schemasList.push(schema);
|
|
78
|
-
}
|
|
79
|
-
for (const member of members) {
|
|
80
|
-
const name = member.name;
|
|
81
|
-
if (!(member instanceof FieldDeclaration)) continue;
|
|
82
|
-
if (!member.type) {
|
|
83
|
-
throw new Error(
|
|
84
|
-
"Fields must be strongly typed! Found " +
|
|
85
|
-
toString(member) +
|
|
86
|
-
" at " +
|
|
87
|
-
node.range.source.normalizedPath,
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
const type = toString(member.type);
|
|
91
|
-
if (type.startsWith("(") && type.includes("=>")) continue;
|
|
92
|
-
const value = member.initializer ? toString(member.initializer) : null;
|
|
93
|
-
if (member.flags == 32 /* CommonFlags.Static */) continue;
|
|
94
|
-
if (member.flags === 512 /* CommonFlags.Private */) continue;
|
|
95
|
-
if (member.flags === 1024 /* CommonFlags.Protected */) continue;
|
|
96
|
-
const mem = new Property();
|
|
97
|
-
mem.name = name.text;
|
|
98
|
-
mem.type = type;
|
|
99
|
-
mem.value = value;
|
|
100
|
-
mem.node = member;
|
|
101
|
-
if (type == "JSON.Raw") {
|
|
102
|
-
mem.flags.set(PropertyFlags.JSON_Raw, []);
|
|
103
|
-
}
|
|
104
|
-
if (member.decorators) {
|
|
105
|
-
for (const decorator of member.decorators) {
|
|
106
|
-
const decoratorName = decorator.name.text;
|
|
107
|
-
const args = getArgs(decorator.args);
|
|
108
|
-
switch (decoratorName) {
|
|
109
|
-
case "alias": {
|
|
110
|
-
if (!args.length)
|
|
111
|
-
throw new Error(
|
|
112
|
-
"Expected 1 argument but got zero at @alias in " +
|
|
113
|
-
node.range.source.normalizedPath,
|
|
114
|
-
);
|
|
115
|
-
mem.alias = args[0];
|
|
116
|
-
mem.flags.set(PropertyFlags.Alias, args);
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
case "omit": {
|
|
120
|
-
mem.flags.set(PropertyFlags.Omit, args);
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
case "omitif": {
|
|
124
|
-
if (!decorator.args?.length)
|
|
125
|
-
throw new Error(
|
|
126
|
-
"Expected 1 argument but got zero at @omitif in " +
|
|
127
|
-
node.range.source.normalizedPath,
|
|
128
|
-
);
|
|
129
|
-
mem.flags.set(PropertyFlags.OmitIf, args);
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
case "omitnull": {
|
|
133
|
-
mem.flags.set(PropertyFlags.OmitNull, args);
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
23
|
+
if (!found)
|
|
24
|
+
return;
|
|
25
|
+
const schema = new SchemaData();
|
|
26
|
+
schema.node = node;
|
|
27
|
+
schema.name = node.name.text;
|
|
28
|
+
const members = [
|
|
29
|
+
...node.members.filter((v) => v.kind === 54 /* NodeKind.FieldDeclaration */),
|
|
30
|
+
];
|
|
31
|
+
if (node.extendsType) {
|
|
32
|
+
schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text);
|
|
33
|
+
if (schema.parent?.members) {
|
|
34
|
+
for (let i = schema.parent.members.length - 1; i >= 0; i--) {
|
|
35
|
+
const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
|
|
36
|
+
if (!replace) {
|
|
37
|
+
members.unshift(schema.parent?.members[i].node);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
137
41
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
mem.initialize = "this." + name.text + ' = ""';
|
|
161
|
-
} else if (type === "Array") {
|
|
162
|
-
mem.initialize =
|
|
163
|
-
"this." + name.text + " = instantiate<" + mem.type + ">()";
|
|
164
|
-
} else if (type === "bool" || type === "boolean") {
|
|
165
|
-
mem.initialize = "this." + name.text + " = false";
|
|
166
|
-
} else if (type === "JSON.Raw") {
|
|
167
|
-
mem.initialize = "this." + name.text + ' = ""';
|
|
168
|
-
} else if (
|
|
169
|
-
type === "u8" ||
|
|
170
|
-
type === "u16" ||
|
|
171
|
-
type === "u32" ||
|
|
172
|
-
type === "u64" ||
|
|
173
|
-
type === "i8" ||
|
|
174
|
-
type === "i16" ||
|
|
175
|
-
type === "i32" ||
|
|
176
|
-
type === "i64"
|
|
177
|
-
) {
|
|
178
|
-
mem.initialize = "this." + name.text + " = 0";
|
|
179
|
-
} else if (type === "f32" || type === "f64") {
|
|
180
|
-
mem.initialize = "this." + name.text + " = 0.0";
|
|
181
|
-
}
|
|
182
|
-
schema.members.push(mem);
|
|
183
|
-
}
|
|
184
|
-
let SERIALIZE_RAW = "__SERIALIZE(): string {\n let out = `{";
|
|
185
|
-
let SERIALIZE_PRETTY = "__SERIALIZE_PRETTY(): string {\n let out = `{";
|
|
186
|
-
let INITIALIZE = "__INITIALIZE(): this {\n";
|
|
187
|
-
let DESERIALIZE =
|
|
188
|
-
"__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n";
|
|
189
|
-
let indent = " ";
|
|
190
|
-
if (!schema.members.length) return;
|
|
191
|
-
found = false;
|
|
192
|
-
if (
|
|
193
|
-
schema.members[0]?.flags.has(PropertyFlags.OmitNull) ||
|
|
194
|
-
schema.members[0]?.flags.has(PropertyFlags.OmitIf)
|
|
195
|
-
) {
|
|
196
|
-
SERIALIZE_RAW += schema.members[0]?.serialize;
|
|
197
|
-
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
|
|
198
|
-
} else {
|
|
199
|
-
SERIALIZE_RAW += schema.members[0]?.serialize + ",";
|
|
200
|
-
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n";
|
|
201
|
-
found = true;
|
|
202
|
-
}
|
|
203
|
-
if (schema.members[0]?.initialize)
|
|
204
|
-
INITIALIZE += " " + schema.members[0]?.initialize + ";\n";
|
|
205
|
-
for (let i = 1; i < schema.members.length; i++) {
|
|
206
|
-
const member = schema.members[i];
|
|
207
|
-
if (member.initialize) INITIALIZE += " " + member.initialize + ";\n";
|
|
208
|
-
if (
|
|
209
|
-
member.flags.has(PropertyFlags.OmitNull) ||
|
|
210
|
-
member.flags.has(PropertyFlags.OmitIf)
|
|
211
|
-
) {
|
|
212
|
-
SERIALIZE_RAW += member.serialize;
|
|
213
|
-
SERIALIZE_PRETTY += member.serialize;
|
|
214
|
-
} else {
|
|
215
|
-
SERIALIZE_RAW += member.serialize + ",";
|
|
216
|
-
SERIALIZE_PRETTY += indent + member.serialize + ",\\n";
|
|
217
|
-
found = true;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
if (found) {
|
|
221
|
-
SERIALIZE_RAW +=
|
|
222
|
-
"`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
|
|
223
|
-
SERIALIZE_PRETTY +=
|
|
224
|
-
"`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
|
|
225
|
-
} else {
|
|
226
|
-
SERIALIZE_RAW += "`;\n};";
|
|
227
|
-
SERIALIZE_PRETTY += "`;\n};";
|
|
228
|
-
}
|
|
229
|
-
INITIALIZE += " return this;\n}";
|
|
230
|
-
const sortedMembers = [];
|
|
231
|
-
const _sorted = schema.members.sort(
|
|
232
|
-
(a, b) => a.name.length - b.name.length,
|
|
233
|
-
);
|
|
234
|
-
let len = 0;
|
|
235
|
-
let offset = 0;
|
|
236
|
-
sortedMembers.push([_sorted[0]]);
|
|
237
|
-
len = _sorted[0]?.name.length;
|
|
238
|
-
for (let i = 1; i < _sorted.length; i++) {
|
|
239
|
-
const member = _sorted[i];
|
|
240
|
-
if (member.alias?.length || member.name.length > len) {
|
|
241
|
-
sortedMembers.push([member]);
|
|
242
|
-
len = member.alias?.length || member.name.length;
|
|
243
|
-
offset++;
|
|
244
|
-
} else {
|
|
245
|
-
sortedMembers[offset].push(member);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
let first = true;
|
|
249
|
-
for (const memberSet of sortedMembers) {
|
|
250
|
-
const firstMember = memberSet[0];
|
|
251
|
-
const name = encodeKey(firstMember.alias || firstMember.name);
|
|
252
|
-
if (name.length === 1) {
|
|
253
|
-
if (first) {
|
|
254
|
-
DESERIALIZE +=
|
|
255
|
-
" if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
256
|
-
first = false;
|
|
257
|
-
} else {
|
|
258
|
-
DESERIALIZE +=
|
|
259
|
-
"else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
42
|
+
if (!members.length) {
|
|
43
|
+
let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}';
|
|
44
|
+
//let SERIALIZE_PRETTY_EMPTY = "__SERIALIZE_PRETTY(): string {\n return \"{}\";\n}";
|
|
45
|
+
let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
|
|
46
|
+
let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
|
|
47
|
+
if (process.env["JSON_DEBUG"]) {
|
|
48
|
+
console.log(SERIALIZE_RAW_EMPTY);
|
|
49
|
+
//console.log(SERIALIZE_PRETTY_EMPTY);
|
|
50
|
+
console.log(INITIALIZE_EMPTY);
|
|
51
|
+
console.log(DESERIALIZE_EMPTY);
|
|
52
|
+
}
|
|
53
|
+
const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
|
|
54
|
+
//const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
|
|
55
|
+
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
|
|
56
|
+
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
|
|
57
|
+
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
58
|
+
node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
|
|
59
|
+
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
60
|
+
node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
61
|
+
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
62
|
+
node.members.push(DESERIALIZE_METHOD_EMPTY);
|
|
63
|
+
this.schemasList.push(schema);
|
|
260
64
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
65
|
+
for (const member of members) {
|
|
66
|
+
const name = member.name;
|
|
67
|
+
if (!(member instanceof FieldDeclaration))
|
|
68
|
+
continue;
|
|
69
|
+
if (!member.type) {
|
|
70
|
+
throw new Error("Fields must be strongly typed! Found " +
|
|
71
|
+
toString(member) +
|
|
72
|
+
" at " +
|
|
73
|
+
node.range.source.normalizedPath);
|
|
74
|
+
}
|
|
75
|
+
const type = toString(member.type);
|
|
76
|
+
if (type.startsWith("(") && type.includes("=>"))
|
|
77
|
+
continue;
|
|
78
|
+
const value = member.initializer ? toString(member.initializer) : null;
|
|
79
|
+
if (member.flags == 32 /* CommonFlags.Static */)
|
|
80
|
+
continue;
|
|
81
|
+
if (member.flags === 512 /* CommonFlags.Private */)
|
|
82
|
+
continue;
|
|
83
|
+
if (member.flags === 1024 /* CommonFlags.Protected */)
|
|
84
|
+
continue;
|
|
85
|
+
const mem = new Property();
|
|
86
|
+
mem.name = name.text;
|
|
87
|
+
mem.type = type;
|
|
88
|
+
mem.value = value;
|
|
89
|
+
mem.node = member;
|
|
90
|
+
if (type.includes("JSON.Raw")) {
|
|
91
|
+
mem.flags.set(PropertyFlags.JSON_Raw, []);
|
|
92
|
+
}
|
|
93
|
+
if (member.type.isNullable) {
|
|
94
|
+
mem.flags.set(PropertyFlags.Null, []);
|
|
95
|
+
}
|
|
96
|
+
if (member.decorators) {
|
|
97
|
+
for (const decorator of member.decorators) {
|
|
98
|
+
const decoratorName = decorator.name.text;
|
|
99
|
+
const args = getArgs(decorator.args);
|
|
100
|
+
switch (decoratorName) {
|
|
101
|
+
case "alias": {
|
|
102
|
+
if (!args.length)
|
|
103
|
+
throw new Error("Expected 1 argument but got zero at @alias in " +
|
|
104
|
+
node.range.source.normalizedPath);
|
|
105
|
+
mem.alias = args[0];
|
|
106
|
+
mem.flags.set(PropertyFlags.Alias, args);
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
case "omit": {
|
|
110
|
+
mem.flags.set(PropertyFlags.Omit, args);
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case "omitif": {
|
|
114
|
+
if (!decorator.args?.length)
|
|
115
|
+
throw new Error("Expected 1 argument but got zero at @omitif in " +
|
|
116
|
+
node.range.source.normalizedPath);
|
|
117
|
+
mem.flags.set(PropertyFlags.OmitIf, args);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case "omitnull": {
|
|
121
|
+
mem.flags.set(PropertyFlags.OmitNull, args);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
mem.generate();
|
|
128
|
+
if (this.schemasList.find((v) => v.name == type)) {
|
|
129
|
+
mem.initialize =
|
|
130
|
+
"this." +
|
|
131
|
+
name.text +
|
|
132
|
+
" = changetype<nonnull<" +
|
|
133
|
+
mem.type +
|
|
134
|
+
">>(__new(offsetof<nonnull<" +
|
|
135
|
+
mem.type +
|
|
136
|
+
">>(), idof<nonnull<" +
|
|
137
|
+
mem.type +
|
|
138
|
+
">>()));\n changetype<nonnull<" +
|
|
139
|
+
mem.type +
|
|
140
|
+
">>(this." +
|
|
141
|
+
name.text +
|
|
142
|
+
").__INITIALIZE()";
|
|
143
|
+
}
|
|
144
|
+
else if (mem.value) {
|
|
145
|
+
mem.initialize = "this." + name.text + " = " + mem.value;
|
|
146
|
+
}
|
|
147
|
+
else if (type === "Map") {
|
|
148
|
+
mem.initialize = "this." + name.text + " = new " + mem.type + "()";
|
|
149
|
+
}
|
|
150
|
+
else if (type === "string") {
|
|
151
|
+
mem.initialize = "this." + name.text + ' = ""';
|
|
152
|
+
}
|
|
153
|
+
else if (type === "Array") {
|
|
154
|
+
mem.initialize =
|
|
155
|
+
"this." + name.text + " = instantiate<" + mem.type + ">()";
|
|
156
|
+
}
|
|
157
|
+
else if (type === "bool" || type === "boolean") {
|
|
158
|
+
mem.initialize = "this." + name.text + " = false";
|
|
159
|
+
}
|
|
160
|
+
else if (type === "JSON.Raw") {
|
|
161
|
+
mem.initialize = "this." + name.text + ' = ""';
|
|
162
|
+
}
|
|
163
|
+
else if (type === "u8" ||
|
|
164
|
+
type === "u16" ||
|
|
165
|
+
type === "u32" ||
|
|
166
|
+
type === "u64" ||
|
|
167
|
+
type === "i8" ||
|
|
168
|
+
type === "i16" ||
|
|
169
|
+
type === "i32" ||
|
|
170
|
+
type === "i64") {
|
|
171
|
+
mem.initialize = "this." + name.text + " = 0";
|
|
172
|
+
}
|
|
173
|
+
else if (type === "f32" || type === "f64") {
|
|
174
|
+
mem.initialize = "this." + name.text + " = 0.0";
|
|
175
|
+
}
|
|
176
|
+
schema.members.push(mem);
|
|
177
|
+
}
|
|
178
|
+
let SERIALIZE_RAW = "__SERIALIZE(): string {\n let out = `{";
|
|
179
|
+
let SERIALIZE_PRETTY = "__SERIALIZE_PRETTY(): string {\n let out = `{";
|
|
180
|
+
let INITIALIZE = "__INITIALIZE(): this {\n";
|
|
181
|
+
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";
|
|
182
|
+
let indent = " ";
|
|
183
|
+
if (!schema.members.length)
|
|
184
|
+
return;
|
|
185
|
+
found = false;
|
|
186
|
+
if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) ||
|
|
187
|
+
schema.members[0]?.flags.has(PropertyFlags.OmitIf)) {
|
|
188
|
+
SERIALIZE_RAW += schema.members[0]?.serialize;
|
|
189
|
+
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
SERIALIZE_RAW += schema.members[0]?.serialize + ",";
|
|
193
|
+
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n";
|
|
194
|
+
found = true;
|
|
269
195
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
196
|
+
if (schema.members[0]?.initialize)
|
|
197
|
+
INITIALIZE += " " + schema.members[0]?.initialize + ";\n";
|
|
198
|
+
for (let i = 1; i < schema.members.length; i++) {
|
|
199
|
+
const member = schema.members[i];
|
|
200
|
+
if (member.initialize)
|
|
201
|
+
INITIALIZE += " " + member.initialize + ";\n";
|
|
202
|
+
if (member.flags.has(PropertyFlags.OmitNull) ||
|
|
203
|
+
member.flags.has(PropertyFlags.OmitIf)) {
|
|
204
|
+
SERIALIZE_RAW += member.serialize;
|
|
205
|
+
SERIALIZE_PRETTY += member.serialize;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
SERIALIZE_RAW += member.serialize + ",";
|
|
209
|
+
SERIALIZE_PRETTY += indent + member.serialize + ",\\n";
|
|
210
|
+
found = true;
|
|
211
|
+
}
|
|
278
212
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
DESERIALIZE += "else if (" + name.length + " === len) {\n";
|
|
213
|
+
if (found) {
|
|
214
|
+
SERIALIZE_RAW +=
|
|
215
|
+
"`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
|
|
216
|
+
SERIALIZE_PRETTY +=
|
|
217
|
+
"`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
|
|
285
218
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
const member = memberSet[i];
|
|
290
|
-
if (!member.deserialize) continue;
|
|
291
|
-
const name = encodeKey(member.alias || member.name);
|
|
292
|
-
if (name.length === 1) {
|
|
293
|
-
DESERIALIZE += ` case ${name.charCodeAt(0)}: {\n ${member.deserialize}\n return true;\n }\n`;
|
|
294
|
-
} else if (name.length === 2) {
|
|
295
|
-
DESERIALIZE += ` case ${charCodeAt32(name, 0)}: {\n ${member.deserialize}\n return true;\n }\n`;
|
|
296
|
-
} else if (name.length === 4) {
|
|
297
|
-
if (f) {
|
|
298
|
-
f = false;
|
|
299
|
-
DESERIALIZE += ` if (${charCodeAt64(name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
|
|
300
|
-
} else {
|
|
301
|
-
DESERIALIZE =
|
|
302
|
-
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
303
|
-
`else if (${charCodeAt64(name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
|
|
304
|
-
}
|
|
305
|
-
} else {
|
|
306
|
-
if (f) {
|
|
307
|
-
f = false;
|
|
308
|
-
DESERIALIZE += ` if (0 == memory.compare(changetype<usize>("${escapeQuote(escapeSlash(name))}"), changetype<usize>(data) + (key_start << 1), ${name.length << 1})) {\n ${member.deserialize}\n return true;\n }\n`;
|
|
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})) {\n ${member.deserialize}\n return true;\n }\n`;
|
|
313
|
-
}
|
|
219
|
+
else {
|
|
220
|
+
SERIALIZE_RAW += "}`;\n return out;\n}";
|
|
221
|
+
SERIALIZE_PRETTY += "}`;\n return out;\n}";
|
|
314
222
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
223
|
+
INITIALIZE += " return this;\n}";
|
|
224
|
+
const sortedMembers = [];
|
|
225
|
+
const _sorted = schema.members.sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length));
|
|
226
|
+
let len = -1;
|
|
227
|
+
let offset = -1;
|
|
228
|
+
for (let i = 0; i < _sorted.length; i++) {
|
|
229
|
+
const member = _sorted[i];
|
|
230
|
+
const _name = member.alias || member.name;
|
|
231
|
+
if (_name.length === len) {
|
|
232
|
+
sortedMembers[offset]?.push(member);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
sortedMembers.push([member]);
|
|
236
|
+
len = _name.length;
|
|
237
|
+
offset++;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
let first = true;
|
|
241
|
+
for (const memberSet of sortedMembers) {
|
|
242
|
+
const firstMember = memberSet[0];
|
|
243
|
+
const _name = encodeKey(firstMember.alias || firstMember.name);
|
|
244
|
+
if (_name.length === 1) {
|
|
245
|
+
if (first) {
|
|
246
|
+
DESERIALIZE +=
|
|
247
|
+
" if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
248
|
+
first = false;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
DESERIALIZE +=
|
|
252
|
+
"else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else if (_name.length === 2) {
|
|
256
|
+
if (first) {
|
|
257
|
+
DESERIALIZE +=
|
|
258
|
+
" if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
259
|
+
first = false;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
DESERIALIZE +=
|
|
263
|
+
"else if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
else if (_name.length === 4) {
|
|
267
|
+
if (first) {
|
|
268
|
+
DESERIALIZE +=
|
|
269
|
+
" if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
|
|
270
|
+
first = false;
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
DESERIALIZE +=
|
|
274
|
+
"else if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
if (first) {
|
|
279
|
+
DESERIALIZE += " if (" + _name.length + " === len) {\n";
|
|
280
|
+
first = false;
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
DESERIALIZE += "else if (" + _name.length + " === len) {\n";
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
let f = true;
|
|
287
|
+
for (let i = 0; i < memberSet.length; i++) {
|
|
288
|
+
const member = memberSet[i];
|
|
289
|
+
if (!member.deserialize)
|
|
290
|
+
continue;
|
|
291
|
+
const _name = encodeKey(member.alias || member.name);
|
|
292
|
+
if (_name.length === 1) {
|
|
293
|
+
DESERIALIZE += ` case ${_name.charCodeAt(0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
|
|
294
|
+
}
|
|
295
|
+
else if (_name.length === 2) {
|
|
296
|
+
DESERIALIZE += ` case ${charCodeAt32(_name, 0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
|
|
297
|
+
}
|
|
298
|
+
else if (_name.length === 4) {
|
|
299
|
+
if (f) {
|
|
300
|
+
f = false;
|
|
301
|
+
DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
DESERIALIZE =
|
|
305
|
+
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
306
|
+
`else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
if (f) {
|
|
311
|
+
f = false;
|
|
312
|
+
DESERIALIZE += ` 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
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
DESERIALIZE =
|
|
316
|
+
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
317
|
+
` 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`;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (_name.length < 3) {
|
|
322
|
+
DESERIALIZE += ` default: {\n return false;\n }\n }\n`;
|
|
323
|
+
}
|
|
324
|
+
else if (_name.length == 4) {
|
|
325
|
+
DESERIALIZE =
|
|
326
|
+
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
327
|
+
` else {\n return false;\n }\n`;
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
DESERIALIZE =
|
|
331
|
+
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
332
|
+
` else {\n return false;\n }\n`;
|
|
333
|
+
}
|
|
334
|
+
DESERIALIZE += " } ";
|
|
335
|
+
}
|
|
336
|
+
DESERIALIZE += "\n return false;\n}";
|
|
337
|
+
//console.log(sortedMembers);
|
|
338
|
+
if (process.env["JSON_DEBUG"]) {
|
|
339
|
+
console.log(SERIALIZE_RAW);
|
|
340
|
+
//console.log(SERIALIZE_PRETTY);
|
|
341
|
+
console.log(INITIALIZE);
|
|
342
|
+
console.log(DESERIALIZE);
|
|
343
|
+
}
|
|
344
|
+
const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node);
|
|
345
|
+
//const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
|
|
346
|
+
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
347
|
+
const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
|
|
348
|
+
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
349
|
+
node.members.push(SERIALIZE_RAW_METHOD);
|
|
350
|
+
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
351
|
+
node.members.push(INITIALIZE_METHOD);
|
|
352
|
+
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
353
|
+
node.members.push(DESERIALIZE_METHOD);
|
|
354
|
+
this.schemasList.push(schema);
|
|
336
355
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
|
|
344
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
345
|
-
node.members.push(SERIALIZE_RAW_METHOD);
|
|
346
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
347
|
-
node.members.push(INITIALIZE_METHOD);
|
|
348
|
-
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
349
|
-
node.members.push(DESERIALIZE_METHOD);
|
|
350
|
-
this.schemasList.push(schema);
|
|
351
|
-
}
|
|
352
|
-
visitSource(node) {
|
|
353
|
-
super.visitSource(node);
|
|
354
|
-
// Only add the import statement to sources that have JSON decorated classes.
|
|
355
|
-
if (!this.sources.has(node)) {
|
|
356
|
-
return;
|
|
356
|
+
visitSource(node) {
|
|
357
|
+
super.visitSource(node);
|
|
358
|
+
// Only add the import statement to sources that have JSON decorated classes.
|
|
359
|
+
if (!this.sources.has(node)) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
357
362
|
}
|
|
358
|
-
}
|
|
359
363
|
}
|
|
360
364
|
export default class Transformer extends Transform {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
365
|
+
// Trigger the transform after parse.
|
|
366
|
+
afterParse(parser) {
|
|
367
|
+
// Create new transform
|
|
368
|
+
const transformer = new JSONTransform();
|
|
369
|
+
// Sort the sources so that user scripts are visited last
|
|
370
|
+
const sources = parser.sources
|
|
371
|
+
.filter((source) => !isStdlib(source))
|
|
372
|
+
.sort((_a, _b) => {
|
|
373
|
+
const a = _a.internalPath;
|
|
374
|
+
const b = _b.internalPath;
|
|
375
|
+
if (a[0] === "~" && b[0] !== "~") {
|
|
376
|
+
return -1;
|
|
377
|
+
}
|
|
378
|
+
else if (a[0] !== "~" && b[0] === "~") {
|
|
379
|
+
return 1;
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
return 0;
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
// Loop over every source
|
|
386
|
+
for (const source of sources) {
|
|
387
|
+
// Ignore all lib and std. Visit everything else.
|
|
388
|
+
if (!isStdlib(source)) {
|
|
389
|
+
transformer.visit(source);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
// Check that every parent and child class is hooked up correctly
|
|
393
|
+
const schemas = transformer.schemasList;
|
|
394
|
+
for (const schema of schemas) {
|
|
395
|
+
if (schema.parent) {
|
|
396
|
+
const parent = schemas.find((v) => v.name === schema.parent?.name);
|
|
397
|
+
if (!parent)
|
|
398
|
+
throw new Error(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator! Add the decorator and rebuild.`);
|
|
399
|
+
}
|
|
377
400
|
}
|
|
378
|
-
});
|
|
379
|
-
// Loop over every source
|
|
380
|
-
for (const source of sources) {
|
|
381
|
-
// Ignore all lib and std. Visit everything else.
|
|
382
|
-
if (!isStdlib(source)) {
|
|
383
|
-
transformer.visit(source);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
// Check that every parent and child class is hooked up correctly
|
|
387
|
-
const schemas = transformer.schemasList;
|
|
388
|
-
for (const schema of schemas) {
|
|
389
|
-
if (schema.parent) {
|
|
390
|
-
const parent = schemas.find((v) => v.name === schema.parent?.name);
|
|
391
|
-
if (!parent)
|
|
392
|
-
throw new Error(
|
|
393
|
-
`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator! Add the decorator and rebuild.`,
|
|
394
|
-
);
|
|
395
|
-
}
|
|
396
401
|
}
|
|
397
|
-
}
|
|
398
402
|
}
|
|
399
403
|
var PropertyFlags;
|
|
400
404
|
(function (PropertyFlags) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
405
|
+
PropertyFlags[PropertyFlags["Null"] = 0] = "Null";
|
|
406
|
+
PropertyFlags[PropertyFlags["Omit"] = 1] = "Omit";
|
|
407
|
+
PropertyFlags[PropertyFlags["OmitNull"] = 2] = "OmitNull";
|
|
408
|
+
PropertyFlags[PropertyFlags["OmitIf"] = 3] = "OmitIf";
|
|
409
|
+
PropertyFlags[PropertyFlags["Alias"] = 4] = "Alias";
|
|
410
|
+
PropertyFlags[PropertyFlags["JSON_Raw"] = 5] = "JSON_Raw";
|
|
406
411
|
})(PropertyFlags || (PropertyFlags = {}));
|
|
407
412
|
class Property {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}
|
|
420
|
-
generate() {
|
|
421
|
-
const name = this.name;
|
|
422
|
-
const escapedName = escapeString(JSON.stringify(this.alias || this.name));
|
|
423
|
-
const type = this.type;
|
|
424
|
-
if (this.flags.has(PropertyFlags.Omit)) return;
|
|
425
|
-
if (this.flags.has(PropertyFlags.JSON_Raw)) {
|
|
426
|
-
this.right_s = "this." + name;
|
|
427
|
-
this.right_d = "data.substring(value_start, value_end);";
|
|
428
|
-
} else {
|
|
429
|
-
this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")";
|
|
430
|
-
this.right_d =
|
|
431
|
-
"__DESERIALIZE<" + type + ">(data.substring(value_start, value_end))";
|
|
413
|
+
constructor() {
|
|
414
|
+
this.name = "";
|
|
415
|
+
this.alias = null;
|
|
416
|
+
this.type = "";
|
|
417
|
+
this.value = null;
|
|
418
|
+
this.flags = new Map();
|
|
419
|
+
this.serialize = null;
|
|
420
|
+
this.deserialize = null;
|
|
421
|
+
this.initialize = null;
|
|
422
|
+
this.right_s = "";
|
|
423
|
+
this.right_d = "";
|
|
432
424
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
425
|
+
generate() {
|
|
426
|
+
const name = this.name;
|
|
427
|
+
const escapedName = escapeString(JSON.stringify(this.alias || this.name));
|
|
428
|
+
const type = this.type;
|
|
429
|
+
if (this.flags.has(PropertyFlags.Omit))
|
|
430
|
+
return;
|
|
431
|
+
if (this.flags.has(PropertyFlags.JSON_Raw)) {
|
|
432
|
+
if (this.flags.has(PropertyFlags.Null)) {
|
|
433
|
+
this.right_s = "(this." + name + " || \"null\")";
|
|
434
|
+
this.right_d = "value_start === value_end - 4 && 30399761348886638 === load<u64>(changetype<usize>(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)";
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
this.right_s = "this." + name;
|
|
438
|
+
this.right_d = "data.substring(value_start, value_end);";
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")";
|
|
443
|
+
this.right_d =
|
|
444
|
+
"__DESERIALIZE<" + type + ">(data.substring(value_start, value_end))";
|
|
445
|
+
}
|
|
446
|
+
if (this.flags.has(PropertyFlags.OmitIf)) {
|
|
447
|
+
const condition = this.flags.get(PropertyFlags.OmitIf)[0];
|
|
448
|
+
if (!condition)
|
|
449
|
+
throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition");
|
|
450
|
+
this.serialize =
|
|
451
|
+
"${" +
|
|
452
|
+
condition +
|
|
453
|
+
' ? "" : \'' +
|
|
454
|
+
escapedName +
|
|
455
|
+
":' + " +
|
|
456
|
+
this.right_s +
|
|
457
|
+
' + ","}';
|
|
458
|
+
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
459
|
+
}
|
|
460
|
+
else if (this.flags.has(PropertyFlags.OmitNull)) {
|
|
461
|
+
this.serialize =
|
|
462
|
+
"${changetype<usize>(this." +
|
|
463
|
+
name +
|
|
464
|
+
") == <usize>0" +
|
|
465
|
+
' ? "" : \'' +
|
|
466
|
+
escapedName +
|
|
467
|
+
":' + " +
|
|
468
|
+
this.right_s +
|
|
469
|
+
' + ","}';
|
|
470
|
+
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
this.serialize = escapedName + ":${" + this.right_s + "}";
|
|
474
|
+
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
475
|
+
}
|
|
462
476
|
}
|
|
463
|
-
}
|
|
464
477
|
}
|
|
465
478
|
class SchemaData {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
479
|
+
constructor() {
|
|
480
|
+
this.name = "";
|
|
481
|
+
this.members = [];
|
|
482
|
+
this.parent = null;
|
|
483
|
+
}
|
|
471
484
|
}
|
|
472
485
|
function charCodeAt32(data, offset) {
|
|
473
|
-
|
|
486
|
+
return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset);
|
|
474
487
|
}
|
|
475
488
|
function charCodeAt64(data, offset) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
);
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
(secondCharCode << 16n) |
|
|
489
|
-
firstCharCode;
|
|
490
|
-
return u64Value;
|
|
489
|
+
if (offset + 3 >= data.length) {
|
|
490
|
+
throw new Error("The string must have at least 4 characters from the specified offset.");
|
|
491
|
+
}
|
|
492
|
+
const firstCharCode = BigInt(data.charCodeAt(offset));
|
|
493
|
+
const secondCharCode = BigInt(data.charCodeAt(offset + 1));
|
|
494
|
+
const thirdCharCode = BigInt(data.charCodeAt(offset + 2));
|
|
495
|
+
const fourthCharCode = BigInt(data.charCodeAt(offset + 3));
|
|
496
|
+
const u64Value = (fourthCharCode << 48n) |
|
|
497
|
+
(thirdCharCode << 32n) |
|
|
498
|
+
(secondCharCode << 16n) |
|
|
499
|
+
firstCharCode;
|
|
500
|
+
return u64Value;
|
|
491
501
|
}
|
|
492
502
|
function encodeKey(key) {
|
|
493
|
-
|
|
494
|
-
|
|
503
|
+
const data = JSON.stringify(key);
|
|
504
|
+
return data.slice(1, data.length - 1);
|
|
495
505
|
}
|
|
496
506
|
function escapeString(data) {
|
|
497
|
-
|
|
507
|
+
return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`");
|
|
498
508
|
}
|
|
499
509
|
function escapeSlash(data) {
|
|
500
|
-
|
|
510
|
+
return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`");
|
|
501
511
|
}
|
|
502
512
|
function escapeQuote(data) {
|
|
503
|
-
|
|
513
|
+
return data.replace(/\"/g, '\\"');
|
|
504
514
|
}
|
|
505
515
|
function getArgs(args) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
516
|
+
if (!args)
|
|
517
|
+
return [];
|
|
518
|
+
let out = [];
|
|
519
|
+
for (const arg of args) {
|
|
520
|
+
if (arg instanceof StringLiteralExpression) {
|
|
521
|
+
out.push(arg.value);
|
|
522
|
+
}
|
|
523
|
+
else if (arg instanceof IntegerLiteralExpression) {
|
|
524
|
+
out.push(i64_to_string(arg.value));
|
|
525
|
+
}
|
|
526
|
+
else if (arg instanceof FloatLiteralExpression) {
|
|
527
|
+
out.push(arg.value.toString());
|
|
528
|
+
}
|
|
529
|
+
else if (arg instanceof NullExpression) {
|
|
530
|
+
out.push(arg.text);
|
|
531
|
+
}
|
|
532
|
+
else if (arg instanceof TrueExpression) {
|
|
533
|
+
out.push(arg.text);
|
|
534
|
+
}
|
|
535
|
+
else if (arg instanceof FalseExpression) {
|
|
536
|
+
out.push(arg.text);
|
|
537
|
+
}
|
|
538
|
+
else if (arg instanceof IdentifierExpression) {
|
|
539
|
+
out.push(arg.text);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return out;
|
|
512
543
|
}
|