json-as 1.3.0 → 1.3.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 (295) hide show
  1. package/CHANGELOG.md +400 -0
  2. package/README.md +137 -32
  3. package/assembly/deserialize/index/arbitrary.ts +1 -1
  4. package/assembly/deserialize/index/array.ts +6 -1
  5. package/assembly/deserialize/index/float.ts +1 -1
  6. package/assembly/deserialize/index/integer.ts +1 -1
  7. package/assembly/deserialize/index/typedarray.ts +14 -0
  8. package/assembly/deserialize/index/unsigned.ts +1 -1
  9. package/assembly/deserialize/simd/string.ts +20 -16
  10. package/assembly/deserialize/simple/arbitrary.ts +1 -1
  11. package/assembly/deserialize/simple/array/generic.ts +42 -0
  12. package/assembly/deserialize/simple/array.ts +8 -1
  13. package/assembly/deserialize/{float.ts → simple/float.ts} +22 -2
  14. package/assembly/deserialize/{integer.ts → simple/integer.ts} +3 -2
  15. package/assembly/deserialize/simple/map.ts +60 -12
  16. package/assembly/deserialize/simple/object.ts +1 -1
  17. package/assembly/deserialize/simple/set.ts +119 -134
  18. package/assembly/deserialize/simple/staticarray.ts +12 -1
  19. package/assembly/deserialize/simple/string.ts +93 -2
  20. package/assembly/deserialize/simple/struct.ts +7 -157
  21. package/assembly/deserialize/simple/typedarray.ts +1 -1
  22. package/assembly/deserialize/{unsigned.ts → simple/unsigned.ts} +3 -2
  23. package/assembly/deserialize/swar/array/array.ts +42 -7
  24. package/assembly/deserialize/swar/array/bool.ts +5 -2
  25. package/assembly/deserialize/swar/array/float.ts +7 -3
  26. package/assembly/deserialize/swar/array/generic.ts +40 -0
  27. package/assembly/deserialize/swar/array/integer.ts +7 -4
  28. package/assembly/deserialize/swar/array/object.ts +20 -4
  29. package/assembly/deserialize/swar/array/shared.ts +18 -4
  30. package/assembly/deserialize/swar/array/string.ts +5 -2
  31. package/assembly/deserialize/swar/array/struct.ts +20 -4
  32. package/assembly/deserialize/swar/array.ts +56 -2
  33. package/assembly/deserialize/swar/string.ts +245 -370
  34. package/assembly/index.ts +207 -194
  35. package/assembly/serialize/index/arbitrary.ts +8 -3
  36. package/assembly/serialize/index/float.ts +1 -1
  37. package/assembly/serialize/index/object.ts +1 -5
  38. package/assembly/serialize/index/typedarray.ts +65 -0
  39. package/assembly/serialize/simd/string.ts +7 -16
  40. package/assembly/serialize/simple/arbitrary.ts +9 -3
  41. package/assembly/serialize/simple/array.ts +17 -6
  42. package/assembly/serialize/simple/float.ts +18 -4
  43. package/assembly/serialize/simple/map.ts +10 -27
  44. package/assembly/serialize/simple/object.ts +1 -5
  45. package/assembly/serialize/simple/set.ts +3 -4
  46. package/assembly/serialize/simple/staticarray.ts +4 -3
  47. package/assembly/serialize/simple/string.ts +3 -11
  48. package/assembly/serialize/simple/typedarray.ts +9 -7
  49. package/assembly/serialize/swar/string.ts +3 -12
  50. package/assembly/tsconfig.json +3 -2
  51. package/assembly/util/dragonbox-cache.ts +1322 -0
  52. package/assembly/util/dragonbox.ts +596 -0
  53. package/assembly/util/swar.ts +49 -0
  54. package/lib/as-bs.ts +92 -70
  55. package/package.json +35 -10
  56. package/transform/lib/index.d.ts +1 -0
  57. package/transform/lib/index.d.ts.map +1 -1
  58. package/transform/lib/index.js +559 -221
  59. package/transform/lib/index.js.map +1 -1
  60. package/transform/lib/linkers/custom.d.ts.map +1 -1
  61. package/transform/lib/linkers/custom.js +7 -3
  62. package/transform/lib/linkers/custom.js.map +1 -1
  63. package/transform/lib/types.d.ts +2 -0
  64. package/transform/lib/types.d.ts.map +1 -1
  65. package/transform/lib/types.js +13 -0
  66. package/transform/lib/types.js.map +1 -1
  67. package/.as-test/coverage/naive/coverage.arbitrary.spec.ts.log.json +0 -5628
  68. package/.as-test/coverage/naive/coverage.array.spec.ts.log.json +0 -5187
  69. package/.as-test/coverage/naive/coverage.bool.spec.ts.log.json +0 -5187
  70. package/.as-test/coverage/naive/coverage.box.spec.ts.log.json +0 -5187
  71. package/.as-test/coverage/naive/coverage.custom.spec.ts.log.json +0 -5187
  72. package/.as-test/coverage/naive/coverage.date.spec.ts.log.json +0 -5187
  73. package/.as-test/coverage/naive/coverage.enum.spec.ts.log.json +0 -5187
  74. package/.as-test/coverage/naive/coverage.float.spec.ts.log.json +0 -5187
  75. package/.as-test/coverage/naive/coverage.generics.spec.ts.log.json +0 -5187
  76. package/.as-test/coverage/naive/coverage.hierarchy.spec.ts.log.json +0 -5187
  77. package/.as-test/coverage/naive/coverage.integer.spec.ts.log.json +0 -5187
  78. package/.as-test/coverage/naive/coverage.map.spec.ts.log.json +0 -5187
  79. package/.as-test/coverage/naive/coverage.namespace.spec.ts.log.json +0 -5187
  80. package/.as-test/coverage/naive/coverage.null.spec.ts.log.json +0 -5187
  81. package/.as-test/coverage/naive/coverage.raw.spec.ts.log.json +0 -5187
  82. package/.as-test/coverage/naive/coverage.resolving.spec.ts.log.json +0 -5628
  83. package/.as-test/coverage/naive/coverage.set.spec.ts.log.json +0 -5187
  84. package/.as-test/coverage/naive/coverage.staticarray.spec.ts.log.json +0 -5187
  85. package/.as-test/coverage/naive/coverage.string.spec.ts.log.json +0 -5187
  86. package/.as-test/coverage/naive/coverage.struct.spec.ts.log.json +0 -5187
  87. package/.as-test/coverage/naive/coverage.types.spec.ts.log.json +0 -5187
  88. package/.as-test/coverage/simd/coverage.arbitrary.spec.ts.log.json +0 -5628
  89. package/.as-test/coverage/simd/coverage.array.spec.ts.log.json +0 -5187
  90. package/.as-test/coverage/simd/coverage.bool.spec.ts.log.json +0 -5187
  91. package/.as-test/coverage/simd/coverage.box.spec.ts.log.json +0 -5187
  92. package/.as-test/coverage/simd/coverage.custom.spec.ts.log.json +0 -5187
  93. package/.as-test/coverage/simd/coverage.date.spec.ts.log.json +0 -5187
  94. package/.as-test/coverage/simd/coverage.enum.spec.ts.log.json +0 -5187
  95. package/.as-test/coverage/simd/coverage.float.spec.ts.log.json +0 -5187
  96. package/.as-test/coverage/simd/coverage.generics.spec.ts.log.json +0 -5187
  97. package/.as-test/coverage/simd/coverage.hierarchy.spec.ts.log.json +0 -5187
  98. package/.as-test/coverage/simd/coverage.integer.spec.ts.log.json +0 -5187
  99. package/.as-test/coverage/simd/coverage.map.spec.ts.log.json +0 -5187
  100. package/.as-test/coverage/simd/coverage.namespace.spec.ts.log.json +0 -5187
  101. package/.as-test/coverage/simd/coverage.null.spec.ts.log.json +0 -5187
  102. package/.as-test/coverage/simd/coverage.raw.spec.ts.log.json +0 -5187
  103. package/.as-test/coverage/simd/coverage.resolving.spec.ts.log.json +0 -5628
  104. package/.as-test/coverage/simd/coverage.set.spec.ts.log.json +0 -5187
  105. package/.as-test/coverage/simd/coverage.staticarray.spec.ts.log.json +0 -5187
  106. package/.as-test/coverage/simd/coverage.string.spec.ts.log.json +0 -5187
  107. package/.as-test/coverage/simd/coverage.struct.spec.ts.log.json +0 -5187
  108. package/.as-test/coverage/simd/coverage.types.spec.ts.log.json +0 -5187
  109. package/.as-test/coverage/swar/coverage.arbitrary.spec.ts.log.json +0 -5628
  110. package/.as-test/coverage/swar/coverage.array.spec.ts.log.json +0 -5187
  111. package/.as-test/coverage/swar/coverage.bool.spec.ts.log.json +0 -5187
  112. package/.as-test/coverage/swar/coverage.box.spec.ts.log.json +0 -5187
  113. package/.as-test/coverage/swar/coverage.custom.spec.ts.log.json +0 -5187
  114. package/.as-test/coverage/swar/coverage.date.spec.ts.log.json +0 -5187
  115. package/.as-test/coverage/swar/coverage.enum.spec.ts.log.json +0 -5187
  116. package/.as-test/coverage/swar/coverage.float.spec.ts.log.json +0 -5187
  117. package/.as-test/coverage/swar/coverage.generics.spec.ts.log.json +0 -5187
  118. package/.as-test/coverage/swar/coverage.hierarchy.spec.ts.log.json +0 -5187
  119. package/.as-test/coverage/swar/coverage.integer.spec.ts.log.json +0 -5187
  120. package/.as-test/coverage/swar/coverage.map.spec.ts.log.json +0 -5187
  121. package/.as-test/coverage/swar/coverage.namespace.spec.ts.log.json +0 -5187
  122. package/.as-test/coverage/swar/coverage.null.spec.ts.log.json +0 -5187
  123. package/.as-test/coverage/swar/coverage.raw.spec.ts.log.json +0 -5187
  124. package/.as-test/coverage/swar/coverage.resolving.spec.ts.log.json +0 -5628
  125. package/.as-test/coverage/swar/coverage.set.spec.ts.log.json +0 -5187
  126. package/.as-test/coverage/swar/coverage.staticarray.spec.ts.log.json +0 -5187
  127. package/.as-test/coverage/swar/coverage.string.spec.ts.log.json +0 -5187
  128. package/.as-test/coverage/swar/coverage.struct.spec.ts.log.json +0 -5187
  129. package/.as-test/coverage/swar/coverage.types.spec.ts.log.json +0 -5187
  130. package/.as-test/logs/naive/run.arbitrary.spec.ts.log.json +0 -943
  131. package/.as-test/logs/naive/run.array.spec.ts.log.json +0 -1053
  132. package/.as-test/logs/naive/run.bool.spec.ts.log.json +0 -257
  133. package/.as-test/logs/naive/run.box.spec.ts.log.json +0 -353
  134. package/.as-test/logs/naive/run.custom.spec.ts.log.json +0 -309
  135. package/.as-test/logs/naive/run.date.spec.ts.log.json +0 -397
  136. package/.as-test/logs/naive/run.enum.spec.ts.log.json +0 -343
  137. package/.as-test/logs/naive/run.float.spec.ts.log.json +0 -453
  138. package/.as-test/logs/naive/run.generics.spec.ts.log.json +0 -393
  139. package/.as-test/logs/naive/run.hierarchy.spec.ts.log.json +0 -325
  140. package/.as-test/logs/naive/run.integer.spec.ts.log.json +0 -373
  141. package/.as-test/logs/naive/run.map.spec.ts.log.json +0 -247
  142. package/.as-test/logs/naive/run.namespace.spec.ts.log.json +0 -361
  143. package/.as-test/logs/naive/run.null.spec.ts.log.json +0 -273
  144. package/.as-test/logs/naive/run.raw.spec.ts.log.json +0 -309
  145. package/.as-test/logs/naive/run.resolving.spec.ts.log.json +0 -273
  146. package/.as-test/logs/naive/run.set.spec.ts.log.json +0 -733
  147. package/.as-test/logs/naive/run.staticarray.spec.ts.log.json +0 -931
  148. package/.as-test/logs/naive/run.string.spec.ts.log.json +0 -2289
  149. package/.as-test/logs/naive/run.struct.spec.ts.log.json +0 -523
  150. package/.as-test/logs/naive/run.types.spec.ts.log.json +0 -273
  151. package/.as-test/logs/naive/test.arbitrary.spec.ts.log.json +0 -943
  152. package/.as-test/logs/naive/test.array.spec.ts.log.json +0 -1053
  153. package/.as-test/logs/naive/test.bool.spec.ts.log.json +0 -257
  154. package/.as-test/logs/naive/test.box.spec.ts.log.json +0 -353
  155. package/.as-test/logs/naive/test.custom.spec.ts.log.json +0 -309
  156. package/.as-test/logs/naive/test.date.spec.ts.log.json +0 -397
  157. package/.as-test/logs/naive/test.enum.spec.ts.log.json +0 -343
  158. package/.as-test/logs/naive/test.float.spec.ts.log.json +0 -453
  159. package/.as-test/logs/naive/test.generics.spec.ts.log.json +0 -393
  160. package/.as-test/logs/naive/test.hierarchy.spec.ts.log.json +0 -325
  161. package/.as-test/logs/naive/test.integer.spec.ts.log.json +0 -373
  162. package/.as-test/logs/naive/test.log.json +0 -2289
  163. package/.as-test/logs/naive/test.map.spec.ts.log.json +0 -247
  164. package/.as-test/logs/naive/test.namespace.spec.ts.log.json +0 -361
  165. package/.as-test/logs/naive/test.null.spec.ts.log.json +0 -273
  166. package/.as-test/logs/naive/test.raw.spec.ts.log.json +0 -309
  167. package/.as-test/logs/naive/test.resolving.spec.ts.log.json +0 -273
  168. package/.as-test/logs/naive/test.set.spec.ts.log.json +0 -733
  169. package/.as-test/logs/naive/test.staticarray.spec.ts.log.json +0 -931
  170. package/.as-test/logs/naive/test.string.spec.ts.log.json +0 -2345
  171. package/.as-test/logs/naive/test.struct.spec.ts.log.json +0 -523
  172. package/.as-test/logs/naive/test.types.spec.ts.log.json +0 -273
  173. package/.as-test/logs/simd/run.arbitrary.spec.ts.log.json +0 -943
  174. package/.as-test/logs/simd/run.array.spec.ts.log.json +0 -1053
  175. package/.as-test/logs/simd/run.bool.spec.ts.log.json +0 -257
  176. package/.as-test/logs/simd/run.box.spec.ts.log.json +0 -353
  177. package/.as-test/logs/simd/run.custom.spec.ts.log.json +0 -309
  178. package/.as-test/logs/simd/run.date.spec.ts.log.json +0 -397
  179. package/.as-test/logs/simd/run.enum.spec.ts.log.json +0 -343
  180. package/.as-test/logs/simd/run.float.spec.ts.log.json +0 -453
  181. package/.as-test/logs/simd/run.generics.spec.ts.log.json +0 -393
  182. package/.as-test/logs/simd/run.hierarchy.spec.ts.log.json +0 -325
  183. package/.as-test/logs/simd/run.integer.spec.ts.log.json +0 -373
  184. package/.as-test/logs/simd/run.map.spec.ts.log.json +0 -247
  185. package/.as-test/logs/simd/run.namespace.spec.ts.log.json +0 -361
  186. package/.as-test/logs/simd/run.null.spec.ts.log.json +0 -273
  187. package/.as-test/logs/simd/run.raw.spec.ts.log.json +0 -309
  188. package/.as-test/logs/simd/run.resolving.spec.ts.log.json +0 -273
  189. package/.as-test/logs/simd/run.set.spec.ts.log.json +0 -733
  190. package/.as-test/logs/simd/run.staticarray.spec.ts.log.json +0 -931
  191. package/.as-test/logs/simd/run.string.spec.ts.log.json +0 -2289
  192. package/.as-test/logs/simd/run.struct.spec.ts.log.json +0 -523
  193. package/.as-test/logs/simd/run.types.spec.ts.log.json +0 -273
  194. package/.as-test/logs/simd/test.arbitrary.spec.ts.log.json +0 -943
  195. package/.as-test/logs/simd/test.array.spec.ts.log.json +0 -1053
  196. package/.as-test/logs/simd/test.bool.spec.ts.log.json +0 -257
  197. package/.as-test/logs/simd/test.box.spec.ts.log.json +0 -353
  198. package/.as-test/logs/simd/test.custom.spec.ts.log.json +0 -309
  199. package/.as-test/logs/simd/test.date.spec.ts.log.json +0 -397
  200. package/.as-test/logs/simd/test.enum.spec.ts.log.json +0 -343
  201. package/.as-test/logs/simd/test.float.spec.ts.log.json +0 -453
  202. package/.as-test/logs/simd/test.generics.spec.ts.log.json +0 -393
  203. package/.as-test/logs/simd/test.hierarchy.spec.ts.log.json +0 -325
  204. package/.as-test/logs/simd/test.integer.spec.ts.log.json +0 -373
  205. package/.as-test/logs/simd/test.log.json +0 -11371
  206. package/.as-test/logs/simd/test.map.spec.ts.log.json +0 -247
  207. package/.as-test/logs/simd/test.namespace.spec.ts.log.json +0 -361
  208. package/.as-test/logs/simd/test.null.spec.ts.log.json +0 -273
  209. package/.as-test/logs/simd/test.raw.spec.ts.log.json +0 -309
  210. package/.as-test/logs/simd/test.resolving.spec.ts.log.json +0 -273
  211. package/.as-test/logs/simd/test.set.spec.ts.log.json +0 -733
  212. package/.as-test/logs/simd/test.staticarray.spec.ts.log.json +0 -931
  213. package/.as-test/logs/simd/test.string.spec.ts.log.json +0 -2345
  214. package/.as-test/logs/simd/test.struct.spec.ts.log.json +0 -523
  215. package/.as-test/logs/simd/test.types.spec.ts.log.json +0 -273
  216. package/.as-test/logs/swar/run.arbitrary.spec.ts.log.json +0 -943
  217. package/.as-test/logs/swar/run.array.spec.ts.log.json +0 -1053
  218. package/.as-test/logs/swar/run.bool.spec.ts.log.json +0 -257
  219. package/.as-test/logs/swar/run.box.spec.ts.log.json +0 -353
  220. package/.as-test/logs/swar/run.custom.spec.ts.log.json +0 -309
  221. package/.as-test/logs/swar/run.date.spec.ts.log.json +0 -397
  222. package/.as-test/logs/swar/run.enum.spec.ts.log.json +0 -343
  223. package/.as-test/logs/swar/run.float.spec.ts.log.json +0 -453
  224. package/.as-test/logs/swar/run.generics.spec.ts.log.json +0 -393
  225. package/.as-test/logs/swar/run.hierarchy.spec.ts.log.json +0 -325
  226. package/.as-test/logs/swar/run.integer.spec.ts.log.json +0 -373
  227. package/.as-test/logs/swar/run.map.spec.ts.log.json +0 -247
  228. package/.as-test/logs/swar/run.namespace.spec.ts.log.json +0 -361
  229. package/.as-test/logs/swar/run.null.spec.ts.log.json +0 -273
  230. package/.as-test/logs/swar/run.raw.spec.ts.log.json +0 -309
  231. package/.as-test/logs/swar/run.resolving.spec.ts.log.json +0 -273
  232. package/.as-test/logs/swar/run.set.spec.ts.log.json +0 -733
  233. package/.as-test/logs/swar/run.staticarray.spec.ts.log.json +0 -931
  234. package/.as-test/logs/swar/run.string.spec.ts.log.json +0 -2289
  235. package/.as-test/logs/swar/run.struct.spec.ts.log.json +0 -523
  236. package/.as-test/logs/swar/run.types.spec.ts.log.json +0 -273
  237. package/.as-test/logs/swar/test.arbitrary.spec.ts.log.json +0 -943
  238. package/.as-test/logs/swar/test.array.spec.ts.log.json +0 -1053
  239. package/.as-test/logs/swar/test.bool.spec.ts.log.json +0 -257
  240. package/.as-test/logs/swar/test.box.spec.ts.log.json +0 -353
  241. package/.as-test/logs/swar/test.custom.spec.ts.log.json +0 -309
  242. package/.as-test/logs/swar/test.date.spec.ts.log.json +0 -397
  243. package/.as-test/logs/swar/test.enum.spec.ts.log.json +0 -343
  244. package/.as-test/logs/swar/test.float.spec.ts.log.json +0 -453
  245. package/.as-test/logs/swar/test.generics.spec.ts.log.json +0 -393
  246. package/.as-test/logs/swar/test.hierarchy.spec.ts.log.json +0 -325
  247. package/.as-test/logs/swar/test.integer.spec.ts.log.json +0 -373
  248. package/.as-test/logs/swar/test.log.json +0 -11371
  249. package/.as-test/logs/swar/test.map.spec.ts.log.json +0 -247
  250. package/.as-test/logs/swar/test.namespace.spec.ts.log.json +0 -361
  251. package/.as-test/logs/swar/test.null.spec.ts.log.json +0 -273
  252. package/.as-test/logs/swar/test.raw.spec.ts.log.json +0 -309
  253. package/.as-test/logs/swar/test.resolving.spec.ts.log.json +0 -273
  254. package/.as-test/logs/swar/test.set.spec.ts.log.json +0 -733
  255. package/.as-test/logs/swar/test.staticarray.spec.ts.log.json +0 -931
  256. package/.as-test/logs/swar/test.string.spec.ts.log.json +0 -2345
  257. package/.as-test/logs/swar/test.struct.spec.ts.log.json +0 -523
  258. package/.as-test/logs/swar/test.types.spec.ts.log.json +0 -273
  259. package/.as-test/logs/test.arbitrary.spec.ts.log.json +0 -943
  260. package/.as-test/logs/test.array.spec.ts.log.json +0 -1053
  261. package/.as-test/logs/test.bool.spec.ts.log.json +0 -257
  262. package/.as-test/logs/test.box.spec.ts.log.json +0 -353
  263. package/.as-test/logs/test.custom.spec.ts.log.json +0 -309
  264. package/.as-test/logs/test.date.spec.ts.log.json +0 -397
  265. package/.as-test/logs/test.enum.spec.ts.log.json +0 -343
  266. package/.as-test/logs/test.float.spec.ts.log.json +0 -453
  267. package/.as-test/logs/test.generics.spec.ts.log.json +0 -393
  268. package/.as-test/logs/test.hierarchy.spec.ts.log.json +0 -325
  269. package/.as-test/logs/test.integer.spec.ts.log.json +0 -373
  270. package/.as-test/logs/test.log.json +0 -11371
  271. package/.as-test/logs/test.map.spec.ts.log.json +0 -247
  272. package/.as-test/logs/test.namespace.spec.ts.log.json +0 -361
  273. package/.as-test/logs/test.null.spec.ts.log.json +0 -273
  274. package/.as-test/logs/test.raw.spec.ts.log.json +0 -309
  275. package/.as-test/logs/test.resolving.spec.ts.log.json +0 -273
  276. package/.as-test/logs/test.set.spec.ts.log.json +0 -733
  277. package/.as-test/logs/test.staticarray.spec.ts.log.json +0 -931
  278. package/.as-test/logs/test.string.spec.ts.log.json +0 -2289
  279. package/.as-test/logs/test.struct.spec.ts.log.json +0 -523
  280. package/.as-test/logs/test.types.spec.ts.log.json +0 -273
  281. package/.as-test/runners/default.bindings.js +0 -68
  282. package/.as-test/runners/default.wasi.js +0 -38
  283. package/ARCHITECTURE.md +0 -323
  284. package/CONTRIBUTING.md +0 -244
  285. package/TODO +0 -1
  286. package/as-test.config.json +0 -40
  287. package/assembly/test.ts +0 -24
  288. package/eslint.config.js +0 -68
  289. package/lib/tsconfig.json +0 -8
  290. package/test.ts +0 -99
  291. package/tools/assemblyscript-eslint-local.js +0 -6
  292. package/tools/assemblyscript-eslint.js +0 -53
  293. package/tools/assemblyscript-prettier-plugin.js +0 -33
  294. package/tools/replacer.js +0 -63
  295. package/transform/tsconfig.json +0 -35
