json-as 0.8.7 → 0.8.8
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 +1 -7
- package/CHANGELOG +1 -3
- package/README.md +16 -26
- package/assembly/__benches__/as-json.ts +88 -0
- package/assembly/__benches__/as-tral.d.ts +1 -0
- package/assembly/__tests__/as-json.spec.ts +673 -0
- package/assembly/__tests__/as-pect.d.ts +1 -0
- package/assembly/deserialize/array/array.ts +1 -1
- package/assembly/deserialize/array/map.ts +1 -1
- package/assembly/deserialize/array/object.ts +1 -1
- package/assembly/deserialize/array.ts +1 -1
- package/assembly/deserialize/box.ts +1 -4
- package/assembly/deserialize/map.ts +1 -1
- package/assembly/deserialize/object.ts +125 -122
- package/assembly/index.d.ts +1 -7
- package/assembly/index.ts +1 -129
- package/assembly/serialize/array.ts +2 -3
- package/assembly/serialize/box.ts +1 -1
- package/assembly/serialize/map.ts +1 -1
- package/assembly/src/json.ts +124 -0
- package/assembly/test.ts +22 -33
- package/bench/benchmark.ts +3 -7
- package/bench.js +3 -14
- package/index.ts +1 -1
- package/package.json +8 -6
- package/transform/lib/index.js +183 -301
- package/transform/package.json +1 -1
- package/transform/src/index.ts +215 -301
- package/transform/tsconfig.json +2 -2
- package/tsconfig.json +102 -94
- package/assembly/__tests__/deserialize.spec.ts +0 -298
- package/assembly/__tests__/serialize.spec.ts +0 -375
- package/transform/lib/index.old.js +0 -257
- package/transform/lib/types.js +0 -17
- package/transform/src/index.old.ts +0 -312
package/transform/lib/index.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Parser, Source, Tokenizer, } 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
|
-
class
|
|
5
|
+
class SchemaData {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.keys = [];
|
|
8
|
+
this.values = [];
|
|
9
|
+
this.types = [];
|
|
10
|
+
this.name = "";
|
|
11
|
+
this.parent = "";
|
|
12
|
+
this.encodeStmts = [];
|
|
13
|
+
this.setDataStmts = [];
|
|
14
|
+
this.initializeStmts = [];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
class AsJSONTransform extends BaseVisitor {
|
|
6
18
|
constructor() {
|
|
7
19
|
super(...arguments);
|
|
8
20
|
this.schemasList = [];
|
|
@@ -10,265 +22,175 @@ class JSONTransform extends BaseVisitor {
|
|
|
10
22
|
}
|
|
11
23
|
visitMethodDeclaration() { }
|
|
12
24
|
visitClassDeclaration(node) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (!node.
|
|
25
|
+
var _c, _d;
|
|
26
|
+
const className = node.name.text;
|
|
27
|
+
if (!((_c = node.decorators) === null || _c === void 0 ? void 0 : _c.length))
|
|
16
28
|
return;
|
|
17
|
-
let
|
|
29
|
+
let foundDecorator = false;
|
|
18
30
|
for (const decorator of node.decorators) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
if (
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
decorator.name.text.toLowerCase() == "json" ||
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
decorator.name.text.toLowerCase() == "serializable")
|
|
36
|
+
foundDecorator = true;
|
|
24
37
|
}
|
|
25
|
-
if (!
|
|
38
|
+
if (!foundDecorator)
|
|
26
39
|
return;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
...node.members
|
|
32
|
-
];
|
|
33
|
-
if (node.extendsType) {
|
|
34
|
-
schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text);
|
|
35
|
-
if (schema.parent?.members) {
|
|
36
|
-
for (let i = 0; i < schema.parent.members.length; i++) {
|
|
37
|
-
const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
|
|
38
|
-
if (!replace)
|
|
39
|
-
schema.members.unshift(schema.parent.members[i]);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
40
|
+
// Prevent from being triggered twice.
|
|
41
|
+
for (const member of node.members) {
|
|
42
|
+
if (member.name.text == "__SERIALIZE")
|
|
43
|
+
return;
|
|
42
44
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
mem.node = member;
|
|
63
|
-
for (const decorator of member.decorators || []) {
|
|
64
|
-
if (decorator.name.text == "alias") {
|
|
65
|
-
if (!decorator.args?.length)
|
|
66
|
-
throw new Error("Expected 1 argument but got zero at @alias in " + node.range.source.normalizedPath);
|
|
67
|
-
mem.flag = PropertyFlags.Alias;
|
|
68
|
-
mem.alias = decorator.args[0].value;
|
|
69
|
-
}
|
|
70
|
-
else if (decorator.name.text == "omit") {
|
|
71
|
-
mem.flag = PropertyFlags.Omit;
|
|
45
|
+
this.currentClass = {
|
|
46
|
+
name: className,
|
|
47
|
+
keys: [],
|
|
48
|
+
values: [],
|
|
49
|
+
types: [],
|
|
50
|
+
parent: node.extendsType ? toString(node.extendsType) : "",
|
|
51
|
+
node: node,
|
|
52
|
+
encodeStmts: [],
|
|
53
|
+
setDataStmts: [],
|
|
54
|
+
initializeStmts: []
|
|
55
|
+
};
|
|
56
|
+
if (this.currentClass.parent.length) {
|
|
57
|
+
const parentSchema = this.schemasList.find((v) => v.name == this.currentClass.parent);
|
|
58
|
+
if (parentSchema === null || parentSchema === void 0 ? void 0 : parentSchema.encodeStmts) {
|
|
59
|
+
parentSchema === null || parentSchema === void 0 ? void 0 : parentSchema.encodeStmts.push((parentSchema === null || parentSchema === void 0 ? void 0 : parentSchema.encodeStmts.pop()) + ",");
|
|
60
|
+
for (let i = 0; i < parentSchema.keys.length; i++) {
|
|
61
|
+
const key = parentSchema.keys[i];
|
|
62
|
+
if (node.members.filter(v => v.name.text == key) == undefined)
|
|
63
|
+
this.currentClass.encodeStmts.unshift(parentSchema.encodeStmts[i]);
|
|
72
64
|
}
|
|
73
|
-
else if (decorator.name.text == "omitnull") {
|
|
74
|
-
mem.flag = PropertyFlags.OmitNull;
|
|
75
|
-
}
|
|
76
|
-
else if (decorator.name.text == "omitif") {
|
|
77
|
-
if (!decorator.args?.length)
|
|
78
|
-
throw new Error("Expected 1 argument but got zero at @omitif in " + node.range.source.normalizedPath);
|
|
79
|
-
mem.args?.push(decorator.args[0].value);
|
|
80
|
-
mem.flag = PropertyFlags.OmitIf;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (mem.flag === PropertyFlags.Alias) {
|
|
84
|
-
mem.name = mem.alias;
|
|
85
|
-
}
|
|
86
|
-
else if (mem.flag === PropertyFlags.None) {
|
|
87
|
-
mem.serialize = escapeString(JSON.stringify(mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
88
|
-
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
|
|
89
|
-
}
|
|
90
|
-
if (mem.flag == PropertyFlags.OmitNull) {
|
|
91
|
-
mem.serialize = "${changetype<usize>(this." + mem.name + ") == <usize>0" + " ? \"\" : '" + escapeString(JSON.stringify(mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
|
|
92
|
-
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
|
|
93
|
-
}
|
|
94
|
-
else if (mem.flag == PropertyFlags.OmitIf) {
|
|
95
|
-
mem.serialize = "${" + mem.args[0] + " ? \"\" : '" + escapeString(JSON.stringify(mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
96
|
-
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
|
|
97
|
-
}
|
|
98
|
-
else if (mem.flag == PropertyFlags.Alias) {
|
|
99
|
-
mem.serialize = escapeString(JSON.stringify(mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
100
|
-
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
|
|
101
|
-
mem.name = name.text;
|
|
102
|
-
}
|
|
103
|
-
const t = mem.node.type.name.identifier.text;
|
|
104
|
-
if (this.schemasList.find(v => v.name == t)) {
|
|
105
|
-
mem.initialize = "this." + name.text + " = changetype<nonnull<" + t + ">>(__new(offsetof<nonnull<" + t + ">>(), idof<nonnull<" + t + ">>()));\n changetype<nonnull<" + t + ">>(this." + name.text + ").__INITIALIZE()";
|
|
106
65
|
}
|
|
107
|
-
else if (mem.value) {
|
|
108
|
-
mem.initialize = "this." + name.text + " = " + mem.value;
|
|
109
|
-
}
|
|
110
|
-
schema.members.push(mem);
|
|
111
|
-
}
|
|
112
|
-
let SERIALIZE_RAW = "@inline __SERIALIZE(): string {\n let out = `{";
|
|
113
|
-
let SERIALIZE_PRETTY = "@inline __SERIALIZE_PRETTY(): string {\n let out = `{";
|
|
114
|
-
let INITIALIZE = "@inline __INITIALIZE(): this {\n";
|
|
115
|
-
let DESERIALIZE = "@inline __DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n";
|
|
116
|
-
let indent = " ";
|
|
117
|
-
if (!schema.members.length)
|
|
118
|
-
return;
|
|
119
|
-
found = false;
|
|
120
|
-
if (schema.members[0]?.flag === PropertyFlags.OmitNull
|
|
121
|
-
|| schema.members[0]?.flag === PropertyFlags.OmitIf) {
|
|
122
|
-
SERIALIZE_RAW += schema.members[0]?.serialize;
|
|
123
|
-
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
SERIALIZE_RAW += schema.members[0]?.serialize + ",";
|
|
127
|
-
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n";
|
|
128
|
-
found = true;
|
|
129
|
-
}
|
|
130
|
-
if (schema.members[0]?.initialize)
|
|
131
|
-
INITIALIZE += " " + schema.members[0]?.initialize + ";\n";
|
|
132
|
-
for (let i = 1; i < schema.members.length; i++) {
|
|
133
|
-
const member = schema.members[i];
|
|
134
|
-
if (member.initialize)
|
|
135
|
-
INITIALIZE += " " + member.initialize + ";\n";
|
|
136
|
-
if (member.flag === PropertyFlags.OmitNull
|
|
137
|
-
|| member.flag === PropertyFlags.OmitIf) {
|
|
138
|
-
SERIALIZE_RAW += member.serialize;
|
|
139
|
-
SERIALIZE_PRETTY += member.serialize;
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
SERIALIZE_RAW += member.serialize + ",";
|
|
143
|
-
SERIALIZE_PRETTY += indent + member.serialize + ",\\n";
|
|
144
|
-
found = true;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (found) {
|
|
148
|
-
SERIALIZE_RAW += "`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
|
|
149
|
-
SERIALIZE_PRETTY += "`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
SERIALIZE_RAW += "`;\n};";
|
|
153
|
-
SERIALIZE_PRETTY += "`;\n};";
|
|
154
66
|
}
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const member = _sorted[i];
|
|
164
|
-
if (member.alias?.length || member.name.length > len) {
|
|
165
|
-
sortedMembers.push([member]);
|
|
166
|
-
len = member.alias?.length || member.name.length;
|
|
167
|
-
offset++;
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
sortedMembers[offset].push(member);
|
|
67
|
+
const parentSchema = this.schemasList.find((v) => v.name == this.currentClass.parent);
|
|
68
|
+
const members = [
|
|
69
|
+
...node.members
|
|
70
|
+
];
|
|
71
|
+
if (parentSchema) {
|
|
72
|
+
for (const mem of parentSchema.node.members) {
|
|
73
|
+
if (members.find(v => v.name === mem.name) == undefined)
|
|
74
|
+
members.unshift(mem);
|
|
171
75
|
}
|
|
172
76
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
DESERIALIZE += "else if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
else if (name.length === 4) {
|
|
196
|
-
if (first) {
|
|
197
|
-
DESERIALIZE += " if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
|
|
198
|
-
first = false;
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
DESERIALIZE += "else if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
if (first) {
|
|
206
|
-
DESERIALIZE += " if (" + name.length + " === len) {\n";
|
|
207
|
-
first = false;
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
DESERIALIZE += "else if (" + name.length + " === len) {\n";
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
let f = true;
|
|
214
|
-
for (let i = 0; i < memberSet.length; i++) {
|
|
215
|
-
const member = memberSet[i];
|
|
216
|
-
const name = encodeKey(member.alias || member.name);
|
|
217
|
-
if (name.length === 1) {
|
|
218
|
-
DESERIALIZE += ` case ${name.charCodeAt(0)}: {\n ${member.deserialize}\n return true;\n }\n`;
|
|
219
|
-
}
|
|
220
|
-
else if (name.length === 2) {
|
|
221
|
-
DESERIALIZE += ` case ${charCodeAt32(name, 0)}: {\n ${member.deserialize}\n return true;\n }\n`;
|
|
222
|
-
}
|
|
223
|
-
else if (name.length === 4) {
|
|
224
|
-
if (f) {
|
|
225
|
-
f = false;
|
|
226
|
-
DESERIALIZE += ` if (${charCodeAt64(name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
|
|
77
|
+
for (const mem of members) {
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
if (mem.type && mem.type.name && mem.type.name.identifier.text) {
|
|
80
|
+
const member = mem;
|
|
81
|
+
const lineText = toString(member);
|
|
82
|
+
//console.log("Member: " + lineText)
|
|
83
|
+
if (!lineText.startsWith("private ") && !lineText.startsWith("static ")) {
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
let type = toString(member.type);
|
|
86
|
+
const name = member.name.text;
|
|
87
|
+
let aliasName = name;
|
|
88
|
+
// @ts-ignore
|
|
89
|
+
if (member.decorators && ((_d = member.decorators[0]) === null || _d === void 0 ? void 0 : _d.name.text) === "alias") {
|
|
90
|
+
if (member.decorators[0] && member.decorators[0].args[0]) {
|
|
91
|
+
// @ts-ignore
|
|
92
|
+
aliasName = member.decorators[0].args[0].value;
|
|
93
|
+
}
|
|
227
94
|
}
|
|
228
|
-
|
|
229
|
-
|
|
95
|
+
this.currentClass.keys.push(name);
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
this.currentClass.types.push(type);
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
if ([
|
|
100
|
+
"u8",
|
|
101
|
+
"i8",
|
|
102
|
+
"u16",
|
|
103
|
+
"i16",
|
|
104
|
+
"u32",
|
|
105
|
+
"i32",
|
|
106
|
+
"u64",
|
|
107
|
+
"i64",
|
|
108
|
+
].includes(type.toLowerCase())) {
|
|
109
|
+
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${this.${name}},`);
|
|
110
|
+
// @ts-ignore
|
|
111
|
+
this.currentClass.setDataStmts.push(`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
112
|
+
this.${name} = __atoi_fast<${type}>(data, val_start << 1, val_end << 1);
|
|
113
|
+
return;
|
|
114
|
+
}`);
|
|
115
|
+
if (member.initializer) {
|
|
116
|
+
this.currentClass.initializeStmts.push(`this.${name} = ${toString(member.initializer)}`);
|
|
117
|
+
}
|
|
230
118
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
119
|
+
else // @ts-ignore
|
|
120
|
+
if ([
|
|
121
|
+
"f32",
|
|
122
|
+
"f64",
|
|
123
|
+
].includes(type.toLowerCase())) {
|
|
124
|
+
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${this.${name}},`);
|
|
125
|
+
// @ts-ignore
|
|
126
|
+
this.currentClass.setDataStmts.push(`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
127
|
+
this.${name} = __parseObjectValue<${type}>(data.slice(val_start, val_end), initializeDefaultValues);
|
|
128
|
+
return;
|
|
129
|
+
}`);
|
|
130
|
+
if (member.initializer) {
|
|
131
|
+
this.currentClass.initializeStmts.push(`this.${name} = ${toString(member.initializer)}`);
|
|
132
|
+
}
|
|
236
133
|
}
|
|
237
134
|
else {
|
|
238
|
-
|
|
135
|
+
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${__JSON_Stringify<${type}>(this.${name})},`);
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
this.currentClass.setDataStmts.push(`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
138
|
+
this.${name} = __parseObjectValue<${type}>(val_start ? data.slice(val_start, val_end) : data, initializeDefaultValues);
|
|
139
|
+
return;
|
|
140
|
+
}`);
|
|
141
|
+
if (member.initializer) {
|
|
142
|
+
this.currentClass.initializeStmts.push(`this.${name} = ${toString(member.initializer)}`);
|
|
143
|
+
}
|
|
239
144
|
}
|
|
240
145
|
}
|
|
241
146
|
}
|
|
242
|
-
if (name.length < 3) {
|
|
243
|
-
DESERIALIZE += ` default: {\n return false;\n }\n }\n`;
|
|
244
|
-
}
|
|
245
|
-
else if (name.length == 4) {
|
|
246
|
-
DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
249
|
-
DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
|
|
250
|
-
}
|
|
251
|
-
DESERIALIZE += " } ";
|
|
252
147
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
148
|
+
let serializeFunc = "";
|
|
149
|
+
if (this.currentClass.encodeStmts.length > 0) {
|
|
150
|
+
const stmt = this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1];
|
|
151
|
+
this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] =
|
|
152
|
+
stmt.slice(0, stmt.length - 1);
|
|
153
|
+
serializeFunc = `
|
|
154
|
+
__SERIALIZE(): string {
|
|
155
|
+
return \`{${this.currentClass.encodeStmts.join("")}}\`;
|
|
156
|
+
}`;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
serializeFunc = `
|
|
160
|
+
__SERIALIZE(): string {
|
|
161
|
+
return "{}";
|
|
162
|
+
}`;
|
|
260
163
|
}
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if (
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
164
|
+
const setKeyFunc = `
|
|
165
|
+
__JSON_Set_Key(key: __Virtual<string>, data: string, val_start: i32, val_end: i32, initializeDefaultValues: boolean): void {
|
|
166
|
+
${this.currentClass.setDataStmts.join("\n ")}
|
|
167
|
+
}
|
|
168
|
+
`;
|
|
169
|
+
let initializeFunc = "";
|
|
170
|
+
if (this.currentClass.initializeStmts.length > 0) {
|
|
171
|
+
initializeFunc = `
|
|
172
|
+
__JSON_Initialize(): void {
|
|
173
|
+
${this.currentClass.initializeStmts.join(";\n")};
|
|
174
|
+
}
|
|
175
|
+
`;
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
initializeFunc = `
|
|
179
|
+
__JSON_Initialize(): void {}
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
const serializeMethod = SimpleParser.parseClassMember(serializeFunc, node);
|
|
183
|
+
node.members.push(serializeMethod);
|
|
184
|
+
const setDataMethod = SimpleParser.parseClassMember(setKeyFunc, node);
|
|
185
|
+
node.members.push(setDataMethod);
|
|
186
|
+
const initializeMethod = SimpleParser.parseClassMember(initializeFunc, node);
|
|
187
|
+
node.members.push(initializeMethod);
|
|
188
|
+
this.schemasList.push(this.currentClass);
|
|
189
|
+
this.sources.add(node.name.range.source);
|
|
190
|
+
// Uncomment to see the generated code for debugging.
|
|
191
|
+
//console.log(serializeFunc);
|
|
192
|
+
//console.log(setKeyFunc);
|
|
193
|
+
//console.log(initializeFunc);
|
|
272
194
|
}
|
|
273
195
|
visitSource(node) {
|
|
274
196
|
super.visitSource(node);
|
|
@@ -276,13 +198,30 @@ class JSONTransform extends BaseVisitor {
|
|
|
276
198
|
if (!this.sources.has(node)) {
|
|
277
199
|
return;
|
|
278
200
|
}
|
|
201
|
+
// Note, the following one liner would be easier, but it fails with an assertion error
|
|
202
|
+
// because as-virtual's SimpleParser doesn't set the parser.currentSource correctly.
|
|
203
|
+
//
|
|
204
|
+
// const stmt = SimpleParser.parseTopLevelStatement('import { Virtual as __Virtual } from "as-virtual/assembly";');
|
|
205
|
+
// ... So we have to do it the long way:
|
|
206
|
+
const txt = 'import { Virtual as __Virtual } from "as-virtual/assembly";';
|
|
207
|
+
const tokenizer = new Tokenizer(new Source(0 /* SourceKind.User */, node.normalizedPath, txt));
|
|
208
|
+
const parser = new Parser();
|
|
209
|
+
parser.currentSource = tokenizer.source;
|
|
210
|
+
const stmt = parser.parseTopLevelStatement(tokenizer);
|
|
211
|
+
// Add the import statement to the top of the source.
|
|
212
|
+
node.statements.unshift(stmt);
|
|
279
213
|
}
|
|
280
214
|
}
|
|
215
|
+
function encodeKey(aliasName) {
|
|
216
|
+
return JSON.stringify(aliasName)
|
|
217
|
+
.replace(/\\/g, "\\\\")
|
|
218
|
+
.replace(/\`/g, '\\`');
|
|
219
|
+
}
|
|
281
220
|
export default class Transformer extends Transform {
|
|
282
221
|
// Trigger the transform after parse.
|
|
283
222
|
afterParse(parser) {
|
|
284
223
|
// Create new transform
|
|
285
|
-
const transformer = new
|
|
224
|
+
const transformer = new AsJSONTransform();
|
|
286
225
|
// Sort the sources so that user scripts are visited last
|
|
287
226
|
const sources = parser.sources
|
|
288
227
|
.filter((source) => !isStdlib(source))
|
|
@@ -310,67 +249,10 @@ export default class Transformer extends Transform {
|
|
|
310
249
|
const schemas = transformer.schemasList;
|
|
311
250
|
for (const schema of schemas) {
|
|
312
251
|
if (schema.parent) {
|
|
313
|
-
const parent = schemas.find((v) => v.name === schema.parent
|
|
252
|
+
const parent = schemas.find((v) => v.name === schema.parent);
|
|
314
253
|
if (!parent)
|
|
315
254
|
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.`);
|
|
316
255
|
}
|
|
317
256
|
}
|
|
318
257
|
}
|
|
319
258
|
}
|
|
320
|
-
var PropertyFlags;
|
|
321
|
-
(function (PropertyFlags) {
|
|
322
|
-
PropertyFlags[PropertyFlags["None"] = 0] = "None";
|
|
323
|
-
PropertyFlags[PropertyFlags["Omit"] = 1] = "Omit";
|
|
324
|
-
PropertyFlags[PropertyFlags["OmitNull"] = 2] = "OmitNull";
|
|
325
|
-
PropertyFlags[PropertyFlags["OmitIf"] = 3] = "OmitIf";
|
|
326
|
-
PropertyFlags[PropertyFlags["Alias"] = 4] = "Alias";
|
|
327
|
-
})(PropertyFlags || (PropertyFlags = {}));
|
|
328
|
-
class Property {
|
|
329
|
-
constructor() {
|
|
330
|
-
this.name = "";
|
|
331
|
-
this.alias = null;
|
|
332
|
-
this.type = "";
|
|
333
|
-
this.value = null;
|
|
334
|
-
this.flag = PropertyFlags.None;
|
|
335
|
-
this.args = [];
|
|
336
|
-
this.serialize = null;
|
|
337
|
-
this.deserialize = null;
|
|
338
|
-
this.initialize = null;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
class SchemaData {
|
|
342
|
-
constructor() {
|
|
343
|
-
this.name = "";
|
|
344
|
-
this.members = [];
|
|
345
|
-
this.parent = null;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
function charCodeAt32(data, offset) {
|
|
349
|
-
return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset);
|
|
350
|
-
}
|
|
351
|
-
function charCodeAt64(data, offset) {
|
|
352
|
-
if (offset + 3 >= data.length) {
|
|
353
|
-
throw new Error("The string must have at least 4 characters from the specified offset.");
|
|
354
|
-
}
|
|
355
|
-
const firstCharCode = BigInt(data.charCodeAt(offset));
|
|
356
|
-
const secondCharCode = BigInt(data.charCodeAt(offset + 1));
|
|
357
|
-
const thirdCharCode = BigInt(data.charCodeAt(offset + 2));
|
|
358
|
-
const fourthCharCode = BigInt(data.charCodeAt(offset + 3));
|
|
359
|
-
const u64Value = (fourthCharCode << 48n) | (thirdCharCode << 32n) | (secondCharCode << 16n) | firstCharCode;
|
|
360
|
-
return u64Value;
|
|
361
|
-
}
|
|
362
|
-
function encodeKey(key) {
|
|
363
|
-
const data = JSON.stringify(key);
|
|
364
|
-
return data.slice(1, data.length - 1);
|
|
365
|
-
}
|
|
366
|
-
function escapeString(data) {
|
|
367
|
-
return data.replace(/\\/g, "\\\\")
|
|
368
|
-
.replace(/\`/g, '\\`');
|
|
369
|
-
}
|
|
370
|
-
function escapeSlash(data) {
|
|
371
|
-
return data.replace(/\\/g, "\\\\")
|
|
372
|
-
.replace(/\`/g, '\\`');
|
|
373
|
-
}
|
|
374
|
-
function escapeQuote(data) {
|
|
375
|
-
return data.replace(/\"/g, "\\\"");
|
|
376
|
-
}
|