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.
@@ -4,266 +4,22 @@ import {
4
4
  IdentifierExpression,
5
5
  NamedTypeNode,
6
6
  StringLiteralExpression,
7
- BinaryExpression,
8
- DecoratorNode,
9
- Token,
10
7
  Parser,
11
- Source,
12
- NodeKind,
13
- Node,
14
- NewExpression,
15
- ObjectLiteralExpression,
16
- CallExpression,
17
- PropertyAccessExpression,
18
- VariableDeclaration,
19
- CommonFlags,
20
- AssertionExpression,
21
- LiteralExpression,
22
- LiteralKind,
23
- TrueExpression,
24
- FalseExpression,
25
- SourceKind,
26
- Tokenizer,
27
- NullExpression
8
+ Source
28
9
  } from "assemblyscript/dist/assemblyscript.js";
29
10
 
30
11
  import { toString, isStdlib } from "visitor-as/dist/utils.js";
31
12
  import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
32
13
  import { Transform } from "assemblyscript/dist/transform.js";
14
+ import { CommonFlags } from "types:assemblyscript/src/common";
15
+ import { DecoratorNode } from "types:assemblyscript/src/ast";
33
16
 
34
17
  class JSONTransform extends BaseVisitor {
35
18
  public schemasList: SchemaData[] = [];
36
19
  public currentClass!: SchemaData;
37
20
  public sources = new Set<Source>();
38
- public boxRefs = new Map<string, string>();
39
- public mustImport: boolean = false;
40
- visitVariableDeclaration(node: VariableDeclaration): void {
41
- let typ: string = "";
42
- let className = "";
43
- // const tempFoo = foo;
44
- if (node.initializer instanceof IdentifierExpression && this.boxRefs.has((<IdentifierExpression>node.initializer).text)) {
45
- this.boxRefs.set(node.name.text, this.boxRefs.get((<IdentifierExpression>node.initializer).text)!);
46
- }
47
- // const foo = new Foo();
48
- else if (node.initializer instanceof NewExpression && this.schemasList.find((v) => v.name == (className = (<NewExpression>node.initializer).typeName.identifier.text))) {
49
- this.boxRefs.set(node.name.text, className);
50
- }
51
- // const foo: Foo = {};
52
- // const foo = {} as Foo;
53
- // const foo = <Foo>{};
54
- else if (node.initializer instanceof ObjectLiteralExpression && this.schemasList.find((v) => v.name == (className = (<NamedTypeNode>node.type).name.identifier.text))) {
55
-
56
- this.boxRefs.set(node.name.text, className);
57
- const schema = (this.schemasList.find((e) => e.name == (<NamedTypeNode>node.type).name.identifier.text) || ((this.currentClass.name === className) ? this.currentClass : null));
58
- if (!schema) return;
59
- for (let i = 0; i < (<ObjectLiteralExpression>node.initializer).names.length; i++) {
60
- const name = (<ObjectLiteralExpression>node.initializer).names[i]!;
61
- const value = (<ObjectLiteralExpression>node.initializer).values[i]!;
62
- if (schema.boxRefs.has(name.text)) {
63
- if (
64
- (
65
- value instanceof LiteralExpression
66
- && (
67
- value.literalKind === LiteralKind.Integer
68
- || value.literalKind === LiteralKind.Float
69
- )
70
- )
71
- || value instanceof TrueExpression
72
- || value instanceof FalseExpression
73
- ) {
74
- this.mustImport = true;
75
- const accessorType = Node.createSimpleTypeName(
76
- "__JSON",
77
- node.range
78
- );
79
- accessorType.next = Node.createSimpleTypeName(
80
- "Box",
81
- node.range
82
- );
83
- const newTypeGeneric = schema.boxRefs.get(name.text)!;
84
- const initializer = Node.createNewExpression(
85
- accessorType,
86
- [
87
- newTypeGeneric
88
- ],
89
- [
90
- value
91
- ],
92
- node.range
93
- );
94
- (<ObjectLiteralExpression>node.initializer).values[i] = initializer;
95
- }
96
- }
97
- }
98
- }
99
- // const foo = changetype<Foo>(ptr);
100
- else if (node.initializer instanceof CallExpression && this.schemasList.find((v) => (<CallExpression>node.initializer).typeArguments?.find((e) => (typ = v.name) == (<NamedTypeNode>e).name.identifier.text))) {
101
- this.boxRefs.set(node.name.text, typ);
102
- }
103
- }
104
- visitBinaryExpression(node: BinaryExpression): void {
105
- if (node.operator == Token.Equals) {
106
- if (node.left.kind == NodeKind.PropertyAccess) {
107
- const left = node.left as PropertyAccessExpression;
108
- // TODO
109
- if ((this.boxRefs.has(toString(left).split(".")[0]!))) {
110
- if (
111
- (
112
- node.right instanceof LiteralExpression
113
- && (
114
- node.right.literalKind === LiteralKind.Integer
115
- || node.right.literalKind === LiteralKind.Float
116
- )
117
- )
118
- || node.right instanceof TrueExpression
119
- || node.right instanceof FalseExpression
120
- ) {
121
- let schema: SchemaData | null = null;
122
- let subLeft = left;
123
- while (true) {
124
- if (subLeft instanceof IdentifierExpression) {
125
- const baseType = this.boxRefs.get(subLeft.text);
126
- schema = (this.schemasList.find((e) => e.name === baseType) || (this.currentClass.name === baseType) ? this.currentClass : null);
127
- break;
128
- } else if (subLeft.expression) {
129
- // @ts-ignore
130
- subLeft = subLeft.expression;
131
- } else {
132
- break;
133
- }
134
- }
135
- if (!schema) return;
136
- this.mustImport = true;
137
- const accessorType = Node.createSimpleTypeName(
138
- "__JSON",
139
- node.range
140
- );
141
- accessorType.next = Node.createSimpleTypeName(
142
- "Box",
143
- node.range
144
- );
145
- const newTypeGeneric = schema.boxRefs.get(left.property.text)!;
146
- const initializer = Node.createNewExpression(
147
- accessorType,
148
- [
149
- newTypeGeneric
150
- ],
151
- [
152
- node.right
153
- ],
154
- node.range
155
- );
156
- node.right = initializer;
157
- }
158
- }
159
- }
160
- }
161
- }
21
+
162
22
  visitMethodDeclaration(): void { }
163
- visitPropertyAccessExpression(node: PropertyAccessExpression): void {
164
- let subNode: AssertionExpression | IdentifierExpression | PropertyAccessExpression = node;
165
- let baseRef = "";
166
- while (true) {
167
- // @ts-ignore
168
- if (subNode.expression instanceof IdentifierExpression) {
169
- // @ts-ignore
170
- if (this.boxRefs.has((<IdentifierExpression>subNode.expression).text)) {
171
- //console.log(subNode);
172
- // @ts-ignore
173
- baseRef = (<IdentifierExpression>subNode.expression).text;
174
- break;
175
- } else {
176
- break;
177
- }
178
- // @ts-ignore
179
- } else if (subNode.expression) {
180
- // @ts-ignore
181
- subNode = subNode.expression;
182
- } else {
183
- break;
184
- }
185
- }
186
- subNode = node;
187
- if (baseRef) {
188
- const baseType = this.boxRefs.get(baseRef);
189
- let properties: IdentifierExpression[] = [];
190
- let lastNode: AssertionExpression | IdentifierExpression | PropertyAccessExpression = subNode;
191
- const schema = (this.schemasList.find((e) => e.name === baseType) || (this.currentClass.name === baseType) ? this.currentClass : null);
192
- while (true) {
193
- if (subNode instanceof AssertionExpression || subNode instanceof PropertyAccessExpression) {
194
- //console.log(subNode);
195
- // @ts-ignore
196
- if (schema?.members.find((e) => e.name === subNode.expression.property?.text)) {
197
- let newExpression = Node.createPropertyAccessExpression(
198
- subNode,
199
- Node.createIdentifierExpression(
200
- "value",
201
- node.range
202
- ),
203
- node.range
204
- );
205
-
206
- const _newExpression = newExpression;
207
-
208
- for (let i = 0; i < properties.length - 1; i++) {
209
- const prop = properties[i]!;
210
- newExpression = Node.createPropertyAccessExpression(
211
- newExpression,
212
- prop,
213
- node.range
214
- );
215
- }
216
- if (subNode instanceof AssertionExpression) {
217
- // @ts-ignore
218
- subNode = subNode.expression;
219
- }
220
- let t = Node.createPropertyAccessExpression(
221
- Node.createParenthesizedExpression(
222
- Node.createTernaryExpression(
223
- subNode,
224
- _newExpression,
225
- Node.createNullExpression(node.range),
226
- node.range
227
- ),
228
- node.range
229
- ),
230
- properties[0]!,
231
- node.range
232
- )
233
- for (let i = 1; i < properties.length; i++) {
234
- const prop = properties[i]!;
235
- t = Node.createPropertyAccessExpression(
236
- t,
237
- prop,
238
- node.range
239
- );
240
- }
241
- node.expression = t.expression;
242
- node.property = t.property;
243
- this.mustImport = true;
244
- break;
245
- } else {
246
- lastNode = subNode;
247
- // @ts-ignore
248
- subNode = subNode.expression;
249
- // @ts-ignore
250
- if (lastNode.property) properties.push(lastNode.property);
251
- }
252
- } else if (subNode instanceof IdentifierExpression) {
253
- break;
254
- // @ts-ignore
255
- } else if (subNode.expression) {
256
- lastNode = subNode;
257
- // @ts-ignore
258
- subNode = subNode.expression;
259
- // @ts-ignore
260
- if (lastNode.property) properties.push(lastNode.property);
261
- } else {
262
- break;
263
- }
264
- }
265
- }
266
- }
267
23
  visitClassDeclaration(node: ClassDeclaration): void {
268
24
  if (!node.decorators?.length) return;
269
25
 
@@ -277,58 +33,10 @@ class JSONTransform extends BaseVisitor {
277
33
  }
278
34
  if (!found) return;
279
35
 
280
- this.mustImport = true;
281
-
282
36
  const schema = new SchemaData();
283
37
  schema.node = node;
284
38
  schema.name = node.name.text;
285
39
 
286
- this.currentClass = schema;
287
-
288
- for (const _member of node.members) {
289
- if (!(_member instanceof FieldDeclaration)) continue;
290
- const member = _member as FieldDeclaration;
291
- if (member.type?.isNullable && isPrimitiveType((<NamedTypeNode>member.type)?.name.identifier.text)) {
292
- const accessorType = Node.createSimpleTypeName(
293
- "__JSON",
294
- node.range
295
- );
296
- accessorType.next = Node.createSimpleTypeName(
297
- "Box",
298
- node.range
299
- );
300
- const newTypeGeneric = member.type as NamedTypeNode;
301
- member.type.isNullable = false;
302
-
303
- const refType = member.type;
304
- schema.boxRefs.set(member.name.text, refType as NamedTypeNode);
305
-
306
- const newType = Node.createNamedType(
307
- accessorType,
308
- [
309
- newTypeGeneric
310
- ],
311
- true,
312
- node.range
313
- );
314
- member.type = newType;
315
-
316
- if (member.initializer) {
317
- const initializer = Node.createNewExpression(
318
- accessorType,
319
- [
320
- newTypeGeneric
321
- ],
322
- [
323
- member.initializer
324
- ],
325
- node.range
326
- )
327
- member.initializer = initializer;
328
- }
329
- }
330
- }
331
-
332
40
  const members = [
333
41
  ...node.members.filter(v => v instanceof FieldDeclaration)
334
42
  ];
@@ -358,9 +66,11 @@ class JSONTransform extends BaseVisitor {
358
66
 
359
67
  let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
360
68
 
361
- // @ts-ignore
362
- if (process && process.env["JSON_DEBUG"]) {
363
- console.log("File: " + node.range.source.normalizedPath + "\n" + toString(node) + "\n\n");
69
+ if (process.env["JSON_DEBUG"]) {
70
+ console.log(SERIALIZE_RAW_EMPTY);
71
+ //console.log(SERIALIZE_PRETTY_EMPTY);
72
+ console.log(INITIALIZE_EMPTY);
73
+ console.log(DESERIALIZE_EMPTY);
364
74
  }
365
75
 
366
76
  const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
@@ -423,28 +133,28 @@ class JSONTransform extends BaseVisitor {
423
133
 
424
134
  if (!mem.flags.length) {
425
135
  mem.flags = [PropertyFlags.None];
426
- mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__JSON.stringify<" + type + ">(this." + name.text + ")}";
427
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">(data.substring(value_start, value_end));"
136
+ mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
137
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));"
428
138
  }
429
139
 
430
140
  if (mem.flags.includes(PropertyFlags.OmitNull)) {
431
- mem.serialize = "${changetype<usize>(this." + mem.name + ") == <usize>0" + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __JSON.stringify<" + type + ">(this." + name.text + ") + \",\"}";
432
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">(data.substring(value_start, value_end));"
141
+ mem.serialize = "${changetype<usize>(this." + mem.name + ") == <usize>0" + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
142
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));"
433
143
  } else if (mem.flags.includes(PropertyFlags.OmitIf)) {
434
- mem.serialize = "${" + mem.args![0]! + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __JSON.stringify<" + type + ">(this." + name.text + ") + \",\"}";
435
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">(data.substring(value_start, value_end));"
144
+ mem.serialize = "${" + mem.args![0]! + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
145
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));"
436
146
  } else if (mem.flags.includes(PropertyFlags.Alias)) {
437
- mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__JSON.stringify<" + type + ">(this." + name.text + ")}";
438
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">(data.substring(value_start, value_end));"
147
+ mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
148
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));"
439
149
  mem.name = name.text;
