json-as 1.0.0-alpha.4 → 1.0.0-beta.2

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.
Files changed (40) hide show
  1. package/.trunk/configs/.markdownlint.yaml +2 -0
  2. package/.trunk/configs/.shellcheckrc +7 -0
  3. package/.trunk/configs/.yamllint.yaml +7 -0
  4. package/.trunk/trunk.yaml +36 -0
  5. package/CHANGELOG +23 -0
  6. package/README.md +59 -57
  7. package/assembly/__benches__/misc.bench.ts +48 -0
  8. package/assembly/__benches__/schemas.ts +25 -0
  9. package/assembly/__benches__/string.bench.ts +24 -0
  10. package/assembly/__benches__/struct.bench.ts +22 -0
  11. package/assembly/__tests__/arbitrary.spec.ts +19 -0
  12. package/assembly/__tests__/custom.spec.ts +42 -0
  13. package/assembly/__tests__/types.ts +3 -3
  14. package/assembly/custom/bench.ts +26 -0
  15. package/assembly/deserialize/simd/string.ts +1 -1
  16. package/assembly/deserialize/simple/arbitrary.ts +1 -1
  17. package/assembly/deserialize/simple/array/arbitrary.ts +47 -24
  18. package/assembly/deserialize/simple/array/{object.ts → struct.ts} +1 -1
  19. package/assembly/deserialize/simple/array.ts +4 -9
  20. package/assembly/deserialize/simple/integer.ts +2 -1
  21. package/assembly/deserialize/simple/map.ts +1 -1
  22. package/assembly/deserialize/simple/object.ts +11 -17
  23. package/assembly/deserialize/simple/struct.ts +158 -0
  24. package/assembly/index.d.ts +15 -1
  25. package/assembly/index.ts +144 -18
  26. package/assembly/serialize/simple/arbitrary.ts +15 -2
  27. package/assembly/serialize/simple/object.ts +43 -6
  28. package/assembly/serialize/simple/struct.ts +7 -0
  29. package/assembly/test.ts +61 -3
  30. package/assembly/util/atoi.ts +1 -1
  31. package/bench/bench.ts +15 -0
  32. package/bench/schemas.ts +5 -0
  33. package/bench/string.bench.ts +16 -0
  34. package/bench.js +11 -2
  35. package/modules/as-bs/assembly/index.ts +3 -3
  36. package/modules/as-bs/assembly/state.ts +8 -0
  37. package/package.json +3 -2
  38. package/transform/lib/index.js +59 -9
  39. package/transform/lib/index.js.map +1 -1
  40. package/transform/src/index.ts +75 -9
@@ -1,4 +1,4 @@
1
- import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, Expression, CommonFlags, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, CallExpression, ImportStatement, NamespaceDeclaration, Node, Statement, Tokenizer, SourceKind, PropertyAccessExpression, Token, CommentHandler, ExpressionStatement, BinaryExpression, NamedTypeNode, Range, FEATURE_SIMD, FunctionExpression } from "assemblyscript/dist/assemblyscript.js";
1
+ import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, Expression, CommonFlags, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, CallExpression, ImportStatement, NamespaceDeclaration, Node, Statement, Tokenizer, SourceKind, PropertyAccessExpression, Token, CommentHandler, ExpressionStatement, BinaryExpression, NamedTypeNode, Range, FEATURE_SIMD, FunctionExpression, MethodDeclaration } from "assemblyscript/dist/assemblyscript.js";
2
2
  import { Transform } from "assemblyscript/dist/transform.js";
3
3
  import { Visitor } from "./visitor.js";
4
4
  import { SimpleParser, toString } from "./util.js";
