json-as 0.9.29 → 1.0.0-alpha.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 (110) hide show
  1. package/.github/workflows/nodejs.yml +0 -3
  2. package/.gitmodules +0 -0
  3. package/.prettierrc.json +3 -2
  4. package/CHANGELOG +24 -0
  5. package/LICENSE +1 -1
  6. package/README.md +23 -7
  7. package/as-test.config.json +1 -1
  8. package/asconfig.json +2 -2
  9. package/assembly/__benches__/misc.bench.ts +0 -34
  10. package/assembly/__tests__/bool.spec.ts +1 -1
  11. package/assembly/__tests__/simd/string.spec.ts +32 -0
  12. package/assembly/custom/memory.ts +25 -0
  13. package/assembly/custom/util.ts +14 -92
  14. package/assembly/deserialize/simd/string.ts +103 -0
  15. package/assembly/deserialize/simple/arbitrary.ts +17 -0
  16. package/assembly/deserialize/simple/array/arbitrary.ts +113 -0
  17. package/assembly/deserialize/simple/array/array.ts +18 -0
  18. package/assembly/deserialize/simple/array/bool.ts +17 -0
  19. package/assembly/deserialize/simple/array/float.ts +28 -0
  20. package/assembly/deserialize/simple/array/integer.ts +27 -0
  21. package/assembly/deserialize/simple/array/map.ts +18 -0
  22. package/assembly/deserialize/simple/array/object.ts +18 -0
  23. package/assembly/deserialize/simple/array/string.ts +22 -0
  24. package/assembly/deserialize/simple/array.ts +48 -0
  25. package/assembly/deserialize/simple/bool.ts +9 -0
  26. package/assembly/deserialize/simple/date.ts +11 -0
  27. package/assembly/deserialize/simple/float.ts +10 -0
  28. package/assembly/deserialize/simple/integer.ts +5 -0
  29. package/assembly/deserialize/simple/map.ts +154 -0
  30. package/assembly/deserialize/simple/object.ts +158 -0
  31. package/assembly/deserialize/simple/string.ts +48 -0
  32. package/assembly/globals/tables.ts +417 -0
  33. package/assembly/index.d.ts +9 -13
  34. package/assembly/index.ts +261 -146
  35. package/assembly/serialize/simd/string.ts +176 -0
  36. package/assembly/serialize/simple/arbitrary.ts +36 -0
  37. package/assembly/serialize/simple/array.ts +32 -0
  38. package/assembly/serialize/simple/bool.ts +19 -0
  39. package/assembly/serialize/simple/date.ts +13 -0
  40. package/assembly/serialize/simple/float.ts +7 -0
  41. package/assembly/serialize/simple/integer.ts +7 -0
  42. package/assembly/serialize/simple/map.ts +43 -0
  43. package/assembly/serialize/simple/object.ts +7 -0
  44. package/assembly/serialize/simple/string.ts +48 -0
  45. package/assembly/test.ts +36 -27
  46. package/assembly/tsconfig.json +2 -91
  47. package/assembly/types.ts +0 -0
  48. package/assembly/util/atoi.ts +35 -0
  49. package/assembly/util/bytes.ts +12 -0
  50. package/assembly/util/concat.ts +9 -0
  51. package/assembly/util/getArrayDepth.ts +17 -0
  52. package/assembly/util/index.ts +5 -0
  53. package/assembly/util/isSpace.ts +4 -0
  54. package/assembly/util/nextPowerOf2.ts +4 -0
  55. package/assembly/util/ptrToStr.ts +7 -0
  56. package/assembly/util/snp.ts +69 -0
  57. package/bench.js +5 -5
  58. package/modules/as-bs/LICENSE +21 -0
  59. package/modules/as-bs/README.md +95 -0
  60. package/modules/as-bs/assembly/index.ts +166 -0
  61. package/modules/as-bs/assembly/tsconfig.json +97 -0
  62. package/modules/as-bs/index.ts +1 -0
  63. package/modules/as-bs/package.json +32 -0
  64. package/package.json +41 -48
  65. package/transform/lib/builder.js +1275 -0
  66. package/transform/lib/builder.js.map +1 -0
  67. package/transform/lib/index.js +548 -443
  68. package/transform/lib/index.js.map +1 -1
  69. package/transform/lib/linker.js +16 -0
  70. package/transform/lib/linker.js.map +1 -0
  71. package/transform/lib/types.js +26 -0
  72. package/transform/lib/types.js.map +1 -0
  73. package/transform/lib/util.js +47 -0
  74. package/transform/lib/util.js.map +1 -0
  75. package/transform/lib/visitor.js +510 -430
  76. package/transform/lib/visitor.js.map +1 -0
  77. package/transform/package.json +1 -33
  78. package/transform/src/builder.ts +1371 -0
  79. package/transform/src/index.ts +574 -340
  80. package/transform/src/linker.ts +21 -0
  81. package/transform/src/types.ts +28 -0
  82. package/transform/src/util.ts +56 -0
  83. package/transform/src/visitor.ts +531 -0
  84. package/transform/tsconfig.json +3 -1
  85. package/assembly/__benches__/as-tral.d.ts +0 -1
  86. package/assembly/__tests__/date.spec.ts +0 -12
  87. package/assembly/custom/bs.ts +0 -202
  88. package/assembly/deserialize/array/array.ts +0 -31
  89. package/assembly/deserialize/array/bool.ts +0 -19
  90. package/assembly/deserialize/array/float.ts +0 -24
  91. package/assembly/deserialize/array/integer.ts +0 -24
  92. package/assembly/deserialize/array/map.ts +0 -27
  93. package/assembly/deserialize/array/object.ts +0 -27
  94. package/assembly/deserialize/array/string.ts +0 -29
  95. package/assembly/deserialize/array.ts +0 -46
  96. package/assembly/deserialize/bool.ts +0 -34
  97. package/assembly/deserialize/date.ts +0 -19
  98. package/assembly/deserialize/float.ts +0 -21
  99. package/assembly/deserialize/integer.ts +0 -16
  100. package/assembly/deserialize/map.ts +0 -139
  101. package/assembly/deserialize/object.ts +0 -211
  102. package/assembly/deserialize/string.ts +0 -149
  103. package/assembly/serialize/array.ts +0 -44
  104. package/assembly/serialize/bool.ts +0 -10
  105. package/assembly/serialize/date.ts +0 -4
  106. package/assembly/serialize/float.ts +0 -4
  107. package/assembly/serialize/integer.ts +0 -5
  108. package/assembly/serialize/map.ts +0 -24
  109. package/assembly/serialize/object.ts +0 -13
  110. package/assembly/serialize/string.ts +0 -284
