json-as 0.5.32 → 0.5.34
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/asconfig.json +5 -2
- package/assembly/__benches__/as-json.ts +11 -7
- package/assembly/test.ts +33 -50
- package/package.json +1 -1
- package/transform/lib/hash.js +74 -0
- package/transform/lib/index.js +31 -38
- package/transform/package.json +4 -2
- package/transform/src/hash.ts +83 -0
- package/transform/src/index.ts +40 -48
package/asconfig.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
2
|
import { backSlashCode, quoteCode } from "../src/chars";
|
|
3
3
|
import { atoi_fast, unsafeCharCodeAt } from "../src/util";
|
|
4
|
+
import { HASH } from "util/hash";
|
|
4
5
|
|
|
5
6
|
@json
|
|
6
7
|
class Vec3 {
|
|
@@ -23,28 +24,28 @@ class Vec3 {
|
|
|
23
24
|
if (inStr === false && char === quoteCode) {
|
|
24
25
|
if (key != null) {
|
|
25
26
|
if (unsafeCharCodeAt(key, 0) == 120) {
|
|
26
|
-
to.x = atoi_fast<i32>(data.
|
|
27
|
+
to.x = atoi_fast<i32>(data.substring(last, pos - 1))
|
|
27
28
|
} else if (unsafeCharCodeAt(key, 0) == 121) {
|
|
28
|
-
to.y = atoi_fast<i32>(data.
|
|
29
|
+
to.y = atoi_fast<i32>(data.substring(last, pos - 1))
|
|
29
30
|
} else if (unsafeCharCodeAt(key, 0) == 122) {
|
|
30
|
-
to.z = atoi_fast<i32>(data.
|
|
31
|
+
to.z = atoi_fast<i32>(data.substring(last, pos - 1))
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
last = ++pos;
|
|
34
35
|
inStr = true;
|
|
35
36
|
} else if (char === quoteCode && unsafeCharCodeAt(data, pos - 1) != backSlashCode) {
|
|
36
37
|
inStr = false;
|
|
37
|
-
key = data.
|
|
38
|
+
key = data.substring(last, pos);
|
|
38
39
|
last = pos += 2;
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
if (key != null) {
|
|
42
43
|
if (unsafeCharCodeAt(key, 0) == 120) {
|
|
43
|
-
to.x = atoi_fast<i32>(data.
|
|
44
|
+
to.x = atoi_fast<i32>(data.substring(last, pos - 1))
|
|
44
45
|
} else if (unsafeCharCodeAt(key, 0) == 121) {
|
|
45
|
-
to.y = atoi_fast<i32>(data.
|
|
46
|
+
to.y = atoi_fast<i32>(data.substring(last, pos - 1))
|
|
46
47
|
} else if (unsafeCharCodeAt(key, 0) == 122) {
|
|
47
|
-
to.z = atoi_fast<i32>(data.
|
|
48
|
+
to.z = atoi_fast<i32>(data.substring(last, pos - 1))
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
return to;
|
|
@@ -65,6 +66,9 @@ bench("Stringify Object (Vec3)", () => {
|
|
|
65
66
|
blackbox<string>(vec.__JSON_Serialize(vec));
|
|
66
67
|
});*/
|
|
67
68
|
|
|
69
|
+
bench("HASH String", () => {
|
|
70
|
+
blackbox<number>(HASH("Hello"));
|
|
71
|
+
})
|
|
68
72
|
// TODO: Make this allocate without crashing
|
|
69
73
|
bench("Parse Object (Vec3)", () => {
|
|
70
74
|
blackbox<Vec3>(vec.__JSON_Deserialize('{"x":0,"y":0,"z":0}', vec));
|
package/assembly/test.ts
CHANGED
|
@@ -2,69 +2,52 @@ import { backSlashCode, quoteCode } from "./src/chars";
|
|
|
2
2
|
import { JSON } from "./src/json";
|
|
3
3
|
import { atoi_fast, unsafeCharCodeAt } from "./src/util";
|
|
4
4
|
|
|
5
|
-
// @json or @serializable work here
|
|
6
5
|
@json
|
|
7
6
|
class Vec3 {
|
|
8
7
|
x!: f32;
|
|
9
8
|
y!: f32;
|
|
10
9
|
z!: f32;
|
|
10
|
+
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
let char = 0;
|
|
21
|
-
let inStr = false;
|
|
22
|
-
let key: string | null = null;
|
|
23
|
-
let pos = 0;
|
|
24
|
-
for (; pos < data.length - 1; pos++) {
|
|
25
|
-
char = unsafeCharCodeAt(data, pos);
|
|
26
|
-
if (inStr === false && char === quoteCode) {
|
|
27
|
-
if (key != null) {
|
|
28
|
-
if (key == "x") {
|
|
29
|
-
to.x = f32.parse(data.slice(last, pos - 1))
|
|
30
|
-
} else if (key == "y") {
|
|
31
|
-
to.y = f32.parse(data.slice(last, pos - 1))
|
|
32
|
-
} else if (key == "z") {
|
|
33
|
-
to.z = f32.parse(data.slice(last, pos - 1))
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
last = ++pos;
|
|
37
|
-
inStr = true;
|
|
38
|
-
} else if (char === quoteCode && unsafeCharCodeAt(data, pos - 1) != backSlashCode) {
|
|
39
|
-
inStr = false;
|
|
40
|
-
key = data.slice(last, pos);
|
|
41
|
-
last = pos += 2;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (key != null) {
|
|
45
|
-
if (key == "x") {
|
|
46
|
-
to.x = f32.parse(data.slice(last, pos - 1))
|
|
47
|
-
} else if (key == "y") {
|
|
48
|
-
to.y = f32.parse(data.slice(last, pos - 1))
|
|
49
|
-
} else if (key == "z") {
|
|
50
|
-
to.z = f32.parse(data.slice(last, pos - 1))
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return to;
|
|
54
|
-
}
|
|
12
|
+
@json
|
|
13
|
+
class Player {
|
|
14
|
+
firstName!: string;
|
|
15
|
+
lastName!: string;
|
|
16
|
+
lastActive!: i32[];
|
|
17
|
+
age!: i32;
|
|
18
|
+
pos!: Vec3 | null;
|
|
19
|
+
isVerified!: boolean;
|
|
55
20
|
}
|
|
56
21
|
|
|
22
|
+
const player: Player = {
|
|
23
|
+
firstName: "Emmet",
|
|
24
|
+
lastName: "West",
|
|
25
|
+
lastActive: [8, 27, 2022],
|
|
26
|
+
age: 23,
|
|
27
|
+
pos: {
|
|
28
|
+
x: 3.4,
|
|
29
|
+
y: 1.2,
|
|
30
|
+
z: 8.3
|
|
31
|
+
},
|
|
32
|
+
isVerified: true
|
|
33
|
+
};
|
|
34
|
+
|
|
57
35
|
const vec: Vec3 = {
|
|
58
|
-
x: 3
|
|
59
|
-
y: 1
|
|
60
|
-
z: 8
|
|
36
|
+
x: 3,
|
|
37
|
+
y: 1,
|
|
38
|
+
z: 8
|
|
61
39
|
}
|
|
62
40
|
|
|
63
|
-
const
|
|
41
|
+
const serializedPlayer = JSON.stringify<Player>(player);
|
|
42
|
+
console.log(serializedPlayer);
|
|
43
|
+
const parsedPlayer = JSON.parse<Player>(serializedPlayer);
|
|
44
|
+
console.log(JSON.stringify(parsedPlayer));
|
|
45
|
+
|
|
46
|
+
const serializedVec3 = JSON.stringify(vec);
|
|
64
47
|
console.log(serializedVec3);
|
|
65
48
|
|
|
66
|
-
const parsedVec3 =
|
|
67
|
-
console.log(
|
|
49
|
+
const parsedVec3 = JSON.parse<Vec3>(serializedVec3);
|
|
50
|
+
console.log(JSON.stringify(parsedVec3));
|
|
68
51
|
|
|
69
52
|
console.log(`atoi_fast("429496729"): ${atoi_fast<i32>("429496729")}`);
|
|
70
53
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// XXHash 32-bit as a starting point, see: https://cyan4973.github.io/xxHash
|
|
2
|
+
// primes
|
|
3
|
+
// @ts-ignore: decorator
|
|
4
|
+
const XXH32_P1 = 2654435761;
|
|
5
|
+
// @ts-ignore: decorator
|
|
6
|
+
const XXH32_P2 = 2246822519;
|
|
7
|
+
// @ts-ignore: decorator
|
|
8
|
+
const XXH32_P3 = 3266489917;
|
|
9
|
+
// @ts-ignore: decorator
|
|
10
|
+
const XXH32_P4 = 668265263;
|
|
11
|
+
// @ts-ignore: decorator
|
|
12
|
+
const XXH32_P5 = 374761393;
|
|
13
|
+
// @ts-ignore: decorator
|
|
14
|
+
const XXH32_SEED = 0;
|
|
15
|
+
function hash32(key, len = 4) {
|
|
16
|
+
let h = XXH32_SEED + XXH32_P5 + len;
|
|
17
|
+
h += key * XXH32_P3;
|
|
18
|
+
h = rotl(h, 17) * XXH32_P4;
|
|
19
|
+
h ^= h >> 15;
|
|
20
|
+
h *= XXH32_P2;
|
|
21
|
+
h ^= h >> 13;
|
|
22
|
+
h *= XXH32_P3;
|
|
23
|
+
h ^= h >> 16;
|
|
24
|
+
return h;
|
|
25
|
+
}
|
|
26
|
+
function rotl(x, r) {
|
|
27
|
+
return (x << r) | (x >>> (32 - r));
|
|
28
|
+
}
|
|
29
|
+
function mix(h, key) {
|
|
30
|
+
return rotl(h + key * XXH32_P2, 13) * XXH32_P1;
|
|
31
|
+
}
|
|
32
|
+
export function hashStr(key) {
|
|
33
|
+
if (key == null)
|
|
34
|
+
return XXH32_SEED;
|
|
35
|
+
let h = key.length;
|
|
36
|
+
let len = h;
|
|
37
|
+
let pos = 0;
|
|
38
|
+
if (len >= 16) {
|
|
39
|
+
let s1 = XXH32_SEED + XXH32_P1 + XXH32_P2;
|
|
40
|
+
let s2 = XXH32_SEED + XXH32_P2;
|
|
41
|
+
let s3 = XXH32_SEED;
|
|
42
|
+
let s4 = XXH32_SEED - XXH32_P1;
|
|
43
|
+
let end = len + pos - 16;
|
|
44
|
+
while (pos <= end) {
|
|
45
|
+
s1 = mix(s1, key.charCodeAt(pos));
|
|
46
|
+
s2 = mix(s2, key.charCodeAt(pos + 1));
|
|
47
|
+
s3 = mix(s3, key.charCodeAt(pos + 2));
|
|
48
|
+
s4 = mix(s4, load(pos, 12));
|
|
49
|
+
pos += 16;
|
|
50
|
+
}
|
|
51
|
+
h += rotl(s1, 1) + rotl(s2, 7) + rotl(s3, 12) + rotl(s4, 18);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
h += XXH32_SEED + XXH32_P5;
|
|
55
|
+
}
|
|
56
|
+
let end = changetype(key) + len - 4;
|
|
57
|
+
while (pos <= end) {
|
|
58
|
+
h += load(pos) * XXH32_P3;
|
|
59
|
+
h = rotl(h, 17) * XXH32_P4;
|
|
60
|
+
pos += 4;
|
|
61
|
+
}
|
|
62
|
+
end = changetype(key) + len;
|
|
63
|
+
while (pos < end) {
|
|
64
|
+
h += load(pos) * XXH32_P5;
|
|
65
|
+
h = rotl(h, 11) * XXH32_P1;
|
|
66
|
+
pos++;
|
|
67
|
+
}
|
|
68
|
+
h ^= h >> 15;
|
|
69
|
+
h *= XXH32_P2;
|
|
70
|
+
h ^= h >> 13;
|
|
71
|
+
h *= XXH32_P3;
|
|
72
|
+
h ^= h >> 16;
|
|
73
|
+
return h;
|
|
74
|
+
}
|
package/transform/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
2
2
|
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
3
3
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
4
4
|
class SchemaData {
|
|
@@ -19,41 +19,6 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
19
19
|
this.sources = [];
|
|
20
20
|
}
|
|
21
21
|
visitMethodDeclaration() { }
|
|
22
|
-
visitFieldDeclaration(node) {
|
|
23
|
-
if (toString(node).startsWith("static"))
|
|
24
|
-
return;
|
|
25
|
-
const lineText = toString(node);
|
|
26
|
-
if (lineText.startsWith("private"))
|
|
27
|
-
return;
|
|
28
|
-
const name = getName(node);
|
|
29
|
-
if (!node.type) {
|
|
30
|
-
throw new Error(`Field ${name} is missing a type declaration`);
|
|
31
|
-
}
|
|
32
|
-
let type = getName(node.type);
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
if (["u8", "i8", "u16", "i16", "u32", "i32", "f32", "u64", "i64", "f64"].includes(type.toLowerCase())) {
|
|
35
|
-
this.currentClass.encodeStmts.push(`"${name}":\${this.${name}.toString()},`);
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
this.currentClass.encodeStmts.push(`"${name}":\${JSON.stringify<${type}>(this.${name})},`);
|
|
39
|
-
}
|
|
40
|
-
this.currentClass.keys.push(name);
|
|
41
|
-
this.currentClass.types.push(type);
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
//this.decodeStmts.push(
|
|
44
|
-
// `${name}: JSON.parseObjectValue<${type}>(values.get("${name}")),\n`
|
|
45
|
-
//);
|
|
46
|
-
// @ts-ignore
|
|
47
|
-
this.currentClass.setDataStmts.push(`if (key == "${name}") {
|
|
48
|
-
this.${name} = JSON.parseObjectValue<${type}>(value);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
`);
|
|
52
|
-
// @ts-ignore
|
|
53
|
-
//this.checkDecodeStmts.push(
|
|
54
|
-
// ' if (!values.has("${name}")) throw new Error("Key "${name}" was not found. Cannot instantiate object.");\n'
|
|
55
|
-
//);
|
|
56
|
-
}
|
|
57
22
|
visitClassDeclaration(node) {
|
|
58
23
|
var _c;
|
|
59
24
|
const className = node.name.text;
|
|
@@ -67,7 +32,7 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
67
32
|
}
|
|
68
33
|
if (!foundDecorator)
|
|
69
34
|
return;
|
|
70
|
-
// Prevent from being triggered twice
|
|
35
|
+
// Prevent from being triggered twice.
|
|
71
36
|
for (const member of node.members) {
|
|
72
37
|
if (member.name.text == "__JSON_Serialize")
|
|
73
38
|
return;
|
|
@@ -94,7 +59,35 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
94
59
|
}
|
|
95
60
|
const parentSchema = this.schemasList.find((v) => v.name == this.currentClass.parent);
|
|
96
61
|
const members = [...node.members, ...(parentSchema ? parentSchema.node.members : [])];
|
|
97
|
-
|
|
62
|
+
for (const mem of members) {
|
|
63
|
+
if (mem.type && mem.type.name && mem.type.name.identifier.text) {
|
|
64
|
+
const member = mem;
|
|
65
|
+
if (toString(member).startsWith("static"))
|
|
66
|
+
return;
|
|
67
|
+
const lineText = toString(member);
|
|
68
|
+
if (lineText.startsWith("private"))
|
|
69
|
+
return;
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
let type = toString(member.type);
|
|
72
|
+
const name = member.name.text;
|
|
73
|
+
this.currentClass.keys.push(name);
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
this.currentClass.types.push(type);
|
|
76
|
+
// @ts-ignore
|
|
77
|
+
if (["u8", "i8", "u16", "i16", "u32", "i32", "f32", "u64", "i64", "f64"].includes(type.toLowerCase())) {
|
|
78
|
+
this.currentClass.encodeStmts.push(`"${name}":\${this.${name}.toString()},`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.currentClass.encodeStmts.push(`"${name}":\${JSON.stringify<${type}>(this.${name})},`);
|
|
82
|
+
}
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
this.currentClass.setDataStmts.push(`if (key == "${name}") {
|
|
85
|
+
this.${name} = JSON.parseObjectValue<${type}>(value);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
98
91
|
let serializeFunc = "";
|
|
99
92
|
if (this.currentClass.encodeStmts.length > 0) {
|
|
100
93
|
const stmt = this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1];
|
package/transform/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@json-as/transform",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.34",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"Rom"
|
|
11
11
|
],
|
|
12
12
|
"license": "MIT",
|
|
13
|
-
"devDependencies": {
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"assemblyscript": "^0.27.1"
|
|
15
|
+
},
|
|
14
16
|
"dependencies": {},
|
|
15
17
|
"repository": {
|
|
16
18
|
"type": "git",
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// XXHash 32-bit as a starting point, see: https://cyan4973.github.io/xxHash
|
|
2
|
+
|
|
3
|
+
// primes
|
|
4
|
+
// @ts-ignore: decorator
|
|
5
|
+
const XXH32_P1: number = 2654435761;
|
|
6
|
+
// @ts-ignore: decorator
|
|
7
|
+
const XXH32_P2: number = 2246822519;
|
|
8
|
+
// @ts-ignore: decorator
|
|
9
|
+
const XXH32_P3: number = 3266489917;
|
|
10
|
+
// @ts-ignore: decorator
|
|
11
|
+
const XXH32_P4: number = 668265263;
|
|
12
|
+
// @ts-ignore: decorator
|
|
13
|
+
const XXH32_P5: number = 374761393;
|
|
14
|
+
// @ts-ignore: decorator
|
|
15
|
+
const XXH32_SEED: number = 0;
|
|
16
|
+
|
|
17
|
+
function hash32(key: number, len: number = 4): number {
|
|
18
|
+
let h: number = XXH32_SEED + XXH32_P5 + len;
|
|
19
|
+
h += key * XXH32_P3;
|
|
20
|
+
h = rotl(h, 17) * XXH32_P4;
|
|
21
|
+
h ^= h >> 15;
|
|
22
|
+
h *= XXH32_P2;
|
|
23
|
+
h ^= h >> 13;
|
|
24
|
+
h *= XXH32_P3;
|
|
25
|
+
h ^= h >> 16;
|
|
26
|
+
return h;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function rotl(x: number, r: number): number {
|
|
30
|
+
return (x << r) | (x >>> (32 - r));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function mix(h: number, key: number): number {
|
|
34
|
+
return rotl(h + key * XXH32_P2, 13) * XXH32_P1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function hashStr(key: string): number {
|
|
38
|
+
if (key == null) return XXH32_SEED;
|
|
39
|
+
|
|
40
|
+
let h: number = key.length;
|
|
41
|
+
let len: number = h;
|
|
42
|
+
let pos = 0;
|
|
43
|
+
|
|
44
|
+
if (len >= 16) {
|
|
45
|
+
let s1 = XXH32_SEED + XXH32_P1 + XXH32_P2;
|
|
46
|
+
let s2 = XXH32_SEED + XXH32_P2;
|
|
47
|
+
let s3 = XXH32_SEED;
|
|
48
|
+
let s4 = XXH32_SEED - XXH32_P1;
|
|
49
|
+
|
|
50
|
+
let end = len + pos - 16;
|
|
51
|
+
while (pos <= end) {
|
|
52
|
+
s1 = mix(s1, key.charCodeAt(pos));
|
|
53
|
+
s2 = mix(s2, key.charCodeAt(pos + 1));
|
|
54
|
+
s3 = mix(s3, key.charCodeAt(pos + 2));
|
|
55
|
+
s4 = mix(s4, load<number>(pos, 12));
|
|
56
|
+
pos += 16;
|
|
57
|
+
}
|
|
58
|
+
h += rotl(s1, 1) + rotl(s2, 7) + rotl(s3, 12) + rotl(s4, 18);
|
|
59
|
+
} else {
|
|
60
|
+
h += XXH32_SEED + XXH32_P5;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let end = changetype<number>(key) + len - 4;
|
|
64
|
+
while (pos <= end) {
|
|
65
|
+
h += load<number>(pos) * XXH32_P3;
|
|
66
|
+
h = rotl(h, 17) * XXH32_P4;
|
|
67
|
+
pos += 4;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
end = changetype<number>(key) + len;
|
|
71
|
+
while (pos < end) {
|
|
72
|
+
h += <number>load<u8>(pos) * XXH32_P5;
|
|
73
|
+
h = rotl(h, 11) * XXH32_P1;
|
|
74
|
+
pos++;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
h ^= h >> 15;
|
|
78
|
+
h *= XXH32_P2;
|
|
79
|
+
h ^= h >> 13;
|
|
80
|
+
h *= XXH32_P3;
|
|
81
|
+
h ^= h >> 16;
|
|
82
|
+
return h;
|
|
83
|
+
}
|
package/transform/src/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
Source,
|
|
5
5
|
Parser
|
|
6
6
|
} from "assemblyscript/dist/assemblyscript";
|
|
7
|
-
import {
|
|
7
|
+
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
8
8
|
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
9
9
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
10
10
|
|
|
@@ -24,48 +24,6 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
24
24
|
public sources: Source[] = [];
|
|
25
25
|
|
|
26
26
|
visitMethodDeclaration(): void { }
|
|
27
|
-
visitFieldDeclaration(node: FieldDeclaration): void {
|
|
28
|
-
if (toString(node).startsWith("static")) return;
|
|
29
|
-
const lineText = toString(node);
|
|
30
|
-
if (lineText.startsWith("private")) return;
|
|
31
|
-
const name = getName(node);
|
|
32
|
-
if (!node.type) {
|
|
33
|
-
throw new Error(`Field ${name} is missing a type declaration`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
let type = getName(node.type);
|
|
37
|
-
// @ts-ignore
|
|
38
|
-
if (["u8", "i8", "u16", "i16", "u32", "i32", "f32", "u64", "i64", "f64"].includes(type.toLowerCase())) {
|
|
39
|
-
this.currentClass.encodeStmts.push(
|
|
40
|
-
`"${name}":\${this.${name}.toString()},`
|
|
41
|
-
);
|
|
42
|
-
} else {
|
|
43
|
-
this.currentClass.encodeStmts.push(
|
|
44
|
-
`"${name}":\${JSON.stringify<${type}>(this.${name})},`
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
this.currentClass.keys.push(name);
|
|
49
|
-
this.currentClass.types.push(type);
|
|
50
|
-
// @ts-ignore
|
|
51
|
-
//this.decodeStmts.push(
|
|
52
|
-
// `${name}: JSON.parseObjectValue<${type}>(values.get("${name}")),\n`
|
|
53
|
-
//);
|
|
54
|
-
|
|
55
|
-
// @ts-ignore
|
|
56
|
-
this.currentClass.setDataStmts.push(
|
|
57
|
-
`if (key == "${name}") {
|
|
58
|
-
this.${name} = JSON.parseObjectValue<${type}>(value);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
`
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
// @ts-ignore
|
|
65
|
-
//this.checkDecodeStmts.push(
|
|
66
|
-
// ' if (!values.has("${name}")) throw new Error("Key "${name}" was not found. Cannot instantiate object.");\n'
|
|
67
|
-
//);
|
|
68
|
-
}
|
|
69
27
|
visitClassDeclaration(node: ClassDeclaration): void {
|
|
70
28
|
const className = node.name.text;
|
|
71
29
|
if (!node.decorators?.length) return;
|
|
@@ -76,7 +34,7 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
76
34
|
}
|
|
77
35
|
if (!foundDecorator) return;
|
|
78
36
|
|
|
79
|
-
// Prevent from being triggered twice
|
|
37
|
+
// Prevent from being triggered twice.
|
|
80
38
|
for (const member of node.members) {
|
|
81
39
|
if (member.name.text == "__JSON_Serialize") return;
|
|
82
40
|
}
|
|
@@ -104,7 +62,41 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
104
62
|
|
|
105
63
|
const parentSchema = this.schemasList.find((v) => v.name == this.currentClass.parent);
|
|
106
64
|
const members = [...node.members, ...(parentSchema ? parentSchema.node.members : [])]
|
|
107
|
-
|
|
65
|
+
|
|
66
|
+
for (const mem of members) {
|
|
67
|
+
if (mem.type && mem.type.name && mem.type.name.identifier.text) {
|
|
68
|
+
const member: FieldDeclaration = mem;
|
|
69
|
+
if (toString(member).startsWith("static")) return;
|
|
70
|
+
const lineText = toString(member);
|
|
71
|
+
if (lineText.startsWith("private")) return;
|
|
72
|
+
|
|
73
|
+
// @ts-ignore
|
|
74
|
+
let type = toString(member.type);
|
|
75
|
+
|
|
76
|
+
const name = member.name.text;
|
|
77
|
+
this.currentClass.keys.push(name);
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
this.currentClass.types.push(type);
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
if (["u8", "i8", "u16", "i16", "u32", "i32", "f32", "u64", "i64", "f64"].includes(type.toLowerCase())) {
|
|
82
|
+
this.currentClass.encodeStmts.push(
|
|
83
|
+
`"${name}":\${this.${name}.toString()},`
|
|
84
|
+
);
|
|
85
|
+
} else {
|
|
86
|
+
this.currentClass.encodeStmts.push(
|
|
87
|
+
`"${name}":\${JSON.stringify<${type}>(this.${name})},`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
// @ts-ignore
|
|
91
|
+
this.currentClass.setDataStmts.push(
|
|
92
|
+
`if (key == "${name}") {
|
|
93
|
+
this.${name} = JSON.parseObjectValue<${type}>(value);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
108
100
|
|
|
109
101
|
let serializeFunc = "";
|
|
110
102
|
|
|
@@ -138,7 +130,7 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
138
130
|
}
|
|
139
131
|
}
|
|
140
132
|
`
|
|
141
|
-
|
|
133
|
+
|
|
142
134
|
const serializeMethod = SimpleParser.parseClassMember(serializeFunc, node);
|
|
143
135
|
node.members.push(serializeMethod);
|
|
144
136
|
|
|
@@ -160,7 +152,7 @@ export default class Transformer extends Transform {
|
|
|
160
152
|
afterParse(parser: Parser): void {
|
|
161
153
|
// Create new transform
|
|
162
154
|
const transformer = new AsJSONTransform();
|
|
163
|
-
|
|
155
|
+
|
|
164
156
|
// Sort the sources so that user scripts are visited last
|
|
165
157
|
const sources = parser.sources.filter(source => !isStdlib(source)).sort((_a, _b) => {
|
|
166
158
|
const a = _a.internalPath
|
|
@@ -173,7 +165,7 @@ export default class Transformer extends Transform {
|
|
|
173
165
|
return 0;
|
|
174
166
|
}
|
|
175
167
|
})
|
|
176
|
-
|
|
168
|
+
|
|
177
169
|
// Loop over every source
|
|
178
170
|
for (const source of sources) {
|
|
179
171
|
// Ignore all lib and std. Visit everything else.
|