json-as 0.9.8-a → 0.9.8-b

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "0.9.8a",
3
+ "version": "0.9.8b",
4
4
  "description": "JSON encoder/decoder for AssemblyScript",
5
5
  "types": "assembly/index.ts",
6
6
  "author": "Jairus Tanaka",
@@ -17,7 +17,7 @@
17
17
  "scripts": {
18
18
  "test": "wasmtime build/test.spec.wasm",
19
19
  "pretest": "asc assembly/__tests__/test.spec.ts --target test",
20
- "build:test": "JSON_DEBUG=write asc assembly/test.ts --target debug",
20
+ "build:test": "asc assembly/test.ts --target debug",
21
21
  "build:bench": "asc bench/benchmark.ts -o bench/benchmark.wasm --transform ./transform --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub",
22
22
  "bench:wasmtime": "wasmtime ./bench/benchmark.wasm",
23
23
  "bench:wasmer": "wasmer --llvm ./bench/benchmark.wasm",
@@ -31,6 +31,7 @@
31
31
  "devDependencies": {
32
32
  "@assemblyscript/wasi-shim": "^0.1.0",
33
33
  "as-bench": "^0.0.0-alpha",
34
+ "as-console": "^1.0.2",
34
35
  "assemblyscript": "^0.27.28",
35
36
  "assemblyscript-prettier": "^3.0.1",
36
37
  "benchmark": "^2.1.4",
@@ -1,4 +1,4 @@
1
- import { FieldDeclaration, IdentifierExpression, Source, Node, NewExpression, ObjectLiteralExpression, CallExpression, PropertyAccessExpression, AssertionExpression, LiteralExpression, TrueExpression, FalseExpression, Tokenizer } from "assemblyscript/dist/assemblyscript.js";
1
+ import { FieldDeclaration } 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";
@@ -7,185 +7,8 @@ class JSONTransform extends BaseVisitor {
7
7
  super(...arguments);
8
8
  this.schemasList = [];
9
9
  this.sources = new Set();
10
- this.boxRefs = new Map();
11
- this.mustImport = false;
12
- }
13
- visitVariableDeclaration(node) {
14
- let typ = "";
15
- let className = "";
16
- // const tempFoo = foo;
17
- if (node.initializer instanceof IdentifierExpression && this.boxRefs.has(node.initializer.text)) {
18
- this.boxRefs.set(node.name.text, this.boxRefs.get(node.initializer.text));
19
- }
20
- // const foo = new Foo();
21
- else if (node.initializer instanceof NewExpression && this.schemasList.find((v) => v.name == (className = node.initializer.typeName.identifier.text))) {
22
- this.boxRefs.set(node.name.text, className);
23
- }
24
- // const foo: Foo = {};
25
- // const foo = {} as Foo;
26
- // const foo = <Foo>{};
27
- else if (node.initializer instanceof ObjectLiteralExpression && this.schemasList.find((v) => v.name == (className = node.type.name.identifier.text))) {
28
- this.boxRefs.set(node.name.text, className);
29
- const schema = (this.schemasList.find((e) => e.name == node.type.name.identifier.text) || ((this.currentClass.name === className) ? this.currentClass : null));
30
- if (!schema)
31
- return;
32
- for (let i = 0; i < node.initializer.names.length; i++) {
33
- const name = node.initializer.names[i];
34
- const value = node.initializer.values[i];
35
- if (schema.boxRefs.has(name.text)) {
36
- if ((value instanceof LiteralExpression
37
- && (value.literalKind === 1 /* LiteralKind.Integer */
38
- || value.literalKind === 0 /* LiteralKind.Float */))
39
- || value instanceof TrueExpression
40
- || value instanceof FalseExpression) {
41
- this.mustImport = true;
42
- const accessorType = Node.createSimpleTypeName("__JSON", node.range);
43
- accessorType.next = Node.createSimpleTypeName("Box", node.range);
44
- const newTypeGeneric = schema.boxRefs.get(name.text);
45
- const initializer = Node.createNewExpression(accessorType, [
46
- newTypeGeneric
47
- ], [
48
- value
49
- ], node.range);
50
- node.initializer.values[i] = initializer;
51
- }
52
- }
53
- }
54
- }
55
- // const foo = changetype<Foo>(ptr);
56
- else if (node.initializer instanceof CallExpression && this.schemasList.find((v) => node.initializer.typeArguments?.find((e) => (typ = v.name) == e.name.identifier.text))) {
57
- this.boxRefs.set(node.name.text, typ);
58
- }
59
- }
60
- visitBinaryExpression(node) {
61
- if (node.operator == 101 /* Token.Equals */) {
62
- if (node.left.kind == 21 /* NodeKind.PropertyAccess */) {
63
- const left = node.left;
64
- // TODO
65
- if ((this.boxRefs.has(toString(left).split(".")[0]))) {
66
- if ((node.right instanceof LiteralExpression
67
- && (node.right.literalKind === 1 /* LiteralKind.Integer */
68
- || node.right.literalKind === 0 /* LiteralKind.Float */))
69
- || node.right instanceof TrueExpression
70
- || node.right instanceof FalseExpression) {
71
- let schema = null;
72
- let subLeft = left;
73
- while (true) {
74
- if (subLeft instanceof IdentifierExpression) {
75
- const baseType = this.boxRefs.get(subLeft.text);
76
- schema = (this.schemasList.find((e) => e.name === baseType) || (this.currentClass.name === baseType) ? this.currentClass : null);
77
- break;
78
- }
79
- else if (subLeft.expression) {
80
- // @ts-ignore
81
- subLeft = subLeft.expression;
82
- }
83
- else {
84
- break;
85
- }
86
- }
87
- if (!schema)
88
- return;
89
- this.mustImport = true;
90
- const accessorType = Node.createSimpleTypeName("__JSON", node.range);
91
- accessorType.next = Node.createSimpleTypeName("Box", node.range);
92
- const newTypeGeneric = schema.boxRefs.get(left.property.text);
93
- const initializer = Node.createNewExpression(accessorType, [
94
- newTypeGeneric
95
- ], [
96
- node.right
97
- ], node.range);
98
- node.right = initializer;
99
- }
100
- }
101
- }
102
- }
103
10
  }
104
11
  visitMethodDeclaration() { }
105
- visitPropertyAccessExpression(node) {
106
- let subNode = node;
107
- let baseRef = "";
108
- while (true) {
109
- // @ts-ignore
110
- if (subNode.expression instanceof IdentifierExpression) {
111
- // @ts-ignore
112
- if (this.boxRefs.has(subNode.expression.text)) {
113
- //console.log(subNode);
114
- // @ts-ignore
115
- baseRef = subNode.expression.text;
116
- break;
117
- }
118
- else {
119
- break;
120
- }
121
- // @ts-ignore
122
- }
123
- else if (subNode.expression) {
124
- // @ts-ignore
125
- subNode = subNode.expression;
126
- }
127
- else {
128
- break;
129
- }
130
- }
131
- subNode = node;
132
- if (baseRef) {
133
- const baseType = this.boxRefs.get(baseRef);
134
- let properties = [];
135
- let lastNode = subNode;
136
- const schema = (this.schemasList.find((e) => e.name === baseType) || (this.currentClass.name === baseType) ? this.currentClass : null);
137
- while (true) {
138
- if (subNode instanceof AssertionExpression || subNode instanceof PropertyAccessExpression) {
139
- //console.log(subNode);
140
- // @ts-ignore
141
- if (schema?.members.find((e) => e.name === subNode.expression.property?.text)) {
142
- let newExpression = Node.createPropertyAccessExpression(subNode, Node.createIdentifierExpression("value", node.range), node.range);
143
- const _newExpression = newExpression;
144
- for (let i = 0; i < properties.length - 1; i++) {
145
- const prop = properties[i];
146
- newExpression = Node.createPropertyAccessExpression(newExpression, prop, node.range);
147
- }
148
- if (subNode instanceof AssertionExpression) {
149
- // @ts-ignore
150
- subNode = subNode.expression;
151
- }
152
- let t = Node.createPropertyAccessExpression(Node.createParenthesizedExpression(Node.createTernaryExpression(subNode, _newExpression, Node.createNullExpression(node.range), node.range), node.range), properties[0], node.range);
153
- for (let i = 1; i < properties.length; i++) {
154
- const prop = properties[i];
155
- t = Node.createPropertyAccessExpression(t, prop, node.range);
156
- }
157
- node.expression = t.expression;
158
- node.property = t.property;
159
- this.mustImport = true;
160
- break;
161
- }
162
- else {
163
- lastNode = subNode;
164
- // @ts-ignore
165
- subNode = subNode.expression;
166
- // @ts-ignore
167
- if (lastNode.property)
168
- properties.push(lastNode.property);
169
- }
170
- }
171
- else if (subNode instanceof IdentifierExpression) {
172
- break;
173
- // @ts-ignore
174
- }
175
- else if (subNode.expression) {
176
- lastNode = subNode;
177
- // @ts-ignore
178
- subNode = subNode.expression;
179
- // @ts-ignore
180
- if (lastNode.property)
181
- properties.push(lastNode.property);
182
- }
183
- else {
184
- break;
185
- }
186
- }
187
- }
188
- }
189
12
  visitClassDeclaration(node) {
190
13
  if (!node.decorators?.length)
191
14
  return;
@@ -199,36 +22,9 @@ class JSONTransform extends BaseVisitor {
199
22
  }
200
23
  if (!found)
201
24
  return;
202
- this.mustImport = true;
203
25
  const schema = new SchemaData();
204
26
  schema.node = node;
205
27
  schema.name = node.name.text;
206
- this.currentClass = schema;
207
- for (const _member of node.members) {
208
- if (!(_member instanceof FieldDeclaration))
209
- continue;
210
- const member = _member;
211
- if (member.type?.isNullable && isPrimitiveType(member.type?.name.identifier.text)) {
212
- const accessorType = Node.createSimpleTypeName("__JSON", node.range);
213
- accessorType.next = Node.createSimpleTypeName("Box", node.range);
214
- const newTypeGeneric = member.type;
215
- member.type.isNullable = false;
216
- const refType = member.type;
217
- schema.boxRefs.set(member.name.text, refType);
218
- const newType = Node.createNamedType(accessorType, [
219
- newTypeGeneric
220
- ], true, node.range);
221
- member.type = newType;
222
- if (member.initializer) {
223
- const initializer = Node.createNewExpression(accessorType, [
224
- newTypeGeneric
225
- ], [
226
- member.initializer
227
- ], node.range);
228
- member.initializer = initializer;
229
- }
230
- }
231
- }
232
28
  const members = [
233
29
  ...node.members.filter(v => v instanceof FieldDeclaration)
234
30
  ];
@@ -248,9 +44,11 @@ class JSONTransform extends BaseVisitor {
248
44
  //let SERIALIZE_PRETTY_EMPTY = "__SERIALIZE_PRETTY(): string {\n return \"{}\";\n}";
249
45
  let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
250
46
  let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
251
- // @ts-ignore
252
- if (process && process.env["JSON_DEBUG"]) {
253
- console.log("File: " + node.range.source.normalizedPath + "\n" + toString(node) + "\n\n");
47
+ if (process.env["JSON_DEBUG"]) {
48
+ console.log(SERIALIZE_RAW_EMPTY);
49
+ //console.log(SERIALIZE_PRETTY_EMPTY);
50
+ console.log(INITIALIZE_EMPTY);
51
+ console.log(DESERIALIZE_EMPTY);
254
52
  }
255
53
  const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
256
54
  //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
@@ -317,31 +115,31 @@ class JSONTransform extends BaseVisitor {
317
115
  }
318
116
  if (!mem.flags.length) {
319
117
  mem.flags = [PropertyFlags.None];
320
- mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__JSON.stringify<" + type + ">(this." + name.text + ")}";
321
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">(data.substring(value_start, value_end));";
118
+ mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
119
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
322
120
  }
323
121
  if (mem.flags.includes(PropertyFlags.OmitNull)) {
324
- mem.serialize = "${changetype<usize>(this." + mem.name + ") == <usize>0" + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __JSON.stringify<" + type + ">(this." + name.text + ") + \",\"}";
325
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">(data.substring(value_start, value_end));";
122
+ mem.serialize = "${changetype<usize>(this." + mem.name + ") == <usize>0" + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
123
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
326
124
  }
327
125
  else if (mem.flags.includes(PropertyFlags.OmitIf)) {
328
- mem.serialize = "${" + mem.args[0] + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __JSON.stringify<" + type + ">(this." + name.text + ") + \",\"}";
329
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">(data.substring(value_start, value_end));";
126
+ mem.serialize = "${" + mem.args[0] + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
127
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
330
128
  }
331
129
  else if (mem.flags.includes(PropertyFlags.Alias)) {
332
- mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__JSON.stringify<" + type + ">(this." + name.text + ")}";
333
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">(data.substring(value_start, value_end));";
130
+ mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
131
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
334
132
  mem.name = name.text;
335
133
  }
336
134
  else if (mem.flags.includes(PropertyFlags.Flatten)) {
337
135
  const nullable = mem.node.type.isNullable;
338
136
  if (nullable) {
339
137
  mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${this." + name.text + " ? __SERIALIZE(changetype<nonnull<" + type + ">>(this." + name.text + ")" + (mem.args?.length ? '.' + mem.args[0] : '') + ") : \"null\"}";
340
- mem.deserialize = "if (value_end - value_start == 4 && load<u64>(changetype<usize>(data) + <usize>(value_start << 1)) == " + charCodeAt64("null", 0) + ") {\n this." + name.text + " = null;\n } else {\n this." + name.text + " = " + "__JSON.parse<" + type + ">('{\"" + mem.args[0] + "\":' + data.substring(value_start, value_end) + \"}\");\n }";
138
+ mem.deserialize = "if (value_end - value_start == 4 && load<u64>(changetype<usize>(data) + <usize>(value_start << 1)) == " + charCodeAt64("null", 0) + ") {\n this." + name.text + " = null;\n } else {\n this." + name.text + " = " + "__DESERIALIZE<" + type + ">('{\"" + mem.args[0] + "\":' + data.substring(value_start, value_end) + \"}\");\n }";
341
139
  }
342
140
  else {
343
141
  mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${this." + name.text + " ? __SERIALIZE(this." + name.text + (mem.args?.length ? '.' + mem.args[0] : '') + ") : \"null\"}";
344
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">('{\"" + mem.args[0] + "\":' + data.substring(value_start, value_end) + \"}\");";
142
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">('{\"" + mem.args[0] + "\":' + data.substring(value_start, value_end) + \"}\");";
345
143
  }
346
144
  mem.name = name.text;
347
145
  }
@@ -497,9 +295,11 @@ class JSONTransform extends BaseVisitor {
497
295
  }
498
296
  DESERIALIZE += "\n return false;\n}";
499
297
  //console.log(sortedMembers);
500
- // @ts-ignore
501
- if (process && process.env["JSON_DEBUG"]) {
502
- console.log("File: " + node.range.source.internalPath + "\n" + toString(node) + "\n\n");
298
+ if (process.env["JSON_DEBUG"]) {
299
+ console.log(SERIALIZE_RAW);
300
+ //console.log(SERIALIZE_PRETTY);
301
+ console.log(INITIALIZE);
302
+ console.log(DESERIALIZE);
503
303
  }
504
304
  const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node);
505
305
  //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
@@ -547,25 +347,6 @@ export default class Transformer extends Transform {
547
347
  // Ignore all lib and std. Visit everything else.
548
348
  if (!isStdlib(source)) {
549
349
  transformer.visit(source);
550
- if (transformer.mustImport) {
551
- const tokenizer = new Tokenizer(new Source(0 /* SourceKind.User */, source.normalizedPath, "import { JSON as __JSON } from \"json-as/assembly\";"));
552
- parser.currentSource = tokenizer.source;
553
- source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
554
- parser.currentSource = source;
555
- const tokenizer2 = new Tokenizer(new Source(0 /* SourceKind.User */, source.normalizedPath, "import { __atoi_fast } from \"json-as/assembly/util\";"));
556
- parser.currentSource = tokenizer2.source;
557
- source.statements.unshift(parser.parseTopLevelStatement(tokenizer2));
558
- parser.currentSource = source;
559
- transformer.mustImport = false;
560
- // @ts-ignore
561
- if (process && process.env["JSON_DEBUG"]?.toString().toLowerCase() == "all") {
562
- console.log("File: " + source.normalizedPath + "\n" + toString(source) + "\n\n");
563
- }
564
- // @ts-ignore
565
- if (process && process.env["JSON_DEBUG"]?.toString().toLowerCase() == "write") {
566
- this.writeFile(source.internalPath + ".ts", toString(source), process.cwd());
567
- }
568
- }
569
350
  }
570
351
  }
571
352
  // Check that every parent and child class is hooked up correctly
@@ -606,7 +387,6 @@ class SchemaData {
606
387
  this.name = "";
607
388
  this.members = [];
608
389
  this.parent = null;
609
- this.boxRefs = new Map();
610
390
  }
611
391
  }
612
392
  function charCodeAt32(data, offset) {
@@ -638,18 +418,3 @@ function escapeSlash(data) {
638
418
  function escapeQuote(data) {
639
419
  return data.replace(/\"/g, "\\\"");
640
420
  }
641
- function isPrimitiveType(data) {
642
- return data == "u8"
643
- || data == "u16"
644
- || data == "u16"
645
- || data == "u32"
646
- || data == "u64"
647
- || data == "i8"
648
- || data == "i16"
649
- || data == "i32"
650
- || data == "i64"
651
- || data == "f32"
652
- || data == "f64"
653
- || data == "bool"
654
- || data == "boolean";
655
- }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@json-as/transform",
3
- "version": "0.9.8a",
3
+ "version": "0.9.8b",
4
4
  "description": "JSON encoder/decoder for AssemblyScript",
5
5
  "main": "./lib/index.js",
6
6
  "author": "Jairus Tanaka",