@@ -41,6 +41,76 @@ class JSONTransform extends Visitor {
41
41
  if (process.env["JSON_DEBUG"]) console.log("Created schema: " + this.schema.name);
42
42
 
43
43
  const members: FieldDeclaration[] = [...(node.members.filter((v) => v.kind === NodeKind.FieldDeclaration && v.flags !== CommonFlags.Static && v.flags !== CommonFlags.Private && v.flags !== CommonFlags.Protected && !v.decorators?.some((decorator) => (<IdentifierExpression>decorator.name).text === "omit")) as FieldDeclaration[])];
44
+ const serializers: MethodDeclaration[] = [...(node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "serializer")))] as MethodDeclaration[];
45
+ const deserializers: MethodDeclaration[] = [...(node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "deserializer")))] as MethodDeclaration[];
46
+
47
+ if (serializers.length > 1) throwError("Multiple serializers detected for class " + node.name.text + " but schemas can only have one serializer!", serializers[1].range);
48
+ if (deserializers.length > 1) throwError("Multiple deserializers detected for class " + node.name.text + " but schemas can only have one deserializer!", deserializers[1].range);
49
+
50
+ if (serializers.length) {
51
+ const serializer = serializers[0];
52
+ 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);
53
+ 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);
54
+ if ((<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);
55
+ if (!serializer.signature.returnType || !(<NamedTypeNode>serializer.signature.returnType).name.identifier.text.includes("string")) throwError("Could not find valid return type for serializer in " + this.schema.name + "!. Set the return type to type 'string' and try again", serializer.signature.returnType.range);
56
+
57
+ if (!serializer.decorators.some((v) => (<IdentifierExpression>v.name).text == "inline")) {
58
+ serializer.decorators.push(
59
+ Node.createDecorator(
60
+ Node.createIdentifierExpression(
61
+ "inline",
62
+ serializer.range
63
+ ),
64
+ null,
65
+ serializer.range
66
+ )
67
+ );
68
+ }
69
+ let SERIALIZER = "";
70
+ SERIALIZER += " @inline __SERIALIZE_CUSTOM(ptr: usize): void {\n";
71
+ SERIALIZER += " const data = this." + serializer.name.text + "(changetype<" + this.schema.name + ">(ptr));\n";
72
+ SERIALIZER += " const dataSize = data.length << 1;\n";
73
+ SERIALIZER += " memory.copy(bs.offset, changetype<usize>(data), dataSize);\n";
74
+ SERIALIZER += " bs.offset += dataSize;\n";
75
+ SERIALIZER += " }\n";
76
+
77
+ if (process.env["JSON_DEBUG"]) console.log(SERIALIZER);
78
+
79
+ const SERIALIZER_METHOD = SimpleParser.parseClassMember(SERIALIZER, node);
80
+
81
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE_CUSTOM")) node.members.push(SERIALIZER_METHOD);
82
+ }
83
+
84
+ if (deserializers.length) {
85
+ const deserializer = deserializers[0];
86
+ if (!deserializer.signature.parameters.length) throwError("Could not find any parameters in custom deserializer for " + this.schema.name + ". Deserializers must have one parameter like 'deserializer(data: string): " + this.schema.name + " {}'", deserializer.range);
87
+ if (deserializer.signature.parameters.length > 1) throwError("Found too many parameters in custom deserializer for " + this.schema.name + ", but deserializers can only accept one parameter of type 'string'!", deserializer.signature.parameters[1].range);
88
+ if ((<NamedTypeNode>deserializer.signature.parameters[0].type).name.identifier.text != "string") throwError("Type of parameter for custom deserializer does not match! It must be 'string'", deserializer.signature.parameters[0].type.range);
89
+ if (!deserializer.signature.returnType || !((<NamedTypeNode>deserializer.signature.returnType).name.identifier.text.includes(this.schema.name) || (<NamedTypeNode>deserializer.signature.returnType).name.identifier.text.includes("this"))) throwError("Could not find valid return type for deserializer in " + this.schema.name + "!. Set the return type to type '" + this.schema.name + "' or 'this' and try again", deserializer.signature.returnType.range);
90
+
91
+ if (!deserializer.decorators.some((v) => (<IdentifierExpression>v.name).text == "inline")) {
92
+ deserializer.decorators.push(
93
+ Node.createDecorator(
94
+ Node.createIdentifierExpression(
95
+ "inline",
96
+ deserializer.range
97
+ ),
98
+ null,
99
+ deserializer.range
100
+ )
101
+ );
102
+ }
103
+ let DESERIALIZER = "";
104
+ DESERIALIZER += " @inline __DESERIALIZE_CUSTOM(data: string): " + this.schema.name + " {\n";
105
+ DESERIALIZER += " return this." + deserializer.name.text + "(data);\n";
106
+ DESERIALIZER += " }\n";
107
+
108
+ if (process.env["JSON_DEBUG"]) console.log(DESERIALIZER);
109
+
110
+ const DESERIALIZER_METHOD = SimpleParser.parseClassMember(DESERIALIZER, node);
111
+
112
+ if (!node.members.find((v) => v.name.text == "__DESERIALIZE_CUSTOM")) node.members.push(DESERIALIZER_METHOD);
113
+ }
44
114
 
45
115
  if (node.extendsType) {
46
116
  const extendsName = node.extendsType?.name.identifier.text;
@@ -356,25 +426,21 @@ class JSONTransform extends Visitor {
356
426
  super.visitClassDeclaration(node);
357
427
  }
358
428
  generateEmptyMethods(node: ClassDeclaration): void {
359
- let SERIALIZE_RAW_EMPTY = '@inline __SERIALIZE(ptr: usize = changetype<usize>(this)): string {\n return "{}";\n}';
360
- let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE(ptr: usize: bool): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
429
+ let SERIALIZE_EMPTY = "@inline __SERIALIZE(ptr: usize): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
361
430
  let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
362
431
  let DESERIALIZE_EMPTY = "@inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n return false;\n}";
363
432
 
364
433
  if (process.env["JSON_DEBUG"]) {
365
- console.log(SERIALIZE_RAW_EMPTY);
366
- console.log(SERIALIZE_BS_EMPTY);
434
+ console.log(SERIALIZE_EMPTY);
367
435
  console.log(INITIALIZE_EMPTY);
368
436
  console.log(DESERIALIZE_EMPTY);
369
437
  }
370
438
 
371
- const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
372
- const SERIALIZE_BS_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_BS_EMPTY, node);
439
+ const SERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_EMPTY, node);
373
440
  const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
374
441
  const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
375
442
 
376
- if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
377
- if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_BS_METHOD_EMPTY);
443
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_METHOD_EMPTY);
378
444
  if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD_EMPTY);
379
445
  if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD_EMPTY);
380
446
  }