json-as 1.1.6 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, CommonFlags, ImportStatement, Node, Tokenizer, SourceKind, NamedTypeNode, Range, FEATURE_SIMD, FunctionExpression, MethodDeclaration, Statement, Program, Feature } from "assemblyscript/dist/assemblyscript.js";
1
+ import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, CommonFlags, ImportStatement, Node, Tokenizer, SourceKind, NamedTypeNode, Range, FEATURE_SIMD, FunctionExpression, MethodDeclaration, Statement, Program, Feature, CallExpression, PropertyAccessExpression } from "assemblyscript/dist/assemblyscript.js";
2
2
  import { Transform } from "assemblyscript/dist/transform.js";
3
3
  import { Visitor } from "./visitor.js";
4
- import { isStdlib, SimpleParser, toString } from "./util.js";
4
+ import { cloneNode, isStdlib, replaceRef, SimpleParser, toString } from "./util.js";
5
5
  import * as path from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { Property, PropertyFlags, Schema } from "./types.js";
@@ -12,6 +12,42 @@ let indent = " ";
12
12
  const DEBUG = process.env["JSON_DEBUG"];
13
13
  const STRICT = !(process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "false");
14
14
 
15
+ class CustomTransform extends Visitor {
16
+ static SN: CustomTransform = new CustomTransform();
17
+
18
+ private modify: boolean = false;
19
+ visitCallExpression(node: CallExpression) {
20
+
21
+ super.visit(node.args, node);
22
+ if (node.expression.kind != NodeKind.PropertyAccess || (node.expression as PropertyAccessExpression).property.text != "stringify") return;
23
+ if ((node.expression as PropertyAccessExpression).expression.kind != NodeKind.Identifier || ((node.expression as PropertyAccessExpression).expression as IdentifierExpression).text != "JSON") return;
24
+
25
+ if (this.modify) {
26
+ (node.expression as PropertyAccessExpression).expression = Node.createPropertyAccessExpression(
27
+ Node.createIdentifierExpression("JSON", node.expression.range),
28
+ Node.createIdentifierExpression("internal", node.expression.range),
29
+ node.expression.range
30
+ );
31
+ }
32
+ this.modify = true;
33
+
34
+ // console.log(toString(node));
35
+ // console.log(SimpleParser.parseStatement("JSON.internal.stringify").expression.expression)
36
+ }
37
+ static visit(node: Node | Node[], ref: Node | null = null): void {
38
+ if (!node) return;
39
+ CustomTransform.SN.modify = true;
40
+ CustomTransform.SN.visit(node, ref);
41
+ CustomTransform.SN.modify = false;
42
+ }
43
+ static hasCall(node: Node | Node[]): boolean {
44
+ if (!node) return;
45
+ CustomTransform.SN.modify = false;
46
+ CustomTransform.SN.visit(node);
47
+ return CustomTransform.SN.modify;
48
+ }
49
+ }
50
+
15
51
  class JSONTransform extends Visitor {
16
52
  static SN: JSONTransform = new JSONTransform();
17
53
 
@@ -61,6 +97,10 @@ class JSONTransform extends Visitor {
61
97
  if (serializers.length) {
62
98
  this.schema.custom = true;
63
99
  const serializer = serializers[0];
100
+ const hasCall = CustomTransform.hasCall(serializer);
101
+
102
+ CustomTransform.visit(serializer);
103
+
64
104
  // if (!serializer.signature.parameters.length) throwError("Could not find any parameters in custom serializer for " + this.schema.name + ". Serializers must have one parameter like 'serializer(self: " + this.schema.name + "): string {}'", serializer.range);
65
105
  if (serializer.signature.parameters.length > 1) throwError("Found too many parameters in custom serializer for " + this.schema.name + ", but serializers can only accept one parameter of type '" + this.schema.name + "'!", serializer.signature.parameters[1].range);
66
106
  if (serializer.signature.parameters.length > 0 && (<NamedTypeNode>serializer.signature.parameters[0].type).name.identifier.text != node.name.text && (<NamedTypeNode>serializer.signature.parameters[0].type).name.identifier.text != "this") throwError("Type of parameter for custom serializer does not match! It should be 'string'either be 'this' or '" + this.schema.name + "'", serializer.signature.parameters[0].type.range);
@@ -71,6 +111,7 @@ class JSONTransform extends Visitor {
71
111
  }
72
112
  SERIALIZE_CUSTOM += " __SERIALIZE(ptr: usize): void {\n";
73
113
  SERIALIZE_CUSTOM += " const data = this." + serializer.name.text + "(" + (serializer.signature.parameters.length ? "this" : "") + ");\n";
114
+ if (hasCall) SERIALIZE_CUSTOM += " bs.resetState();\n";
74
115
  SERIALIZE_CUSTOM += " const dataSize = data.length << 1;\n";
75
116
  SERIALIZE_CUSTOM += " memory.copy(bs.offset, changetype<usize>(data), dataSize);\n";
76
117
  SERIALIZE_CUSTOM += " bs.offset += dataSize;\n";
@@ -199,13 +240,18 @@ class JSONTransform extends Visitor {
199
240
  }
200
241
 
201
242
  for (const member of this.schema.members) {
202
- const nonNullType = member.type.replace(" | null", "");
203
- if (!isPrimitive(nonNullType)) {
204
- const schema = this.schemas.find((v) => v.name == nonNullType);
205
- if (schema && !this.schema.deps.includes(schema)) {
243
+ if (isStruct(member.type)) {
244
+ const schema = this.schemas.find((v) => v.name == stripNull(member.type));
245
+ if (!schema) continue;
246
+
247
+ if (!this.schema.deps.includes(schema)) {
206
248
  this.schema.deps.push(schema);
207
249
  this.schema.byteSize += schema.byteSize;
208
250
  }
251
+
252
+ // if (schema.custom) {
253
+ // member.flags.set(PropertyFlags.Custom, null);
254
+ // }
209
255
  }
210
256
  }
211
257
 
@@ -360,6 +406,11 @@ class JSONTransform extends Visitor {
360
406
  // if (shouldGroup) DESERIALIZE += " const keySize = keyEnd - keyStart;\n";
361
407
 
362
408
  const groupMembers = (members: Property[]): Property[][] => {
409
+ // const customMembers = this.schema.members.filter((m) => m.flags.has(PropertyFlags.Custom));
410
+ // console.log("Custom members: ", customMembers.map((m) => m.name));
411
+
412
+ // members.push(...customMembers)
413
+
363
414
  const groups = new Map<number, Property[]>();
364
415
 
365
416
  for (const member of members) {
@@ -384,7 +435,44 @@ class JSONTransform extends Visitor {
384
435
  .sort((a, b) => b.length - a.length);
385
436
  };
386
437
 
387
- const generateGroups = (members: Property[], cb: (group: Property[]) => void) => {
438
+ // const groupMembers = (members: Property[]): Property[][] => {
439
+ // const customMembers = this.schema.members.filter((m) =>
440
+ // m.flags.has(PropertyFlags.Custom)
441
+ // );
442
+ // console.log("Custom members: ", customMembers.map((m) => m.name));
443
+
444
+ // const customSet = new Set(customMembers);
445
+ // members = members.filter((m) => !customSet.has(m));
446
+ // members.push(...customMembers);
447
+
448
+ // const groups = new Map<number, Property[]>();
449
+
450
+ // for (const member of members) {
451
+ // const name = member.alias || member.name;
452
+ // const length = name.length;
453
+
454
+ // if (!groups.has(length)) {
455
+ // groups.set(length, []);
456
+ // }
457
+
458
+ // groups.get(length)!.push(member);
459
+ // }
460
+
461
+ // return [...groups.entries()]
462
+ // .sort(([a], [b]) => a - b)
463
+ // .map(([_, group]) => {
464
+ // const regulars = group.filter((m) => !customSet.has(m));
465
+ // const customs = group.filter((m) => customSet.has(m));
466
+
467
+ // const sortByLength = (a: Property, b: Property) =>
468
+ // (a.alias || a.name).length - (b.alias || b.name).length;
469
+
470
+ // return [...regulars.sort(sortByLength), ...customs.sort(sortByLength)];
471
+ // });
472
+ // };
473
+
474
+
475
+ const generateGroups = (members: Property[], cb: (group: Property[]) => void, nil: boolean = false) => {
388
476
  const groups = groupMembers(members);
389
477
  DESERIALIZE += " switch (<u32>keyEnd - <u32>keyStart) {\n";
390
478
 
@@ -396,7 +484,7 @@ class JSONTransform extends Visitor {
396
484
  }
397
485
 
398
486
  DESERIALIZE += " }\n";
399
- if (!(members[0].node.type.isNullable || isBoolean(members[0].type)))DESERIALIZE += " break;\n";
487
+ if (!members[0].node.type.isNullable && !isBoolean(members[0].type)) DESERIALIZE += " break;\n";
400
488
  }
401
489
 
402
490
  const generateComparisions = (members: Property[]) => {
@@ -677,7 +765,7 @@ class JSONTransform extends Visitor {
677
765
  DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n';
678
766
  DESERIALIZE += indent + " }\n";
679
767
  }
680
- });
768
+ }, true);
681
769
 
682
770
  DESERIALIZE += " }"; // Close first char check
683
771
  DESERIALIZE += "\n }"; // Close first char check
@@ -1100,4 +1188,4 @@ function getComparision(data: string) {
1100
1188
  return toMemCCheck(data);
1101
1189
  }
1102
1190
  }
1103
- }
1191
+ }
@@ -4,6 +4,7 @@ export enum PropertyFlags {
4
4
  OmitNull,
5
5
  OmitIf,
6
6
  Raw,
7
+ Custom
7
8
  }
8
9
 
9
10
  export class Property {
@@ -1,5 +1,5 @@
1
1
  // Taken from https://github.com/as-pect/visitor-as/blob/master/src/simpleParser.ts
2
- import { Parser, Tokenizer, Source, SourceKind, Expression, Statement, NamespaceDeclaration, ClassDeclaration, DeclarationStatement, Range, Node } from "assemblyscript/dist/assemblyscript.js";
2
+ import { Parser, Tokenizer, Source, SourceKind, Expression, Statement, NamespaceDeclaration, ClassDeclaration, DeclarationStatement, Range, Node, NodeKind } from "assemblyscript/dist/assemblyscript.js";
3
3
  import { ASTBuilder } from "./builder.js";
4
4
 
5
5
  export class SimpleParser {
@@ -54,3 +54,80 @@ export function isStdlib(s: Source | { range: Range }): boolean {
54
54
  export function toString(node: Node): string {
55
55
  return ASTBuilder.build(node);
56
56
  }
57
+
58
+ export function replaceRef(
59
+ node: Node,
60
+ replacement: Node | Node[],
61
+ ref: Node | Node[] | null,
62
+ ): void {
63
+ if (!node || !ref) return;
64
+ const nodeExpr = stripExpr(node);
65
+
66
+ if (Array.isArray(ref)) {
67
+ for (let i = 0; i < ref.length; i++) {
68
+ if (stripExpr(ref[i]) === nodeExpr) {
69
+ if (Array.isArray(replacement)) ref.splice(i, 1, ...replacement);
70
+ else ref.splice(i, 1, replacement);
71
+ return; // Exit early after replacement
72
+ }
73
+ }
74
+ } else if (typeof ref === "object") {
75
+ for (const key of Object.keys(ref)) {
76
+ const current = ref[key] as Node | Node[];
77
+ if (Array.isArray(current)) {
78
+ for (let i = 0; i < current.length; i++) {
79
+ if (stripExpr(current[i]) === nodeExpr) {
80
+ if (Array.isArray(replacement))
81
+ current.splice(i, 1, ...replacement);
82
+ else current.splice(i, 1, replacement);
83
+ return;
84
+ }
85
+ }
86
+ } else if (stripExpr(current) === nodeExpr) {
87
+ ref[key] = replacement;
88
+ return;
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ export function cloneNode(
95
+ input: Node | Node[] | null,
96
+ seen = new WeakMap(),
97
+ path = "",
98
+ ): Node | Node[] | null {
99
+ if (input === null || typeof input !== "object") return input;
100
+
101
+ if (Array.isArray(input)) {
102
+ return input.map((item, index) =>
103
+ cloneNode(item, seen, `${path}[${index}]`),
104
+ ) as Node | Node[] | null;
105
+ }
106
+
107
+ if (seen.has(input)) return seen.get(input);
108
+
109
+ const prototype = Object.getPrototypeOf(input);
110
+ const clone = Array.isArray(input) ? [] : Object.create(prototype);
111
+ seen.set(input, clone);
112
+
113
+ for (const key of Reflect.ownKeys(input)) {
114
+ const value = input[key];
115
+ const newPath = path ? `${path}.${String(key)}` : String(key);
116
+
117
+ if (newPath.endsWith(".source")) {
118
+ clone[key] = value;
119
+ } else if (value && typeof value === "object") {
120
+ clone[key] = cloneNode(value, seen, newPath);
121
+ } else {
122
+ clone[key] = value;
123
+ }
124
+ }
125
+
126
+ return clone as Node | Node[] | null;
127
+ }
128
+
129
+ export function stripExpr(node: Node): Node {
130
+ if (!node) return node;
131
+ if (node.kind == NodeKind.Expression) return node["expression"];
132
+ return node;
133
+ }