@@ -19,10 +19,63 @@ function needsReferenceLoad(type) {
19
19
  }
20
20
  function getSerializeCall(type, realName) {
21
21
  if (type == "ArrayBuffer") {
22
- return `JSON.__serializeArrayBuffer(load<ArrayBuffer>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
22
+ return `JSON.__serialize<ArrayBuffer>(load<ArrayBuffer>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
23
23
  }
24
24
  return needsReferenceLoad(type) ? `JSON.__serialize<${type}>(changetype<${type}>(load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))));\n` : `JSON.__serialize<${type}>(load<${type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
25
25
  }
26
+ const CUSTOM_JSON_KINDS = new Set(["any", "string", "number", "object", "array", "boolean", "null", "any | null", "string | null", "number | null", "object | null", "array | null", "boolean | null"]);
27
+ function parseCustomJsonKind(method, decoratorName) {
28
+ const decorator = method.decorators?.find((v) => v.name.text.toLowerCase() == decoratorName);
29
+ if (!decorator || !decorator.args || decorator.args.length == 0)
30
+ return "any";
31
+ if (decorator.args.length > 1)
32
+ throwError(`@${decoratorName} accepts at most one argument`, decorator.range);
33
+ const arg = decorator.args[0];
34
+ if (arg.kind != 16 || arg.literalKind != 2) {
35
+ throwError(`@${decoratorName} argument must be a string literal like @${decoratorName}("string")`, arg.range);
36
+ }
37
+ const kind = arg.value;
38
+ if (!CUSTOM_JSON_KINDS.has(kind)) {
39
+ throwError(`Unsupported @${decoratorName} JSON type '${kind}'. Expected one of: any, string, number, object, array, boolean, null`, arg.range);
40
+ }
41
+ return kind;
42
+ }
43
+ function addMemberToCustomBucket(sortedMembers, member, kind) {
44
+ const isNullable = kind.endsWith(" | null");
45
+ const baseKind = isNullable ? kind.slice(0, kind.length - 7) : kind;
46
+ if (isNullable)
47
+ sortedMembers.null.push(member);
48
+ switch (baseKind) {
49
+ case "string":
50
+ sortedMembers.string.push(member);
51
+ break;
52
+ case "number":
53
+ sortedMembers.number.push(member);
54
+ break;
55
+ case "boolean":
56
+ sortedMembers.boolean.push(member);
57
+ break;
58
+ case "null":
59
+ if (!isNullable)
60
+ sortedMembers.null.push(member);
61
+ break;
62
+ case "array":
63
+ sortedMembers.array.push(member);
64
+ break;
65
+ case "object":
66
+ sortedMembers.object.push(member);
67
+ break;
68
+ default:
69
+ sortedMembers.string.push(member);
70
+ sortedMembers.number.push(member);
71
+ sortedMembers.object.push(member);
72
+ sortedMembers.array.push(member);
73
+ sortedMembers.boolean.push(member);
74
+ if (!isNullable)
75
+ sortedMembers.null.push(member);
76
+ break;
77
+ }
78
+ }
26
79
  export class JSONTransform extends Visitor {
27
80
  static SN = new JSONTransform();
28
81
  program;
@@ -34,6 +87,46 @@ export class JSONTransform extends Visitor {
34
87
  imports = [];
35
88
  simdStatements = [];
36
89
  visitedClasses = new Set();
90
+ collectInheritedFieldMembers(node, source, members, visited = new Set()) {
91
+ if (!node.extendsType)
92
+ return;
93
+ const extendsName = source.resolveExtendsName(node);
94
+ if (!extendsName || visited.has(extendsName))
95
+ return;
96
+ visited.add(extendsName);
97
+ let baseDecl = source.getClass(extendsName);
98
+ let baseSource = baseDecl ? source : null;
99
+ if (!baseDecl) {
100
+ const imported = source.getImportedClass(extendsName, this.parser);
101
+ if (imported) {
102
+ baseDecl = imported;
103
+ baseSource = this.sources.get(imported.range.source);
104
+ }
105
+ }
106
+ if (!baseDecl) {
107
+ const available = source.getAvailableClass(extendsName, this.parser);
108
+ if (available) {
109
+ baseDecl = available;
110
+ baseSource = this.sources.get(available.range.source);
111
+ }
112
+ }
113
+ if (!baseDecl || !baseSource)
114
+ return;
115
+ const isDecoratedBase = !!baseDecl.decorators?.some((decorator) => {
116
+ const name = decorator.name.text;
117
+ return name === "json" || name === "serializable";
118
+ });
119
+ if (isDecoratedBase)
120
+ return;
121
+ this.collectInheritedFieldMembers(baseDecl, baseSource, members, visited);
122
+ const inheritedMembers = baseDecl.members.filter((v) => v.kind === 54 && !v.is(32) && !v.is(512) && !v.is(1024) && !v.decorators?.some((decorator) => decorator.name.text === "omit"));
123
+ for (let i = inheritedMembers.length - 1; i >= 0; i--) {
124
+ const inherited = inheritedMembers[i];
125
+ if (!members.some((member) => member.name.text == inherited.name.text)) {
126
+ members.unshift(inherited);
127
+ }
128
+ }
129
+ }
37
130
  visitClassDeclarationRef(node) {
38
131
  if (!node.decorators?.length ||
39
132
  !node.decorators.some((decorator) => {
@@ -88,13 +181,14 @@ export class JSONTransform extends Visitor {
88
181
  return;
89
182
  if (!this.schemas.has(source.internalPath))
90
183
  this.schemas.set(source.internalPath, []);
91
- 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"))];
184
+ const members = [...node.members.filter((v) => v.kind === 54 && !v.is(32) && !v.is(512) && !v.is(1024) && !v.decorators?.some((decorator) => decorator.name.text === "omit"))];
92
185
  const serializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "serializer") && !v.name.text.startsWith("__try"))];
93
186
  const deserializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "deserializer") && !v.name.text.startsWith("__try"))];
94
187
  const schema = new Schema();
95
188
  schema.node = node;
96
189
  schema.name = source.getQualifiedName(node);
97
190
  if (node.extendsType) {
191
+ this.collectInheritedFieldMembers(node, source, members);
98
192
  const extendsName = source.resolveExtendsName(node);
99
193
  if (!schema.parent) {
100
194
  const depSearch = schema.deps.find((v) => v.name == extendsName);
@@ -140,6 +234,30 @@ export class JSONTransform extends Visitor {
140
234
  schema.deps.push(schem);
141
235
  schema.parent = schem;
142
236
  }
237
+ else {
238
+ const availableSearch = source.getAvailableClass(extendsName, this.parser);
239
+ if (availableSearch) {
240
+ if (DEBUG > 0)
241
+ console.log("Found " + availableSearch.name.text + " from available sources for " + source.internalPath);
242
+ const availableSource = this.sources.get(availableSearch.range.source);
243
+ if (availableSearch.decorators?.some((decorator) => {
244
+ const name = decorator.name.text;
245
+ return name === "json" || name === "serializable";
246
+ })) {
247
+ if (!this.visitedClasses.has(availableSource.getFullPath(availableSearch))) {
248
+ this.visitClassDeclarationRef(availableSearch);
249
+ this.schemas.get(availableSource.internalPath).push(this.schema);
250
+ this.visitClassDeclaration(node);
251
+ return;
252
+ }
253
+ const schem = this.schemas.get(availableSource.internalPath)?.find((s) => s.name == extendsName);
254
+ if (schem) {
255
+ schema.deps.push(schem);
256
+ schema.parent = schem;
257
+ }
258
+ }
259
+ }
260
+ }
143
261
  }
144
262
  }
145
263
  }
@@ -240,7 +358,7 @@ export class JSONTransform extends Visitor {
240
358
  this.schema = schema;
241
359
  this.visitedClasses.add(fullClassPath);
242
360
  const codegenMode = getCodegenMode(this.program);
243
- const useFastPath = USE_FAST_PATH && codegenMode !== JSONMode.NAIVE;
361
+ const requestedFastPath = USE_FAST_PATH && codegenMode !== JSONMode.NAIVE;
244
362
  let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
245
363
  let INITIALIZE = "@inline __INITIALIZE(): this {\n";
246
364
  let DESERIALIZE = "__DESERIALIZE_SLOW<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n";
@@ -256,7 +374,9 @@ export class JSONTransform extends Visitor {
256
374
  if (serializers.length) {
257
375
  this.schema.custom = true;
258
376
  const serializer = serializers[0];
377
+ const serializerJsonKind = parseCustomJsonKind(serializer, "serializer");
259
378
  const hasCall = CustomTransform.hasCall(serializer);
379
+ this.schema.customJsonKind = serializerJsonKind;
260
380
  CustomTransform.visit(serializer);
261
381
  if (serializer.signature.parameters.length > 1)
262
382
  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);
@@ -268,9 +388,16 @@ export class JSONTransform extends Visitor {
268
388
  serializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", serializer.range), null, serializer.range));
269
389
  }
270
390
  SERIALIZE_CUSTOM += " __SERIALIZE(ptr: usize): void {\n";
271
- SERIALIZE_CUSTOM += " const data = this." + serializer.name.text + "(" + (serializer.signature.parameters.length ? "this" : "") + ");\n";
272
- if (hasCall)
273
- SERIALIZE_CUSTOM += " bs.resetState();\n";
391
+ if (hasCall) {
392
+ SERIALIZE_CUSTOM += " const savedOffset = bs.offset;\n";
393
+ SERIALIZE_CUSTOM += " const savedStackSize = bs.stackSize;\n";
394
+ }
395
+ SERIALIZE_CUSTOM += " const self = changetype<this>(ptr);\n";
396
+ SERIALIZE_CUSTOM += " const data = self." + serializer.name.text + "(" + (serializer.signature.parameters.length ? "self" : "") + ");\n";
397
+ if (hasCall) {
398
+ SERIALIZE_CUSTOM += " bs.offset = savedOffset;\n";
399
+ SERIALIZE_CUSTOM += " bs.stackSize = savedStackSize;\n";
400
+ }
274
401
  SERIALIZE_CUSTOM += " const dataSize = data.length << 1;\n";
275
402
  SERIALIZE_CUSTOM += " memory.copy(bs.offset, changetype<usize>(data), dataSize);\n";
276
403
  SERIALIZE_CUSTOM += " bs.offset += dataSize;\n";
@@ -279,6 +406,12 @@ export class JSONTransform extends Visitor {
279
406
  if (deserializers.length) {
280
407
  this.schema.custom = true;
281
408
  const deserializer = deserializers[0];
409
+ const deserializerJsonKind = parseCustomJsonKind(deserializer, "deserializer");
410
+ if (this.schema.customJsonKind != "any" && deserializerJsonKind != "any" && this.schema.customJsonKind != deserializerJsonKind) {
411
+ throwError(`@serializer and @deserializer JSON types for ${this.schema.name} must match`, deserializer.range);
412
+ }
413
+ if (this.schema.customJsonKind == "any")
414
+ this.schema.customJsonKind = deserializerJsonKind;
282
415
  if (!deserializer.signature.parameters.length)
283
416
  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);
284
417
  if (deserializer.signature.parameters.length > 1)
@@ -290,10 +423,8 @@ export class JSONTransform extends Visitor {
290
423
  if (!deserializer.decorators.some((v) => v.name.text == "inline")) {
291
424
  deserializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", deserializer.range), null, deserializer.range));
292
425
  }
293
- DESERIALIZE_CUSTOM += " __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n";
294
- DESERIALIZE_CUSTOM += " const data = inline.always(this." + deserializer.name.text + "(JSON.Util.ptrToStr(srcStart, srcEnd)));\n";
295
- DESERIALIZE_CUSTOM += " memory.copy(changetype<usize>(out), changetype<usize>(data), offsetof<nonnull<__JSON_T>>());\n";
296
- DESERIALIZE_CUSTOM += " return srcEnd;\n";
426
+ DESERIALIZE_CUSTOM += " @inline __DESERIALIZE_CUSTOM(data: string): this {\n";
427
+ DESERIALIZE_CUSTOM += " return inline.always(this." + deserializer.name.text + "(data));\n";
297
428
  DESERIALIZE_CUSTOM += " }\n";
298
429
  }
299
430
  if (!members.length && !deserializers.length && !serializers.length) {
@@ -316,6 +447,7 @@ export class JSONTransform extends Visitor {
316
447
  mem.value = value;
317
448
  mem.node = member;
318
449
  mem.byteSize = sizeof(mem.type);
450
+ mem.custom = schema.deps.some((dep) => dep?.name == stripNull(type) && dep.custom);
319
451
  this.schema.byteSize += mem.byteSize;
320
452
  if (member.decorators) {
321
453
  for (const decorator of member.decorators) {
@@ -354,6 +486,12 @@ export class JSONTransform extends Visitor {
354
486
  }
355
487
  if (!this.schema.static)
356
488
  this.schema.members = sortMembers(this.schema.members);
489
+ const hasOmitIfMembers = this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitIf));
490
+ const hasOmitNullMembers = this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull));
491
+ const hasOptionalMembers = hasOmitIfMembers || hasOmitNullMembers;
492
+ const supportsFastOptionalPath = requestedFastPath && hasOptionalMembers;
493
+ const hasTypeParams = !!node.typeParameters && node.typeParameters.length > 0;
494
+ const useFastPath = requestedFastPath && !hasTypeParams && (this.schema.static || supportsFastOptionalPath);
357
495
  indent = " ";
358
496
  if (this.schema.static == false) {
359
497
  if (this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull))) {
@@ -371,36 +509,34 @@ export class JSONTransform extends Visitor {
371
509
  const aliasName = JSON.stringify(member.alias || member.name);
372
510
  const realName = member.name;
373
511
  const isLast = i == this.schema.members.length - 1;
374
- if (!useFastPath) {
375
- if (member.value) {
376
- if (member.value != "null" && member.value != "0" && member.value != "0.0" && member.value != "false") {
377
- INITIALIZE += ` store<${member.type}>(changetype<usize>(this), ${member.value}, offsetof<this>(${JSON.stringify(member.name)}));\n`;
378
- }
512
+ if (member.value) {
513
+ if (member.value != "null" && member.value != "0" && member.value != "0.0" && member.value != "false") {
514
+ INITIALIZE += ` store<${member.type}>(changetype<usize>(this), ${member.value}, offsetof<this>(${JSON.stringify(member.name)}));\n`;
379
515
  }
380
- else if (member.generic) {
381
- INITIALIZE += ` if (isManaged<nonnull<${member.type}>>() || isReference<nonnull<${member.type}>>()) {\n`;
382
- INITIALIZE += ` store<${member.type}>(changetype<usize>(this), changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())), offsetof<this>(${JSON.stringify(member.name)}));\n`;
383
- INITIALIZE += ` if (isDefined(this.${member.name}.__INITIALIZE)) changetype<nonnull<${member.type}>>(this.${member.name}).__INITIALIZE();\n`;
384
- INITIALIZE += ` }\n`;
516
+ }
517
+ else if (member.generic) {
518
+ INITIALIZE += ` if (isManaged<nonnull<${member.type}>>() || isReference<nonnull<${member.type}>>()) {\n`;
519
+ INITIALIZE += ` store<${member.type}>(changetype<usize>(this), changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())), offsetof<this>(${JSON.stringify(member.name)}));\n`;
520
+ INITIALIZE += ` if (isDefined(this.${member.name}.__INITIALIZE)) changetype<nonnull<${member.type}>>(this.${member.name}).__INITIALIZE();\n`;
521
+ INITIALIZE += ` }\n`;
522
+ }
523
+ else if (!member.node.type.isNullable) {
524
+ if (this.getSchema(member.type)) {
525
+ INITIALIZE += ` store<${member.type}>(changetype<usize>(this), changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
385
526
  }
