json-as 0.9.22 → 0.9.24
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 +1 -1
- package/assembly/__benches__/string.bench.ts +0 -5
- package/assembly/deserialize/string.ts +0 -1
- package/assembly/serialize/bool.ts +0 -12
- package/assembly/serialize/string.ts +199 -208
- package/package.json +3 -2
- package/transform/lib/index.js +151 -160
- package/transform/package.json +1 -1
- package/transform/src/index.ts +229 -188
package/transform/lib/index.js
CHANGED
|
@@ -1,76 +1,74 @@
|
|
|
1
|
-
import { FieldDeclaration, IdentifierExpression, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression,
|
|
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
|
-
import chalk from "chalk";
|
|
6
|
-
const json_types = ["Array", "string", "String", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean", "Map", "Date"];
|
|
7
5
|
class JSONTransform extends BaseVisitor {
|
|
8
|
-
types = json_types;
|
|
9
6
|
schemasList = [];
|
|
10
7
|
currentClass;
|
|
11
8
|
sources = new Set();
|
|
12
|
-
|
|
13
|
-
if (node.extendsType) {
|
|
14
|
-
if (schema.parent?.members) {
|
|
15
|
-
for (let i = schema.parent.members.length - 1; i >= 0; i--) {
|
|
16
|
-
const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
|
|
17
|
-
if (!replace) {
|
|
18
|
-
members.unshift(schema.parent?.members[i].node);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
this.appendParentFields(schema.parent.node, schema, members);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
handleEmptyClass(node, schema, members) {
|
|
26
|
-
let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}';
|
|
27
|
-
let SERIALIZE_PRETTY_EMPTY = '__SERIALIZE_PRETTY(): string {\n return "{}";\n}';
|
|
28
|
-
let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
|
|
29
|
-
let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
|
|
30
|
-
if (process.env["JSON_DEBUG"]) {
|
|
31
|
-
console.log(SERIALIZE_RAW_EMPTY);
|
|
32
|
-
console.log(SERIALIZE_PRETTY_EMPTY);
|
|
33
|
-
console.log(INITIALIZE_EMPTY);
|
|
34
|
-
console.log(DESERIALIZE_EMPTY);
|
|
35
|
-
}
|
|
36
|
-
const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
|
|
37
|
-
const SERIALIZE_PRETTY_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_PRETTY_EMPTY, node);
|
|
38
|
-
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
|
|
39
|
-
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
|
|
40
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
41
|
-
node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
|
|
42
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE_PRETTY"))
|
|
43
|
-
node.members.push(SERIALIZE_PRETTY_METHOD_EMPTY);
|
|
44
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
45
|
-
node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
46
|
-
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
47
|
-
node.members.push(DESERIALIZE_METHOD_EMPTY);
|
|
48
|
-
}
|
|
49
|
-
filterMembers(members) {
|
|
50
|
-
return members.filter((v) => v instanceof FieldDeclaration && !v.decorators?.find((v) => v.name.text == "omit"));
|
|
51
|
-
}
|
|
9
|
+
visitMethodDeclaration() { }
|
|
52
10
|
visitClassDeclaration(node) {
|
|
53
11
|
if (!node.decorators?.length)
|
|
54
12
|
return;
|
|
55
|
-
|
|
13
|
+
let found = false;
|
|
14
|
+
for (const decorator of node.decorators) {
|
|
15
|
+
const name = decorator.name.text;
|
|
16
|
+
if (name === "json" || name === "serializable") {
|
|
17
|
+
found = true;
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (!found)
|
|
56
22
|
return;
|
|
57
|
-
this.types = json_types;
|
|
58
23
|
const schema = new SchemaData();
|
|
59
24
|
schema.node = node;
|
|
60
25
|
schema.name = node.name.text;
|
|
26
|
+
const members = [
|
|
27
|
+
...node.members.filter((v) => v.kind === 54 /* NodeKind.FieldDeclaration */),
|
|
28
|
+
];
|
|
61
29
|
if (node.extendsType) {
|
|
62
30
|
schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text);
|
|
31
|
+
if (schema.parent?.members) {
|
|
32
|
+
for (let i = schema.parent.members.length - 1; i >= 0; i--) {
|
|
33
|
+
const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
|
|
34
|
+
if (!replace) {
|
|
35
|
+
members.unshift(schema.parent?.members[i].node);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
63
39
|
}
|
|
64
|
-
const _members = [...node.members];
|
|
65
|
-
this.appendParentFields(node, schema, _members);
|
|
66
|
-
const members = this.filterMembers(_members);
|
|
67
40
|
if (!members.length) {
|
|
68
|
-
|
|
41
|
+
let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}';
|
|
42
|
+
//let SERIALIZE_PRETTY_EMPTY = "__SERIALIZE_PRETTY(): string {\n return \"{}\";\n}";
|
|
43
|
+
let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
|
|
44
|
+
let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
|
|
45
|
+
if (process.env["JSON_DEBUG"]) {
|
|
46
|
+
console.log(SERIALIZE_RAW_EMPTY);
|
|
47
|
+
//console.log(SERIALIZE_PRETTY_EMPTY);
|
|
48
|
+
console.log(INITIALIZE_EMPTY);
|
|
49
|
+
console.log(DESERIALIZE_EMPTY);
|
|
50
|
+
}
|
|
51
|
+
const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
|
|
52
|
+
//const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
|
|
53
|
+
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
|
|
54
|
+
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
|
|
55
|
+
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
56
|
+
node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
|
|
57
|
+
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
58
|
+
node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
59
|
+
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
60
|
+
node.members.push(DESERIALIZE_METHOD_EMPTY);
|
|
61
|
+
this.schemasList.push(schema);
|
|
69
62
|
}
|
|
70
63
|
for (const member of members) {
|
|
71
64
|
const name = member.name;
|
|
65
|
+
if (!(member instanceof FieldDeclaration))
|
|
66
|
+
continue;
|
|
72
67
|
if (!member.type) {
|
|
73
|
-
throw new Error("Fields must be strongly typed! Found " +
|
|
68
|
+
throw new Error("Fields must be strongly typed! Found " +
|
|
69
|
+
toString(member) +
|
|
70
|
+
" at " +
|
|
71
|
+
node.range.source.normalizedPath);
|
|
74
72
|
}
|
|
75
73
|
const type = toString(member.type);
|
|
76
74
|
if (type.startsWith("(") && type.includes("=>"))
|
|
@@ -100,7 +98,8 @@ class JSONTransform extends BaseVisitor {
|
|
|
100
98
|
switch (decoratorName) {
|
|
101
99
|
case "alias": {
|
|
102
100
|
if (!args.length)
|
|
103
|
-
throw new Error("Expected 1 argument but got zero at @alias in " +
|
|
101
|
+
throw new Error("Expected 1 argument but got zero at @alias in " +
|
|
102
|
+
node.range.source.normalizedPath);
|
|
104
103
|
mem.alias = args[0];
|
|
105
104
|
mem.flags.set(PropertyFlags.Alias, args);
|
|
106
105
|
break;
|
|
@@ -111,7 +110,8 @@ class JSONTransform extends BaseVisitor {
|
|
|
111
110
|
}
|
|
112
111
|
case "omitif": {
|
|
113
112
|
if (!decorator.args?.length)
|
|
114
|
-
throw new Error("Expected 1 argument but got zero at @omitif in " +
|
|
113
|
+
throw new Error("Expected 1 argument but got zero at @omitif in " +
|
|
114
|
+
node.range.source.normalizedPath);
|
|
115
115
|
mem.flags.set(PropertyFlags.OmitIf, args);
|
|
116
116
|
break;
|
|
117
117
|
}
|
|
@@ -122,10 +122,22 @@ class JSONTransform extends BaseVisitor {
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
-
|
|
126
|
-
mem.generate();
|
|
125
|
+
mem.generate();
|
|
127
126
|
if (this.schemasList.find((v) => v.name == type)) {
|
|
128
|
-
mem.initialize =
|
|
127
|
+
mem.initialize =
|
|
128
|
+
"this." +
|
|
129
|
+
name.text +
|
|
130
|
+
" = changetype<nonnull<" +
|
|
131
|
+
mem.type +
|
|
132
|
+
">>(__new(offsetof<nonnull<" +
|
|
133
|
+
mem.type +
|
|
134
|
+
">>(), idof<nonnull<" +
|
|
135
|
+
mem.type +
|
|
136
|
+
">>()));\n changetype<nonnull<" +
|
|
137
|
+
mem.type +
|
|
138
|
+
">>(this." +
|
|
139
|
+
name.text +
|
|
140
|
+
").__INITIALIZE()";
|
|
129
141
|
}
|
|
130
142
|
else if (mem.value) {
|
|
131
143
|
mem.initialize = "this." + name.text + " = " + mem.value;
|
|
@@ -137,7 +149,8 @@ class JSONTransform extends BaseVisitor {
|
|
|
137
149
|
mem.initialize = "this." + name.text + ' = ""';
|
|
138
150
|
}
|
|
139
151
|
else if (type === "Array") {
|
|
140
|
-
mem.initialize =
|
|
152
|
+
mem.initialize =
|
|
153
|
+
"this." + name.text + " = instantiate<" + mem.type + ">()";
|
|
141
154
|
}
|
|
142
155
|
else if (type === "bool" || type === "boolean") {
|
|
143
156
|
mem.initialize = "this." + name.text + " = false";
|
|
@@ -145,7 +158,14 @@ class JSONTransform extends BaseVisitor {
|
|
|
145
158
|
else if (type === "JSON.Raw") {
|
|
146
159
|
mem.initialize = "this." + name.text + ' = ""';
|
|
147
160
|
}
|
|
148
|
-
else if (type === "u8" ||
|
|
161
|
+
else if (type === "u8" ||
|
|
162
|
+
type === "u16" ||
|
|
163
|
+
type === "u32" ||
|
|
164
|
+
type === "u64" ||
|
|
165
|
+
type === "i8" ||
|
|
166
|
+
type === "i16" ||
|
|
167
|
+
type === "i32" ||
|
|
168
|
+
type === "i64") {
|
|
149
169
|
mem.initialize = "this." + name.text + " = 0";
|
|
150
170
|
}
|
|
151
171
|
else if (type === "f32" || type === "f64") {
|
|
@@ -160,14 +180,15 @@ class JSONTransform extends BaseVisitor {
|
|
|
160
180
|
let indent = " ";
|
|
161
181
|
if (!schema.members.length)
|
|
162
182
|
return;
|
|
163
|
-
|
|
164
|
-
if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) ||
|
|
183
|
+
found = false;
|
|
184
|
+
if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) ||
|
|
185
|
+
schema.members[0]?.flags.has(PropertyFlags.OmitIf)) {
|
|
165
186
|
SERIALIZE_RAW += schema.members[0]?.serialize;
|
|
166
|
-
SERIALIZE_PRETTY += "\\n" +
|
|
187
|
+
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
|
|
167
188
|
}
|
|
168
189
|
else {
|
|
169
190
|
SERIALIZE_RAW += schema.members[0]?.serialize + ",";
|
|
170
|
-
SERIALIZE_PRETTY += "\\n" +
|
|
191
|
+
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n";
|
|
171
192
|
found = true;
|
|
172
193
|
}
|
|
173
194
|
if (schema.members[0]?.initialize)
|
|
@@ -176,21 +197,22 @@ class JSONTransform extends BaseVisitor {
|
|
|
176
197
|
const member = schema.members[i];
|
|
177
198
|
if (member.initialize)
|
|
178
199
|
INITIALIZE += " " + member.initialize + ";\n";
|
|
179
|
-
if (member.flags.has(PropertyFlags.
|
|
180
|
-
|
|
181
|
-
if (member.flags.has(PropertyFlags.OmitNull) || member.flags.has(PropertyFlags.OmitIf)) {
|
|
200
|
+
if (member.flags.has(PropertyFlags.OmitNull) ||
|
|
201
|
+
member.flags.has(PropertyFlags.OmitIf)) {
|
|
182
202
|
SERIALIZE_RAW += member.serialize;
|
|
183
|
-
SERIALIZE_PRETTY += member.
|
|
203
|
+
SERIALIZE_PRETTY += member.serialize;
|
|
184
204
|
}
|
|
185
205
|
else {
|
|
186
206
|
SERIALIZE_RAW += member.serialize + ",";
|
|
187
|
-
SERIALIZE_PRETTY += indent + member.
|
|
207
|
+
SERIALIZE_PRETTY += indent + member.serialize + ",\\n";
|
|
188
208
|
found = true;
|
|
189
209
|
}
|
|
190
210
|
}
|
|
191
211
|
if (found) {
|
|
192
|
-
SERIALIZE_RAW +=
|
|
193
|
-
|
|
212
|
+
SERIALIZE_RAW +=
|
|
213
|
+
"`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
|
|
214
|
+
SERIALIZE_PRETTY +=
|
|
215
|
+
"`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
|
|
194
216
|
}
|
|
195
217
|
else {
|
|
196
218
|
SERIALIZE_RAW += "}`;\n return out;\n}";
|
|
@@ -219,29 +241,35 @@ class JSONTransform extends BaseVisitor {
|
|
|
219
241
|
const _name = encodeKey(firstMember.alias || firstMember.name);
|
|
220
242
|
if (_name.length === 1) {
|
|
221
243
|
if (first) {
|
|
222
|
-
DESERIALIZE +=
|
|
244
|
+
DESERIALIZE +=
|
|
245
|
+
" if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
223
246
|
first = false;
|
|
224
247
|
}
|
|
225
248
|
else {
|
|
226
|
-
DESERIALIZE +=
|
|
249
|
+
DESERIALIZE +=
|
|
250
|
+
"else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
227
251
|
}
|
|
228
252
|
}
|
|
229
253
|
else if (_name.length === 2) {
|
|
230
254
|
if (first) {
|
|
231
|
-
DESERIALIZE +=
|
|
255
|
+
DESERIALIZE +=
|
|
256
|
+
" if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
232
257
|
first = false;
|
|
233
258
|
}
|
|
234
259
|
else {
|
|
235
|
-
DESERIALIZE +=
|
|
260
|
+
DESERIALIZE +=
|
|
261
|
+
"else if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
236
262
|
}
|
|
237
263
|
}
|
|
238
264
|
else if (_name.length === 4) {
|
|
239
265
|
if (first) {
|
|
240
|
-
DESERIALIZE +=
|
|
266
|
+
DESERIALIZE +=
|
|
267
|
+
" if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
|
|
241
268
|
first = false;
|
|
242
269
|
}
|
|
243
270
|
else {
|
|
244
|
-
DESERIALIZE +=
|
|
271
|
+
DESERIALIZE +=
|
|
272
|
+
"else if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
|
|
245
273
|
}
|
|
246
274
|
}
|
|
247
275
|
else {
|
|
@@ -271,7 +299,9 @@ class JSONTransform extends BaseVisitor {
|
|
|
271
299
|
DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
|
|
272
300
|
}
|
|
273
301
|
else {
|
|
274
|
-
DESERIALIZE =
|
|
302
|
+
DESERIALIZE =
|
|
303
|
+
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
304
|
+
`else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
|
|
275
305
|
}
|
|
276
306
|
}
|
|
277
307
|
else {
|
|
@@ -280,7 +310,9 @@ class JSONTransform extends BaseVisitor {
|
|
|
280
310
|
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`;
|
|
281
311
|
}
|
|
282
312
|
else {
|
|
283
|
-
DESERIALIZE =
|
|
313
|
+
DESERIALIZE =
|
|
314
|
+
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
315
|
+
` 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`;
|
|
284
316
|
}
|
|
285
317
|
}
|
|
286
318
|
}
|
|
@@ -288,10 +320,14 @@ class JSONTransform extends BaseVisitor {
|
|
|
288
320
|
DESERIALIZE += ` default: {\n return false;\n }\n }\n`;
|
|
289
321
|
}
|
|
290
322
|
else if (_name.length == 4) {
|
|
291
|
-
DESERIALIZE =
|
|
323
|
+
DESERIALIZE =
|
|
324
|
+
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
325
|
+
` else {\n return false;\n }\n`;
|
|
292
326
|
}
|
|
293
327
|
else {
|
|
294
|
-
DESERIALIZE =
|
|
328
|
+
DESERIALIZE =
|
|
329
|
+
DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
|
|
330
|
+
` else {\n return false;\n }\n`;
|
|
295
331
|
}
|
|
296
332
|
DESERIALIZE += " } ";
|
|
297
333
|
}
|
|
@@ -299,18 +335,16 @@ class JSONTransform extends BaseVisitor {
|
|
|
299
335
|
//console.log(sortedMembers);
|
|
300
336
|
if (process.env["JSON_DEBUG"]) {
|
|
301
337
|
console.log(SERIALIZE_RAW);
|
|
302
|
-
console.log(SERIALIZE_PRETTY);
|
|
338
|
+
//console.log(SERIALIZE_PRETTY);
|
|
303
339
|
console.log(INITIALIZE);
|
|
304
340
|
console.log(DESERIALIZE);
|
|
305
341
|
}
|
|
306
342
|
const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node);
|
|
307
|
-
const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
|
|
343
|
+
//const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
|
|
308
344
|
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
309
345
|
const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
|
|
310
346
|
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
311
347
|
node.members.push(SERIALIZE_RAW_METHOD);
|
|
312
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE_PRETTY"))
|
|
313
|
-
node.members.push(SERIALIZE_PRETTY_METHOD);
|
|
314
348
|
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
315
349
|
node.members.push(INITIALIZE_METHOD);
|
|
316
350
|
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
@@ -336,13 +370,15 @@ export default class Transformer extends Transform {
|
|
|
336
370
|
.sort((_a, _b) => {
|
|
337
371
|
const a = _a.internalPath;
|
|
338
372
|
const b = _b.internalPath;
|
|
339
|
-
if (a[0] !== "~" && b[0] === "~") {
|
|
340
|
-
return 1;
|
|
341
|
-
}
|
|
342
373
|
if (a[0] === "~" && b[0] !== "~") {
|
|
343
374
|
return -1;
|
|
344
375
|
}
|
|
345
|
-
|
|
376
|
+
else if (a[0] !== "~" && b[0] === "~") {
|
|
377
|
+
return 1;
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
return 0;
|
|
381
|
+
}
|
|
346
382
|
});
|
|
347
383
|
// Loop over every source
|
|
348
384
|
for (const source of sources) {
|
|
@@ -354,70 +390,14 @@ export default class Transformer extends Transform {
|
|
|
354
390
|
// Check that every parent and child class is hooked up correctly
|
|
355
391
|
const schemas = transformer.schemasList;
|
|
356
392
|
for (const schema of schemas) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
393
|
+
if (schema.parent) {
|
|
394
|
+
const parent = schemas.find((v) => v.name === schema.parent?.name);
|
|
395
|
+
if (!parent)
|
|
396
|
+
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.`);
|
|
361
397
|
}
|
|
362
398
|
}
|
|
363
399
|
}
|
|
364
400
|
}
|
|
365
|
-
function checkInheritance(schema, schemas) {
|
|
366
|
-
if (!schema.parent && schema.node.extendsType) {
|
|
367
|
-
if (schemas.find(v => v.node.name.text === schema.node.extendsType?.name.identifier.text))
|
|
368
|
-
return;
|
|
369
|
-
const extending = toString(schema.node.extendsType);
|
|
370
|
-
logError(`Schema ${schema.name} extends ${extending}, but ${extending} does not include the @json decorator!`);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
function checkTypeCorrectness(schema, schemas) {
|
|
374
|
-
const parent = schemas.find((v) => v.name === schema.parent?.name);
|
|
375
|
-
const generic_types = [...(schema?.node.typeParameters?.map((v) => v.name.text) || []), ...(parent?.node.typeParameters?.map((v) => v.name.text) || [])];
|
|
376
|
-
const member_types = [...(schema.members.map((v) => v.node.type.name.identifier.text) || [])];
|
|
377
|
-
const scopeTypes = new Set([...json_types, ...generic_types, ...member_types]);
|
|
378
|
-
for (const typ of member_types) {
|
|
379
|
-
if (typ === "JSON")
|
|
380
|
-
continue; // JSON.Raw, JSON.Box, JSON.Any, ect...
|
|
381
|
-
if (json_types.includes(typ))
|
|
382
|
-
continue;
|
|
383
|
-
if (generic_types.includes(typ))
|
|
384
|
-
continue;
|
|
385
|
-
const check = schemas.find((v) => v.name == typ);
|
|
386
|
-
if (!check)
|
|
387
|
-
logError(`Type ${typ} is not a JSON compatible type or does not include the @json flag!`);
|
|
388
|
-
}
|
|
389
|
-
for (const member of schema.members) {
|
|
390
|
-
const invalidType = checkType(schema, schemas, member.node.type, member, scopeTypes, schema.name);
|
|
391
|
-
if (invalidType)
|
|
392
|
-
logError(`Type ${invalidType.type} in ${invalidType.path} does not implement a JSON compatible type!\n${chalk.dim(` at ${member.node.range.source.normalizedPath.replace("~lib/", "./node_modules/")}`)}`);
|
|
393
|
-
}
|
|
394
|
-
return null;
|
|
395
|
-
}
|
|
396
|
-
function checkType(schema, schemas, typ, member, scopeTypes, path) {
|
|
397
|
-
path += "." + member.name;
|
|
398
|
-
if (schemas.find(v => v.node.name.text === typ.name.identifier.text))
|
|
399
|
-
scopeTypes.add(typ.name.identifier.text);
|
|
400
|
-
if (!scopeTypes.has(typ.name.identifier.text))
|
|
401
|
-
return { type: toString(typ), path };
|
|
402
|
-
if (typ.isNullable && isPrimitive(typ))
|
|
403
|
-
return { type: toString(typ), path };
|
|
404
|
-
if (typ.typeArguments?.length && typ.typeArguments?.length > 0) {
|
|
405
|
-
for (const ty of typ.typeArguments.filter((v) => v instanceof NamedTypeNode)) {
|
|
406
|
-
const check = checkType(schema, schemas, ty, member, scopeTypes, path);
|
|
407
|
-
if (check)
|
|
408
|
-
return { type: toString(typ), path };
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
if (scopeTypes.has(typ.name.identifier.text))
|
|
413
|
-
return null;
|
|
414
|
-
}
|
|
415
|
-
return null;
|
|
416
|
-
}
|
|
417
|
-
function logError(message) {
|
|
418
|
-
console.log("\n" + chalk.bold.bgRed(" Error ") + chalk.dim(":") + " " + message + "\n");
|
|
419
|
-
process.exit(1);
|
|
420
|
-
}
|
|
421
401
|
var PropertyFlags;
|
|
422
402
|
(function (PropertyFlags) {
|
|
423
403
|
PropertyFlags[PropertyFlags["Null"] = 0] = "Null";
|
|
@@ -434,7 +414,6 @@ class Property {
|
|
|
434
414
|
value = null;
|
|
435
415
|
flags = new Map();
|
|
436
416
|
serialize = null;
|
|
437
|
-
serialize_pretty = null;
|
|
438
417
|
deserialize = null;
|
|
439
418
|
initialize = null;
|
|
440
419
|
node;
|
|
@@ -448,7 +427,7 @@ class Property {
|
|
|
448
427
|
return;
|
|
449
428
|
if (this.flags.has(PropertyFlags.JSON_Raw)) {
|
|
450
429
|
if (this.flags.has(PropertyFlags.Null)) {
|
|
451
|
-
this.right_s = "(this." + name +
|
|
430
|
+
this.right_s = "(this." + name + " || \"null\")";
|
|
452
431
|
this.right_d = "value_start === value_end - 4 && 30399761348886638 === load<u64>(changetype<usize>(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)";
|
|
453
432
|
}
|
|
454
433
|
else {
|
|
@@ -458,24 +437,37 @@ class Property {
|
|
|
458
437
|
}
|
|
459
438
|
else {
|
|
460
439
|
this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")";
|
|
461
|
-
this.right_d =
|
|
440
|
+
this.right_d =
|
|
441
|
+
"__DESERIALIZE<" + type + ">(data.substring(value_start, value_end))";
|
|
462
442
|
}
|
|
463
443
|
if (this.flags.has(PropertyFlags.OmitIf)) {
|
|
464
444
|
const condition = this.flags.get(PropertyFlags.OmitIf)[0];
|
|
465
445
|
if (!condition)
|
|
466
446
|
throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition");
|
|
467
|
-
this.serialize =
|
|
468
|
-
|
|
447
|
+
this.serialize =
|
|
448
|
+
"${" +
|
|
449
|
+
condition +
|
|
450
|
+
' ? "" : \'' +
|
|
451
|
+
escapedName +
|
|
452
|
+
":' + " +
|
|
453
|
+
this.right_s +
|
|
454
|
+
' + ","}';
|
|
469
455
|
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
470
456
|
}
|
|
471
457
|
else if (this.flags.has(PropertyFlags.OmitNull)) {
|
|
472
|
-
this.serialize =
|
|
473
|
-
|
|
458
|
+
this.serialize =
|
|
459
|
+
"${changetype<usize>(this." +
|
|
460
|
+
name +
|
|
461
|
+
") == <usize>0" +
|
|
462
|
+
' ? "" : \'' +
|
|
463
|
+
escapedName +
|
|
464
|
+
":' + " +
|
|
465
|
+
this.right_s +
|
|
466
|
+
' + ","}';
|
|
474
467
|
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
475
468
|
}
|
|
476
469
|
else {
|
|
477
470
|
this.serialize = escapedName + ":${" + this.right_s + "}";
|
|
478
|
-
this.serialize_pretty = escapedName + ": ${" + this.right_s + "}";
|
|
479
471
|
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
480
472
|
}
|
|
481
473
|
}
|
|
@@ -497,7 +489,10 @@ function charCodeAt64(data, offset) {
|
|
|
497
489
|
const secondCharCode = BigInt(data.charCodeAt(offset + 1));
|
|
498
490
|
const thirdCharCode = BigInt(data.charCodeAt(offset + 2));
|
|
499
491
|
const fourthCharCode = BigInt(data.charCodeAt(offset + 3));
|
|
500
|
-
const u64Value = (fourthCharCode << 48n) |
|
|
492
|
+
const u64Value = (fourthCharCode << 48n) |
|
|
493
|
+
(thirdCharCode << 32n) |
|
|
494
|
+
(secondCharCode << 16n) |
|
|
495
|
+
firstCharCode;
|
|
501
496
|
return u64Value;
|
|
502
497
|
}
|
|
503
498
|
function encodeKey(key) {
|
|
@@ -542,7 +537,3 @@ function getArgs(args) {
|
|
|
542
537
|
}
|
|
543
538
|
return out;
|
|
544
539
|
}
|
|
545
|
-
function isPrimitive(type) {
|
|
546
|
-
const primitives = new Set(["u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean"]);
|
|
547
|
-
return primitives.has(type.name.identifier.text);
|
|
548
|
-
}
|