redscript-mc 2.6.2 → 3.0.0

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 (636) hide show
  1. package/.github/workflows/ci.yml +11 -0
  2. package/CHANGELOG.md +18 -9
  3. package/README-benchmarks.md +48 -0
  4. package/README-vscode-test.md +251 -0
  5. package/RELEASE_NOTES.md +74 -0
  6. package/ROADMAP.md +131 -167
  7. package/benchmarks/_shared.ts +468 -0
  8. package/benchmarks/baseline.json +2816 -0
  9. package/benchmarks/baseline.md +13 -0
  10. package/benchmarks/compiler-perf.report.json +207 -0
  11. package/benchmarks/compiler-perf.ts +76 -0
  12. package/benchmarks/results.md +13 -0
  13. package/benchmarks/stdlib-complexity.report.json +2606 -0
  14. package/benchmarks/stdlib-complexity.ts +54 -0
  15. package/benchmarks/stdlib-size.md +57 -0
  16. package/benchmarks/stdlib-size.ts +91 -0
  17. package/coverage-report.md +177 -0
  18. package/dist/src/__tests__/budget.test.js +4 -0
  19. package/dist/src/__tests__/cache/cache-behavior.test.d.ts +10 -0
  20. package/dist/src/__tests__/cache/cache-behavior.test.js +425 -0
  21. package/dist/src/__tests__/cache-extra.test.d.ts +5 -0
  22. package/dist/src/__tests__/cache-extra.test.js +211 -0
  23. package/dist/src/__tests__/cli-init.test.d.ts +1 -0
  24. package/dist/src/__tests__/cli-init.test.js +97 -0
  25. package/dist/src/__tests__/cli-publish.test.d.ts +9 -0
  26. package/dist/src/__tests__/cli-publish.test.js +189 -0
  27. package/dist/src/__tests__/cli.test.js +76 -0
  28. package/dist/src/__tests__/compile-preprocess.test.d.ts +11 -0
  29. package/dist/src/__tests__/compile-preprocess.test.js +328 -0
  30. package/dist/src/__tests__/compiler/break-stmt.test.d.ts +1 -0
  31. package/dist/src/__tests__/compiler/break-stmt.test.js +58 -0
  32. package/dist/src/__tests__/compiler/const-decl.test.d.ts +1 -0
  33. package/dist/src/__tests__/compiler/const-decl.test.js +123 -0
  34. package/dist/src/__tests__/compiler/continue-stmt.test.d.ts +1 -0
  35. package/dist/src/__tests__/compiler/continue-stmt.test.js +67 -0
  36. package/dist/src/__tests__/compiler/coroutine-extended.test.d.ts +17 -0
  37. package/dist/src/__tests__/compiler/coroutine-extended.test.js +565 -0
  38. package/dist/src/__tests__/compiler/deprecated.test.d.ts +4 -0
  39. package/dist/src/__tests__/compiler/deprecated.test.js +285 -0
  40. package/dist/src/__tests__/compiler/do-while.test.d.ts +1 -0
  41. package/dist/src/__tests__/compiler/do-while.test.js +120 -0
  42. package/dist/src/__tests__/compiler/enum-payload.test.d.ts +9 -0
  43. package/dist/src/__tests__/compiler/enum-payload.test.js +272 -0
  44. package/dist/src/__tests__/compiler/interface.test.d.ts +10 -0
  45. package/dist/src/__tests__/compiler/interface.test.js +258 -0
  46. package/dist/src/__tests__/compiler/labeled-loops.test.d.ts +1 -0
  47. package/dist/src/__tests__/compiler/labeled-loops.test.js +263 -0
  48. package/dist/src/__tests__/compiler/match-string.test.d.ts +1 -0
  49. package/dist/src/__tests__/compiler/match-string.test.js +43 -0
  50. package/dist/src/__tests__/compiler/memoize.test.d.ts +1 -0
  51. package/dist/src/__tests__/compiler/memoize.test.js +113 -0
  52. package/dist/src/__tests__/compiler/method-chain.test.d.ts +5 -0
  53. package/dist/src/__tests__/compiler/method-chain.test.js +115 -0
  54. package/dist/src/__tests__/compiler/module-import.test.d.ts +12 -0
  55. package/dist/src/__tests__/compiler/module-import.test.js +261 -0
  56. package/dist/src/__tests__/compiler/option-extensions.test.d.ts +6 -0
  57. package/dist/src/__tests__/compiler/option-extensions.test.js +191 -0
  58. package/dist/src/__tests__/compiler/profile-decorator.test.d.ts +1 -0
  59. package/dist/src/__tests__/compiler/profile-decorator.test.js +69 -0
  60. package/dist/src/__tests__/compiler/string-advanced.test.d.ts +7 -0
  61. package/dist/src/__tests__/compiler/string-advanced.test.js +281 -0
  62. package/dist/src/__tests__/compiler/struct-extends.test.d.ts +1 -0
  63. package/dist/src/__tests__/compiler/struct-extends.test.js +95 -0
  64. package/dist/src/__tests__/compiler/throttle-retry.test.d.ts +1 -0
  65. package/dist/src/__tests__/compiler/throttle-retry.test.js +166 -0
  66. package/dist/src/__tests__/compiler/tuple-type.test.d.ts +10 -0
  67. package/dist/src/__tests__/compiler/tuple-type.test.js +229 -0
  68. package/dist/src/__tests__/compiler/watch-decorator.test.d.ts +1 -0
  69. package/dist/src/__tests__/compiler/watch-decorator.test.js +65 -0
  70. package/dist/src/__tests__/config/project-config.test.d.ts +1 -0
  71. package/dist/src/__tests__/config/project-config.test.js +199 -0
  72. package/dist/src/__tests__/config-decorator.test.d.ts +8 -0
  73. package/dist/src/__tests__/config-decorator.test.js +142 -0
  74. package/dist/src/__tests__/diagnostics-extra.test.d.ts +6 -0
  75. package/dist/src/__tests__/diagnostics-extra.test.js +132 -0
  76. package/dist/src/__tests__/emit/compile-branches.test.d.ts +1 -0
  77. package/dist/src/__tests__/emit/compile-branches.test.js +123 -0
  78. package/dist/src/__tests__/emit/compile-coverage.test.d.ts +25 -0
  79. package/dist/src/__tests__/emit/compile-coverage.test.js +617 -0
  80. package/dist/src/__tests__/emit/compile-extra-branches.test.d.ts +12 -0
  81. package/dist/src/__tests__/emit/compile-extra-branches.test.js +225 -0
  82. package/dist/src/__tests__/emit/compile-mocked-branches.test.d.ts +0 -0
  83. package/dist/src/__tests__/emit/compile-mocked-branches.test.js +238 -0
  84. package/dist/src/__tests__/emit/execute-chain.test.d.ts +10 -0
  85. package/dist/src/__tests__/emit/execute-chain.test.js +94 -0
  86. package/dist/src/__tests__/emit/index.test.js +2 -1
  87. package/dist/src/__tests__/emit/modules-branches.test.d.ts +1 -0
  88. package/dist/src/__tests__/emit/modules-branches.test.js +88 -0
  89. package/dist/src/__tests__/emit/modules-coverage.test.d.ts +15 -0
  90. package/dist/src/__tests__/emit/modules-coverage.test.js +221 -0
  91. package/dist/src/__tests__/emit/modules-errors.test.d.ts +12 -0
  92. package/dist/src/__tests__/emit/modules-errors.test.js +169 -0
  93. package/dist/src/__tests__/emit/modules-rewrite.test.d.ts +17 -0
  94. package/dist/src/__tests__/emit/modules-rewrite.test.js +204 -0
  95. package/dist/src/__tests__/emit/source-map.test.d.ts +1 -0
  96. package/dist/src/__tests__/emit/source-map.test.js +167 -0
  97. package/dist/src/__tests__/enum.test.js +9 -4
  98. package/dist/src/__tests__/error-recovery.test.d.ts +7 -0
  99. package/dist/src/__tests__/error-recovery.test.js +217 -0
  100. package/dist/src/__tests__/events-types-extra.test.d.ts +10 -0
  101. package/dist/src/__tests__/events-types-extra.test.js +91 -0
  102. package/dist/src/__tests__/events-types.test.d.ts +4 -0
  103. package/dist/src/__tests__/events-types.test.js +56 -0
  104. package/dist/src/__tests__/formatter.test.js +13 -5
  105. package/dist/src/__tests__/hir/lower-extra.test.d.ts +9 -0
  106. package/dist/src/__tests__/hir/lower-extra.test.js +140 -0
  107. package/dist/src/__tests__/hir/monomorphize-extra.test.d.ts +15 -0
  108. package/dist/src/__tests__/hir/monomorphize-extra.test.js +200 -0
  109. package/dist/src/__tests__/hir/monomorphize-extra2.test.d.ts +16 -0
  110. package/dist/src/__tests__/hir/monomorphize-extra2.test.js +316 -0
  111. package/dist/src/__tests__/incremental.test.js +10 -2
  112. package/dist/src/__tests__/index-extra.test.d.ts +10 -0
  113. package/dist/src/__tests__/index-extra.test.js +71 -0
  114. package/dist/src/__tests__/lexer.test.js +2 -2
  115. package/dist/src/__tests__/lint/rules.test.d.ts +5 -0
  116. package/dist/src/__tests__/lint/rules.test.js +208 -0
  117. package/dist/src/__tests__/lir/lower.test.js +29 -0
  118. package/dist/src/__tests__/lir/verify.test.js +30 -0
  119. package/dist/src/__tests__/lsp/completion.test.d.ts +7 -0
  120. package/dist/src/__tests__/lsp/completion.test.js +583 -0
  121. package/dist/src/__tests__/lsp/definition.test.d.ts +7 -0
  122. package/dist/src/__tests__/lsp/definition.test.js +454 -0
  123. package/dist/src/__tests__/lsp/diagnostics.test.d.ts +10 -0
  124. package/dist/src/__tests__/lsp/diagnostics.test.js +98 -0
  125. package/dist/src/__tests__/lsp/hover-docs.test.d.ts +10 -0
  126. package/dist/src/__tests__/lsp/hover-docs.test.js +210 -0
  127. package/dist/src/__tests__/lsp.test.js +4 -1
  128. package/dist/src/__tests__/mc-integration/item-entity-events.test.js +4 -0
  129. package/dist/src/__tests__/mc-integration/stdlib-coverage-2.test.js +4 -0
  130. package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.d.ts +13 -0
  131. package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.js +1227 -0
  132. package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.d.ts +13 -0
  133. package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.js +1509 -0
  134. package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.d.ts +14 -0
  135. package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.js +1374 -0
  136. package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.d.ts +10 -0
  137. package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.js +759 -0
  138. package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.d.ts +13 -0
  139. package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.js +855 -0
  140. package/dist/src/__tests__/mc-integration/stdlib-coverage.test.js +4 -0
  141. package/dist/src/__tests__/mc-integration/syntax-coverage.test.js +4 -0
  142. package/dist/src/__tests__/mc-validator-coverage.test.d.ts +13 -0
  143. package/dist/src/__tests__/mc-validator-coverage.test.js +296 -0
  144. package/dist/src/__tests__/mc-validator-extra.test.d.ts +13 -0
  145. package/dist/src/__tests__/mc-validator-extra.test.js +245 -0
  146. package/dist/src/__tests__/mir/lower-extra.test.d.ts +20 -0
  147. package/dist/src/__tests__/mir/lower-extra.test.js +361 -0
  148. package/dist/src/__tests__/mir/lower-extra2.test.d.ts +17 -0
  149. package/dist/src/__tests__/mir/lower-extra2.test.js +317 -0
  150. package/dist/src/__tests__/mir/lower-extra3.test.d.ts +19 -0
  151. package/dist/src/__tests__/mir/lower-extra3.test.js +249 -0
  152. package/dist/src/__tests__/mir/lower-extra4.test.d.ts +23 -0
  153. package/dist/src/__tests__/mir/lower-extra4.test.js +606 -0
  154. package/dist/src/__tests__/mir/lower-extra5.test.d.ts +25 -0
  155. package/dist/src/__tests__/mir/lower-extra5.test.js +543 -0
  156. package/dist/src/__tests__/mir/lower-extra6.test.d.ts +16 -0
  157. package/dist/src/__tests__/mir/lower-extra6.test.js +471 -0
  158. package/dist/src/__tests__/mir/lower-extra7.test.d.ts +35 -0
  159. package/dist/src/__tests__/mir/lower-extra7.test.js +921 -0
  160. package/dist/src/__tests__/mir/lower-extra8.test.d.ts +19 -0
  161. package/dist/src/__tests__/mir/lower-extra8.test.js +626 -0
  162. package/dist/src/__tests__/mir/lower-extra9.test.d.ts +14 -0
  163. package/dist/src/__tests__/mir/lower-extra9.test.js +717 -0
  164. package/dist/src/__tests__/optimizer/auto-inline.test.d.ts +1 -0
  165. package/dist/src/__tests__/optimizer/auto-inline.test.js +176 -0
  166. package/dist/src/__tests__/optimizer/cse.test.d.ts +4 -0
  167. package/dist/src/__tests__/optimizer/cse.test.js +178 -0
  168. package/dist/src/__tests__/optimizer/inline_fn.test.d.ts +1 -0
  169. package/dist/src/__tests__/optimizer/inline_fn.test.js +221 -0
  170. package/dist/src/__tests__/optimizer/licm.test.d.ts +1 -0
  171. package/dist/src/__tests__/optimizer/licm.test.js +244 -0
  172. package/dist/src/__tests__/optimizer/optimizer-extended.test.d.ts +12 -0
  173. package/dist/src/__tests__/optimizer/optimizer-extended.test.js +993 -0
  174. package/dist/src/__tests__/optimizer/strength-reduction.test.d.ts +1 -0
  175. package/dist/src/__tests__/optimizer/strength-reduction.test.js +86 -0
  176. package/dist/src/__tests__/optimizer/tco.test.d.ts +14 -0
  177. package/dist/src/__tests__/optimizer/tco.test.js +203 -0
  178. package/dist/src/__tests__/parser-coverage.test.d.ts +25 -0
  179. package/dist/src/__tests__/parser-coverage.test.js +491 -0
  180. package/dist/src/__tests__/parser-extra.test.d.ts +6 -0
  181. package/dist/src/__tests__/parser-extra.test.js +451 -0
  182. package/dist/src/__tests__/parser.test.js +12 -0
  183. package/dist/src/__tests__/repl-extra.test.d.ts +13 -0
  184. package/dist/src/__tests__/repl-extra.test.js +174 -0
  185. package/dist/src/__tests__/repl-server-extra.test.d.ts +10 -0
  186. package/dist/src/__tests__/repl-server-extra.test.js +161 -0
  187. package/dist/src/__tests__/repl-server.test.d.ts +6 -0
  188. package/dist/src/__tests__/repl-server.test.js +146 -0
  189. package/dist/src/__tests__/runtime-extra.test.d.ts +15 -0
  190. package/dist/src/__tests__/runtime-extra.test.js +732 -0
  191. package/dist/src/__tests__/singleton-decorator.test.d.ts +11 -0
  192. package/dist/src/__tests__/singleton-decorator.test.js +260 -0
  193. package/dist/src/__tests__/sourcemap.test.js +1 -1
  194. package/dist/src/__tests__/stdlib/advanced.test.d.ts +5 -0
  195. package/dist/src/__tests__/stdlib/advanced.test.js +301 -0
  196. package/dist/src/__tests__/stdlib/bigint.test.d.ts +4 -0
  197. package/dist/src/__tests__/stdlib/bigint.test.js +83 -0
  198. package/dist/src/__tests__/stdlib/bits.test.d.ts +4 -0
  199. package/dist/src/__tests__/stdlib/bits.test.js +96 -0
  200. package/dist/src/__tests__/stdlib/bossbar.test.d.ts +4 -0
  201. package/dist/src/__tests__/stdlib/bossbar.test.js +72 -0
  202. package/dist/src/__tests__/stdlib/color.test.d.ts +4 -0
  203. package/dist/src/__tests__/stdlib/color.test.js +84 -0
  204. package/dist/src/__tests__/stdlib/combat.test.d.ts +4 -0
  205. package/dist/src/__tests__/stdlib/combat.test.js +64 -0
  206. package/dist/src/__tests__/stdlib/cooldown.test.d.ts +4 -0
  207. package/dist/src/__tests__/stdlib/cooldown.test.js +64 -0
  208. package/dist/src/__tests__/stdlib/dialog.test.js +15 -7
  209. package/dist/src/__tests__/stdlib/ecs.test.d.ts +4 -0
  210. package/dist/src/__tests__/stdlib/ecs.test.js +81 -0
  211. package/dist/src/__tests__/stdlib/effects.test.d.ts +4 -0
  212. package/dist/src/__tests__/stdlib/effects.test.js +72 -0
  213. package/dist/src/__tests__/stdlib/events.test.d.ts +4 -0
  214. package/dist/src/__tests__/stdlib/events.test.js +55 -0
  215. package/dist/src/__tests__/stdlib/expr.test.d.ts +4 -0
  216. package/dist/src/__tests__/stdlib/expr.test.js +77 -0
  217. package/dist/src/__tests__/stdlib/fft.test.d.ts +4 -0
  218. package/dist/src/__tests__/stdlib/fft.test.js +82 -0
  219. package/dist/src/__tests__/stdlib/graph.test.d.ts +4 -0
  220. package/dist/src/__tests__/stdlib/graph.test.js +102 -0
  221. package/dist/src/__tests__/stdlib/interactions.test.d.ts +4 -0
  222. package/dist/src/__tests__/stdlib/interactions.test.js +60 -0
  223. package/dist/src/__tests__/stdlib/inventory.test.d.ts +4 -0
  224. package/dist/src/__tests__/stdlib/inventory.test.js +68 -0
  225. package/dist/src/__tests__/stdlib/linalg.test.d.ts +5 -0
  226. package/dist/src/__tests__/stdlib/linalg.test.js +78 -0
  227. package/dist/src/__tests__/stdlib/map.test.d.ts +1 -0
  228. package/dist/src/__tests__/stdlib/map.test.js +84 -0
  229. package/dist/src/__tests__/stdlib/math.test.js +19 -6
  230. package/dist/src/__tests__/stdlib/math_hp.test.d.ts +4 -0
  231. package/dist/src/__tests__/stdlib/math_hp.test.js +80 -0
  232. package/dist/src/__tests__/stdlib/mobs.test.d.ts +4 -0
  233. package/dist/src/__tests__/stdlib/mobs.test.js +61 -0
  234. package/dist/src/__tests__/stdlib/noise.test.d.ts +4 -0
  235. package/dist/src/__tests__/stdlib/noise.test.js +73 -0
  236. package/dist/src/__tests__/stdlib/ode.test.d.ts +4 -0
  237. package/dist/src/__tests__/stdlib/ode.test.js +68 -0
  238. package/dist/src/__tests__/stdlib/parabola.test.d.ts +4 -0
  239. package/dist/src/__tests__/stdlib/parabola.test.js +77 -0
  240. package/dist/src/__tests__/stdlib/particles.test.d.ts +4 -0
  241. package/dist/src/__tests__/stdlib/particles.test.js +68 -0
  242. package/dist/src/__tests__/stdlib/physics.test.d.ts +4 -0
  243. package/dist/src/__tests__/stdlib/physics.test.js +76 -0
  244. package/dist/src/__tests__/stdlib/player.test.d.ts +4 -0
  245. package/dist/src/__tests__/stdlib/player.test.js +64 -0
  246. package/dist/src/__tests__/stdlib/quaternion.test.d.ts +4 -0
  247. package/dist/src/__tests__/stdlib/quaternion.test.js +73 -0
  248. package/dist/src/__tests__/stdlib/queue.test.d.ts +1 -0
  249. package/dist/src/__tests__/stdlib/queue.test.js +97 -0
  250. package/dist/src/__tests__/stdlib/random.test.d.ts +4 -0
  251. package/dist/src/__tests__/stdlib/random.test.js +76 -0
  252. package/dist/src/__tests__/stdlib/result.test.d.ts +12 -0
  253. package/dist/src/__tests__/stdlib/result.test.js +329 -0
  254. package/dist/src/__tests__/stdlib/scheduler.test.js +19 -8
  255. package/dist/src/__tests__/stdlib/set_int.test.d.ts +1 -0
  256. package/dist/src/__tests__/stdlib/set_int.test.js +88 -0
  257. package/dist/src/__tests__/stdlib/sets.test.d.ts +6 -0
  258. package/dist/src/__tests__/stdlib/sets.test.js +60 -0
  259. package/dist/src/__tests__/stdlib/signal.test.d.ts +4 -0
  260. package/dist/src/__tests__/stdlib/signal.test.js +84 -0
  261. package/dist/src/__tests__/stdlib/spawn.test.d.ts +4 -0
  262. package/dist/src/__tests__/stdlib/spawn.test.js +68 -0
  263. package/dist/src/__tests__/stdlib/string.test.d.ts +12 -0
  264. package/dist/src/__tests__/stdlib/string.test.js +231 -0
  265. package/dist/src/__tests__/stdlib/strings.test.d.ts +4 -0
  266. package/dist/src/__tests__/stdlib/strings.test.js +83 -0
  267. package/dist/src/__tests__/stdlib/tags.test.d.ts +4 -0
  268. package/dist/src/__tests__/stdlib/tags.test.js +57 -0
  269. package/dist/src/__tests__/stdlib/teams.test.d.ts +4 -0
  270. package/dist/src/__tests__/stdlib/teams.test.js +72 -0
  271. package/dist/src/__tests__/stdlib/timer.test.d.ts +4 -0
  272. package/dist/src/__tests__/stdlib/timer.test.js +79 -0
  273. package/dist/src/__tests__/stdlib/vec.test.d.ts +5 -0
  274. package/dist/src/__tests__/stdlib/vec.test.js +94 -0
  275. package/dist/src/__tests__/stdlib/world.test.d.ts +4 -0
  276. package/dist/src/__tests__/stdlib/world.test.js +72 -0
  277. package/dist/src/__tests__/struct-display.test.d.ts +1 -0
  278. package/dist/src/__tests__/struct-display.test.js +64 -0
  279. package/dist/src/__tests__/test-framework/runner.test.d.ts +10 -0
  280. package/dist/src/__tests__/test-framework/runner.test.js +193 -0
  281. package/dist/src/__tests__/tuner/adapters.test.d.ts +14 -0
  282. package/dist/src/__tests__/tuner/adapters.test.js +194 -0
  283. package/dist/src/__tests__/tuner/simulator-extra.test.d.ts +4 -0
  284. package/dist/src/__tests__/tuner/simulator-extra.test.js +193 -0
  285. package/dist/src/__tests__/typechecker-coverage.test.d.ts +30 -0
  286. package/dist/src/__tests__/typechecker-coverage.test.js +627 -0
  287. package/dist/src/__tests__/typechecker.test.js +3 -3
  288. package/dist/src/__tests__/watch-decorator.test.d.ts +1 -0
  289. package/dist/src/__tests__/watch-decorator.test.js +54 -0
  290. package/dist/src/ast/types.d.ts +102 -3
  291. package/dist/src/cache/incremental.d.ts +13 -14
  292. package/dist/src/cache/incremental.js +106 -89
  293. package/dist/src/cache/index.d.ts +8 -2
  294. package/dist/src/cache/index.js +18 -6
  295. package/dist/src/cli.d.ts +1 -0
  296. package/dist/src/cli.js +466 -17
  297. package/dist/src/config/project-config.d.ts +29 -0
  298. package/dist/src/config/project-config.js +180 -0
  299. package/dist/src/diagnostics/index.d.ts +9 -0
  300. package/dist/src/diagnostics/index.js +18 -1
  301. package/dist/src/emit/compile.d.ts +10 -0
  302. package/dist/src/emit/compile.js +395 -50
  303. package/dist/src/emit/index.d.ts +40 -0
  304. package/dist/src/emit/index.js +307 -14
  305. package/dist/src/emit/modules.js +21 -3
  306. package/dist/src/emit/sourcemap.d.ts +23 -27
  307. package/dist/src/emit/sourcemap.js +52 -30
  308. package/dist/src/formatter/index.js +33 -8
  309. package/dist/src/hir/deprecated.d.ts +13 -0
  310. package/dist/src/hir/deprecated.js +218 -0
  311. package/dist/src/hir/lower.js +114 -8
  312. package/dist/src/hir/monomorphize.js +22 -2
  313. package/dist/src/hir/types.d.ts +65 -1
  314. package/dist/src/index.d.ts +6 -0
  315. package/dist/src/index.js +18 -3
  316. package/dist/src/lexer/index.d.ts +2 -1
  317. package/dist/src/lexer/index.js +39 -3
  318. package/dist/src/lint/index.d.ts +45 -0
  319. package/dist/src/lint/index.js +930 -0
  320. package/dist/src/lir/lower.js +29 -2
  321. package/dist/src/lir/types.d.ts +2 -0
  322. package/dist/src/lsp/server.js +92 -5
  323. package/dist/src/mir/lower.js +775 -34
  324. package/dist/src/mir/macro.js +36 -2
  325. package/dist/src/mir/types.d.ts +12 -0
  326. package/dist/src/mir/verify.js +9 -0
  327. package/dist/src/optimizer/auto-inline.d.ts +2 -0
  328. package/dist/src/optimizer/auto-inline.js +67 -0
  329. package/dist/src/optimizer/cse.d.ts +20 -0
  330. package/dist/src/optimizer/cse.js +234 -0
  331. package/dist/src/optimizer/inline.d.ts +26 -0
  332. package/dist/src/optimizer/inline.js +286 -0
  333. package/dist/src/optimizer/interprocedural.js +4 -0
  334. package/dist/src/optimizer/licm.d.ts +32 -0
  335. package/dist/src/optimizer/licm.js +371 -0
  336. package/dist/src/optimizer/pipeline.js +12 -2
  337. package/dist/src/optimizer/strength_reduction.d.ts +15 -0
  338. package/dist/src/optimizer/strength_reduction.js +90 -0
  339. package/dist/src/optimizer/tco.d.ts +53 -0
  340. package/dist/src/optimizer/tco.js +238 -0
  341. package/dist/src/parser/index.d.ts +32 -0
  342. package/dist/src/parser/index.js +421 -59
  343. package/dist/src/repl-server.d.ts +13 -0
  344. package/dist/src/repl-server.js +127 -0
  345. package/dist/src/structs/expand.d.ts +15 -0
  346. package/dist/src/structs/expand.js +46 -0
  347. package/dist/src/testing/runner.d.ts +40 -0
  348. package/dist/src/testing/runner.js +237 -0
  349. package/dist/src/typechecker/index.d.ts +3 -0
  350. package/dist/src/typechecker/index.js +254 -9
  351. package/dist/tsconfig.tsbuildinfo +1 -1
  352. package/doc-drafts/redscript-docs/docs/en/stdlib/graph.md +104 -0
  353. package/doc-drafts/redscript-docs/docs/en/stdlib/parabola.md +113 -0
  354. package/doc-drafts/redscript-docs/docs/en/stdlib/pathfind.md +104 -0
  355. package/doc-drafts/redscript-docs/docs/en/stdlib/physics.md +134 -0
  356. package/doc-drafts/redscript-docs/docs/en/stdlib/quaternion.md +135 -0
  357. package/doc-drafts/redscript-docs/docs/zh/stdlib/graph.md +104 -0
  358. package/doc-drafts/redscript-docs/docs/zh/stdlib/parabola.md +113 -0
  359. package/doc-drafts/redscript-docs/docs/zh/stdlib/pathfind.md +104 -0
  360. package/doc-drafts/redscript-docs/docs/zh/stdlib/physics.md +134 -0
  361. package/doc-drafts/redscript-docs/docs/zh/stdlib/quaternion.md +135 -0
  362. package/docs/stdlib/result.md +156 -0
  363. package/docs/stdlib/result.zh.md +156 -0
  364. package/editors/vscode/fixtures/test.mcrs +7 -0
  365. package/editors/vscode/out/extension.js +2095 -225
  366. package/editors/vscode/out/lsp-server.js +519 -51
  367. package/editors/vscode/package-lock.json +9 -4
  368. package/editors/vscode/package.json +1 -1
  369. package/examples/display-demo.mcrs +64 -0
  370. package/examples/game/racing.mcrs +301 -0
  371. package/examples/game/tower_defense.mcrs +311 -0
  372. package/examples/math/physics_sim.mcrs +322 -0
  373. package/examples/rpg/boss_fight.mcrs +313 -0
  374. package/examples/rpg/health_system.mcrs +237 -0
  375. package/examples/rpg/inventory.mcrs +265 -0
  376. package/examples/util/debug_hud.mcrs +279 -0
  377. package/jest.config.js +10 -0
  378. package/package.json +12 -3
  379. package/playground/index.html +823 -0
  380. package/scripts/gen-docs.ts +533 -0
  381. package/scripts/update-redscript-docs-stdlib.sh +770 -0
  382. package/src/__tests__/budget.test.ts +5 -0
  383. package/src/__tests__/cache/cache-behavior.test.ts +480 -0
  384. package/src/__tests__/cache-extra.test.ts +199 -0
  385. package/src/__tests__/cli-docs.test.ts +77 -0
  386. package/src/__tests__/cli-init.test.ts +91 -0
  387. package/src/__tests__/cli-publish.test.ts +190 -0
  388. package/src/__tests__/cli.test.ts +117 -1
  389. package/src/__tests__/compile-preprocess.test.ts +366 -0
  390. package/src/__tests__/compiler/break-stmt.test.ts +66 -0
  391. package/src/__tests__/compiler/const-decl.test.ts +141 -0
  392. package/src/__tests__/compiler/continue-stmt.test.ts +81 -0
  393. package/src/__tests__/compiler/coroutine-extended.test.ts +723 -0
  394. package/src/__tests__/compiler/deprecated.test.ts +305 -0
  395. package/src/__tests__/compiler/do-while.test.ts +130 -0
  396. package/src/__tests__/compiler/enum-payload.test.ts +299 -0
  397. package/src/__tests__/compiler/interface.test.ts +287 -0
  398. package/src/__tests__/compiler/labeled-loops.test.ts +279 -0
  399. package/src/__tests__/compiler/match-string.test.ts +45 -0
  400. package/src/__tests__/compiler/memoize.test.ts +126 -0
  401. package/src/__tests__/compiler/method-chain.test.ts +121 -0
  402. package/src/__tests__/compiler/module-import.test.ts +240 -0
  403. package/src/__tests__/compiler/option-extensions.test.ts +207 -0
  404. package/src/__tests__/compiler/profile-decorator.test.ts +79 -0
  405. package/src/__tests__/compiler/string-advanced.test.ts +310 -0
  406. package/src/__tests__/compiler/struct-extends.test.ts +109 -0
  407. package/src/__tests__/compiler/throttle-retry.test.ts +191 -0
  408. package/src/__tests__/compiler/tuple-type.test.ts +263 -0
  409. package/src/__tests__/compiler/watch-decorator.test.ts +72 -0
  410. package/src/__tests__/config/project-config.test.ts +181 -0
  411. package/src/__tests__/config-decorator.test.ts +157 -0
  412. package/src/__tests__/diagnostics-extra.test.ts +155 -0
  413. package/src/__tests__/emit/compile-branches.test.ts +135 -0
  414. package/src/__tests__/emit/compile-coverage.test.ts +696 -0
  415. package/src/__tests__/emit/compile-extra-branches.test.ts +228 -0
  416. package/src/__tests__/emit/compile-mocked-branches.test.ts +249 -0
  417. package/src/__tests__/emit/compile.test.ts +6 -1
  418. package/src/__tests__/emit/execute-chain.test.ts +114 -0
  419. package/src/__tests__/emit/index.test.ts +2 -1
  420. package/src/__tests__/emit/modules-branches.test.ts +90 -0
  421. package/src/__tests__/emit/modules-coverage.test.ts +241 -0
  422. package/src/__tests__/emit/modules-errors.test.ts +192 -0
  423. package/src/__tests__/emit/modules-rewrite.test.ts +232 -0
  424. package/src/__tests__/emit/source-map.test.ts +152 -0
  425. package/src/__tests__/enum.test.ts +9 -4
  426. package/src/__tests__/error-recovery.test.ts +226 -0
  427. package/src/__tests__/events-types-extra.test.ts +110 -0
  428. package/src/__tests__/events-types.test.ts +66 -0
  429. package/src/__tests__/formatter.test.ts +15 -5
  430. package/src/__tests__/generics.test.ts +16 -9
  431. package/src/__tests__/hir/lower-extra.test.ts +151 -0
  432. package/src/__tests__/hir/monomorphize-coverage.test.ts +432 -0
  433. package/src/__tests__/hir/monomorphize-extra.test.ts +220 -0
  434. package/src/__tests__/hir/monomorphize-extra2.test.ts +350 -0
  435. package/src/__tests__/impl.test.ts +12 -8
  436. package/src/__tests__/incremental.test.ts +10 -2
  437. package/src/__tests__/index-extra.test.ts +79 -0
  438. package/src/__tests__/lexer.test.ts +2 -2
  439. package/src/__tests__/lint/hir-coverage.test.ts +1716 -0
  440. package/src/__tests__/lint/rules-coverage.test.ts +598 -0
  441. package/src/__tests__/lint/rules.test.ts +230 -0
  442. package/src/__tests__/lir/lower.test.ts +33 -0
  443. package/src/__tests__/lir/verify.test.ts +33 -0
  444. package/src/__tests__/lsp/completion.test.ts +687 -0
  445. package/src/__tests__/lsp/definition.test.ts +499 -0
  446. package/src/__tests__/lsp/diagnostics.test.ts +108 -0
  447. package/src/__tests__/lsp/hover-docs.test.ts +222 -0
  448. package/src/__tests__/lsp.test.ts +4 -1
  449. package/src/__tests__/mc-integration/item-entity-events.test.ts +5 -0
  450. package/src/__tests__/mc-integration/stdlib-coverage-2.test.ts +5 -0
  451. package/src/__tests__/mc-integration/stdlib-coverage-3.test.ts +1105 -0
  452. package/src/__tests__/mc-integration/stdlib-coverage-4.test.ts +1366 -0
  453. package/src/__tests__/mc-integration/stdlib-coverage-5.test.ts +1245 -0
  454. package/src/__tests__/mc-integration/stdlib-coverage-6.test.ts +755 -0
  455. package/src/__tests__/mc-integration/stdlib-coverage-7.test.ts +771 -0
  456. package/src/__tests__/mc-integration/stdlib-coverage.test.ts +5 -0
  457. package/src/__tests__/mc-integration/syntax-coverage.test.ts +5 -0
  458. package/src/__tests__/mc-validator-coverage.test.ts +325 -0
  459. package/src/__tests__/mc-validator-extra.test.ts +252 -0
  460. package/src/__tests__/mir/lower-extra.test.ts +402 -0
  461. package/src/__tests__/mir/lower-extra2.test.ts +348 -0
  462. package/src/__tests__/mir/lower-extra3.test.ts +277 -0
  463. package/src/__tests__/mir/lower-extra4.test.ts +636 -0
  464. package/src/__tests__/mir/lower-extra5.test.ts +612 -0
  465. package/src/__tests__/mir/lower-extra6.test.ts +520 -0
  466. package/src/__tests__/mir/lower-extra7.test.ts +1045 -0
  467. package/src/__tests__/mir/lower-extra8.test.ts +704 -0
  468. package/src/__tests__/mir/lower-extra9.test.ts +821 -0
  469. package/src/__tests__/optimizer/auto-inline.test.ts +206 -0
  470. package/src/__tests__/optimizer/cse.test.ts +195 -0
  471. package/src/__tests__/optimizer/inline_fn.test.ts +263 -0
  472. package/src/__tests__/optimizer/licm.test.ts +358 -0
  473. package/src/__tests__/optimizer/nbt-coalesce.test.ts +147 -0
  474. package/src/__tests__/optimizer/optimizer-extended.test.ts +1081 -0
  475. package/src/__tests__/optimizer/scoreboard-batch.test.ts +141 -0
  476. package/src/__tests__/optimizer/strength-reduction.test.ts +111 -0
  477. package/src/__tests__/optimizer/tco-coverage.test.ts +309 -0
  478. package/src/__tests__/optimizer/tco.test.ts +238 -0
  479. package/src/__tests__/option.test.ts +14 -7
  480. package/src/__tests__/parser-coverage.test.ts +576 -0
  481. package/src/__tests__/parser-extra.test.ts +531 -0
  482. package/src/__tests__/parser.test.ts +14 -0
  483. package/src/__tests__/repl-extra.test.ts +195 -0
  484. package/src/__tests__/repl-server-extra.test.ts +150 -0
  485. package/src/__tests__/repl-server.test.ts +122 -0
  486. package/src/__tests__/runtime-extra.test.ts +862 -0
  487. package/src/__tests__/singleton-decorator.test.ts +285 -0
  488. package/src/__tests__/sourcemap.test.ts +1 -1
  489. package/src/__tests__/stdlib/advanced.test.ts +312 -0
  490. package/src/__tests__/stdlib/bigint.test.ts +57 -0
  491. package/src/__tests__/stdlib/bits.test.ts +75 -0
  492. package/src/__tests__/stdlib/bossbar.test.ts +45 -0
  493. package/src/__tests__/stdlib/color.test.ts +60 -0
  494. package/src/__tests__/stdlib/combat.test.ts +35 -0
  495. package/src/__tests__/stdlib/cooldown.test.ts +35 -0
  496. package/src/__tests__/stdlib/dialog.test.ts +14 -6
  497. package/src/__tests__/stdlib/ecs.test.ts +54 -0
  498. package/src/__tests__/stdlib/effects.test.ts +45 -0
  499. package/src/__tests__/stdlib/events.test.ts +23 -0
  500. package/src/__tests__/stdlib/expr.test.ts +48 -0
  501. package/src/__tests__/stdlib/fft.test.ts +54 -0
  502. package/src/__tests__/stdlib/graph.test.ts +77 -0
  503. package/src/__tests__/stdlib/interactions.test.ts +30 -0
  504. package/src/__tests__/stdlib/inventory.test.ts +40 -0
  505. package/src/__tests__/stdlib/linalg.test.ts +52 -0
  506. package/src/__tests__/stdlib/map.test.ts +55 -0
  507. package/src/__tests__/stdlib/math.test.ts +19 -5
  508. package/src/__tests__/stdlib/math_hp.test.ts +55 -0
  509. package/src/__tests__/stdlib/mobs.test.ts +40 -0
  510. package/src/__tests__/stdlib/noise.test.ts +46 -0
  511. package/src/__tests__/stdlib/ode.test.ts +40 -0
  512. package/src/__tests__/stdlib/parabola.test.ts +51 -0
  513. package/src/__tests__/stdlib/particles.test.ts +40 -0
  514. package/src/__tests__/stdlib/physics.test.ts +50 -0
  515. package/src/__tests__/stdlib/player.test.ts +35 -0
  516. package/src/__tests__/stdlib/quaternion.test.ts +46 -0
  517. package/src/__tests__/stdlib/queue.test.ts +73 -0
  518. package/src/__tests__/stdlib/random.test.ts +50 -0
  519. package/src/__tests__/stdlib/result.test.ts +326 -0
  520. package/src/__tests__/stdlib/scheduler.test.ts +18 -7
  521. package/src/__tests__/stdlib/set_int.test.ts +62 -0
  522. package/src/__tests__/stdlib/sets.test.ts +28 -0
  523. package/src/__tests__/stdlib/signal.test.ts +60 -0
  524. package/src/__tests__/stdlib/spawn.test.ts +40 -0
  525. package/src/__tests__/stdlib/string.test.ts +224 -0
  526. package/src/__tests__/stdlib/strings.test.ts +55 -0
  527. package/src/__tests__/stdlib/tags.test.ts +32 -0
  528. package/src/__tests__/stdlib/teams.test.ts +45 -0
  529. package/src/__tests__/stdlib/timer.test.ts +53 -0
  530. package/src/__tests__/stdlib/vec.test.ts +72 -0
  531. package/src/__tests__/stdlib/world.test.ts +45 -0
  532. package/src/__tests__/struct-display.test.ts +69 -0
  533. package/src/__tests__/test-framework/runner.test.ts +208 -0
  534. package/src/__tests__/tuner/adapters.test.ts +232 -0
  535. package/src/__tests__/tuner/simulator-extra.test.ts +222 -0
  536. package/src/__tests__/tuple.test.ts +11 -4
  537. package/src/__tests__/typechecker-coverage.test.ts +671 -0
  538. package/src/__tests__/typechecker.test.ts +4 -3
  539. package/src/__tests__/watch-decorator.test.ts +59 -0
  540. package/src/ast/types.ts +65 -3
  541. package/src/cache/incremental.ts +128 -99
  542. package/src/cache/index.ts +35 -8
  543. package/src/cli.ts +538 -29
  544. package/src/config/project-config.ts +176 -0
  545. package/src/diagnostics/index.ts +22 -0
  546. package/src/docs.ts +98 -0
  547. package/src/emit/compile.ts +408 -51
  548. package/src/emit/index.ts +366 -18
  549. package/src/emit/modules.ts +19 -3
  550. package/src/emit/sourcemap.ts +64 -43
  551. package/src/formatter/index.ts +35 -8
  552. package/src/hir/deprecated.ts +212 -0
  553. package/src/hir/lower.ts +128 -8
  554. package/src/hir/monomorphize.ts +24 -2
  555. package/src/hir/types.ts +26 -1
  556. package/src/index.ts +23 -3
  557. package/src/lexer/index.ts +45 -6
  558. package/src/lint/index.ts +922 -0
  559. package/src/lir/lower.ts +30 -2
  560. package/src/lir/types.ts +4 -0
  561. package/src/lsp/server.ts +100 -1
  562. package/src/mir/lower.ts +785 -40
  563. package/src/mir/macro.ts +30 -2
  564. package/src/mir/types.ts +13 -0
  565. package/src/mir/verify.ts +10 -2
  566. package/src/optimizer/auto-inline.ts +86 -0
  567. package/src/optimizer/copy_prop.ts +2 -2
  568. package/src/optimizer/coroutine.ts +3 -3
  569. package/src/optimizer/cse.ts +205 -0
  570. package/src/optimizer/dce.ts +2 -2
  571. package/src/optimizer/inline.ts +335 -0
  572. package/src/optimizer/interprocedural.ts +5 -1
  573. package/src/optimizer/licm.ts +454 -0
  574. package/src/optimizer/nbt-coalesce.ts +109 -0
  575. package/src/optimizer/pipeline.ts +16 -2
  576. package/src/optimizer/scoreboard-batch.ts +52 -0
  577. package/src/optimizer/strength_reduction.ts +95 -0
  578. package/src/optimizer/tco.ts +267 -0
  579. package/src/optimizer/unroll.ts +2 -2
  580. package/src/parser/index.ts +426 -53
  581. package/src/repl-server.ts +102 -0
  582. package/src/stdlib/advanced.mcrs +271 -101
  583. package/src/stdlib/bigint.mcrs +97 -11
  584. package/src/stdlib/bits.mcrs +75 -12
  585. package/src/stdlib/bossbar.mcrs +37 -8
  586. package/src/stdlib/calculus.mcrs +82 -26
  587. package/src/stdlib/color.mcrs +98 -16
  588. package/src/stdlib/combat.mcrs +23 -5
  589. package/src/stdlib/cooldown.mcrs +19 -0
  590. package/src/stdlib/dialog.mcrs +45 -7
  591. package/src/stdlib/easing.mcrs +132 -12
  592. package/src/stdlib/ecs.mcrs +142 -25
  593. package/src/stdlib/effects.mcrs +88 -12
  594. package/src/stdlib/events.mcrs +21 -2
  595. package/src/stdlib/expr.mcrs +18 -3
  596. package/src/stdlib/fft.mcrs +66 -56
  597. package/src/stdlib/geometry.mcrs +137 -39
  598. package/src/stdlib/graph.mcrs +73 -0
  599. package/src/stdlib/heap.mcrs +49 -8
  600. package/src/stdlib/i18n/zh.yaml +2891 -0
  601. package/src/stdlib/interactions.mcrs +43 -20
  602. package/src/stdlib/inventory.mcrs +14 -3
  603. package/src/stdlib/linalg.mcrs +185 -30
  604. package/src/stdlib/list.mcrs +168 -18
  605. package/src/stdlib/map.mcrs +112 -0
  606. package/src/stdlib/math.mcrs +68 -18
  607. package/src/stdlib/math_hp.mcrs +124 -33
  608. package/src/stdlib/matrix.mcrs +133 -20
  609. package/src/stdlib/mobs.mcrs +87 -0
  610. package/src/stdlib/noise.mcrs +65 -21
  611. package/src/stdlib/ode.mcrs +96 -0
  612. package/src/stdlib/parabola.mcrs +104 -29
  613. package/src/stdlib/particles.mcrs +78 -21
  614. package/src/stdlib/pathfind.mcrs +89 -35
  615. package/src/stdlib/physics.mcrs +134 -26
  616. package/src/stdlib/player.mcrs +18 -0
  617. package/src/stdlib/quaternion.mcrs +213 -9
  618. package/src/stdlib/queue.mcrs +123 -0
  619. package/src/stdlib/random.mcrs +63 -18
  620. package/src/stdlib/result.mcrs +111 -0
  621. package/src/stdlib/scheduler.mcrs +59 -10
  622. package/src/stdlib/set_int.mcrs +240 -0
  623. package/src/stdlib/sets.mcrs +49 -19
  624. package/src/stdlib/signal.mcrs +151 -79
  625. package/src/stdlib/sort.mcrs +44 -24
  626. package/src/stdlib/spawn.mcrs +30 -7
  627. package/src/stdlib/state.mcrs +40 -5
  628. package/src/stdlib/strings.mcrs +131 -3
  629. package/src/stdlib/tags.mcrs +2 -2
  630. package/src/stdlib/teams.mcrs +22 -10
  631. package/src/stdlib/timer.mcrs +36 -6
  632. package/src/stdlib/vec.mcrs +44 -9
  633. package/src/stdlib/world.mcrs +57 -25
  634. package/src/structs/expand.ts +64 -0
  635. package/src/testing/runner.ts +271 -0
  636. package/src/typechecker/index.ts +273 -9