386
- else if (!member.node.type.isNullable) {
387
- if (this.getSchema(member.type)) {
388
- INITIALIZE += ` store<${member.type}>(changetype<usize>(this), changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
389
- }
390
- else if (member.type.startsWith("Array<")) {
391
- INITIALIZE += ` store<${member.type}>(changetype<usize>(this), [], offsetof<this>(${JSON.stringify(member.name)}));\n`;
392
- }
393
- else if (member.type.startsWith("Map<")) {
394
- INITIALIZE += ` store<${member.type}>(changetype<usize>(this), new ${member.type}(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
395
- }
396
- else if (member.type.startsWith("Set<")) {
397
- INITIALIZE += ` store<${member.type}>(changetype<usize>(this), new ${member.type}(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
398
- }
399
- else if (member.type.startsWith("StaticArray<")) {
400
- }
401
- else if (member.type == "string" || member.type == "String") {
402
- INITIALIZE += ` store<${member.type}>(changetype<usize>(this), "", offsetof<this>(${JSON.stringify(member.name)}));\n`;
403
- }
527
+ else if (member.type.startsWith("Array<")) {
528
+ INITIALIZE += ` store<${member.type}>(changetype<usize>(this), [], offsetof<this>(${JSON.stringify(member.name)}));\n`;
529
+ }
530
+ else if (member.type.startsWith("Map<")) {
531
+ INITIALIZE += ` store<${member.type}>(changetype<usize>(this), new ${member.type}(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
532
+ }
533
+ else if (member.type.startsWith("Set<")) {
534
+ INITIALIZE += ` store<${member.type}>(changetype<usize>(this), new ${member.type}(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
535
+ }
536
+ else if (member.type.startsWith("StaticArray<")) {
537
+ }
538
+ else if (member.type == "string" || member.type == "String") {
539
+ INITIALIZE += ` store<${member.type}>(changetype<usize>(this), "", offsetof<this>(${JSON.stringify(member.name)}));\n`;
404
540
  }
405
541
  }
406
542
  const SIMD_ENABLED = this.program.options.hasFeature(16);
@@ -482,19 +618,20 @@ export class JSONTransform extends Visitor {
482
618
  };
483
619
  for (const member of this.schema.members) {
484
620
  const type = stripNull(member.type);
485
- if (member.custom || member.generic) {
486
- sortedMembers.string.push(member);
487
- sortedMembers.number.push(member);
488
- sortedMembers.object.push(member);
489
- sortedMembers.array.push(member);
490
- sortedMembers.boolean.push(member);
491
- sortedMembers.null.push(member);
621
+ const customDep = this.schema.deps.find((dep) => dep && (dep.name == type || dep.name.endsWith("." + type)) && dep.custom);
622
+ const isCustomType = member.custom || !!customDep;
623
+ if (isCustomType || member.generic) {
624
+ addMemberToCustomBucket(sortedMembers, member, member.generic ? "any" : customDep?.customJsonKind || "any");
625
+ if (member.node.type.isNullable)
626
+ sortedMembers.null.push(member);
492
627
  }
493
628
  else {
494
629
  if (member.node.type.isNullable)
495
630
  sortedMembers.null.push(member);
496
- if (isString(type) || type == "JSON.Raw")
631
+ if (isString(type) || type == "Date")
497
632
  sortedMembers.string.push(member);
633
+ else if (type == "JSON.Raw")
634
+ sortedMembers.object.push(member);
498
635
  else if (isBoolean(type) || type.startsWith("JSON.Box<bool"))
499
636
  sortedMembers.boolean.push(member);
500
637
  else if (isPrimitive(type) || type.startsWith("JSON.Box<") || isEnum(type, this.sources.get(this.schema.node.range.source), this.parser))
@@ -534,21 +671,15 @@ export class JSONTransform extends Visitor {
534
671
  const FLOAT_TYPES = ["f32", "f64"];
535
672
  const INTEGER_TYPES = [...UNSIGNED_INTEGER_TYPES, ...SIGNED_INTEGER_TYPES];
536
673
  const STRING_FIELD_DESERIALIZER = codegenMode === JSONMode.SIMD ? "deserializeStringField_SIMD" : "deserializeStringField_SWAR";
537
- const getArrayValueType = (type) => {
538
- if (type.startsWith("Array<") || type.startsWith("StaticArray<")) {
539
- return stripNull(type.slice(type.indexOf("<") + 1, -1).trim());
540
- }
541
- return null;
542
- };
543
- const getDeserializer = (type, srcPtr, outPtr, member, keyOffset = 0) => {
674
+ const getDeserializer = (type, srcPtr, outPtr, member, keyOffset = 0, fastPath = false) => {
544
675
  const out = [];
545
676
  const resolvedType = stripNull(type);
677
+ const resolvedSchema = this.getSchema(resolvedType);
546
678
  const fieldOffset = `offsetof<this>(${JSON.stringify(member.name)})`;
547
- const fieldPtr = `${outPtr} + offsetof<this>(${JSON.stringify(member.name)})`;
548
679
  const valuePtr = keyOffset ? `${srcPtr} + ${keyOffset}` : srcPtr;
549
680
  if (INTEGER_TYPES.includes(resolvedType)) {
550
681
  const helper = SIGNED_INTEGER_TYPES.includes(resolvedType) ? "deserializeIntegerField" : "deserializeUnsignedField";
551
- out.push(`${srcPtr} = ${helper}<${resolvedType}>(${valuePtr}, srcEnd, ${fieldPtr});`);
682
+ out.push(`${srcPtr} = ${helper}<${resolvedType}>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
552
683
  }
553
684
  else if (["string", "String"].includes(resolvedType)) {
554
685
  out.push("{");
@@ -558,125 +689,69 @@ export class JSONTransform extends Visitor {
558
689
  out.push(` ${srcPtr} = ${valuePtr} + 8;`);
559
690
  out.push(" } else {");
560
691
  }
561
- out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${member.type}>(${valuePtr}, srcEnd, ${fieldPtr});`);
692
+ out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${member.type}>(${valuePtr}, srcEnd, ${outPtr} + ${fieldOffset});`);
562
693
  if (member.node.type.isNullable) {
563
694
  out.push(" }");
564
695
  }
565
696
  out.push("}");
566
697
  }
567
- else if (isBoolean(resolvedType)) {
568
- out.push("{");
569
- out.push(` if (load<u64>(${srcPtr}) == 28429475166421108) {`);
570
- out.push(` store<${resolvedType}>(${outPtr}, true, ${fieldOffset});`);
571
- out.push(` ${srcPtr} += 8;`);
572
- out.push(" } else if (load<u64>(" + srcPtr + ") == 32370086184550502 && load<u16>(" + srcPtr + ", 8) == 101) {");
573
- out.push(` store<${resolvedType}>(${outPtr}, false, ${fieldOffset});`);
574
- out.push(` ${srcPtr} += 10;`);
575
- out.push(" } else break;");
576
- out.push("}");
577
- }
578
- else if (FLOAT_TYPES.includes(resolvedType)) {
579
- out.push(`${srcPtr} = deserializeFloatField<${resolvedType}>(${valuePtr}, srcEnd, ${fieldPtr});`);
580
- }
581
- else if (this.getSchema(resolvedType)) {
698
+ else if (resolvedType == "Date") {
582
699
  out.push("{");
583
700
  if (member.node.type.isNullable) {
584
- out.push(` if (load<u64>(${srcPtr}) == 30399761348886638) {`);
585
- out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(0), ${fieldOffset});`);
586
- out.push(` ${srcPtr} += 8;`);
701
+ out.push(` if (load<u64>(${valuePtr}) == 30399761348886638) {`);
702
+ out.push(` store<${member.type}>(${outPtr}, changetype<${member.type}>(0), ${fieldOffset});`);
703
+ out.push(` ${srcPtr} = ${valuePtr} + 8;`);
587
704
  out.push(" } else {");
588
705
  }
589
- out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
590
- out.push(" if (changetype<usize>(value) == 0) {");
591
- out.push(` value = changetype<${resolvedType}>(__new(offsetof<nonnull<${resolvedType}>>(), idof<nonnull<${resolvedType}>>()));`);
592
- out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
706
+ out.push(` if (load<u16>(${valuePtr}) != 0x22) break;`);
707
+ out.push(` let dateEnd = ${valuePtr} + 2;`);
708
+ out.push(` while (dateEnd < srcEnd) {`);
709
+ out.push(" if (load<u16>(dateEnd) == 0x22 && load<u16>(dateEnd - 2) != 0x5c) break;");
710
+ out.push(" dateEnd += 2;");
593
711
  out.push(" }");
594
- out.push(` ${srcPtr} = changetype<nonnull<${resolvedType}>>(value).__DESERIALIZE<${resolvedType}>(${srcPtr}, srcEnd, value);`);
712
+ out.push(" if (dateEnd >= srcEnd) break;");
713
+ out.push(` store<${resolvedType}>(${outPtr}, JSON.__deserialize<${resolvedType}>(${valuePtr}, dateEnd + 2), ${fieldOffset});`);
714
+ out.push(` ${srcPtr} = dateEnd + 2;`);
595
715
  if (member.node.type.isNullable) {
596
716
  out.push(" }");
597
717
  }
598
718
  out.push("}");
599
719
  }
600
- else if (resolvedType.startsWith("Array<")) {
601
- const valueType = getArrayValueType(resolvedType);
602
- if (valueType && ["string", "String"].includes(valueType)) {
603
- out.push("{");
604
- out.push(` if (load<u16>(${srcPtr}) != 0x5b) break;`);
605
- out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
606
- out.push(" if (changetype<usize>(value) == 0) {");
607
- out.push(` value = [];`);
608
- out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
609
- out.push(" }");
610
- out.push(" let index = 0;");
611
- out.push(` ${srcPtr} += 2;`);
612
- out.push(` if (load<u16>(${srcPtr}) == 0x5d) {`);
613
- out.push(" value.length = 0;");
614
- out.push(` ${srcPtr} += 2;`);
615
- out.push(" } else while (true) {");
616
- out.push(' if (index >= value.length) value.push("");');
617
- out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${valueType}>(${srcPtr}, srcEnd, value.dataStart + ((<usize>index) << alignof<${valueType}>()));`);
618
- out.push(" index++;");
619
- out.push(` const code = load<u16>(${srcPtr});`);
620
- out.push(" if (code == 0x2c) {");
621
- out.push(` ${srcPtr} += 2;`);
622
- out.push(" continue;");
623
- out.push(" }");
624
- out.push(" if (code == 0x5d) {");
625
- out.push(" value.length = index;");
626
- out.push(` ${srcPtr} += 2;`);
627
- out.push(" break;");
628
- out.push(" }");
629
- out.push(" break;");
630
- out.push(" }");
631
- out.push("}");
632
- }
633
- else if (valueType && this.getSchema(valueType)) {
634
- out.push("{");
635
- out.push(` if (load<u16>(${srcPtr}) != 0x5b) break;`);
636
- out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
637
- out.push(" if (changetype<usize>(value) == 0) {");
638
- out.push(` value = [];`);
639
- out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
640
- out.push(" }");
641
- out.push(" let index = 0;");
642
- out.push(` ${srcPtr} += 2;`);
643
- out.push(` if (load<u16>(${srcPtr}) == 0x5d) {`);
644
- out.push(" value.length = 0;");
645
- out.push(` ${srcPtr} += 2;`);
646
- out.push(" } else while (true) {");
647
- out.push(` let item: ${valueType};`);
648
- out.push(" if (index < value.length) {");
649
- out.push(" item = unchecked(value[index]);");
650
- out.push(" if (changetype<usize>(item) == 0) {");
651
- out.push(` item = changetype<${valueType}>(__new(offsetof<nonnull<${valueType}>>(), idof<nonnull<${valueType}>>()));`);
652
- out.push(" unchecked((value[index] = item));");
653
- out.push(" }");
654
- out.push(" } else {");
655
- out.push(` item = changetype<${valueType}>(__new(offsetof<nonnull<${valueType}>>(), idof<nonnull<${valueType}>>()));`);
656
- out.push(" value.push(item);");
657
- out.push(" }");
658
- out.push(` ${srcPtr} = changetype<nonnull<${valueType}>>(item).__DESERIALIZE<${valueType}>(${srcPtr}, srcEnd, item);`);
659
- out.push(" index++;");
660
- out.push(` const code = load<u16>(${srcPtr});`);
661
- out.push(" if (code == 0x2c) {");
662
- out.push(` ${srcPtr} += 2;`);
663
- out.push(" continue;");
664
- out.push(" }");
665
- out.push(" if (code == 0x5d) {");
666
- out.push(" value.length = index;");
667
- out.push(` ${srcPtr} += 2;`);
668
- out.push(" break;");
669
- out.push(" }");
670
- out.push(" break;");
671
- out.push(" }");
672
- out.push("}");
720
+ else if (resolvedType.startsWith("JSON.Box<") || resolvedType.startsWith("Box<")) {
721
+ const innerType = resolvedType.slice(resolvedType.indexOf("<") + 1, -1).trim();
722
+ out.push("{");
723
+ if (member.node.type.isNullable) {
724
+ out.push(` if (load<u64>(${valuePtr}) == 30399761348886638) {`);
725
+ out.push(` store<${member.type}>(${outPtr}, changetype<${member.type}>(0), ${fieldOffset});`);
726
+ out.push(` ${srcPtr} = ${valuePtr} + 8;`);
727
+ out.push(" } else {");
728
+ }
729
+ if (innerType == "bool" || innerType == "boolean") {
730
+ out.push(` if (load<u64>(${valuePtr}) == 28429475166421108) {`);
731
+ out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(JSON.Box.from<${innerType}>(true)), ${fieldOffset});`);
732
+ out.push(` ${srcPtr} = ${valuePtr} + 8;`);
733
+ out.push(" } else if (load<u64>(" + valuePtr + ") == 32370086184550502 && load<u16>(" + valuePtr + ", 8) == 101) {");
734
+ out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(JSON.Box.from<${innerType}>(false)), ${fieldOffset});`);
735
+ out.push(` ${srcPtr} = ${valuePtr} + 10;`);
736
+ out.push(" } else break;");
673
737
  }
674
738
  else {
675
- out.push(`${srcPtr} = deserializeArrayField_SWAR<${resolvedType}>(${srcPtr}, srcEnd, ${fieldPtr});`);
676
- out.push(`if (!${srcPtr}) break;`);
739
+ out.push(` let boxEnd = ${valuePtr};`);
740
+ out.push(" while (boxEnd < srcEnd) {");
741
+ out.push(" const code = load<u16>(boxEnd);");
742
+ out.push(" if (code == 0x2c || code == 0x7d) break;");
743
+ out.push(" boxEnd += 2;");
744
+ out.push(" }");
745
+ out.push(` if (boxEnd <= ${valuePtr}) break;`);
746
+ out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(JSON.Box.from<${innerType}>(JSON.__deserialize<${innerType}>(${valuePtr}, boxEnd))), ${fieldOffset});`);
747
+ out.push(` ${srcPtr} = boxEnd;`);
677
748
  }
749
+ if (member.node.type.isNullable) {
750
+ out.push(" }");
751
+ }
752
+ out.push("}");
678
753
  }
679
- else {
754
+ else if (resolvedType == "JSON.Raw") {
680
755
  out.push("{");
681
756
  out.push(` const valueStart = ${srcPtr};`);
682
757
  out.push(" let depth: i32 = 0;");
@@ -708,41 +783,212 @@ export class JSONTransform extends Visitor {
708
783
  out.push(` ${srcPtr} += 2;`);
709
784
  out.push(" }");
710
785
  out.push(` if (inString || depth != 0 || ${srcPtr} <= valueStart) break;`);
711
- out.push(` store<${resolvedType}>(${outPtr}, JSON.__deserialize<${resolvedType}>(valueStart, ${srcPtr}), ${fieldOffset});`);
786
+ out.push(` store<${member.type}>(${outPtr}, JSON.Raw.from(JSON.Util.ptrToStr(valueStart, ${srcPtr})), ${fieldOffset});`);
787
+ out.push("}");
788
+ }
789
+ else if (isBoolean(resolvedType)) {
790
+ out.push(`if (load<u64>(${srcPtr}) == 28429475166421108) {`);
791
+ out.push(` store<${resolvedType}>(${outPtr}, true, ${fieldOffset});`);
792
+ out.push(` ${srcPtr} += 8;`);
793
+ out.push("} else if (load<u64>(" + srcPtr + ") == 32370086184550502 && load<u16>(" + srcPtr + ", 8) == 101) {");
794
+ out.push(` store<${resolvedType}>(${outPtr}, false, ${fieldOffset});`);
795
+ out.push(` ${srcPtr} += 10;`);
796
+ out.push("} else break;");
797
+ }
798
+ else if (FLOAT_TYPES.includes(resolvedType)) {
799
+ out.push(`${srcPtr} = deserializeFloatField<${resolvedType}>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
800
+ }
801
+ else if (resolvedSchema && !resolvedSchema.custom) {
802
+ if (fastPath) {
803
+ out.push("break;");
804
+ return out;
805
+ }
806
+ out.push("{");
807
+ if (member.node.type.isNullable) {
808
+ out.push(` if (load<u64>(${srcPtr}) == 30399761348886638) {`);
809
+ out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(0), ${fieldOffset});`);
810
+ out.push(` ${srcPtr} += 8;`);
811
+ out.push(" } else {");
812
+ }
813
+ out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
814
+ out.push(` if (changetype<usize>(value) == 0) {`);
815
+ out.push(` value = changetype<${resolvedType}>(__new(offsetof<nonnull<${resolvedType}>>(), idof<nonnull<${resolvedType}>>()));`);
816
+ out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
817
+ out.push(" }");
818
+ out.push(` const valueStart = ${valuePtr};`);
819
+ out.push(` const valueEnd = JSON.Util.scanValueEnd(valueStart, srcEnd);`);
820
+ out.push(" if (!valueEnd) break;");
821
+ if (fastPath) {
822
+ out.push(` ${srcPtr} = changetype<nonnull<${resolvedType}>>(value).__DESERIALIZE_FAST<${resolvedType}>(valueStart, valueEnd, value);`);
823
+ }
824
+ else {
825
+ out.push(` ${srcPtr} = changetype<nonnull<${resolvedType}>>(value).__DESERIALIZE_SLOW<${resolvedType}>(valueStart, valueEnd, value);`);
826
+ }
827
+ if (member.node.type.isNullable) {
828
+ out.push(" }");
829
+ }
712
830
  out.push("}");
713
831
  }
832
+ else if (resolvedType.startsWith("Array<")) {
833
+ out.push("{");
834
+ if (member.node.type.isNullable) {
835
+ out.push(` if (load<u64>(${valuePtr}) == 30399761348886638) {`);
836
+ out.push(` store<${member.type}>(${outPtr}, changetype<${member.type}>(0), ${fieldOffset});`);
837
+ out.push(` ${srcPtr} = ${valuePtr} + 8;`);
838
+ out.push(" } else {");
839
+ }
840
+ out.push(` if (load<u16>(${valuePtr}) == 0x5b && load<u16>(${valuePtr}, 2) == 0x5d) {`);
841
+ out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
842
+ if (member.node.type.isNullable) {
843
+ out.push(` if (changetype<usize>(value) == 0) {`);
844
+ out.push(` value = changetype<${resolvedType}>(instantiate<nonnull<${resolvedType}>>());`);
845
+ out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
846
+ out.push(" }");
847
+ }
848
+ out.push(" value.length = 0;");
849
+ out.push(` ${srcPtr} = ${valuePtr} + 4;`);
850
+ out.push(" } else {");
851
+ if (member.node.type.isNullable) {
852
+ out.push(` ${srcPtr} = deserializeArrayField_SWAR<${resolvedType}>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
853
+ }
854
+ else {
855
+ out.push(` ${srcPtr} = deserializeArrayInto_SWAR<${resolvedType}>(${valuePtr}, srcEnd, load<${resolvedType}>(${outPtr}, ${fieldOffset}));`);
856
+ }
857
+ out.push(` if (!${srcPtr}) break;`);
858
+ out.push(" }");
859
+ if (member.node.type.isNullable) {
860
+ out.push(" }");
861
+ }
862
+ out.push("}");
863
+ }
864
+ else if (resolvedType.startsWith("Map<")) {
865
+ if (member.node.type.isNullable) {
866
+ out.push(`${srcPtr} = deserializeMapField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
867
+ }
868
+ else {
869
+ out.push(`${srcPtr} = deserializeMapInto<${resolvedType}>(${srcPtr}, srcEnd, load<${resolvedType}>(${outPtr}, ${fieldOffset}));`);
870
+ }
871
+ out.push(`if (!${srcPtr}) break;`);
872
+ }
873
+ else if (resolvedType.startsWith("Set<")) {
874
+ if (member.node.type.isNullable) {
875
+ out.push(`${srcPtr} = deserializeSetField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
876
+ }
877
+ else {
878
+ out.push(`${srcPtr} = deserializeSetInto<${resolvedType}>(${srcPtr}, srcEnd, load<${resolvedType}>(${outPtr}, ${fieldOffset}));`);
879
+ }
880
+ out.push(`if (!${srcPtr}) break;`);
881
+ }
882
+ else if (resolvedType.startsWith("StaticArray<")) {
883
+ out.push(`${srcPtr} = deserializeStaticArrayField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
884
+ out.push(`if (!${srcPtr}) break;`);
885
+ }
886
+ else if (resolvedType == "JSON.Value" || resolvedType == "JSON.Obj" || isEnum(resolvedType, this.sources.get(this.schema.node.range.source), this.parser)) {
887
+ out.push("break;");
888
+ }
889
+ else {
890
+ out.push("break;");
891
+ }
714
892
  return out;
715
893
  };
716
894
  indent = " ";
717
- DESERIALIZE_FAST += indent + "const dst = changetype<usize>(out);\n";
895
+ DESERIALIZE_FAST += indent + "const start = srcStart;\n";
718
896
  DESERIALIZE_FAST += indent + "do {\n";
719
897
  indent += " ";
720
- for (let i = 0; i < this.schema.members.length; i++) {
721
- const member = this.schema.members[i];
722
- const key = JSON.stringify(member.alias || member.name);
723
- if (key.length <= 2)
724
- throw new Error("Key cannot be empty!");
725
- const keySection = (i == 0 ? "{" : ",") + key + ":";
726
- DESERIALIZE_FAST += indent + `if ( // ${keySection}\n${(indent += " ")}${getComparisions(keySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) break;\n`;
727
- const keyOffset = keySection.length << 1;
728
- const resolvedType = stripNull(member.type);
729
- const inlineStringValue = ["string", "String"].includes(resolvedType);
730
- if (!inlineStringValue) {
731
- DESERIALIZE_FAST += indent + `srcStart += ${keyOffset};\n\n`;
732
- }
733
- const deserializer = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? keyOffset : 0);
734
- if (!deserializer.length) {
735
- DESERIALIZE_FAST += indent + "break;\n\n";
736
- continue;
898
+ if (supportsFastOptionalPath) {
899
+ DESERIALIZE_FAST += indent + "if (load<u16>(srcStart) !== 0x7b) break; // {\n";
900
+ DESERIALIZE_FAST += indent + "srcStart += 2;\n";
901
+ DESERIALIZE_FAST += indent + "let seenAny = false;\n\n";
902
+ for (let i = 0; i < this.schema.members.length; i++) {
903
+ const member = this.schema.members[i];
904
+ const key = JSON.stringify(member.alias || member.name);
905
+ if (key.length <= 2)
906
+ throw new Error("Key cannot be empty!");
907
+ const firstKeySection = key + ":";
908
+ const nextKeySection = "," + key + ":";
909
+ const firstKeyOffset = firstKeySection.length << 1;
910
+ const nextKeyOffset = nextKeySection.length << 1;
911
+ const resolvedType = stripNull(member.type);
912
+ const inlineStringValue = ["string", "String"].includes(resolvedType);
913
+ const deserializerFirst = getDeserializer(member.type, "srcStart", "changetype<usize>(out)", member, inlineStringValue ? firstKeyOffset : 0, true);
914
+ const deserializerNext = getDeserializer(member.type, "srcStart", "changetype<usize>(out)", member, inlineStringValue ? nextKeyOffset : 0, true);
915
+ const isOptional = member.flags.has(PropertyFlags.OmitNull) || member.flags.has(PropertyFlags.OmitIf);
916
+ if (!deserializerFirst.length || !deserializerNext.length) {
917
+ DESERIALIZE_FAST += indent + "break;\n\n";
918
+ continue;
919
+ }
920
+ DESERIALIZE_FAST += indent + "if (!seenAny) {\n";
921
+ indent += " ";
922
+ DESERIALIZE_FAST += indent + `if ( // ${firstKeySection}\n${(indent += " ")}${getComparisions(firstKeySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) {\n`;
923
+ indent += " ";
924
+ if (isOptional) {
925
+ DESERIALIZE_FAST += indent + "// optional @omitnull field omitted\n";
926
+ }
927
+ else {
928
+ DESERIALIZE_FAST += indent + "break;\n";
929
+ }
930
+ indent = indent.slice(0, -2);
931
+ DESERIALIZE_FAST += indent + "} else {\n";
932
+ indent += " ";
933
+ if (!inlineStringValue)
934
+ DESERIALIZE_FAST += indent + `srcStart += ${firstKeyOffset};\n`;
935
+ DESERIALIZE_FAST += indent + deserializerFirst.join("\n" + indent) + "\n";
936
+ DESERIALIZE_FAST += indent + "seenAny = true;\n";
937
+ indent = indent.slice(0, -2);
938
+ DESERIALIZE_FAST += indent + "}\n";
939
+ indent = indent.slice(0, -2);
940
+ DESERIALIZE_FAST += indent + "} else {\n";
941
+ indent += " ";
942
+ DESERIALIZE_FAST += indent + `if ( // ${nextKeySection}\n${(indent += " ")}${getComparisions(nextKeySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) {\n`;
943
+ indent += " ";
944
+ if (isOptional) {
945
+ DESERIALIZE_FAST += indent + "// optional @omitnull field omitted\n";
946
+ }
947
+ else {
948
+ DESERIALIZE_FAST += indent + "break;\n";
949
+ }
950
+ indent = indent.slice(0, -2);
951
+ DESERIALIZE_FAST += indent + "} else {\n";
952
+ indent += " ";
953
+ if (!inlineStringValue)
954
+ DESERIALIZE_FAST += indent + `srcStart += ${nextKeyOffset};\n`;
955
+ DESERIALIZE_FAST += indent + deserializerNext.join("\n" + indent) + "\n";
956
+ indent = indent.slice(0, -2);
957
+ DESERIALIZE_FAST += indent + "}\n";
958
+ indent = indent.slice(0, -2);
959
+ DESERIALIZE_FAST += indent + "}\n\n";
960
+ }
961
+ }
962
+ else {
963
+ for (let i = 0; i < this.schema.members.length; i++) {
964
+ const member = this.schema.members[i];
965
+ const key = JSON.stringify(member.alias || member.name);
966
+ if (key.length <= 2)
967
+ throw new Error("Key cannot be empty!");
968
+ const keySection = (i == 0 ? "{" : ",") + key + ":";
969
+ DESERIALIZE_FAST += indent + `if ( // ${keySection}\n${(indent += " ")}${getComparisions(keySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) break;\n`;
970
+ const keyOffset = keySection.length << 1;
971
+ const resolvedType = stripNull(member.type);
972
+ const inlineStringValue = ["string", "String"].includes(resolvedType);
973
+ if (!inlineStringValue) {
974
+ DESERIALIZE_FAST += indent + `srcStart += ${keyOffset};\n\n`;
975
+ }
976
+ const deserializer = getDeserializer(member.type, "srcStart", "changetype<usize>(out)", member, inlineStringValue ? keyOffset : 0, true);
977
+ if (!deserializer.length) {
978
+ DESERIALIZE_FAST += indent + "break;\n\n";
979
+ continue;
980
+ }
981
+ DESERIALIZE_FAST += indent + deserializer.join("\n" + indent) + "\n\n";
737
982
  }
738
- DESERIALIZE_FAST += indent + deserializer.join("\n" + indent) + "\n\n";
739
983
  }
740
984
  DESERIALIZE_FAST += indent + "if (load<u16>(srcStart) !== 0x7d) break; // }\n";
741
985
  DESERIALIZE_FAST += indent + "srcStart += 2;\n";
742
986
  DESERIALIZE_FAST += indent + "return srcStart;\n";
743
987
  indent = indent.slice(0, -2);
744
988
  DESERIALIZE_FAST += indent + "} while (false);\n\n";
745
- DESERIALIZE_FAST += indent + 'throw new Error("Failed to parse JSON ");';
989
+ DESERIALIZE_FAST += indent + "if (isDefined(out.__INITIALIZE)) out.__INITIALIZE();\n";
990
+ DESERIALIZE_FAST += indent + "const end = JSON.Util.scanValueEnd(start, srcEnd);\n";
991
+ DESERIALIZE_FAST += indent + "return out.__DESERIALIZE_SLOW(start, end ? end : srcEnd, out);";
746
992
  indent = indent.slice(0, -2);
747
993
  DESERIALIZE_FAST += indent + "}";
748
994
  DESERIALIZE += indent + " let keyStart: usize = 0;\n";
@@ -976,7 +1222,7 @@ export class JSONTransform extends Visitor {
976
1222
  generateConsts(group);
977
1223
  const first = group[0];
978
1224
  const fName = first.alias || first.name;
979
- DESERIALIZE += indent + " if (" + (first.generic ? "isDefined(out.__DESERIALIZE) &&" : "") + getComparison(fName) + ") { // " + fName + "\n";
1225
+ DESERIALIZE += indent + " if (" + getComparison(fName) + ") { // " + fName + "\n";
980
1226
  DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
981
1227
  DESERIALIZE += indent + " keyStart = 0;\n";
982
1228
  DESERIALIZE += indent + " break;\n";
@@ -984,7 +1230,7 @@ export class JSONTransform extends Visitor {
984
1230
  for (let i = 1; i < group.length; i++) {
985
1231
  const mem = group[i];
986
1232
  const memName = mem.alias || mem.name;
987
- DESERIALIZE += indent + " else if (" + (mem.generic ? "isDefined(out.__DESERIALIZE) &&" : "") + getComparison(memName) + ") { // " + memName + "\n";
1233
+ DESERIALIZE += indent + " else if (" + getComparison(memName) + ") { // " + memName + "\n";
988
1234
  DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
989
1235
  DESERIALIZE += indent + " keyStart = 0;\n";
990
1236
  DESERIALIZE += indent + " break;\n";
@@ -1075,7 +1321,20 @@ export class JSONTransform extends Visitor {
1075
1321
  const first = group[0];
1076
1322
  const fName = first.alias || first.name;
1077
1323
  DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
1078
- DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
1324
+ if (first.type.startsWith("JSON.Box<bool") || first.type.startsWith("JSON.Box<boolean") || first.type.startsWith("Box<bool") || first.type.startsWith("Box<boolean")) {
1325
+ DESERIALIZE +=
1326
+ indent +
1327
+ " store<" +
1328
+ first.type +
1329
+ ">(changetype<usize>(out), changetype<" +
1330
+ first.type +
1331
+ ">(JSON.Box.from<bool>(true)), offsetof<this>(" +
1332
+ JSON.stringify(first.name) +
1333
+ "));\n";
1334
+ }
1335
+ else {
1336
+ DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
1337
+ }
1079
1338
  DESERIALIZE += indent + " srcStart += 2;\n";
1080
1339
  DESERIALIZE += indent + " keyStart = 0;\n";
1081
1340
  DESERIALIZE += indent + " break;\n";
@@ -1084,7 +1343,20 @@ export class JSONTransform extends Visitor {
1084
1343
  const mem = group[i];
1085
1344
  const memName = mem.alias || mem.name;
1086
1345
  DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
1087
- DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
1346
+ if (mem.type.startsWith("JSON.Box<bool") || mem.type.startsWith("JSON.Box<boolean") || mem.type.startsWith("Box<bool") || mem.type.startsWith("Box<boolean")) {
1347
+ DESERIALIZE +=
1348
+ indent +
1349
+ " store<" +
1350
+ mem.type +
1351
+ ">(changetype<usize>(out), changetype<" +
1352
+ mem.type +
1353
+ ">(JSON.Box.from<bool>(true)), offsetof<this>(" +
1354
+ JSON.stringify(mem.name) +
1355
+ "));\n";
1356
+ }
1357
+ else {
1358
+ DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
1359
+ }
1088
1360
  DESERIALIZE += indent + " srcStart += 2;\n";
1089
1361
  DESERIALIZE += indent + " keyStart = 0;\n";
1090
1362
  DESERIALIZE += indent + " break;\n";
@@ -1119,7 +1391,20 @@ export class JSONTransform extends Visitor {
1119
1391
  const first = group[0];
1120
1392
  const fName = first.alias || first.name;
1121
1393
  DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
1122
- DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
1394
+ if (first.type.startsWith("JSON.Box<bool") || first.type.startsWith("JSON.Box<boolean") || first.type.startsWith("Box<bool") || first.type.startsWith("Box<boolean")) {
1395
+ DESERIALIZE +=
1396
+ indent +
1397
+ " store<" +
1398
+ first.type +
1399
+ ">(changetype<usize>(out), changetype<" +
1400
+ first.type +
1401
+ ">(JSON.Box.from<bool>(false)), offsetof<this>(" +
1402
+ JSON.stringify(first.name) +
1403
+ "));\n";
1404
+ }
1405
+ else {
1406
+ DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
1407
+ }
1123
1408
  DESERIALIZE += indent + " srcStart += 2;\n";
1124
1409
  DESERIALIZE += indent + " keyStart = 0;\n";
1125
1410
  DESERIALIZE += indent + " break;\n";
@@ -1128,7 +1413,20 @@ export class JSONTransform extends Visitor {
1128
1413
  const mem = group[i];
1129
1414
  const memName = mem.alias || mem.name;
1130
1415
  DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
1131
- DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
1416
+ if (mem.type.startsWith("JSON.Box<bool") || mem.type.startsWith("JSON.Box<boolean") || mem.type.startsWith("Box<bool") || mem.type.startsWith("Box<boolean")) {
1417
+ DESERIALIZE +=
1418
+ indent +
1419
+ " store<" +
1420
+ mem.type +
1421
+ ">(changetype<usize>(out), changetype<" +
1422
+ mem.type +
1423
+ ">(JSON.Box.from<bool>(false)), offsetof<this>(" +
1424
+ JSON.stringify(mem.name) +
1425
+ "));\n";
1426
+ }
1427
+ else {
1428
+ DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
1429
+ }
1132
1430
  DESERIALIZE += indent + " srcStart += 2;\n";
1133
1431
  DESERIALIZE += indent + " keyStart = 0;\n";
1134
1432
  DESERIALIZE += indent + " break;\n";
@@ -1209,27 +1507,26 @@ export class JSONTransform extends Visitor {
1209
1507
  SERIALIZE += indent + "bs.offset += 2;\n";
1210
1508
  SERIALIZE += "}";
1211
1509
  SERIALIZE = SERIALIZE.slice(0, 32) + indent + "bs.proposeSize(" + this.schema.byteSize + ");\n" + SERIALIZE.slice(32);
1212
- if (!useFastPath) {
1213
- INITIALIZE += " return this;\n";
1214
- INITIALIZE += "}";
1215
- }
1510
+ INITIALIZE += " return this;\n";
1511
+ INITIALIZE += "}";
1216
1512
  if (DEBUG > 0) {
1217
1513
  console.log(SERIALIZE_CUSTOM || SERIALIZE);
1218
- if (!useFastPath)
1219
- console.log(INITIALIZE);
1514
+ console.log(INITIALIZE);
1220
1515
  console.log(DESERIALIZE_CUSTOM || DESERIALIZE);
1221
1516
  }
1222
- const DESERIALIZE_DIRECT = useFastPath ? DESERIALIZE_FAST.replace("@inline __DESERIALIZE_FAST<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {", "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {") : DESERIALIZE.replace("__DESERIALIZE_SLOW<__JSON_T>", "__DESERIALIZE<__JSON_T>");
1223
1517
  const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE_CUSTOM || SERIALIZE, node);
1224
- const INITIALIZE_METHOD = !useFastPath ? SimpleParser.parseClassMember(INITIALIZE, node) : null;
1225
- const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE_CUSTOM || DESERIALIZE_DIRECT, node);
1518
+ const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
1519
+ const DESERIALIZE_CUSTOM_METHOD = DESERIALIZE_CUSTOM ? SimpleParser.parseClassMember(DESERIALIZE_CUSTOM, node) : null;
1520
+ const DESERIALIZE_SLOW_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
1226
1521
  const DESERIALIZE_FAST_METHOD = useFastPath ? SimpleParser.parseClassMember(DESERIALIZE_FAST, node) : null;
1227
1522
  if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
1228
1523
  node.members.push(SERIALIZE_METHOD);
1229
- if (!useFastPath && INITIALIZE_METHOD && !node.members.find((v) => v.name.text == "__INITIALIZE"))
1524
+ if (INITIALIZE_METHOD && !node.members.find((v) => v.name.text == "__INITIALIZE"))
1230
1525
  node.members.push(INITIALIZE_METHOD);
1231
- if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
1232
- node.members.push(DESERIALIZE_METHOD);
1526
+ if (DESERIALIZE_CUSTOM_METHOD && !node.members.find((v) => v.name.text == "__DESERIALIZE_CUSTOM"))
1527
+ node.members.push(DESERIALIZE_CUSTOM_METHOD);
1528
+ if (!DESERIALIZE_CUSTOM && DESERIALIZE_SLOW_METHOD && !node.members.find((v) => v.name.text == "__DESERIALIZE_SLOW"))
1529
+ node.members.push(DESERIALIZE_SLOW_METHOD);
1233
1530
  if (!DESERIALIZE_CUSTOM && useFastPath && DESERIALIZE_FAST_METHOD && !node.members.find((v) => v.name.text == "__DESERIALIZE_FAST"))
1234
1531
  node.members.push(DESERIALIZE_FAST_METHOD);
1235
1532
  super.visitClassDeclaration(node);
@@ -1241,23 +1538,21 @@ export class JSONTransform extends Visitor {
1241
1538
  generateEmptyMethods(node) {
1242
1539
  const SERIALIZE_EMPTY = "@inline __SERIALIZE(ptr: usize): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
1243
1540
  const INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
1244
- const DESERIALIZE_EMPTY = "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n return srcEnd;\n}";
1245
- const useFastPath = USE_FAST_PATH && getCodegenMode(this.program) !== JSONMode.NAIVE;
1541
+ const DESERIALIZE_SLOW_EMPTY = "@inline __DESERIALIZE_SLOW<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n return srcEnd;\n}";
1246
1542
  if (DEBUG > 0) {
1247
1543
  console.log(SERIALIZE_EMPTY);
1248
- if (!useFastPath)
1249
- console.log(INITIALIZE_EMPTY);
1250
- console.log(DESERIALIZE_EMPTY);
1544
+ console.log(INITIALIZE_EMPTY);
1545
+ console.log(DESERIALIZE_SLOW_EMPTY);
1251
1546
  }
1252
1547
  const SERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_EMPTY, node);
1253
- const INITIALIZE_METHOD_EMPTY = !useFastPath ? SimpleParser.parseClassMember(INITIALIZE_EMPTY, node) : null;
1254
- const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
1548
+ const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
1549
+ const DESERIALIZE_SLOW_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_SLOW_EMPTY, node);
1255
1550
  if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
1256
1551
  node.members.push(SERIALIZE_METHOD_EMPTY);
1257
- if (!useFastPath && INITIALIZE_METHOD_EMPTY && !node.members.find((v) => v.name.text == "__INITIALIZE"))
1552
+ if (INITIALIZE_METHOD_EMPTY && !node.members.find((v) => v.name.text == "__INITIALIZE"))
1258
1553
  node.members.push(INITIALIZE_METHOD_EMPTY);
1259
- if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
1260
- node.members.push(DESERIALIZE_METHOD_EMPTY);
1554
+ if (!node.members.find((v) => v.name.text == "__DESERIALIZE_SLOW"))
1555
+ node.members.push(DESERIALIZE_SLOW_METHOD_EMPTY);
1261
1556
  }
1262
1557
  visitImportStatement(node) {
1263
1558
  super.visitImportStatement(node);
@@ -1271,15 +1566,6 @@ export class JSONTransform extends Visitor {
1271
1566
  this.baseCWD = this.baseCWD.replaceAll("/", path.sep);
1272
1567
  const baseDir = path.resolve(fileURLToPath(import.meta.url), "..", "..", "..");
1273
1568
  let fromPath = node.range.source.normalizedPath.replaceAll("/", path.sep);
1274
- const isLib = path.dirname(baseDir).endsWith("node_modules");
1275
- if (!isLib && !this.parser.sources.some((s) => s.normalizedPath.startsWith("assembly/index"))) {
1276
- const newPath = path.join(baseDir, "assembly", "index.ts");
1277
- this.parser.parseFile(readFileSync(newPath).toString(), newPath, false);
1278
- }
1279
- else if (isLib && !this.parser.sources.some((s) => s.normalizedPath.startsWith("~lib/json-as/assembly/index"))) {
1280
- const newPath = "~lib/json-as/assembly/index.ts";
1281
- this.parser.parseFile(readFileSync(path.join(baseDir, "assembly", "index.ts")).toString(), newPath, false);
1282
- }
1283
1569
  fromPath = fromPath.startsWith("~lib") ? fromPath.slice(5) : path.join(this.baseCWD, fromPath);
1284
1570
  const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
1285
1571
  const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
@@ -1287,14 +1573,28 @@ export class JSONTransform extends Visitor {
1287
1573
  const deserializeIntegerFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeIntegerField" || d.name.text == "deserializeIntegerField"));
1288
1574
  const deserializeUnsignedFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeUnsignedField" || d.name.text == "deserializeUnsignedField"));
1289
1575
  const deserializeFloatFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeFloatField" || d.name.text == "deserializeFloatField"));
1576
+ const scanValueEndImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "scanValueEnd" || d.name.text == "scanValueEnd"));
1290
1577
  const deserializeArrayField_SWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeArrayField_SWAR" || d.name.text == "deserializeArrayField_SWAR"));
1578
+ const deserializeArrayInto_SWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeArrayInto_SWAR" || d.name.text == "deserializeArrayInto_SWAR"));
1579
+ const deserializeMapFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeMapField" || d.name.text == "deserializeMapField"));
1580
+ const deserializeMapIntoImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeMapInto" || d.name.text == "deserializeMapInto"));
1581
+ const deserializeSetFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeSetField" || d.name.text == "deserializeSetField"));
1582
+ const deserializeSetIntoImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeSetInto" || d.name.text == "deserializeSetInto"));
1583
+ const deserializeStaticArrayFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStaticArrayField" || d.name.text == "deserializeStaticArrayField"));
1291
1584
  const deserializeStringFieldSWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStringField_SWAR" || d.name.text == "deserializeStringField_SWAR"));
1292
1585
  const deserializeStringFieldSIMDImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStringField_SIMD" || d.name.text == "deserializeStringField_SIMD"));
1293
1586
  const sourceText = readFileSync(fromPath).toString();
1294
1587
  const hasLocalDeserializeIntegerField = /\bdeserializeIntegerField\b/.test(sourceText);
1295
1588
  const hasLocalDeserializeUnsignedField = /\bdeserializeUnsignedField\b/.test(sourceText);
1296
1589
  const hasLocalDeserializeFloatField = /\bdeserializeFloatField\b/.test(sourceText);
1590
+ const hasLocalScanValueEnd = /\bscanValueEnd\b/.test(sourceText);
1297
1591
  const hasLocaldeserializeArrayField_SWAR = /\bdeserializeArrayField_SWAR\b/.test(sourceText);
1592
+ const hasLocaldeserializeArrayInto_SWAR = /\bdeserializeArrayInto_SWAR\b/.test(sourceText);
1593
+ const hasLocaldeserializeMapField = /\bdeserializeMapField\b/.test(sourceText);
1594
+ const hasLocaldeserializeMapInto = /\bdeserializeMapInto\b/.test(sourceText);
1595
+ const hasLocaldeserializeSetField = /\bdeserializeSetField\b/.test(sourceText);
1596
+ const hasLocaldeserializeSetInto = /\bdeserializeSetInto\b/.test(sourceText);
1597
+ const hasLocaldeserializeStaticArrayField = /\bdeserializeStaticArrayField\b/.test(sourceText);
1298
1598
  const hasLocalDeserializeStringFieldSWAR = /\bdeserializeStringField_SWAR\b/.test(sourceText);
1299
1599
  const hasLocalDeserializeStringFieldSIMD = /\bdeserializeStringField_SIMD\b/.test(sourceText);
1300
1600
  let baseRel = path.posix.join(...path.relative(path.dirname(fromPath), path.join(baseDir)).split(path.sep));
@@ -1323,19 +1623,25 @@ export class JSONTransform extends Visitor {
1323
1623
  console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1324
1624
  }
1325
1625
  if (!deserializeIntegerFieldImport && !hasLocalDeserializeIntegerField) {
1326
- const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeIntegerField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "integer"), node.range), node.range);
1626
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeIntegerField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "integer"), node.range), node.range);
1327
1627
  node.range.source.statements.unshift(replaceNode);
1328
1628
  if (DEBUG > 0)
1329
1629
  console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1330
1630
  }
1331
1631
  if (!deserializeUnsignedFieldImport && !hasLocalDeserializeUnsignedField) {
1332
- const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeUnsignedField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "unsigned"), node.range), node.range);
1632
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeUnsignedField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "unsigned"), node.range), node.range);
1333
1633
  node.range.source.statements.unshift(replaceNode);
1334
1634
  if (DEBUG > 0)
1335
1635
  console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1336
1636
  }
1337
1637
  if (!deserializeFloatFieldImport && !hasLocalDeserializeFloatField) {
1338
- const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeFloatField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "float"), node.range), node.range);
1638
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeFloatField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "float"), node.range), node.range);
1639
+ node.range.source.statements.unshift(replaceNode);
1640
+ if (DEBUG > 0)
1641
+ console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1642
+ }
1643
+ if (!scanValueEndImport && !hasLocalScanValueEnd) {
1644
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("scanValueEnd", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "swar", "array", "shared"), node.range), node.range);
1339
1645
  node.range.source.statements.unshift(replaceNode);
1340
1646
  if (DEBUG > 0)
1341
1647
  console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
@@ -1346,6 +1652,42 @@ export class JSONTransform extends Visitor {
1346
1652
  if (DEBUG > 0)
1347
1653
  console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1348
1654
  }
1655
+ if (!deserializeArrayInto_SWARImport && !hasLocaldeserializeArrayInto_SWAR) {
1656
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeArrayInto_SWAR", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "swar", "array"), node.range), node.range);
1657
+ node.range.source.statements.unshift(replaceNode);
1658
+ if (DEBUG > 0)
1659
+ console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1660
+ }
1661
+ if (!deserializeMapFieldImport && !hasLocaldeserializeMapField) {
1662
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeMapField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "map"), node.range), node.range);
1663
+ node.range.source.statements.unshift(replaceNode);
1664
+ if (DEBUG > 0)
1665
+ console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1666
+ }
1667
+ if (!deserializeMapIntoImport && !hasLocaldeserializeMapInto) {
1668
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeMapInto", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "map"), node.range), node.range);
1669
+ node.range.source.statements.unshift(replaceNode);
1670
+ if (DEBUG > 0)
1671
+ console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1672
+ }
1673
+ if (!deserializeSetFieldImport && !hasLocaldeserializeSetField) {
1674
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeSetField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "set"), node.range), node.range);
1675
+ node.range.source.statements.unshift(replaceNode);
1676
+ if (DEBUG > 0)
1677
+ console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1678
+ }
1679
+ if (!deserializeSetIntoImport && !hasLocaldeserializeSetInto) {
1680
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeSetInto", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "set"), node.range), node.range);
1681
+ node.range.source.statements.unshift(replaceNode);
1682
+ if (DEBUG > 0)
1683
+ console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1684
+ }
1685
+ if (!deserializeStaticArrayFieldImport && !hasLocaldeserializeStaticArrayField) {
1686
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStaticArrayField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "staticarray"), node.range), node.range);
1687
+ node.range.source.statements.unshift(replaceNode);
1688
+ if (DEBUG > 0)
1689
+ console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
1690
+ }
1349
1691
  const codegenMode = getCodegenMode(this.program);
1350
1692
  if (codegenMode !== JSONMode.SIMD && !deserializeStringFieldSWARImport && !hasLocalDeserializeStringFieldSWAR) {
1351
1693
  const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStringField_SWAR", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "swar", "string"), node.range), node.range);
@@ -1456,11 +1798,7 @@ export default class Transformer extends Transform {
1456
1798
  }
1457
1799
  }
1458
1800
  afterParse(parser) {
1459
- const transformer = JSONTransform.SN;
1460
- transformer.schemas = new Map();
1461
- transformer.sources = new SourceSet();
1462
- transformer.visitedClasses = new Set();
1463
- transformer.simdStatements = [];
1801
+ const transformer = new JSONTransform();
1464
1802
  const sources = parser.sources
1465
1803
  .filter((source) => {
1466
1804
  const p = source.internalPath;