440
150
  } else if (mem.flags.includes(PropertyFlags.Flatten)) {
441
151
  const nullable = (mem.node.type as NamedTypeNode).isNullable;
442
152
  if (nullable) {
443
153
  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\"}";
444
- 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 }";
154
+ 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 }";
445
155
  } else {
446
156
  mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${this." + name.text + " ? __SERIALIZE(this." + name.text + (mem.args?.length ? '.' + mem.args[0]! : '') + ") : \"null\"}";
447
- mem.deserialize = "this." + name.text + " = " + "__JSON.parse<" + type + ">('{\"" + mem.args![0]! + "\":' + data.substring(value_start, value_end) + \"}\");";
157
+ mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">('{\"" + mem.args![0]! + "\":' + data.substring(value_start, value_end) + \"}\");";
448
158
  }
449
159
  mem.name = name.text;
450
160
  }
@@ -598,9 +308,12 @@ class JSONTransform extends BaseVisitor {
598
308
  DESERIALIZE += "\n return false;\n}"
599
309
 
600
310
  //console.log(sortedMembers);
601
- // @ts-ignore
602
- if (process && process.env["JSON_DEBUG"]) {
603
- console.log("File: " + node.range.source.internalPath + "\n" + toString(node) + "\n\n");
311
+
312
+ if (process.env["JSON_DEBUG"]) {
313
+ console.log(SERIALIZE_RAW);
314
+ //console.log(SERIALIZE_PRETTY);
315
+ console.log(INITIALIZE);
316
+ console.log(DESERIALIZE);
604
317
  }
605
318
 
606
319
  const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node);
@@ -650,37 +363,6 @@ export default class Transformer extends Transform {
650
363
  // Ignore all lib and std. Visit everything else.
651
364
  if (!isStdlib(source)) {
652
365
  transformer.visit(source);
653
- if (transformer.mustImport) {
654
- const tokenizer = new Tokenizer(
655
- new Source(
656
- SourceKind.User,
657
- source.normalizedPath,
658
- "import { JSON as __JSON } from \"json-as/assembly\";"
659
- )
660
- );
661
- parser.currentSource = tokenizer.source;
662
- source.statements.unshift(parser.parseTopLevelStatement(tokenizer)!);
663
- parser.currentSource = source;
664
- const tokenizer2 = new Tokenizer(
665
- new Source(
666
- SourceKind.User,
667
- source.normalizedPath,
668
- "import { __atoi_fast } from \"json-as/assembly/util\";"
669
- )
670
- );
671
- parser.currentSource = tokenizer2.source;
672
- source.statements.unshift(parser.parseTopLevelStatement(tokenizer2)!);
673
- parser.currentSource = source;
674
- transformer.mustImport = false;
675
- // @ts-ignore
676
- if (process && process.env["JSON_DEBUG"]?.toString().toLowerCase() == "all") {
677
- console.log("File: " + source.normalizedPath + "\n" + toString(source) + "\n\n");
678
- }
679
- // @ts-ignore
680
- if (process && process.env["JSON_DEBUG"]?.toString().toLowerCase() == "write") {
681
- this.writeFile(source.internalPath + ".ts", toString(source), process.cwd());
682
- }
683
- }
684
366
  }
685
367
  }
686
368
  // Check that every parent and child class is hooked up correctly
@@ -722,7 +404,6 @@ class SchemaData {
722
404
  public name: string = "";
723
405
  public members: Property[] = []
724
406
  public parent: SchemaData | null = null;
725
- public boxRefs: Map<string, NamedTypeNode> = new Map<string, NamedTypeNode>();
726
407
  public node!: ClassDeclaration;
727
408
  }
728
409
 
@@ -762,20 +443,4 @@ function escapeSlash(data: string): string {
762
443
 
763
444
  function escapeQuote(data: string): string {
764
445
  return data.replace(/\"/g, "\\\"");
765
- }
766
-
767
- function isPrimitiveType(data: string): boolean {
768
- return data == "u8"
769
- || data == "u16"
770
- || data == "u16"
771
- || data == "u32"
772
- || data == "u64"
773
- || data == "i8"
774
- || data == "i16"
775
- || data == "i32"
776
- || data == "i64"
777
- || data == "f32"
778
- || data == "f64"
779
- || data == "bool"
780
- || data == "boolean";
781
446
  }