@@ -1,468 +1,573 @@
1
- import { FieldDeclaration, IdentifierExpression, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression } from "assemblyscript/dist/assemblyscript.js";
2
- import { toString, isStdlib } from "visitor-as/dist/utils.js";
3
- import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
1
+ import { IdentifierExpression, Source, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, Node, Tokenizer } from "assemblyscript/dist/assemblyscript.js";
4
2
  import { Transform } from "assemblyscript/dist/transform.js";
5
- class JSONTransform extends BaseVisitor {
6
- schemasList = [];
7
- currentClass;
8
- sources = new Set();
9
- visitMethodDeclaration() { }
10
- visitClassDeclaration(node) {
11
- if (!node.decorators?.length)
12
- return;
13
- let found = false;
14
- for (const decorator of node.decorators) {
15
- const name = decorator.name.text;
16
- if (name === "json" || name === "serializable") {
17
- found = true;
18
- break;
19
- }
20
- }
21
- if (!found)
22
- return;
23
- const schema = new SchemaData();
24
- schema.node = node;
25
- schema.name = node.name.text;
26
- const members = [...node.members.filter((v) => v.kind === 54)];
27
- if (node.extendsType) {
28
- schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text);
29
- if (schema.parent?.members) {
30
- for (let i = schema.parent.members.length - 1; i >= 0; i--) {
31
- const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
32
- if (!replace) {
33
- members.unshift(schema.parent?.members[i].node);
34
- }
35
- }
36
- }
37
- }
38
- if (!members.length) {
39
- let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}';
40
- let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
41
- let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
42
- if (process.env["JSON_DEBUG"]) {
43
- console.log(SERIALIZE_RAW_EMPTY);
44
- console.log(INITIALIZE_EMPTY);
45
- console.log(DESERIALIZE_EMPTY);
46
- }
47
- const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
48
- const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
49
- const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
50
- if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
51
- node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
52
- if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
53
- node.members.push(INITIALIZE_METHOD_EMPTY);
54
- if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
55
- node.members.push(DESERIALIZE_METHOD_EMPTY);
56
- this.schemasList.push(schema);
57
- }
58
- for (const member of members) {
59
- const name = member.name;
60
- if (!(member instanceof FieldDeclaration))
61
- continue;
62
- if (!member.type) {
63
- throw new Error("Fields must be strongly typed! Found " + toString(member) + " at " + node.range.source.normalizedPath);
64
- }
65
- const type = toString(member.type);
66
- if (type.startsWith("(") && type.includes("=>"))
67
- continue;
68
- const value = member.initializer ? toString(member.initializer) : null;
69
- if (member.flags == 32)
70
- continue;
71
- if (member.flags === 512)
72
- continue;
73
- if (member.flags === 1024)
74
- continue;
75
- if (member.decorators && node.decorators.some((v) => v.name.text == "omit"))
76
- continue;
77
- const mem = new Property();
78
- mem.name = name.text;
79
- mem.type = type;
80
- mem.value = value;
81
- mem.node = member;
82
- if (type.includes("JSON.Raw")) {
83
- mem.flags.set(PropertyFlags.JSON_Raw, []);
84
- }
85
- if (member.type.isNullable) {
86
- mem.flags.set(PropertyFlags.Null, []);
87
- }
88
- if (member.decorators) {
89
- for (const decorator of member.decorators) {
90
- const decoratorName = decorator.name.text;
91
- const args = getArgs(decorator.args);
92
- switch (decoratorName) {
93
- case "alias": {
94
- if (!args.length)
95
- throw new Error("Expected 1 argument but got zero at @alias in " + node.range.source.normalizedPath);
96
- mem.alias = args[0];
97
- mem.flags.set(PropertyFlags.Alias, args);
98
- break;
99
- }
100
- case "omit": {
101
- mem.flags.set(PropertyFlags.Omit, args);
102
- break;
103
- }
104
- case "omitif": {
105
- if (!decorator.args?.length)
106
- throw new Error("Expected 1 argument but got zero at @omitif in " + node.range.source.normalizedPath);
107
- mem.flags.set(PropertyFlags.OmitIf, args);
108
- break;
109
- }
110
- case "omitnull": {
111
- mem.flags.set(PropertyFlags.OmitNull, args);
112
- break;
113
- }
114
- }
115
- }
116
- }
117
- mem.generate(false);
118
- if (this.schemasList.find((v) => v.name == type)) {
119
- mem.initialize = "this." + name.text + " = changetype<nonnull<" + mem.type + ">>(__new(offsetof<nonnull<" + mem.type + ">>(), idof<nonnull<" + mem.type + ">>()));\n changetype<nonnull<" + mem.type + ">>(this." + name.text + ").__INITIALIZE()";
120
- }
121
- else if (mem.value) {
122
- mem.initialize = "this." + name.text + " = " + mem.value;
123
- }
124
- else if (type === "Map") {
125
- mem.initialize = "this." + name.text + " = new " + mem.type + "()";
126
- }
127
- else if (type === "string") {
128
- mem.initialize = "this." + name.text + ' = ""';
129
- }
130
- else if (type === "Array") {
131
- mem.initialize = "this." + name.text + " = instantiate<" + mem.type + ">()";
132
- }
133
- else if (type === "bool" || type === "boolean") {
134
- mem.initialize = "this." + name.text + " = false";
135
- }
136
- else if (type === "JSON.Raw") {
137
- mem.initialize = "this." + name.text + ' = ""';
138
- }
139
- else if (type === "u8" || type === "u16" || type === "u32" || type === "u64" || type === "i8" || type === "i16" || type === "i32" || type === "i64") {
140
- mem.initialize = "this." + name.text + " = 0";
141
- }
142
- else if (type === "f32" || type === "f64") {
143
- mem.initialize = "this." + name.text + " = 0.0";
144
- }
145
- schema.members.push(mem);
3
+ import { Visitor } from "./visitor.js";
4
+ import { SimpleParser, toString } from "./util.js";
5
+ import * as path from "path";
6
+ import { fileURLToPath } from "url";
7
+ import { Property, PropertyFlags, Schema } from "./types.js";
8
+ import { getClasses, getImportedClass } from "./linker.js";
9
+ let indent = " ";
10
+ class JSONTransform extends Visitor {
11
+ parser;
12
+ schemas = [];
13
+ schema;
14
+ sources = new Set();
15
+ imports = [];
16
+ jsonImport = null;
17
+ bsImport = null;
18
+ newStmts = { simd: [] };
19
+ visitClassDeclaration(node) {
20
+ if (!node.decorators?.length) return;
21
+ if (
22
+ !node.decorators.some((decorator) => {
23
+ const name = decorator.name.text;
24
+ return name === "json" || name === "serializable";
25
+ })
26
+ )
27
+ return;
28
+ this.schema = new Schema();
29
+ this.schema.node = node;
30
+ this.schema.name = node.name.text;
31
+ this.schemas.push(this.schema);
32
+ if (process.env["JSON_DEBUG"]) console.log("Created schema: " + this.schema.name);
33
+ const members = [...node.members.filter((v) => v.kind === 54 && v.flags !== 32 && v.flags !== 512 && v.flags !== 1024 && !v.decorators?.some((decorator) => decorator.name.text === "omit"))];
34
+ if (node.extendsType) {
35
+ const extendsName = node.extendsType?.name.identifier.text;
36
+ this.schema.parent = this.schemas.find((v) => v.name == extendsName);
37
+ if (!this.schema.parent) {
38
+ const internalSearch = getClasses(node.range.source).find((v) => v.name.text == extendsName);
39
+ if (internalSearch) {
40
+ if (process.env["JSON_DEBUG"]) console.log("Found " + extendsName + " internally");
41
+ this.visitClassDeclaration(internalSearch);
42
+ this.visitClassDeclaration(node);
43
+ return;
146
44
  }
147
- let SERIALIZE_RAW = "__SERIALIZE(): string {\n let out = `{";
148
- let SERIALIZE_PRETTY = "__SERIALIZE_PRETTY(): string {\n let out = `{";
149
- let INITIALIZE = "__INITIALIZE(): this {\n";
150
- let DESERIALIZE = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n";
151
- let indent = " ";
152
- if (!schema.members.length)
153
- return;
154
- found = false;
155
- if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) || schema.members[0]?.flags.has(PropertyFlags.OmitIf)) {
156
- SERIALIZE_RAW += schema.members[0]?.serialize;
157
- SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
45
+ const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
46
+ if (externalSearch) {
47
+ if (process.env["JSON_DEBUG"]) console.log("Found " + extendsName + " externally");
48
+ this.visitClassDeclaration(externalSearch);
49
+ this.visitClassDeclaration(node);
50
+ return;
158
51
  }
159
- else {
160
- SERIALIZE_RAW += schema.members[0]?.serialize + ",";
161
- SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n";
162
- found = true;
52
+ }
53
+ if (this.schema.parent?.members) {
54
+ for (let i = this.schema.parent.members.length - 1; i >= 0; i--) {
55
+ const replace = this.schema.members.find((v) => v.name == this.schema.parent?.members[i]?.name);
56
+ if (!replace) {
57
+ members.unshift(this.schema.parent?.members[i].node);
58
+ }
163
59
  }
164
- if (schema.members[0]?.initialize)
165
- INITIALIZE += " " + schema.members[0]?.initialize + ";\n";
166
- for (let i = 1; i < schema.members.length; i++) {
167
- const member = schema.members[i];
168
- if (member.initialize)
169
- INITIALIZE += " " + member.initialize + ";\n";
170
- if (member.flags.has(PropertyFlags.OmitNull) || member.flags.has(PropertyFlags.OmitIf)) {
171
- SERIALIZE_RAW += member.serialize;
172
- SERIALIZE_PRETTY += member.serialize;
173
- }
174
- else {
175
- SERIALIZE_RAW += member.serialize + ",";
176
- SERIALIZE_PRETTY += indent + member.serialize + ",\\n";
177
- found = true;
178
- }
179
- }
180
- if (found) {
181
- SERIALIZE_RAW += "`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
182
- SERIALIZE_PRETTY += "`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
60
+ }
61
+ }
62
+ if (!members.length) {
63
+ this.generateEmptyMethods(node);
64
+ return;
65
+ }
66
+ this.addRequiredImports(node);
67
+ for (const member of members) {
68
+ if (!member.type) throwError("Fields must be strongly typed", node.range);
69
+ const type = toString(member.type);
70
+ const name = member.name;
71
+ const value = member.initializer ? toString(member.initializer) : null;
72
+ if (type.startsWith("(") && type.includes("=>")) continue;
73
+ const mem = new Property();
74
+ mem.name = name.text;
75
+ mem.type = type;
76
+ mem.value = value;
77
+ mem.node = member;
78
+ mem.byteSize = sizeof(mem.type);
79
+ this.schema.byteSize += mem.byteSize;
80
+ if (type.includes("JSON.Raw")) mem.flags.set(PropertyFlags.Raw, null);
81
+ if (member.decorators) {
82
+ for (const decorator of member.decorators) {
83
+ const decoratorName = decorator.name.text.toLowerCase().trim();
84
+ switch (decoratorName) {
85
+ case "alias": {
86
+ const args = getArgs(decorator.args);
87
+ if (!args.length) throwError("@alias must have an argument of type string or number", member.range);
88
+ mem.alias = args[0];
89
+ break;
90
+ }
91
+ case "omitif": {
92
+ let arg = decorator.args[0];
93
+ if (!decorator.args?.length) throwError("@omitif must have an argument or callback that resolves to type bool", member.range);
94
+ mem.flags.set(PropertyFlags.OmitIf, arg);
95
+ this.schema.static = false;
96
+ break;
97
+ }
98
+ case "omitnull": {
99
+ if (isPrimitive(type)) {
100
+ throwError("@omitnull cannot be used on primitive types!", member.range);
101
+ } else if (!member.type.isNullable) {
102
+ throwError("@omitnull cannot be used on non-nullable types!", member.range);
103
+ }
104
+ mem.flags.set(PropertyFlags.OmitNull, null);
105
+ this.schema.static = false;
106
+ break;
107
+ }
108
+ }
183
109
  }
184
- else {
185
- SERIALIZE_RAW += "}`;\n return out;\n}";
186
- SERIALIZE_PRETTY += "}`;\n return out;\n}";
110
+ }
111
+ this.schema.members.push(mem);
112
+ }
113
+ if (!this.schema.static) this.schema.members = sortMembers(this.schema.members);
114
+ let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
115
+ let INITIALIZE = "@inline __INITIALIZE(): this {\n";
116
+ let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n switch (<u32>keyEnd - <u32>keyStart) {\n";
117
+ let ALLOCATE = "@inline __ALLOCATE(): void {\n";
118
+ indent = " ";
119
+ if (this.schema.static == false) {
120
+ if (this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull))) {
121
+ SERIALIZE += indent + "let block: usize = 0;\n";
122
+ }
123
+ this.schema.byteSize += 2;
124
+ SERIALIZE += indent + "store<u16>(bs.offset, 123, 0); // {\n";
125
+ SERIALIZE += indent + "bs.offset += 2;\n";
126
+ }
127
+ for (const member of this.schema.members) {
128
+ const nonNullType = member.type.replace(" | null", "");
129
+ if (!isPrimitive(nonNullType)) {
130
+ const schema = this.schemas.find((v) => v.name == nonNullType);
131
+ if (schema && !this.schema.deps.includes(schema)) {
132
+ this.schema.deps.push(schema);
133
+ this.schema.byteSize += schema.byteSize;
187
134
  }
188
- INITIALIZE += " return this;\n}";
189
- const sortedMembers = [];
190
- const _sorted = schema.members.sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length));
191
- let len = -1;
192
- let offset = -1;
193
- for (let i = 0; i < _sorted.length; i++) {
194
- const member = _sorted[i];
195
- const _name = member.alias || member.name;
196
- if (_name.length === len) {
197
- sortedMembers[offset]?.push(member);
198
- }
199
- else {
200
- sortedMembers.push([member]);
201
- len = _name.length;
202
- offset++;
203
- }
135
+ }
136
+ }
137
+ let isPure = this.schema.static;
138
+ let isRegular = isPure;
139
+ let isFirst = true;
140
+ for (let i = 0; i < this.schema.members.length; i++) {
141
+ const member = this.schema.members[i];
142
+ const aliasName = JSON.stringify(member.alias || member.name);
143
+ const realName = member.name;
144
+ const isLast = i == this.schema.members.length - 1;
145
+ const nonNullType = member.type.replace(" | null", "");
146
+ if (member.value) {
147
+ INITIALIZE += ` this.${member.name} = ${member.value};\n`;
148
+ } else if (this.schemas.find((v) => nonNullType == v.name)) {
149
+ INITIALIZE += ` this.${member.name} = changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE();\n`;
150
+ } else if (member.type.startsWith("Array<") || member.type.startsWith("Map<")) {
151
+ INITIALIZE += ` this.${member.name} = [];\n`;
152
+ } else if (member.type == "string" || member.type == "String" || member.type == "JSON.Raw") {
153
+ INITIALIZE += ` this.${member.name} = "";\n`;
154
+ }
155
+ if (!isRegular && !member.flags.has(PropertyFlags.OmitIf) && !member.flags.has(PropertyFlags.OmitNull)) isRegular = true;
156
+ if (isRegular && isPure) {
157
+ const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
158
+ this.schema.byteSize += keyPart.length << 1;
159
+ SERIALIZE += this.getStores(keyPart)
160
+ .map((v) => indent + v + "\n")
161
+ .join("");
162
+ SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
163
+ if (isFirst) isFirst = false;
164
+ } else if (isRegular && !isPure) {
165
+ const keyPart = (isFirst ? "" : ",") + aliasName + ":";
166
+ this.schema.byteSize += keyPart.length << 1;
167
+ SERIALIZE += this.getStores(keyPart)
168
+ .map((v) => indent + v + "\n")
169
+ .join("");
170
+ SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
171
+ if (isFirst) isFirst = false;
172
+ } else {
173
+ if (member.flags.has(PropertyFlags.OmitNull)) {
174
+ SERIALIZE += indent + `if ((block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0) {\n`;
175
+ indentInc();
176
+ const keyPart = aliasName + ":";
177
+ this.schema.byteSize += keyPart.length << 1;
178
+ SERIALIZE += this.getStores(keyPart)
179
+ .map((v) => indent + v + "\n")
180
+ .join("");
181
+ SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
182
+ if (!isLast) {
183
+ this.schema.byteSize += 2;
184
+ SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
185
+ SERIALIZE += indent + `bs.offset += 2;\n`;
186
+ }
187
+ indentDec();
188
+ this.schema.byteSize += 2;
189
+ SERIALIZE += indent + `}\n`;
190
+ } else if (member.flags.has(PropertyFlags.OmitIf)) {
191
+ if (member.flags.get(PropertyFlags.OmitIf).kind == 14) {
192
+ const arg = member.flags.get(PropertyFlags.OmitIf);
193
+ arg.declaration.signature.returnType.name = Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name.range);
194
+ SERIALIZE += indent + `if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
195
+ } else {
196
+ SERIALIZE += indent + `if (${toString(member.flags.get(PropertyFlags.OmitIf))}) {\n`;
197
+ }
198
+ indentInc();
199
+ SERIALIZE += this.getStores(aliasName + ":")
200
+ .map((v) => indent + v + "\n")
201
+ .join("");
202
+ SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
203
+ if (!isLast) {
204
+ this.schema.byteSize += 2;
205
+ SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
206
+ SERIALIZE += indent + `bs.offset += 2;\n`;
207
+ }
208
+ indentDec();
209
+ SERIALIZE += indent + `}\n`;
204
210
  }
205
- let first = true;
206
- for (const memberSet of sortedMembers) {
207
- const firstMember = memberSet[0];
208
- const _name = encodeKey(firstMember.alias || firstMember.name);
209
- if (_name.length === 1) {
210
- if (first) {
211
- DESERIALIZE += " if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
212
- first = false;
213
- }
214
- else {
215
- DESERIALIZE += "else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
216
- }
217
- }
218
- else if (_name.length === 2) {
219
- if (first) {
220
- DESERIALIZE += " if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
221
- first = false;
222
- }
223
- else {
224
- DESERIALIZE += "else if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
225
- }
226
- }
227
- else if (_name.length === 4) {
228
- if (first) {
229
- DESERIALIZE += " if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
230
- first = false;
231
- }
232
- else {
233
- DESERIALIZE += "else if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
234
- }
235
- }
236
- else {
237
- if (first) {
238
- DESERIALIZE += " if (" + _name.length + " === len) {\n";
239
- first = false;
240
- }
241
- else {
242
- DESERIALIZE += "else if (" + _name.length + " === len) {\n";
243
- }
244
- }
245
- let f = true;
246
- for (let i = 0; i < memberSet.length; i++) {
247
- const member = memberSet[i];
248
- if (!member.deserialize)
249
- continue;
250
- const _name = encodeKey(member.alias || member.name);
251
- if (_name.length === 1) {
252
- DESERIALIZE += ` case ${_name.charCodeAt(0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
253
- }
254
- else if (_name.length === 2) {
255
- DESERIALIZE += ` case ${charCodeAt32(_name, 0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
256
- }
257
- else if (_name.length === 4) {
258
- if (f) {
259
- f = false;
260
- DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
261
- }
262
- else {
263
- DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
264
- }
265
- }
266
- else {
267
- if (f) {
268
- f = false;
269
- DESERIALIZE += ` if (0 === memory.compare(changetype<usize>("${escapeQuote(escapeSlash(_name))}"), changetype<usize>(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
270
- }
271
- else {
272
- DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else if (0 === memory.compare(changetype<usize>("${escapeQuote(escapeSlash(_name))}"), changetype<usize>(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
273
- }
274
- }
275
- }
276
- if (_name.length < 3) {
277
- DESERIALIZE += ` default: {\n return false;\n }\n }\n`;
278
- }
279
- else if (_name.length == 4) {
280
- DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
281
- }
282
- else {
283
- DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
284
- }
285
- DESERIALIZE += " } ";
211
+ }
212
+ }
213
+ let sortedMembers = [];
214
+ let len = -1;
215
+ this.schema.members
216
+ .slice()
217
+ .sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length))
218
+ .forEach((member) => {
219
+ const _nameLength = member.alias?.length || member.name.length;
220
+ if (_nameLength === len) {
221
+ sortedMembers[sortedMembers.length - 1].push(member);
222
+ } else {
223
+ sortedMembers.push([member]);
224
+ len = _nameLength;
286
225
  }
287
- DESERIALIZE += "\n return false;\n}";
288
- if (process.env["JSON_DEBUG"]) {
289
- console.log(SERIALIZE_RAW);
290
- console.log(INITIALIZE);
291
- console.log(DESERIALIZE);
226
+ });
227
+ sortedMembers = sortedMembers.sort((a, b) => b.length - a.length);
228
+ indentInc();
229
+ for (const memberGroup of sortedMembers) {
230
+ const memberLen = (memberGroup[0].alias || memberGroup[0].name).length << 1;
231
+ DESERIALIZE += `${indent}case ${memberLen}: {\n`;
232
+ indentInc();
233
+ if (memberLen == 2) DESERIALIZE += `${indent}switch (load<u16>(keyStart)) {\n`;
234
+ else if (memberLen == 4) DESERIALIZE += `${indent}switch (load<u32>(keyStart)) {\n`;
235
+ else if (memberLen == 6) DESERIALIZE += `${indent}let code = (<u64>load<u32>(keyStart) << 16) | <u64>load<u16>(keyStart, 4);\n`;
236
+ else DESERIALIZE += toMemCDecl(memberLen, indent);
237
+ for (let i = 0; i < memberGroup.length; i++) {
238
+ const member = memberGroup[i];
239
+ const memberName = member.alias || member.name;
240
+ if (memberLen == 2) {
241
+ DESERIALIZE += `${indent} case ${memberName.charCodeAt(0)}: { // ${memberName}\n`;
242
+ DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
243
+ DESERIALIZE += `${indent} return;\n`;
244
+ DESERIALIZE += `${indent} }\n`;
245
+ } else if (memberLen == 4) {
246
+ DESERIALIZE += `${indent} case ${toU32(memberName)}: { // ${memberName}\n`;
247
+ DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
248
+ DESERIALIZE += `${indent} return;\n`;
249
+ DESERIALIZE += `${indent} }\n`;
250
+ } else if (memberLen == 6) {
251
+ DESERIALIZE += i == 0 ? indent : "";
252
+ DESERIALIZE += `if (code == ${toU48(memberName)}) { // ${memberName}\n`;
253
+ DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
254
+ DESERIALIZE += `${indent} return;\n`;
255
+ DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
256
+ } else {
257
+ DESERIALIZE += i == 0 ? indent : "";
258
+ DESERIALIZE += `if (${toMemCCheck(memberName)}) { // ${memberName}\n`;
259
+ DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
260
+ DESERIALIZE += `${indent} return;\n`;
261
+ DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
292
262
  }
293
- const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node);
294
- const DESERIALIZE_SAFE = DESERIALIZE.replaceAll("__DESERIALIZE", "__DESERIALIZE_SAFE");
295
- const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
296
- const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
297
- const DESERIALIZE_SAFE_METHOD = SimpleParser.parseClassMember(DESERIALIZE_SAFE, node);
298
- if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
299
- node.members.push(SERIALIZE_RAW_METHOD);
300
- if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
301
- node.members.push(INITIALIZE_METHOD);
302
- if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
303
- node.members.push(DESERIALIZE_METHOD);
304
- if (!node.members.find((v) => v.name.text == "__DESERIALIZE_SAFE"))
305
- node.members.push(DESERIALIZE_SAFE_METHOD);
306
- this.schemasList.push(schema);
263
+ }
264
+ if (memberLen < 6) {
265
+ DESERIALIZE += `${indent}}\n`;
266
+ }
267
+ indentDec();
268
+ DESERIALIZE += `${indent} return;\n`;
269
+ DESERIALIZE += `${indent}}\n`;
307
270
  }
308
- visitSource(node) {
309
- super.visitSource(node);
310
- if (!this.sources.has(node)) {
311
- return;
312
- }
271
+ indentDec();
272
+ DESERIALIZE += `${indent}}\n`;
273
+ indentDec();
274
+ DESERIALIZE += `${indent}}\n`;
275
+ indent = " ";
276
+ this.schema.byteSize += 2;
277
+ SERIALIZE += indent + "store<u16>(bs.offset, 125, 0); // }\n";
278
+ SERIALIZE += indent + "bs.offset += 2;\n";
279
+ SERIALIZE += "}";
280
+ ALLOCATE += indent + "bs.ensureSize(" + this.schema.byteSize + ");\n";
281
+ ALLOCATE += "}";
282
+ INITIALIZE += " return this;\n";
283
+ INITIALIZE += "}";
284
+ if (process.env["JSON_DEBUG"]) {
285
+ console.log(SERIALIZE);
286
+ console.log(INITIALIZE);
287
+ console.log(DESERIALIZE);
288
+ console.log(ALLOCATE);
313
289
  }
290
+ const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE, node);
291
+ const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
292
+ const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
293
+ const ALLOCATE_METHOD = SimpleParser.parseClassMember(ALLOCATE, node);
294
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_METHOD);
295
+ if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD);
296
+ if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD);
297
+ if (!node.members.find((v) => v.name.text == "__ALLOCATE")) node.members.push(ALLOCATE_METHOD);
298
+ super.visitClassDeclaration(node);
299
+ }
300
+ generateEmptyMethods(node) {
301
+ let SERIALIZE_RAW_EMPTY = '@inline __SERIALIZE(ptr: usize = changetype<usize>(this)): string {\n return "{}";\n}';
302
+ let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE(ptr: usize: bool): void {\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
303
+ let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
304
+ let DESERIALIZE_EMPTY = "@inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n return false;\n}";
305
+ let ALLOCATE_EMPTY = "@inline __ALLOCATE(): void {\n bs.ensureSize(4);\n}";
306
+ if (process.env["JSON_DEBUG"]) {
307
+ console.log(SERIALIZE_RAW_EMPTY);
308
+ console.log(SERIALIZE_BS_EMPTY);
309
+ console.log(INITIALIZE_EMPTY);
310
+ console.log(DESERIALIZE_EMPTY);
311
+ console.log(ALLOCATE_EMPTY);
312
+ }
313
+ const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
314
+ const SERIALIZE_BS_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_BS_EMPTY, node);
315
+ const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
316
+ const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
317
+ const ALLOCATE_METHOD_EMPTY = SimpleParser.parseClassMember(ALLOCATE_EMPTY, node);
318
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
319
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_BS_METHOD_EMPTY);
320
+ if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD_EMPTY);
321
+ if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD_EMPTY);
322
+ if (!node.members.find((v) => v.name.text == "__ALLOCATE")) node.members.push(ALLOCATE_METHOD_EMPTY);
323
+ }
324
+ visitImportStatement(node) {
325
+ super.visitImportStatement(node);
326
+ const source = this.parser.sources.find((src) => src.internalPath == node.internalPath);
327
+ if (!source) return;
328
+ if (source.statements.some((stmt) => stmt.kind === 59 && stmt.name.text === "JSON")) this.imports.push(node);
329
+ }
330
+ visitSource(node) {
331
+ this.imports = [];
332
+ super.visitSource(node);
333
+ }
334
+ addRequiredImports(node) {
335
+ if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "bs"))) {
336
+ const __filename = fileURLToPath(import.meta.url);
337
+ const __dirname = path.dirname(__filename);
338
+ let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../modules/as-bs/"));
339
+ if (!relativePath.startsWith(".") && !relativePath.startsWith("/")) relativePath = "./" + relativePath;
340
+ const txt = `import { bs } from "${relativePath}";`;
341
+ if (!this.bsImport) {
342
+ this.bsImport = txt;
343
+ if (process.env["JSON_DEBUG"]) console.log("Added as-bs import: " + txt + "\n");
344
+ }
345
+ }
346
+ if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "JSON"))) {
347
+ const __filename = fileURLToPath(import.meta.url);
348
+ const __dirname = path.dirname(__filename);
349
+ let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../assembly/index.ts"));
350
+ if (!relativePath.startsWith(".") && !relativePath.startsWith("/")) relativePath = "./" + relativePath;
351
+ const txt = `import { JSON } from "${relativePath}";`;
352
+ if (!this.jsonImport) {
353
+ this.jsonImport = txt;
354
+ if (process.env["JSON_DEBUG"]) console.log("Added json-as import: " + txt + "\n");
355
+ }
356
+ }
357
+ }
358
+ getStores(data, simd = false) {
359
+ const out = [];
360
+ const sizes = strToNum(data, simd);
361
+ let offset = 0;
362
+ for (const [size, num] of sizes) {
363
+ if (size == "v128") {
364
+ let index = this.newStmts.simd.findIndex((v) => v.includes(num));
365
+ let name = "SIMD_" + (index == -1 ? this.newStmts.simd.length : index);
366
+ if (index && !this.newStmts.simd.includes(`const ${name} = ${num};`)) this.newStmts.simd.push(`const ${name} = ${num};`);
367
+ out.push("store<v128>(bs.offset, " + name + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 8));
368
+ offset += 16;
369
+ }
370
+ if (size == "u64") {
371
+ out.push("store<u64>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 4));
372
+ offset += 8;
373
+ } else if (size == "u32") {
374
+ out.push("store<u32>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 2));
375
+ offset += 4;
376
+ } else if (size == "u16") {
377
+ out.push("store<u16>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 1));
378
+ offset += 2;
379
+ }
380
+ }
381
+ out.push("bs.offset += " + offset + ";");
382
+ return out;
383
+ }
314
384
  }
315
385
  export default class Transformer extends Transform {
316
- afterParse(parser) {
317
- const transformer = new JSONTransform();
318
- const sources = parser.sources
319
- .filter((source) => !isStdlib(source))
320
- .sort((_a, _b) => {
321
- const a = _a.internalPath;
322
- const b = _b.internalPath;
323
- if (a[0] === "~" && b[0] !== "~") {
324
- return -1;
325
- }
326
- else if (a[0] !== "~" && b[0] === "~") {
327
- return 1;
328
- }
329
- else {
330
- return 0;
331
- }
332
- });
333
- for (const source of sources) {
334
- if (!isStdlib(source)) {
335
- transformer.visit(source);
336
- }
337
- }
338
- const schemas = transformer.schemasList;
339
- for (const schema of schemas) {
340
- if (schema.parent) {
341
- const parent = schemas.find((v) => v.name === schema.parent?.name);
342
- if (!parent)
343
- throw new Error(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator! Add the decorator and rebuild.`);
344
- }
345
- }
386
+ afterParse(parser) {
387
+ const transformer = new JSONTransform();
388
+ const sources = parser.sources.sort((_a, _b) => {
389
+ const a = _a.internalPath;
390
+ const b = _b.internalPath;
391
+ if (a[0] == "~" && b[0] !== "~") {
392
+ return -1;
393
+ } else if (a[0] !== "~" && b[0] == "~") {
394
+ return 1;
395
+ } else {
396
+ return 0;
397
+ }
398
+ });
399
+ transformer.parser = parser;
400
+ for (const source of sources) {
401
+ transformer.imports = [];
402
+ transformer.currentSource = source;
403
+ transformer.visit(source);
404
+ if (transformer.newStmts.simd) {
405
+ const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.newStmts.simd.join("\n")));
406
+ parser.currentSource = tokenizer.source;
407
+ for (let i = 0; i < transformer.newStmts.simd.length; i++) source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
408
+ parser.currentSource = source;
409
+ transformer.newStmts.simd = [];
410
+ }
411
+ if (transformer.jsonImport) {
412
+ const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.jsonImport));
413
+ parser.currentSource = tokenizer.source;
414
+ source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
415
+ parser.currentSource = source;
416
+ transformer.jsonImport = null;
417
+ }
418
+ if (transformer.bsImport) {
419
+ const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.bsImport));
420
+ parser.currentSource = tokenizer.source;
421
+ source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
422
+ parser.currentSource = source;
423
+ transformer.bsImport = null;
424
+ }
425
+ }
426
+ const schemas = transformer.schemas;
427
+ for (const schema of schemas) {
428
+ if (schema.parent) {
429
+ const parent = schemas.find((v) => v.name == schema.parent?.name);
430
+ if (!parent) throwError(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator!`, schema.parent.node.range);
431
+ }
346
432
  }
433
+ }
347
434
  }
348
- var PropertyFlags;
349
- (function (PropertyFlags) {
350
- PropertyFlags[PropertyFlags["Null"] = 0] = "Null";
351
- PropertyFlags[PropertyFlags["Omit"] = 1] = "Omit";
352
- PropertyFlags[PropertyFlags["OmitNull"] = 2] = "OmitNull";
353
- PropertyFlags[PropertyFlags["OmitIf"] = 3] = "OmitIf";
354
- PropertyFlags[PropertyFlags["Alias"] = 4] = "Alias";
355
- PropertyFlags[PropertyFlags["JSON_Raw"] = 5] = "JSON_Raw";
356
- })(PropertyFlags || (PropertyFlags = {}));
357
- class Property {
358
- name = "";
359
- alias = null;
360
- type = "";
361
- value = null;
362
- flags = new Map();
363
- serialize = null;
364
- deserialize = null;
365
- initialize = null;
366
- node;
367
- right_s = "";
368
- right_d = "";
369
- generate(safe) {
370
- const name = this.name;
371
- const escapedName = escapeString(JSON.stringify(this.alias || this.name));
372
- const type = this.type;
373
- if (this.flags.has(PropertyFlags.Omit))
374
- return;
375
- if (this.flags.has(PropertyFlags.JSON_Raw)) {
376
- if (this.flags.has(PropertyFlags.Null)) {
377
- this.right_s = "(this." + name + ' || "null")';
378
- this.right_d = "value_start === value_end - 4 && 30399761348886638 === load<u64>(changetype<usize>(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)";
379
- }
380
- else {
381
- this.right_s = "this." + name;
382
- this.right_d = "data.substring(value_start, value_end);";
383
- }
384
- }
385
- else {
386
- this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")";
387
- this.right_d = (safe ? "__DESERIALIZE_SAFE" : "__DESERIALIZE") + "<" + type + ">(data.substring(value_start, value_end))";
388
- }
389
- if (this.flags.has(PropertyFlags.OmitIf)) {
390
- const condition = this.flags.get(PropertyFlags.OmitIf)[0];
391
- if (!condition)
392
- throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition");
393
- this.serialize = "${" + condition + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}';
394
- this.deserialize = "this." + name + " = " + this.right_d + ";";
395
- }
396
- else if (this.flags.has(PropertyFlags.OmitNull)) {
397
- this.serialize = "${changetype<usize>(this." + name + ") == <usize>0" + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}';
398
- this.deserialize = "this." + name + " = " + this.right_d + ";";
399
- }
400
- else {
401
- this.serialize = escapedName + ":${" + this.right_s + "}";
402
- this.deserialize = "this." + name + " = " + this.right_d + ";";
403
- }
435
+ function sortMembers(members) {
436
+ return members.sort((a, b) => {
437
+ const aMove = a.flags.has(PropertyFlags.OmitIf) || a.flags.has(PropertyFlags.OmitNull);
438
+ const bMove = b.flags.has(PropertyFlags.OmitIf) || b.flags.has(PropertyFlags.OmitNull);
439
+ if (aMove && !bMove) {
440
+ return -1;
441
+ } else if (!aMove && bMove) {
442
+ return 1;
443
+ } else {
444
+ return 0;
404
445
  }
446
+ });
405
447
  }
406
- class SchemaData {
407
- name = "";
408
- members = [];
409
- parent = null;
410
- node;
448
+ function getArgs(args) {
449
+ if (!args) return [];
450
+ let out = [];
451
+ for (const arg of args) {
452
+ if (arg instanceof StringLiteralExpression) {
453
+ out.push(arg.value);
454
+ } else if (arg instanceof IntegerLiteralExpression) {
455
+ out.push(i64_to_string(arg.value));
456
+ } else if (arg instanceof FloatLiteralExpression) {
457
+ out.push(arg.value.toString());
458
+ } else if (arg instanceof NullExpression) {
459
+ out.push(arg.text);
460
+ } else if (arg instanceof TrueExpression) {
461
+ out.push(arg.text);
462
+ } else if (arg instanceof FalseExpression) {
463
+ out.push(arg.text);
464
+ } else if (arg instanceof IdentifierExpression) {
465
+ out.push(arg.text);
466
+ }
467
+ }
468
+ return out;
411
469
  }
412
- function charCodeAt32(data, offset) {
413
- return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset);
470
+ function toU16(data, offset = 0) {
471
+ return data.charCodeAt(offset + 0).toString();
414
472
  }
415
- function charCodeAt64(data, offset) {
416
- if (offset + 3 >= data.length) {
417
- throw new Error("The string must have at least 4 characters from the specified offset.");
418
- }
419
- const firstCharCode = BigInt(data.charCodeAt(offset));
420
- const secondCharCode = BigInt(data.charCodeAt(offset + 1));
421
- const thirdCharCode = BigInt(data.charCodeAt(offset + 2));
422
- const fourthCharCode = BigInt(data.charCodeAt(offset + 3));
423
- const u64Value = (fourthCharCode << 48n) | (thirdCharCode << 32n) | (secondCharCode << 16n) | firstCharCode;
424
- return u64Value;
473
+ function toU32(data, offset = 0) {
474
+ return ((data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0)).toString();
425
475
  }
426
- function encodeKey(key) {
427
- const data = JSON.stringify(key);
428
- return data.slice(1, data.length - 1);
476
+ function toU48(data, offset = 0) {
477
+ return ((BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0))).toString();
429
478
  }
430
- function escapeString(data) {
431
- return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`");
479
+ function toU64(data, offset = 0) {
480
+ return ((BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0))).toString();
432
481
  }
433
- function escapeSlash(data) {
434
- return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`");
482
+ function toMemCDecl(n, indent) {
483
+ let out = "";
484
+ let offset = 0;
485
+ let index = 0;
486
+ while (n >= 8) {
487
+ out += `${indent}const code${index++} = load<u64>(keyStart, ${offset});\n`;
488
+ offset += 8;
489
+ n -= 8;
490
+ }
491
+ while (n >= 4) {
492
+ out += `${indent}const code${index++} = load<u32>(keyStart, ${offset});\n`;
493
+ offset += 4;
494
+ n -= 4;
495
+ }
496
+ if (n == 1) out += `${indent}const code${index++} = load<u16>(keyStart, ${offset});\n`;
497
+ return out;
435
498
  }
436
- function escapeQuote(data) {
437
- return data.replace(/\"/g, '\\"');
499
+ function toMemCCheck(data) {
500
+ let n = data.length << 1;
501
+ let out = "";
502
+ let offset = 0;
503
+ let index = 0;
504
+ while (n >= 8) {
505
+ out += ` && code${index++} == ${toU64(data, offset >> 1)}`;
506
+ offset += 8;
507
+ n -= 8;
508
+ }
509
+ while (n >= 4) {
510
+ out += ` && code${index++} == ${toU32(data, offset >> 1)}`;
511
+ offset += 4;
512
+ n -= 4;
513
+ }
514
+ if (n == 1) out += ` && code${index++} == ${toU16(data, offset >> 1)}`;
515
+ return out.slice(4);
438
516
  }
439
- function getArgs(args) {
440
- if (!args)
441
- return [];
442
- let out = [];
443
- for (const arg of args) {
444
- if (arg instanceof StringLiteralExpression) {
445
- out.push(arg.value);
446
- }
447
- else if (arg instanceof IntegerLiteralExpression) {
448
- out.push(i64_to_string(arg.value));
449
- }
450
- else if (arg instanceof FloatLiteralExpression) {
451
- out.push(arg.value.toString());
452
- }
453
- else if (arg instanceof NullExpression) {
454
- out.push(arg.text);
455
- }
456
- else if (arg instanceof TrueExpression) {
457
- out.push(arg.text);
458
- }
459
- else if (arg instanceof FalseExpression) {
460
- out.push(arg.text);
461
- }
462
- else if (arg instanceof IdentifierExpression) {
463
- out.push(arg.text);
464
- }
465
- }
466
- return out;
517
+ function strToNum(data, simd = false, offset = 0) {
518
+ const out = [];
519
+ let n = data.length;
520
+ while (n >= 8 && simd) {
521
+ out.push(["v128", "i16x8(" + data.charCodeAt(offset + 0) + ", " + data.charCodeAt(offset + 1) + ", " + data.charCodeAt(offset + 2) + ", " + data.charCodeAt(offset + 3) + ", " + data.charCodeAt(offset + 4) + ", " + data.charCodeAt(offset + 5) + ", " + data.charCodeAt(offset + 6) + ", " + data.charCodeAt(offset + 7) + ")"]);
522
+ offset += 8;
523
+ n -= 8;
524
+ }
525
+ while (n >= 4) {
526
+ const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0));
527
+ out.push(["u64", value.toString()]);
528
+ offset += 4;
529
+ n -= 4;
530
+ }
531
+ while (n >= 2) {
532
+ const value = (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0);
533
+ out.push(["u32", value.toString()]);
534
+ offset += 2;
535
+ n -= 2;
536
+ }
537
+ if (n === 1) {
538
+ const value = data.charCodeAt(offset + 0);
539
+ out.push(["u16", value.toString()]);
540
+ }
541
+ return out;
542
+ }
543
+ function isPrimitive(type) {
544
+ const primitiveTypes = ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "f32", "f64", "bool", "boolean"];
545
+ return primitiveTypes.some((v) => type.includes(v));
546
+ }
547
+ function throwError(message, range) {
548
+ const err = new Error();
549
+ err.stack = `${message}\n at ${range.source.normalizedPath}:${range.source.lineAt(range.start)}:${range.source.columnAt()}\n`;
550
+ throw err;
551
+ }
552
+ function indentInc() {
553
+ indent += " ";
554
+ }
555
+ function indentDec() {
556
+ indent = indent.slice(0, Math.max(0, indent.length - 2));
557
+ }
558
+ function sizeof(type) {
559
+ if (type == "u8") return 6;
560
+ else if (type == "i8") return 8;
561
+ else if (type == "u16") return 10;
562
+ else if (type == "i16") return 12;
563
+ else if (type == "u32") return 20;
564
+ else if (type == "i32") return 22;
565
+ else if (type == "u64") return 40;
566
+ else if (type == "i64") return 40;
567
+ else if (type == "bool" || type == "boolean") return 10;
568
+ else return 0;
569
+ }
570
+ function allPrimitive(schema) {
571
+ return !schema.members.some((p) => p.byteSize == 0);
467
572
  }
468
- //# sourceMappingURL=index.js.map
573
+ //# sourceMappingURL=index.js.map