json-as 1.0.0-alpha.1 → 1.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitmodules +0 -0
- package/.prettierignore +6 -0
- package/.prettierrc.json +0 -1
- package/CHANGELOG +20 -1
- package/README.md +4 -3
- package/as-test.config.json +1 -1
- package/asconfig.json +1 -29
- package/assembly/__benches__/misc.bench.ts +0 -19
- package/assembly/__tests__/array.spec.ts +67 -0
- package/assembly/__tests__/bool.spec.ts +4 -12
- package/assembly/__tests__/float.spec.ts +11 -21
- package/assembly/__tests__/integer.spec.ts +7 -9
- package/assembly/__tests__/null.spec.ts +12 -0
- package/assembly/__tests__/obj.spec.ts +137 -3
- package/assembly/__tests__/simd/string.spec.ts +21 -21
- package/assembly/__tests__/string.spec.ts +6 -4
- package/assembly/__tests__/test.spec.ts +120 -191
- package/assembly/deserialize/simple/bool.ts +1 -1
- package/assembly/deserialize/simple/map.ts +1 -1
- package/assembly/deserialize/simple/object.ts +2 -3
- package/assembly/deserialize/simple/string.ts +4 -3
- package/assembly/globals/tables.ts +74 -416
- package/assembly/index.ts +20 -25
- package/assembly/serialize/simd/string.ts +11 -11
- package/assembly/serialize/simple/array.ts +5 -5
- package/assembly/serialize/simple/bool.ts +3 -3
- package/assembly/serialize/simple/date.ts +2 -2
- package/assembly/serialize/simple/float.ts +2 -2
- package/assembly/serialize/simple/integer.ts +2 -2
- package/assembly/serialize/simple/map.ts +7 -7
- package/assembly/serialize/simple/string.ts +5 -5
- package/assembly/test.ts +4 -48
- package/assembly/util/bytes.ts +1 -1
- package/modules/as-bs/LICENSE +21 -0
- package/modules/as-bs/README.md +95 -0
- package/modules/as-bs/assembly/index.ts +116 -0
- package/modules/as-bs/assembly/tsconfig.json +97 -0
- package/modules/as-bs/index.ts +1 -0
- package/modules/as-bs/package.json +32 -0
- package/modules/test/assembly/index.ts +22 -0
- package/package.json +5 -10
- package/run-tests.sh +15 -0
- package/transform/lib/builder.js +1262 -1340
- package/transform/lib/index.js +512 -572
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linker.js +10 -12
- package/transform/lib/types.js +19 -18
- package/transform/lib/types.js.map +1 -1
- package/transform/lib/util.js +34 -34
- package/transform/lib/visitor.js +526 -529
- package/transform/package.json +2 -1
- package/transform/src/index.ts +20 -9
- package/transform/src/types.ts +1 -0
- package/modules/bs/index.ts +0 -167
- package/modules/tsconfig.json +0 -8
- package/transform/lib/index.old.js +0 -404
- package/transform/lib/index.old.js.map +0 -1
package/transform/package.json
CHANGED
package/transform/src/index.ts
CHANGED
|
@@ -137,7 +137,7 @@ class JSONTransform extends Visitor {
|
|
|
137
137
|
|
|
138
138
|
let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
|
|
139
139
|
let INITIALIZE = "@inline __INITIALIZE(): this {\n";
|
|
140
|
-
let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n switch (keyEnd - keyStart) {\n";
|
|
140
|
+
let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n switch (<u32>keyEnd - <u32>keyStart) {\n";
|
|
141
141
|
let ALLOCATE = "@inline __ALLOCATE(): void {\n";
|
|
142
142
|
|
|
143
143
|
indent = " ";
|
|
@@ -151,6 +151,17 @@ class JSONTransform extends Visitor {
|
|
|
151
151
|
SERIALIZE += indent + "bs.offset += 2;\n";
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
for (const member of this.schema.members) {
|
|
155
|
+
const nonNullType = member.type.replace(" | null", "");
|
|
156
|
+
if (!isPrimitive(nonNullType)) {
|
|
157
|
+
const schema = this.schemas.find((v) => v.name == nonNullType);
|
|
158
|
+
if (schema && !this.schema.deps.includes(schema)) {
|
|
159
|
+
this.schema.deps.push(schema);
|
|
160
|
+
this.schema.byteSize += schema.byteSize;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
154
165
|
let isPure = this.schema.static;
|
|
155
166
|
let isRegular = isPure;
|
|
156
167
|
let isFirst = true;
|
|
@@ -214,7 +225,7 @@ class JSONTransform extends Visitor {
|
|
|
214
225
|
const arg = member.flags.get(PropertyFlags.OmitIf) as FunctionExpression;
|
|
215
226
|
// @ts-ignore: type
|
|
216
227
|
arg.declaration.signature.returnType.name = Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name.range);
|
|
217
|
-
SERIALIZE += indent + `if ((${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
|
|
228
|
+
SERIALIZE += indent + `if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
|
|
218
229
|
} else {
|
|
219
230
|
SERIALIZE += indent + `if (${toString(member.flags.get(PropertyFlags.OmitIf))}) {\n`;
|
|
220
231
|
}
|
|
@@ -310,7 +321,7 @@ class JSONTransform extends Visitor {
|
|
|
310
321
|
SERIALIZE += indent + "bs.offset += 2;\n";
|
|
311
322
|
SERIALIZE += "}";
|
|
312
323
|
|
|
313
|
-
ALLOCATE += indent + "bs.
|
|
324
|
+
ALLOCATE += indent + "bs.proposeSize(" + this.schema.byteSize + ");\n";
|
|
314
325
|
ALLOCATE += "}";
|
|
315
326
|
|
|
316
327
|
INITIALIZE += " return this;\n";
|
|
@@ -400,7 +411,7 @@ class JSONTransform extends Visitor {
|
|
|
400
411
|
addRequiredImports(node: ClassDeclaration): void {
|
|
401
412
|
// if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "bs"))) {
|
|
402
413
|
// if (!this.bsImport) {
|
|
403
|
-
// this.bsImport =
|
|
414
|
+
// this.bsImport = "import { bs } from \"as-bs\"";
|
|
404
415
|
// if (process.env["JSON_DEBUG"]) console.log("Added as-bs import: " + this.bsImport + "\n");
|
|
405
416
|
// }
|
|
406
417
|
// }
|
|
@@ -408,7 +419,7 @@ class JSONTransform extends Visitor {
|
|
|
408
419
|
const __filename = fileURLToPath(import.meta.url);
|
|
409
420
|
const __dirname = path.dirname(__filename);
|
|
410
421
|
|
|
411
|
-
let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../modules/bs/
|
|
422
|
+
let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../modules/as-bs/"));
|
|
412
423
|
|
|
413
424
|
if (!relativePath.startsWith(".") && !relativePath.startsWith("/")) relativePath = "./" + relativePath;
|
|
414
425
|
// if (!existsSync(relativePath)) {
|
|
@@ -416,9 +427,9 @@ class JSONTransform extends Visitor {
|
|
|
416
427
|
// }
|
|
417
428
|
|
|
418
429
|
const txt = `import { bs } from "${relativePath}";`;
|
|
419
|
-
if (!this.
|
|
420
|
-
this.
|
|
421
|
-
if (process.env["JSON_DEBUG"]) console.log("Added bs import: " + txt + "\n");
|
|
430
|
+
if (!this.bsImport) {
|
|
431
|
+
this.bsImport = txt;
|
|
432
|
+
if (process.env["JSON_DEBUG"]) console.log("Added as-bs import: " + txt + "\n");
|
|
422
433
|
}
|
|
423
434
|
}
|
|
424
435
|
|
|
@@ -441,7 +452,7 @@ class JSONTransform extends Visitor {
|
|
|
441
452
|
}
|
|
442
453
|
}
|
|
443
454
|
|
|
444
|
-
getStores(data: string, simd: boolean =
|
|
455
|
+
getStores(data: string, simd: boolean = false): string[] {
|
|
445
456
|
const out: string[] = [];
|
|
446
457
|
const sizes = strToNum(data, simd);
|
|
447
458
|
let offset = 0;
|
package/transform/src/types.ts
CHANGED
package/modules/bs/index.ts
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
|
|
2
|
-
|
|
3
|
-
let maxOffset: usize = __new(0, idof<ArrayBuffer>());
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Central buffer namespace for managing memory operations.
|
|
7
|
-
*/
|
|
8
|
-
export namespace bs {
|
|
9
|
-
/** Current buffer pointer. */
|
|
10
|
-
export let buffer: usize = maxOffset;
|
|
11
|
-
|
|
12
|
-
/** Current offset within the buffer. */
|
|
13
|
-
export let offset: usize = maxOffset;
|
|
14
|
-
|
|
15
|
-
/** Byte length of the buffer. */
|
|
16
|
-
export let byteLength: usize = 0;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Sets the buffer to a given data object and initializes related properties.
|
|
20
|
-
* @param data - The data object to set as the buffer.
|
|
21
|
-
*/
|
|
22
|
-
// @ts-ignore: Decorator valid here
|
|
23
|
-
@inline export function setBuffer<T>(data: T, byteLength: usize = bytes(data)): void {
|
|
24
|
-
buffer = changetype<usize>(data);
|
|
25
|
-
offset = changetype<usize>(data);
|
|
26
|
-
byteLength = byteLength;
|
|
27
|
-
maxOffset = byteLength + buffer;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Ensures the buffer has sufficient capacity for a given size.
|
|
32
|
-
* If necessary, reallocates the buffer to accommodate the new size.
|
|
33
|
-
* @param size - The size to ensure capacity for.
|
|
34
|
-
*/
|
|
35
|
-
// @ts-ignore: Decorator valid here
|
|
36
|
-
@inline export function ensureCapacity(size: u32): void {
|
|
37
|
-
const newSize = offset + size;
|
|
38
|
-
if (newSize > maxOffset) {
|
|
39
|
-
const newPtr = __renew(buffer, (byteLength = nextPowerOf2(newSize - buffer)));
|
|
40
|
-
offset = offset - buffer + newPtr;
|
|
41
|
-
maxOffset = newPtr + byteLength;
|
|
42
|
-
buffer = newPtr;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Ensures the buffer size is sufficient for a given size.
|
|
48
|
-
* If necessary, reallocates the buffer to the exact new size.
|
|
49
|
-
* @param size - The size to ensure.
|
|
50
|
-
*/
|
|
51
|
-
// @ts-ignore: Decorator valid here
|
|
52
|
-
@inline export function ensureSize(size: u32): void {
|
|
53
|
-
const newSize = offset + size;
|
|
54
|
-
if (newSize > maxOffset) {
|
|
55
|
-
const newPtr = __renew(buffer, (byteLength = newSize - buffer));
|
|
56
|
-
offset = offset - buffer + newPtr;
|
|
57
|
-
maxOffset = newPtr + byteLength;
|
|
58
|
-
buffer = newPtr;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Resizes the buffer to the specified size.
|
|
64
|
-
* @param newSize - The new buffer size.
|
|
65
|
-
*/
|
|
66
|
-
// @ts-ignore: Decorator valid here
|
|
67
|
-
@inline export function resize(newSize: u32): void {
|
|
68
|
-
const newPtr = __renew(buffer, newSize);
|
|
69
|
-
byteLength = newSize;
|
|
70
|
-
buffer = newPtr;
|
|
71
|
-
offset = buffer + newSize;
|
|
72
|
-
maxOffset = buffer + byteLength;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Gets the remaining space available in the buffer.
|
|
77
|
-
* @returns The number of bytes remaining.
|
|
78
|
-
*/
|
|
79
|
-
// @ts-ignore: Decorator valid here
|
|
80
|
-
@inline export function getRemainingSize(): usize {
|
|
81
|
-
return maxOffset - offset;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Clears data from a specified offset onward.
|
|
86
|
-
* @param fromOffset - The starting offset to clear from.
|
|
87
|
-
*/
|
|
88
|
-
// @ts-ignore: Decorator valid here
|
|
89
|
-
@inline export function clearFromOffset(fromOffset: usize): void {
|
|
90
|
-
if (fromOffset < offset) {
|
|
91
|
-
memory.fill(fromOffset, 0, offset - fromOffset);
|
|
92
|
-
offset = fromOffset;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Shrinks the buffer to fit the current offset.
|
|
98
|
-
*/
|
|
99
|
-
// @ts-ignore: Decorator valid here
|
|
100
|
-
@inline export function shrink(): void {
|
|
101
|
-
if (offset > maxOffset) {
|
|
102
|
-
byteLength = offset - buffer;
|
|
103
|
-
buffer = __renew(buffer, byteLength);
|
|
104
|
-
maxOffset = byteLength + buffer;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Shrinks the buffer and resets the offset, returning the buffer as a specified type.
|
|
110
|
-
* @returns The buffer cast to the specified type.
|
|
111
|
-
*/
|
|
112
|
-
// @ts-ignore: Decorator valid here
|
|
113
|
-
@inline export function shrinkTo<T>(): T {
|
|
114
|
-
shrink();
|
|
115
|
-
offset = buffer;
|
|
116
|
-
return changetype<T>(buffer);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Copies the buffer's content to a new object of a specified type.
|
|
121
|
-
* Optionally shrinks the buffer after copying.
|
|
122
|
-
* @param s - Whether to shrink the buffer after copying.
|
|
123
|
-
* @returns The new object containing the buffer's content.
|
|
124
|
-
*/
|
|
125
|
-
// @ts-ignore: Decorator valid here
|
|
126
|
-
@inline export function out<T>(s: bool = false): T {
|
|
127
|
-
const len = offset - buffer;
|
|
128
|
-
const _out = __new(len, idof<T>());
|
|
129
|
-
memory.copy(_out, buffer, len);
|
|
130
|
-
if (s) shrink();
|
|
131
|
-
offset = buffer;
|
|
132
|
-
return changetype<T>(_out);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Copies the buffer's content to a given destination pointer.
|
|
137
|
-
* Optionally shrinks the buffer after copying.
|
|
138
|
-
* @param dst - The destination pointer.
|
|
139
|
-
* @param s - Whether to shrink the buffer after copying.
|
|
140
|
-
* @returns The destination pointer cast to the specified type.
|
|
141
|
-
*/
|
|
142
|
-
// @ts-ignore: Decorator valid here
|
|
143
|
-
@inline export function outTo<T>(dst: usize, s: bool = false): T {
|
|
144
|
-
const len = offset - buffer;
|
|
145
|
-
if (len != changetype<OBJECT>(dst - TOTAL_OVERHEAD).rtSize) __renew(len, idof<T>());
|
|
146
|
-
memory.copy(dst, buffer, len);
|
|
147
|
-
if (s) shrink();
|
|
148
|
-
offset = buffer;
|
|
149
|
-
return changetype<T>(dst);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// @ts-ignore: Decorator valid here
|
|
154
|
-
@inline function nextPowerOf2(n: u32): u32 {
|
|
155
|
-
return 1 << (32 - clz(n - 1));
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// @ts-ignore: Decorator valid here
|
|
159
|
-
@inline function bytes<T>(o: T): i32 {
|
|
160
|
-
if (isInteger<T>() || isFloat<T>()) {
|
|
161
|
-
return sizeof<T>();
|
|
162
|
-
} else if (isManaged<T>() || isReference<T>()) {
|
|
163
|
-
return changetype<OBJECT>(changetype<usize>(o) - TOTAL_OVERHEAD).rtSize;
|
|
164
|
-
} else {
|
|
165
|
-
ERROR("Cannot convert type " + nameof<T>() + " to bytes!");
|
|
166
|
-
}
|
|
167
|
-
}
|
package/modules/tsconfig.json
DELETED
|
@@ -1,404 +0,0 @@
|
|
|
1
|
-
import { FieldDeclaration, IdentifierExpression, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression } from "assemblyscript/dist/assemblyscript.js";
|
|
2
|
-
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
3
|
-
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
4
|
-
import { Transform } from "assemblyscript/dist/transform.js";
|
|
5
|
-
class JSONTransform extends BaseVisitor {
|
|
6
|
-
schemasList = [];
|
|
7
|
-
currentClass;
|
|
8
|
-
sources = new Set();
|
|
9
|
-
visitMethodDeclaration() {}
|
|
10
|
-
visitClassDeclaration(node) {
|
|
11
|
-
if (!node.decorators?.length) return;
|
|
12
|
-
let found = false;
|
|
13
|
-
for (const decorator of node.decorators) {
|
|
14
|
-
const name = decorator.name.text;
|
|
15
|
-
if (name === "json" || name === "serializable") {
|
|
16
|
-
found = true;
|
|
17
|
-
break;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
if (!found) return;
|
|
21
|
-
const schema = new SchemaData();
|
|
22
|
-
schema.node = node;
|
|
23
|
-
schema.name = node.name.text;
|
|
24
|
-
const members = [...node.members.filter((v) => v.kind === 54)];
|
|
25
|
-
if (node.extendsType) {
|
|
26
|
-
schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text);
|
|
27
|
-
if (schema.parent?.members) {
|
|
28
|
-
for (let i = schema.parent.members.length - 1; i >= 0; i--) {
|
|
29
|
-
const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
|
|
30
|
-
if (!replace) {
|
|
31
|
-
members.unshift(schema.parent?.members[i].node);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
if (!members.length) {
|
|
37
|
-
let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}';
|
|
38
|
-
let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
|
|
39
|
-
let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
|
|
40
|
-
if (process.env["JSON_DEBUG"]) {
|
|
41
|
-
console.log(SERIALIZE_RAW_EMPTY);
|
|
42
|
-
console.log(INITIALIZE_EMPTY);
|
|
43
|
-
console.log(DESERIALIZE_EMPTY);
|
|
44
|
-
}
|
|
45
|
-
const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
|
|
46
|
-
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
|
|
47
|
-
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
|
|
48
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
|
|
49
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
50
|
-
if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD_EMPTY);
|
|
51
|
-
this.schemasList.push(schema);
|
|
52
|
-
}
|
|
53
|
-
for (const member of members) {
|
|
54
|
-
const name = member.name;
|
|
55
|
-
if (!(member instanceof FieldDeclaration)) continue;
|
|
56
|
-
if (!member.type) {
|
|
57
|
-
throw new Error("Fields must be strongly typed! Found " + toString(member) + " at " + node.range.source.normalizedPath);
|
|
58
|
-
}
|
|
59
|
-
const type = toString(member.type);
|
|
60
|
-
if (type.startsWith("(") && type.includes("=>")) continue;
|
|
61
|
-
const value = member.initializer ? toString(member.initializer) : null;
|
|
62
|
-
if (member.flags == 32) continue;
|
|
63
|
-
if (member.flags === 512) continue;
|
|
64
|
-
if (member.flags === 1024) continue;
|
|
65
|
-
const mem = new Property();
|
|
66
|
-
mem.name = name.text;
|
|
67
|
-
mem.type = type;
|
|
68
|
-
mem.value = value;
|
|
69
|
-
mem.node = member;
|
|
70
|
-
if (type.includes("JSON.Raw")) {
|
|
71
|
-
mem.flags.set(PropertyFlags.JSON_Raw, []);
|
|
72
|
-
}
|
|
73
|
-
if (member.type.isNullable) {
|
|
74
|
-
mem.flags.set(PropertyFlags.Null, []);
|
|
75
|
-
}
|
|
76
|
-
if (member.decorators) {
|
|
77
|
-
for (const decorator of member.decorators) {
|
|
78
|
-
const decoratorName = decorator.name.text;
|
|
79
|
-
const args = getArgs(decorator.args);
|
|
80
|
-
switch (decoratorName) {
|
|
81
|
-
case "alias": {
|
|
82
|
-
if (!args.length) throw new Error("Expected 1 argument but got zero at @alias in " + node.range.source.normalizedPath);
|
|
83
|
-
mem.alias = args[0];
|
|
84
|
-
mem.flags.set(PropertyFlags.Alias, args);
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
case "omit": {
|
|
88
|
-
mem.flags.set(PropertyFlags.Omit, args);
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
case "omitif": {
|
|
92
|
-
if (!decorator.args?.length) throw new Error("Expected 1 argument but got zero at @omitif in " + node.range.source.normalizedPath);
|
|
93
|
-
mem.flags.set(PropertyFlags.OmitIf, args);
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
case "omitnull": {
|
|
97
|
-
mem.flags.set(PropertyFlags.OmitNull, args);
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
mem.generate(false);
|
|
104
|
-
if (this.schemasList.find((v) => v.name == type)) {
|
|
105
|
-
mem.initialize = "this." + name.text + " = changetype<nonnull<" + mem.type + ">>(__new(offsetof<nonnull<" + mem.type + ">>(), idof<nonnull<" + mem.type + ">>()));\n changetype<nonnull<" + mem.type + ">>(this." + name.text + ").__INITIALIZE()";
|
|
106
|
-
} else if (mem.value) {
|
|
107
|
-
mem.initialize = "this." + name.text + " = " + mem.value;
|
|
108
|
-
} else if (type === "Map") {
|
|
109
|
-
mem.initialize = "this." + name.text + " = new " + mem.type + "()";
|
|
110
|
-
} else if (type === "string") {
|
|
111
|
-
mem.initialize = "this." + name.text + ' = ""';
|
|
112
|
-
} else if (type === "Array") {
|
|
113
|
-
mem.initialize = "this." + name.text + " = instantiate<" + mem.type + ">()";
|
|
114
|
-
} else if (type === "bool" || type === "boolean") {
|
|
115
|
-
mem.initialize = "this." + name.text + " = false";
|
|
116
|
-
} else if (type === "JSON.Raw") {
|
|
117
|
-
mem.initialize = "this." + name.text + ' = ""';
|
|
118
|
-
} else if (type === "u8" || type === "u16" || type === "u32" || type === "u64" || type === "i8" || type === "i16" || type === "i32" || type === "i64") {
|
|
119
|
-
mem.initialize = "this." + name.text + " = 0";
|
|
120
|
-
} else if (type === "f32" || type === "f64") {
|
|
121
|
-
mem.initialize = "this." + name.text + " = 0.0";
|
|
122
|
-
}
|
|
123
|
-
schema.members.push(mem);
|
|
124
|
-
}
|
|
125
|
-
let SERIALIZE_RAW = "__SERIALIZE(): string {\n let out = `{";
|
|
126
|
-
let SERIALIZE_PRETTY = "__SERIALIZE_PRETTY(): string {\n let out = `{";
|
|
127
|
-
let INITIALIZE = "__INITIALIZE(): this {\n";
|
|
128
|
-
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";
|
|
129
|
-
let indent = " ";
|
|
130
|
-
if (!schema.members.length) return;
|
|
131
|
-
found = false;
|
|
132
|
-
if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) || schema.members[0]?.flags.has(PropertyFlags.OmitIf)) {
|
|
133
|
-
SERIALIZE_RAW += schema.members[0]?.serialize;
|
|
134
|
-
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
|
|
135
|
-
} else {
|
|
136
|
-
SERIALIZE_RAW += schema.members[0]?.serialize + ",";
|
|
137
|
-
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n";
|
|
138
|
-
found = true;
|
|
139
|
-
}
|
|
140
|
-
if (schema.members[0]?.initialize) INITIALIZE += " " + schema.members[0]?.initialize + ";\n";
|
|
141
|
-
for (let i = 1; i < schema.members.length; i++) {
|
|
142
|
-
const member = schema.members[i];
|
|
143
|
-
if (member.initialize) INITIALIZE += " " + member.initialize + ";\n";
|
|
144
|
-
if (member.flags.has(PropertyFlags.OmitNull) || member.flags.has(PropertyFlags.OmitIf)) {
|
|
145
|
-
SERIALIZE_RAW += member.serialize;
|
|
146
|
-
SERIALIZE_PRETTY += member.serialize;
|
|
147
|
-
} else {
|
|
148
|
-
SERIALIZE_RAW += member.serialize + ",";
|
|
149
|
-
SERIALIZE_PRETTY += indent + member.serialize + ",\\n";
|
|
150
|
-
found = true;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
if (found) {
|
|
154
|
-
SERIALIZE_RAW += "`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
|
|
155
|
-
SERIALIZE_PRETTY += "`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
|
|
156
|
-
} else {
|
|
157
|
-
SERIALIZE_RAW += "}`;\n return out;\n}";
|
|
158
|
-
SERIALIZE_PRETTY += "}`;\n return out;\n}";
|
|
159
|
-
}
|
|
160
|
-
INITIALIZE += " return this;\n}";
|
|
161
|
-
const sortedMembers = [];
|
|
162
|
-
const _sorted = schema.members.sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length));
|
|
163
|
-
let len = -1;
|
|
164
|
-
let offset = -1;
|
|
165
|
-
for (let i = 0; i < _sorted.length; i++) {
|
|
166
|
-
const member = _sorted[i];
|
|
167
|
-
const _name = member.alias || member.name;
|
|
168
|
-
if (_name.length === len) {
|
|
169
|
-
sortedMembers[offset]?.push(member);
|
|
170
|
-
} else {
|
|
171
|
-
sortedMembers.push([member]);
|
|
172
|
-
len = _name.length;
|
|
173
|
-
offset++;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
let first = true;
|
|
177
|
-
for (const memberSet of sortedMembers) {
|
|
178
|
-
const firstMember = memberSet[0];
|
|
179
|
-
const _name = encodeKey(firstMember.alias || firstMember.name);
|
|
180
|
-
if (_name.length === 1) {
|
|
181
|
-
if (first) {
|
|
182
|
-
DESERIALIZE += " if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
183
|
-
first = false;
|
|
184
|
-
} else {
|
|
185
|
-
DESERIALIZE += "else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
186
|
-
}
|
|
187
|
-
} else if (_name.length === 2) {
|
|
188
|
-
if (first) {
|
|
189
|
-
DESERIALIZE += " if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
190
|
-
first = false;
|
|
191
|
-
} else {
|
|
192
|
-
DESERIALIZE += "else if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
|
|
193
|
-
}
|
|
194
|
-
} else if (_name.length === 4) {
|
|
195
|
-
if (first) {
|
|
196
|
-
DESERIALIZE += " if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
|
|
197
|
-
first = false;
|
|
198
|
-
} else {
|
|
199
|
-
DESERIALIZE += "else if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
|
|
200
|
-
}
|
|
201
|
-
} else {
|
|
202
|
-
if (first) {
|
|
203
|
-
DESERIALIZE += " if (" + _name.length + " === len) {\n";
|
|
204
|
-
first = false;
|
|
205
|
-
} else {
|
|
206
|
-
DESERIALIZE += "else if (" + _name.length + " === len) {\n";
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
let f = true;
|
|
210
|
-
for (let i = 0; i < memberSet.length; i++) {
|
|
211
|
-
const member = memberSet[i];
|
|
212
|
-
if (!member.deserialize) continue;
|
|
213
|
-
const _name = encodeKey(member.alias || member.name);
|
|
214
|
-
if (_name.length === 1) {
|
|
215
|
-
DESERIALIZE += ` case ${_name.charCodeAt(0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
|
|
216
|
-
} else if (_name.length === 2) {
|
|
217
|
-
DESERIALIZE += ` case ${charCodeAt32(_name, 0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
|
|
218
|
-
} else if (_name.length === 4) {
|
|
219
|
-
if (f) {
|
|
220
|
-
f = false;
|
|
221
|
-
DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
|
|
222
|
-
} else {
|
|
223
|
-
DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
|
|
224
|
-
}
|
|
225
|
-
} else {
|
|
226
|
-
if (f) {
|
|
227
|
-
f = false;
|
|
228
|
-
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`;
|
|
229
|
-
} else {
|
|
230
|
-
DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` 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`;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
if (_name.length < 3) {
|
|
235
|
-
DESERIALIZE += ` default: {\n return false;\n }\n }\n`;
|
|
236
|
-
} else if (_name.length == 4) {
|
|
237
|
-
DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
|
|
238
|
-
} else {
|
|
239
|
-
DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
|
|
240
|
-
}
|
|
241
|
-
DESERIALIZE += " } ";
|
|
242
|
-
}
|
|
243
|
-
DESERIALIZE += "\n return false;\n}";
|
|
244
|
-
if (process.env["JSON_DEBUG"]) {
|
|
245
|
-
console.log(SERIALIZE_RAW);
|
|
246
|
-
console.log(INITIALIZE);
|
|
247
|
-
console.log(DESERIALIZE);
|
|
248
|
-
}
|
|
249
|
-
const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node);
|
|
250
|
-
const DESERIALIZE_SAFE = DESERIALIZE.replaceAll("__DESERIALIZE", "__DESERIALIZE_SAFE");
|
|
251
|
-
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
252
|
-
const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
|
|
253
|
-
const DESERIALIZE_SAFE_METHOD = SimpleParser.parseClassMember(DESERIALIZE_SAFE, node);
|
|
254
|
-
if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_METHOD);
|
|
255
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD);
|
|
256
|
-
if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD);
|
|
257
|
-
if (!node.members.find((v) => v.name.text == "__DESERIALIZE_SAFE")) node.members.push(DESERIALIZE_SAFE_METHOD);
|
|
258
|
-
this.schemasList.push(schema);
|
|
259
|
-
}
|
|
260
|
-
visitSource(node) {
|
|
261
|
-
super.visitSource(node);
|
|
262
|
-
if (!this.sources.has(node)) {
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
export default class Transformer extends Transform {
|
|
268
|
-
afterParse(parser) {
|
|
269
|
-
const transformer = new JSONTransform();
|
|
270
|
-
const sources = parser.sources
|
|
271
|
-
.filter((source) => !isStdlib(source))
|
|
272
|
-
.sort((_a, _b) => {
|
|
273
|
-
const a = _a.internalPath;
|
|
274
|
-
const b = _b.internalPath;
|
|
275
|
-
if (a[0] === "~" && b[0] !== "~") {
|
|
276
|
-
return -1;
|
|
277
|
-
} else if (a[0] !== "~" && b[0] === "~") {
|
|
278
|
-
return 1;
|
|
279
|
-
} else {
|
|
280
|
-
return 0;
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
for (const source of sources) {
|
|
284
|
-
if (!isStdlib(source)) {
|
|
285
|
-
transformer.visit(source);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
const schemas = transformer.schemasList;
|
|
289
|
-
for (const schema of schemas) {
|
|
290
|
-
if (schema.parent) {
|
|
291
|
-
const parent = schemas.find((v) => v.name === schema.parent?.name);
|
|
292
|
-
if (!parent) 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.`);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
var PropertyFlags;
|
|
298
|
-
(function (PropertyFlags) {
|
|
299
|
-
PropertyFlags[(PropertyFlags["Null"] = 0)] = "Null";
|
|
300
|
-
PropertyFlags[(PropertyFlags["Omit"] = 1)] = "Omit";
|
|
301
|
-
PropertyFlags[(PropertyFlags["OmitNull"] = 2)] = "OmitNull";
|
|
302
|
-
PropertyFlags[(PropertyFlags["OmitIf"] = 3)] = "OmitIf";
|
|
303
|
-
PropertyFlags[(PropertyFlags["Alias"] = 4)] = "Alias";
|
|
304
|
-
PropertyFlags[(PropertyFlags["JSON_Raw"] = 5)] = "JSON_Raw";
|
|
305
|
-
})(PropertyFlags || (PropertyFlags = {}));
|
|
306
|
-
class Property {
|
|
307
|
-
name = "";
|
|
308
|
-
alias = null;
|
|
309
|
-
type = "";
|
|
310
|
-
value = null;
|
|
311
|
-
flags = new Map();
|
|
312
|
-
serialize = null;
|
|
313
|
-
deserialize = null;
|
|
314
|
-
initialize = null;
|
|
315
|
-
node;
|
|
316
|
-
right_s = "";
|
|
317
|
-
right_d = "";
|
|
318
|
-
generate(safe) {
|
|
319
|
-
const name = this.name;
|
|
320
|
-
const escapedName = escapeString(JSON.stringify(this.alias || this.name));
|
|
321
|
-
const type = this.type;
|
|
322
|
-
if (this.flags.has(PropertyFlags.Omit)) return;
|
|
323
|
-
if (this.flags.has(PropertyFlags.JSON_Raw)) {
|
|
324
|
-
if (this.flags.has(PropertyFlags.Null)) {
|
|
325
|
-
this.right_s = "(this." + name + ' || "null")';
|
|
326
|
-
this.right_d = "value_start === value_end - 4 && 30399761348886638 === load<u64>(changetype<usize>(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)";
|
|
327
|
-
} else {
|
|
328
|
-
this.right_s = "this." + name;
|
|
329
|
-
this.right_d = "data.substring(value_start, value_end);";
|
|
330
|
-
}
|
|
331
|
-
} else {
|
|
332
|
-
this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")";
|
|
333
|
-
this.right_d = (safe ? "__DESERIALIZE_SAFE" : "__DESERIALIZE") + "<" + type + ">(data.substring(value_start, value_end))";
|
|
334
|
-
}
|
|
335
|
-
if (this.flags.has(PropertyFlags.OmitIf)) {
|
|
336
|
-
const condition = this.flags.get(PropertyFlags.OmitIf)[0];
|
|
337
|
-
if (!condition) throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition");
|
|
338
|
-
this.serialize = "${" + condition + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}';
|
|
339
|
-
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
340
|
-
} else if (this.flags.has(PropertyFlags.OmitNull)) {
|
|
341
|
-
this.serialize = "${changetype<usize>(this." + name + ") == <usize>0" + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}';
|
|
342
|
-
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
343
|
-
} else {
|
|
344
|
-
this.serialize = escapedName + ":${" + this.right_s + "}";
|
|
345
|
-
this.deserialize = "this." + name + " = " + this.right_d + ";";
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
class SchemaData {
|
|
350
|
-
name = "";
|
|
351
|
-
members = [];
|
|
352
|
-
parent = null;
|
|
353
|
-
node;
|
|
354
|
-
}
|
|
355
|
-
function charCodeAt32(data, offset) {
|
|
356
|
-
return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset);
|
|
357
|
-
}
|
|
358
|
-
function charCodeAt64(data, offset) {
|
|
359
|
-
if (offset + 3 >= data.length) {
|
|
360
|
-
throw new Error("The string must have at least 4 characters from the specified offset.");
|
|
361
|
-
}
|
|
362
|
-
const firstCharCode = BigInt(data.charCodeAt(offset));
|
|
363
|
-
const secondCharCode = BigInt(data.charCodeAt(offset + 1));
|
|
364
|
-
const thirdCharCode = BigInt(data.charCodeAt(offset + 2));
|
|
365
|
-
const fourthCharCode = BigInt(data.charCodeAt(offset + 3));
|
|
366
|
-
const u64Value = (fourthCharCode << 48n) | (thirdCharCode << 32n) | (secondCharCode << 16n) | firstCharCode;
|
|
367
|
-
return u64Value;
|
|
368
|
-
}
|
|
369
|
-
function encodeKey(key) {
|
|
370
|
-
const data = JSON.stringify(key);
|
|
371
|
-
return data.slice(1, data.length - 1);
|
|
372
|
-
}
|
|
373
|
-
function escapeString(data) {
|
|
374
|
-
return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`");
|
|
375
|
-
}
|
|
376
|
-
function escapeSlash(data) {
|
|
377
|
-
return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`");
|
|
378
|
-
}
|
|
379
|
-
function escapeQuote(data) {
|
|
380
|
-
return data.replace(/\"/g, '\\"');
|
|
381
|
-
}
|
|
382
|
-
function getArgs(args) {
|
|
383
|
-
if (!args) return [];
|
|
384
|
-
let out = [];
|
|
385
|
-
for (const arg of args) {
|
|
386
|
-
if (arg instanceof StringLiteralExpression) {
|
|
387
|
-
out.push(arg.value);
|
|
388
|
-
} else if (arg instanceof IntegerLiteralExpression) {
|
|
389
|
-
out.push(i64_to_string(arg.value));
|
|
390
|
-
} else if (arg instanceof FloatLiteralExpression) {
|
|
391
|
-
out.push(arg.value.toString());
|
|
392
|
-
} else if (arg instanceof NullExpression) {
|
|
393
|
-
out.push(arg.text);
|
|
394
|
-
} else if (arg instanceof TrueExpression) {
|
|
395
|
-
out.push(arg.text);
|
|
396
|
-
} else if (arg instanceof FalseExpression) {
|
|
397
|
-
out.push(arg.text);
|
|
398
|
-
} else if (arg instanceof IdentifierExpression) {
|
|
399
|
-
out.push(arg.text);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
return out;
|
|
403
|
-
}
|
|
404
|
-
//# sourceMappingURL=index.old.js.map
|