@@ -0,0 +1,425 @@
1
+ "use strict";
2
+ /**
3
+ * cache-behavior.test.ts
4
+ *
5
+ * Focused tests for cache behavior:
6
+ * - Same code compiled twice → second compile uses cache
7
+ * - Modified code → cache invalidation
8
+ * - stdlib / shared module caching
9
+ * - Edge cases to push src/cache/ coverage > 85%
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ const fs = __importStar(require("fs"));
46
+ const os = __importStar(require("os"));
47
+ const path = __importStar(require("path"));
48
+ const index_1 = require("../../cache/index");
49
+ const deps_1 = require("../../cache/deps");
50
+ const incremental_1 = require("../../cache/incremental");
51
+ // ---------------------------------------------------------------------------
52
+ // Helpers
53
+ // ---------------------------------------------------------------------------
54
+ function makeTmpDir() {
55
+ return fs.mkdtempSync(path.join(os.tmpdir(), 'rs-cache-behavior-'));
56
+ }
57
+ function writeFile(dir, name, content) {
58
+ const filePath = path.join(dir, name);
59
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
60
+ fs.writeFileSync(filePath, content);
61
+ return filePath;
62
+ }
63
+ /** Bump mtime forward so hasChanged detects a modification. */
64
+ function touchFile(filePath, offsetMs = 5_000) {
65
+ const now = Date.now() + offsetMs;
66
+ fs.utimesSync(filePath, new Date(now), new Date(now));
67
+ }
68
+ /** Write new content and bump mtime. */
69
+ function modifyFile(filePath, newContent) {
70
+ fs.writeFileSync(filePath, newContent);
71
+ touchFile(filePath);
72
+ }
73
+ // ---------------------------------------------------------------------------
74
+ // FileCache — uncovered branches
75
+ // ---------------------------------------------------------------------------
76
+ describe('FileCache — stat throws on cached file (branch coverage)', () => {
77
+ test('hasChanged returns true when stat throws after entry is cached', () => {
78
+ const cache = new index_1.FileCache('/tmp/test-no-file');
79
+ // Manually insert an entry for a path that does NOT exist on disk
80
+ const fakePath = '/absolutely/nonexistent/ghost.mcrs';
81
+ cache.set(fakePath, { hash: 'deadbeef', mtime: 12345 });
82
+ // stat will throw → branch at line 53 returns true
83
+ expect(cache.hasChanged(fakePath)).toBe(true);
84
+ });
85
+ test('update on nonexistent file removes entry (catch branch)', () => {
86
+ const tmp = makeTmpDir();
87
+ const cache = new index_1.FileCache(tmp);
88
+ // First create file, cache it
89
+ const filePath = writeFile(tmp, 'ghost.mcrs', 'fn ghost() {}');
90
+ cache.update(filePath);
91
+ expect(cache.size).toBe(1);
92
+ // Delete the file — now update should catch the error and delete the entry
93
+ fs.unlinkSync(filePath);
94
+ // Manually wipe mtime so hasChanged considers it changed
95
+ cache.set(filePath, { hash: 'stale', mtime: 0 });
96
+ cache.update(filePath); // stat throws inside update → delete branch
97
+ expect(cache.get(filePath)).toBeUndefined();
98
+ });
99
+ });
100
+ describe('FileCache — update HIR on unchanged file', () => {
101
+ test('update with HIR on unchanged file stores HIR without marking changed', () => {
102
+ const tmp = makeTmpDir();
103
+ const cache = new index_1.FileCache(tmp);
104
+ const filePath = writeFile(tmp, 'stable.mcrs', 'fn stable() {}');
105
+ // Initial update — mark file as cached
106
+ cache.update(filePath);
107
+ expect(cache.hasChanged(filePath)).toBe(false);
108
+ // Call update again with a fake HIR on an unchanged file
109
+ const fakeHir = { functions: [] };
110
+ const changed = cache.update(filePath, fakeHir);
111
+ expect(changed).toBe(false); // file didn't change
112
+ // HIR should now be attached
113
+ const entry = cache.get(filePath);
114
+ expect(entry?.hir).toBe(fakeHir);
115
+ });
116
+ });
117
+ describe('FileCache — load with wrong version is ignored', () => {
118
+ test('load skips entries when cache version !== 1', () => {
119
+ const tmp = makeTmpDir();
120
+ const cacheDir = path.join(tmp, '.cache');
121
+ fs.mkdirSync(cacheDir, { recursive: true });
122
+ // Write a v2 cache file
123
+ fs.writeFileSync(path.join(cacheDir, 'cache.json'), JSON.stringify({ version: 99, entries: { '/some/file.mcrs': { hash: 'abc', mtime: 1 } } }));
124
+ const cache = new index_1.FileCache(cacheDir);
125
+ cache.load();
126
+ expect(cache.size).toBe(0); // version mismatch — ignored
127
+ });
128
+ });
129
+ // ---------------------------------------------------------------------------
130
+ // Behavior: same code twice → second compile is cached
131
+ // ---------------------------------------------------------------------------
132
+ describe('Cache hit: same code compiled twice', () => {
133
+ let tmpDir;
134
+ let cacheDir;
135
+ let outDir;
136
+ beforeEach(() => {
137
+ tmpDir = makeTmpDir();
138
+ cacheDir = path.join(tmpDir, '.cache');
139
+ outDir = path.join(tmpDir, 'out');
140
+ (0, incremental_1.resetCompileCache)();
141
+ });
142
+ afterEach(() => {
143
+ fs.rmSync(tmpDir, { recursive: true, force: true });
144
+ });
145
+ test('second compile of unchanged file produces cache hit', () => {
146
+ const src = writeFile(tmpDir, 'hello.mcrs', 'fn hello() { let x: int = 1; }');
147
+ const cache = new index_1.FileCache(cacheDir);
148
+ const depGraph = new deps_1.DependencyGraph();
149
+ // First compile — must be a miss
150
+ const r1 = (0, incremental_1.compileIncremental)([src], cache, depGraph, { output: outDir });
151
+ expect(r1.recompiled).toBe(1);
152
+ expect(r1.cached).toBe(0);
153
+ // Second compile — same file, same content → cache hit
154
+ const r2 = (0, incremental_1.compileIncremental)([src], cache, depGraph, { output: outDir });
155
+ expect(r2.recompiled).toBe(0);
156
+ expect(r2.cached).toBe(1);
157
+ });
158
+ test('cache persists across FileCache reload', () => {
159
+ const src = writeFile(tmpDir, 'hello.mcrs', 'fn hello() { let x: int = 1; }');
160
+ // First pass: compile and save cache to disk
161
+ const cache1 = new index_1.FileCache(cacheDir);
162
+ const depGraph1 = new deps_1.DependencyGraph();
163
+ (0, incremental_1.compileIncremental)([src], cache1, depGraph1, { output: outDir });
164
+ cache1.save();
165
+ // Reset in-memory compile cache to simulate a fresh process
166
+ (0, incremental_1.resetCompileCache)();
167
+ // Second pass: load cache from disk — still a hit for the FileCache checks
168
+ const cache2 = new index_1.FileCache(cacheDir);
169
+ cache2.load();
170
+ expect(cache2.hasChanged(src)).toBe(false);
171
+ });
172
+ });
173
+ // ---------------------------------------------------------------------------
174
+ // Behavior: modifying code invalidates cache
175
+ // ---------------------------------------------------------------------------
176
+ describe('Cache invalidation: modified source', () => {
177
+ let tmpDir;
178
+ let cacheDir;
179
+ let outDir;
180
+ beforeEach(() => {
181
+ tmpDir = makeTmpDir();
182
+ cacheDir = path.join(tmpDir, '.cache');
183
+ outDir = path.join(tmpDir, 'out');
184
+ (0, incremental_1.resetCompileCache)();
185
+ });
186
+ afterEach(() => {
187
+ fs.rmSync(tmpDir, { recursive: true, force: true });
188
+ });
189
+ test('modified file is recompiled after cache hit', () => {
190
+ const src = writeFile(tmpDir, 'counter.mcrs', 'fn counter() { let n: int = 0; }');
191
+ const cache = new index_1.FileCache(cacheDir);
192
+ const depGraph = new deps_1.DependencyGraph();
193
+ // First compile
194
+ (0, incremental_1.compileIncremental)([src], cache, depGraph, { output: outDir });
195
+ // Modify the file
196
+ modifyFile(src, 'fn counter() { let n: int = 99; }');
197
+ // hasChanged should now return true
198
+ expect(cache.hasChanged(src)).toBe(true);
199
+ // Second compile — should recompile
200
+ const r2 = (0, incremental_1.compileIncremental)([src], cache, depGraph, { output: outDir });
201
+ expect(r2.recompiled).toBe(1);
202
+ expect(r2.cached).toBe(0);
203
+ });
204
+ test('mtime change with same content still returns cached (hash match)', () => {
205
+ const tmp2 = makeTmpDir();
206
+ const cache = new index_1.FileCache(tmp2);
207
+ const filePath = writeFile(tmp2, 'stable.mcrs', 'fn stable() {}');
208
+ cache.update(filePath);
209
+ // Touch mtime without changing content
210
+ touchFile(filePath);
211
+ // mtime changed but hash should match → hasChanged returns false
212
+ expect(cache.hasChanged(filePath)).toBe(false);
213
+ fs.rmSync(tmp2, { recursive: true, force: true });
214
+ });
215
+ test('delete file from cache then recompile triggers miss', () => {
216
+ const src = writeFile(tmpDir, 'foo.mcrs', 'fn foo() { let x: int = 5; }');
217
+ const cache = new index_1.FileCache(cacheDir);
218
+ const depGraph = new deps_1.DependencyGraph();
219
+ // Compile once
220
+ (0, incremental_1.compileIncremental)([src], cache, depGraph, { output: outDir });
221
+ expect(cache.hasChanged(src)).toBe(false);
222
+ // Evict from FileCache
223
+ cache.delete(src);
224
+ expect(cache.hasChanged(src)).toBe(true);
225
+ });
226
+ });
227
+ // ---------------------------------------------------------------------------
228
+ // Behavior: stdlib / shared module caching
229
+ // ---------------------------------------------------------------------------
230
+ describe('Stdlib / shared module caching', () => {
231
+ let tmpDir;
232
+ let cacheDir;
233
+ let outDir;
234
+ beforeEach(() => {
235
+ tmpDir = makeTmpDir();
236
+ cacheDir = path.join(tmpDir, '.cache');
237
+ outDir = path.join(tmpDir, 'out');
238
+ (0, incremental_1.resetCompileCache)();
239
+ });
240
+ afterEach(() => {
241
+ fs.rmSync(tmpDir, { recursive: true, force: true });
242
+ });
243
+ test('unchanged stdlib module cached across multiple entry files', () => {
244
+ // Simulate a stdlib module shared by many files
245
+ const stdlib = writeFile(tmpDir, 'stdlib/math.mcrs', 'fn math_add(a: int, b: int): int { return a + b; }');
246
+ const file1 = writeFile(tmpDir, 'prog1.mcrs', `import "stdlib/math.mcrs";\nfn prog1() { math_add(1, 2); }`);
247
+ const file2 = writeFile(tmpDir, 'prog2.mcrs', `import "stdlib/math.mcrs";\nfn prog2() { math_add(3, 4); }`);
248
+ const cache = new index_1.FileCache(cacheDir);
249
+ const depGraph = new deps_1.DependencyGraph();
250
+ // First compile — all miss
251
+ const r1 = (0, incremental_1.compileIncremental)([file1, file2], cache, depGraph, { output: outDir });
252
+ expect(r1.recompiled).toBe(2);
253
+ expect(r1.cached).toBe(0);
254
+ // Second compile — stdlib unchanged, both files cached
255
+ const r2 = (0, incremental_1.compileIncremental)([file1, file2], cache, depGraph, { output: outDir });
256
+ expect(r2.recompiled).toBe(0);
257
+ expect(r2.cached).toBe(2);
258
+ // Verify stdlib itself is tracked in cache
259
+ expect(cache.hasChanged(stdlib)).toBe(false);
260
+ });
261
+ test('stdlib change invalidates all dependents', () => {
262
+ const stdlib = writeFile(tmpDir, 'stdlib/core.mcrs', 'fn core_fn() { let v: int = 1; }');
263
+ const file1 = writeFile(tmpDir, 'a.mcrs', `import "stdlib/core.mcrs";\nfn a() { core_fn(); }`);
264
+ const file2 = writeFile(tmpDir, 'b.mcrs', `import "stdlib/core.mcrs";\nfn b() { core_fn(); }`);
265
+ const isolated = writeFile(tmpDir, 'isolated.mcrs', 'fn isolated() { let x: int = 42; }');
266
+ const cache = new index_1.FileCache(cacheDir);
267
+ const depGraph = new deps_1.DependencyGraph();
268
+ // Compile all three
269
+ (0, incremental_1.compileIncremental)([file1, file2, isolated], cache, depGraph, { output: outDir });
270
+ // Modify stdlib
271
+ modifyFile(stdlib, 'fn core_fn() { let v: int = 999; }');
272
+ // Both file1 and file2 depend on stdlib → recompile; isolated is unaffected
273
+ const r2 = (0, incremental_1.compileIncremental)([file1, file2, isolated], cache, depGraph, { output: outDir });
274
+ expect(r2.recompiled).toBe(2); // file1 + file2
275
+ expect(r2.cached).toBe(1); // isolated
276
+ expect(r2.errors.size).toBe(0);
277
+ });
278
+ test('stdlib module hash stays stable when content unchanged', () => {
279
+ const stdlib = writeFile(tmpDir, 'stdlib/stable.mcrs', 'fn stable_fn() { let s: int = 0; }');
280
+ const cache = new index_1.FileCache(tmpDir);
281
+ const h1 = (0, index_1.hashFile)(stdlib);
282
+ cache.update(stdlib);
283
+ // Reload from entry
284
+ const entry = cache.get(stdlib);
285
+ expect(entry?.hash).toBe(h1);
286
+ // No modification — hash should remain identical
287
+ const h2 = (0, index_1.hashFile)(stdlib);
288
+ expect(h1).toBe(h2);
289
+ expect(cache.hasChanged(stdlib)).toBe(false);
290
+ });
291
+ });
292
+ // ---------------------------------------------------------------------------
293
+ // DependencyGraph — uncovered branches (line 52, 125-130)
294
+ // ---------------------------------------------------------------------------
295
+ describe('DependencyGraph — edge cases', () => {
296
+ let tmpDir;
297
+ beforeEach(() => {
298
+ tmpDir = makeTmpDir();
299
+ });
300
+ afterEach(() => {
301
+ fs.rmSync(tmpDir, { recursive: true, force: true });
302
+ });
303
+ test('removeFile removes the file from the graph', () => {
304
+ const a = writeFile(tmpDir, 'a.mcrs', 'fn a() {}');
305
+ const graph = new deps_1.DependencyGraph();
306
+ graph.addFile(a);
307
+ expect(graph.getAllFiles()).toContain(path.resolve(a));
308
+ graph.removeFile(a);
309
+ expect(graph.getAllFiles()).not.toContain(path.resolve(a));
310
+ });
311
+ test('getAllFiles returns all tracked files', () => {
312
+ const a = writeFile(tmpDir, 'a.mcrs', 'fn a() {}');
313
+ const b = writeFile(tmpDir, 'b.mcrs', 'fn b() {}');
314
+ const graph = new deps_1.DependencyGraph();
315
+ graph.addFile(a);
316
+ graph.addFile(b);
317
+ const files = graph.getAllFiles();
318
+ expect(files).toHaveLength(2);
319
+ expect(files).toContain(path.resolve(a));
320
+ expect(files).toContain(path.resolve(b));
321
+ });
322
+ test('clear empties the graph', () => {
323
+ const a = writeFile(tmpDir, 'a.mcrs', 'fn a() {}');
324
+ const graph = new deps_1.DependencyGraph();
325
+ graph.addFile(a);
326
+ expect(graph.getAllFiles()).toHaveLength(1);
327
+ graph.clear();
328
+ expect(graph.getAllFiles()).toHaveLength(0);
329
+ });
330
+ test('getDirectDeps returns empty set for unknown file', () => {
331
+ const graph = new deps_1.DependencyGraph();
332
+ const deps = graph.getDirectDeps('/nonexistent.mcrs');
333
+ expect(deps.size).toBe(0);
334
+ });
335
+ test('parseImports with inline source string (no disk read)', () => {
336
+ const source = `import "util.mcrs";\nimport "math.mcrs";\nfn main() {}`;
337
+ const fakePath = path.join(tmpDir, 'main.mcrs');
338
+ const imports = (0, deps_1.parseImports)(fakePath, source);
339
+ expect(imports).toHaveLength(2);
340
+ expect(imports[0]).toBe(path.resolve(tmpDir, 'util.mcrs'));
341
+ expect(imports[1]).toBe(path.resolve(tmpDir, 'math.mcrs'));
342
+ });
343
+ test('cyclic dependency does not cause infinite loop in getTransitiveDeps', () => {
344
+ // Simulate a cycle: a → b → a (shouldn't happen in practice but must be safe)
345
+ const a = path.resolve(tmpDir, 'a.mcrs');
346
+ const b = path.resolve(tmpDir, 'b.mcrs');
347
+ writeFile(tmpDir, 'a.mcrs', 'fn a() {}');
348
+ writeFile(tmpDir, 'b.mcrs', 'fn b() {}');
349
+ const graph = new deps_1.DependencyGraph();
350
+ // Manually force a cycle via addFile with inline source
351
+ graph.addFile(a, `import "b.mcrs";\nfn a() {}`);
352
+ graph.addFile(b, `import "a.mcrs";\nfn b() {}`);
353
+ // Should not throw or loop forever
354
+ expect(() => graph.getTransitiveDeps(a)).not.toThrow();
355
+ const deps = graph.getTransitiveDeps(a);
356
+ expect(deps.has(b)).toBe(true);
357
+ });
358
+ });
359
+ // ---------------------------------------------------------------------------
360
+ // compileIncremental — uncovered branches (lines 67, 113)
361
+ // ---------------------------------------------------------------------------
362
+ describe('compileIncremental — edge cases', () => {
363
+ let tmpDir;
364
+ let cacheDir;
365
+ let outDir;
366
+ beforeEach(() => {
367
+ tmpDir = makeTmpDir();
368
+ cacheDir = path.join(tmpDir, '.cache');
369
+ outDir = path.join(tmpDir, 'out');
370
+ (0, incremental_1.resetCompileCache)();
371
+ });
372
+ afterEach(() => {
373
+ fs.rmSync(tmpDir, { recursive: true, force: true });
374
+ });
375
+ test('deleted entry file is removed from dep graph gracefully', () => {
376
+ // Write a file, then delete it before compileIncremental runs
377
+ const ghost = path.join(tmpDir, 'ghost.mcrs');
378
+ fs.writeFileSync(ghost, 'fn ghost() {}');
379
+ fs.unlinkSync(ghost);
380
+ const cache = new index_1.FileCache(cacheDir);
381
+ const depGraph = new deps_1.DependencyGraph();
382
+ // Should not throw; error captured in result
383
+ const r = (0, incremental_1.compileIncremental)([ghost], cache, depGraph, { output: outDir });
384
+ // Either an error is captured or the file is skipped
385
+ expect(r.recompiled + r.errors.size).toBeGreaterThanOrEqual(0);
386
+ });
387
+ test('dep count change triggers recompile (depHashes.size mismatch branch)', () => {
388
+ // Compile 'a' with no deps first
389
+ const a = writeFile(tmpDir, 'a.mcrs', 'fn a_func() { let x: int = 1; }');
390
+ const cache = new index_1.FileCache(cacheDir);
391
+ const depGraph = new deps_1.DependencyGraph();
392
+ // First compile: a has no deps
393
+ const r1 = (0, incremental_1.compileIncremental)([a], cache, depGraph, { output: outDir });
394
+ expect(r1.recompiled).toBe(1);
395
+ // Now add a new dep to a — simulate by modifying a to import lib, then compile
396
+ const lib = writeFile(tmpDir, 'lib.mcrs', 'fn lib_fn() { let l: int = 0; }');
397
+ modifyFile(a, `import "lib.mcrs";\nfn a_func() { lib_fn(); }`);
398
+ // Second compile: a now has one dep → depHashes.size mismatch triggers recompile
399
+ const r2 = (0, incremental_1.compileIncremental)([a], cache, depGraph, { output: outDir });
400
+ expect(r2.recompiled).toBe(1);
401
+ expect(r2.errors.size).toBe(0);
402
+ });
403
+ test('multiple files: partial recompile on single change', () => {
404
+ const files = ['fn1', 'fn2', 'fn3'].map(name => writeFile(tmpDir, `${name}.mcrs`, `fn ${name}() { let x: int = 1; }`));
405
+ const cache = new index_1.FileCache(cacheDir);
406
+ const depGraph = new deps_1.DependencyGraph();
407
+ // First compile — all miss
408
+ const r1 = (0, incremental_1.compileIncremental)(files, cache, depGraph, { output: outDir });
409
+ expect(r1.recompiled).toBe(3);
410
+ // Modify only fn2
411
+ modifyFile(files[1], 'fn fn2() { let x: int = 999; }');
412
+ const r2 = (0, incremental_1.compileIncremental)(files, cache, depGraph, { output: outDir });
413
+ expect(r2.recompiled).toBe(1);
414
+ expect(r2.cached).toBe(2);
415
+ });
416
+ test('empty file list returns zero counts', () => {
417
+ const cache = new index_1.FileCache(cacheDir);
418
+ const depGraph = new deps_1.DependencyGraph();
419
+ const r = (0, incremental_1.compileIncremental)([], cache, depGraph, { output: outDir });
420
+ expect(r.recompiled).toBe(0);
421
+ expect(r.cached).toBe(0);
422
+ expect(r.errors.size).toBe(0);
423
+ });
424
+ });
425
+ //# sourceMappingURL=cache-behavior.test.js.map
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Extra coverage for src/cache/index.ts
3
+ * Targets: save/load, hasChanged with mtime, update branches, delete, clear.
4
+ */
5
+ export {};
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ /**
3
+ * Extra coverage for src/cache/index.ts
4
+ * Targets: save/load, hasChanged with mtime, update branches, delete, clear.
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const fs = __importStar(require("fs"));
41
+ const os = __importStar(require("os"));
42
+ const path = __importStar(require("path"));
43
+ const cache_1 = require("../cache");
44
+ function makeTmpDir() {
45
+ return fs.mkdtempSync(path.join(os.tmpdir(), 'rs-cache-test-'));
46
+ }
47
+ function writeTmpFile(dir, name, content) {
48
+ const p = path.join(dir, name);
49
+ fs.writeFileSync(p, content);
50
+ return p;
51
+ }
52
+ describe('FileCache — basic get/set', () => {
53
+ test('get returns undefined for unknown file', () => {
54
+ const cache = new cache_1.FileCache('/tmp/test-cache-nonexistent');
55
+ expect(cache.get('/nonexistent/file.mcrs')).toBeUndefined();
56
+ });
57
+ test('set then get returns entry', () => {
58
+ const cache = new cache_1.FileCache('/tmp/test-cache');
59
+ const filePath = '/tmp/fake.mcrs';
60
+ cache.set(filePath, { hash: 'abc123', mtime: 1000 });
61
+ const entry = cache.get(filePath);
62
+ expect(entry).toBeDefined();
63
+ expect(entry.hash).toBe('abc123');
64
+ });
65
+ test('size reflects number of entries', () => {
66
+ const cache = new cache_1.FileCache('/tmp/test-cache');
67
+ expect(cache.size).toBe(0);
68
+ cache.set('/tmp/a.mcrs', { hash: 'h1', mtime: 1 });
69
+ cache.set('/tmp/b.mcrs', { hash: 'h2', mtime: 2 });
70
+ expect(cache.size).toBe(2);
71
+ });
72
+ test('delete removes an entry', () => {
73
+ const cache = new cache_1.FileCache('/tmp/test-cache');
74
+ cache.set('/tmp/a.mcrs', { hash: 'h1', mtime: 1 });
75
+ expect(cache.size).toBe(1);
76
+ cache.delete('/tmp/a.mcrs');
77
+ expect(cache.size).toBe(0);
78
+ });
79
+ test('clear removes all entries', () => {
80
+ const cache = new cache_1.FileCache('/tmp/test-cache');
81
+ cache.set('/tmp/a.mcrs', { hash: 'h1', mtime: 1 });
82
+ cache.set('/tmp/b.mcrs', { hash: 'h2', mtime: 2 });
83
+ cache.clear();
84
+ expect(cache.size).toBe(0);
85
+ });
86
+ });
87
+ describe('FileCache — hasChanged', () => {
88
+ test('returns true for uncached file', () => {
89
+ const tmp = makeTmpDir();
90
+ const cache = new cache_1.FileCache(tmp);
91
+ const filePath = writeTmpFile(tmp, 'test.mcrs', 'hello');
92
+ expect(cache.hasChanged(filePath)).toBe(true);
93
+ });
94
+ test('returns false when mtime matches', () => {
95
+ const tmp = makeTmpDir();
96
+ const cache = new cache_1.FileCache(tmp);
97
+ const filePath = writeTmpFile(tmp, 'test.mcrs', 'hello');
98
+ const stat = fs.statSync(filePath);
99
+ cache.set(filePath, { hash: 'irrelevant', mtime: stat.mtimeMs });
100
+ expect(cache.hasChanged(filePath)).toBe(false);
101
+ });
102
+ test('returns true when content hash differs (mtime changed)', () => {
103
+ const tmp = makeTmpDir();
104
+ const cache = new cache_1.FileCache(tmp);
105
+ const filePath = writeTmpFile(tmp, 'test.mcrs', 'hello');
106
+ // Cache with old mtime (0) and wrong hash
107
+ cache.set(filePath, { hash: 'wronghash', mtime: 0 });
108
+ // mtime is different → compare hash
109
+ expect(cache.hasChanged(filePath)).toBe(true);
110
+ });
111
+ test('returns true for nonexistent file', () => {
112
+ const cache = new cache_1.FileCache('/tmp/nonexistent-cache');
113
+ expect(cache.hasChanged('/tmp/definitelynotafile.mcrs')).toBe(true);
114
+ });
115
+ });
116
+ describe('FileCache — update', () => {
117
+ test('update on changed file returns true and caches entry', () => {
118
+ const tmp = makeTmpDir();
119
+ const cache = new cache_1.FileCache(tmp);
120
+ const filePath = writeTmpFile(tmp, 'test.mcrs', 'content');
121
+ const changed = cache.update(filePath);
122
+ expect(changed).toBe(true);
123
+ expect(cache.get(filePath)).toBeDefined();
124
+ expect(cache.get(filePath).hash).toBeTruthy();
125
+ });
126
+ test('update on unchanged file returns false', () => {
127
+ const tmp = makeTmpDir();
128
+ const cache = new cache_1.FileCache(tmp);
129
+ const filePath = writeTmpFile(tmp, 'test.mcrs', 'content');
130
+ cache.update(filePath); // first call: changed
131
+ const changed2 = cache.update(filePath); // second call: not changed
132
+ expect(changed2).toBe(false);
133
+ });
134
+ test('update stores HIR when provided and content changed', () => {
135
+ const tmp = makeTmpDir();
136
+ const cache = new cache_1.FileCache(tmp);
137
+ const filePath = writeTmpFile(tmp, 'test.mcrs', 'content');
138
+ const fakeHir = { namespace: 'test', functions: [], structs: [], enums: [], implBlocks: [], imports: [] };
139
+ cache.update(filePath, fakeHir);
140
+ expect(cache.get(filePath).hir).toBe(fakeHir);
141
+ });
142
+ test('update stores HIR when content unchanged but HIR provided', () => {
143
+ const tmp = makeTmpDir();
144
+ const cache = new cache_1.FileCache(tmp);
145
+ const filePath = writeTmpFile(tmp, 'test.mcrs', 'content');
146
+ cache.update(filePath); // mark as cached
147
+ // Second update with HIR but no content change
148
+ const fakeHir = { namespace: 'test2', functions: [], structs: [], enums: [], implBlocks: [], imports: [] };
149
+ cache.update(filePath, fakeHir);
150
+ expect(cache.get(filePath).hir).toBe(fakeHir);
151
+ });
152
+ });
153
+ describe('FileCache — save/load', () => {
154
+ test('save and load round-trip persists entries', () => {
155
+ const tmp = makeTmpDir();
156
+ const cache = new cache_1.FileCache(tmp);
157
+ const filePath = writeTmpFile(tmp, 'test.mcrs', 'hello world');
158
+ cache.update(filePath);
159
+ cache.save();
160
+ // Load into a new cache instance
161
+ const cache2 = new cache_1.FileCache(tmp);
162
+ cache2.load();
163
+ const entry = cache2.get(filePath);
164
+ expect(entry).toBeDefined();
165
+ expect(entry.hash).toBe(cache.get(filePath).hash);
166
+ expect(entry.mtime).toBe(cache.get(filePath).mtime);
167
+ // HIR is NOT persisted
168
+ expect(entry.hir).toBeUndefined();
169
+ });
170
+ test('load silently ignores missing cache file', () => {
171
+ const tmp = makeTmpDir();
172
+ const cache = new cache_1.FileCache(tmp);
173
+ expect(() => cache.load()).not.toThrow();
174
+ expect(cache.size).toBe(0);
175
+ });
176
+ test('load silently ignores corrupt cache file', () => {
177
+ const tmp = makeTmpDir();
178
+ fs.writeFileSync(path.join(tmp, 'cache.json'), 'not valid json{{{');
179
+ const cache = new cache_1.FileCache(tmp);
180
+ expect(() => cache.load()).not.toThrow();
181
+ expect(cache.size).toBe(0);
182
+ });
183
+ test('load ignores wrong version', () => {
184
+ const tmp = makeTmpDir();
185
+ fs.writeFileSync(path.join(tmp, 'cache.json'), JSON.stringify({ version: 99, entries: {} }));
186
+ const cache = new cache_1.FileCache(tmp);
187
+ cache.load();
188
+ expect(cache.size).toBe(0);
189
+ });
190
+ });
191
+ describe('hashFile', () => {
192
+ test('returns a hex string', () => {
193
+ const tmp = makeTmpDir();
194
+ const filePath = writeTmpFile(tmp, 'test.mcrs', 'hello');
195
+ const hash = (0, cache_1.hashFile)(filePath);
196
+ expect(hash).toMatch(/^[0-9a-f]{64}$/);
197
+ });
198
+ test('same content gives same hash', () => {
199
+ const tmp = makeTmpDir();
200
+ const f1 = writeTmpFile(tmp, 'a.mcrs', 'same content');
201
+ const f2 = writeTmpFile(tmp, 'b.mcrs', 'same content');
202
+ expect((0, cache_1.hashFile)(f1)).toBe((0, cache_1.hashFile)(f2));
203
+ });
204
+ test('different content gives different hash', () => {
205
+ const tmp = makeTmpDir();
206
+ const f1 = writeTmpFile(tmp, 'a.mcrs', 'hello');
207
+ const f2 = writeTmpFile(tmp, 'b.mcrs', 'world');
208
+ expect((0, cache_1.hashFile)(f1)).not.toBe((0, cache_1.hashFile)(f2));
209
+ });
210
+ });
211
+ //# sourceMappingURL=cache-extra.test.js.map
@@ -0,0 +1 @@
1
+ export {};