@typecad/cuttlefish 0.1.0-alpha.1

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 (377) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/dist/api/board-types.d.ts +1 -0
  4. package/dist/api/board-types.js +4 -0
  5. package/dist/api/capabilities.d.ts +12 -0
  6. package/dist/api/capabilities.js +1 -0
  7. package/dist/api/config.d.ts +120 -0
  8. package/dist/api/config.js +7 -0
  9. package/dist/api/index.d.ts +5 -0
  10. package/dist/api/index.js +2 -0
  11. package/dist/api/schema/builder.d.ts +14 -0
  12. package/dist/api/schema/builder.js +15 -0
  13. package/dist/api/schema/index.d.ts +2 -0
  14. package/dist/api/schema/index.js +1 -0
  15. package/dist/api/schema/types.d.ts +257 -0
  16. package/dist/api/schema/types.js +4 -0
  17. package/dist/api/shared/async-runtime-static.d.ts +8 -0
  18. package/dist/api/shared/async-runtime-static.js +201 -0
  19. package/dist/api/shared/async-types.d.ts +42 -0
  20. package/dist/api/shared/async-types.js +8 -0
  21. package/dist/api/shared/board-resolver.d.ts +12 -0
  22. package/dist/api/shared/board-resolver.js +7 -0
  23. package/dist/api/shared/cpp-type-ir.d.ts +229 -0
  24. package/dist/api/shared/cpp-type-ir.js +672 -0
  25. package/dist/api/shared/display-adapter.d.ts +12 -0
  26. package/dist/api/shared/display-adapter.js +145 -0
  27. package/dist/api/shared/display-adapters/eink-mono.d.ts +2 -0
  28. package/dist/api/shared/display-adapters/eink-mono.js +53 -0
  29. package/dist/api/shared/display-adapters/sdl.d.ts +2 -0
  30. package/dist/api/shared/display-adapters/sdl.js +452 -0
  31. package/dist/api/shared/display-adapters/ssd1309.d.ts +2 -0
  32. package/dist/api/shared/display-adapters/ssd1309.js +136 -0
  33. package/dist/api/shared/display-adapters/st7796.d.ts +2 -0
  34. package/dist/api/shared/display-adapters/st7796.js +132 -0
  35. package/dist/api/shared/display-capabilities.d.ts +45 -0
  36. package/dist/api/shared/display-capabilities.js +54 -0
  37. package/dist/api/shared/display-op-ir.d.ts +62 -0
  38. package/dist/api/shared/display-op-ir.js +19 -0
  39. package/dist/api/shared/display-profile.d.ts +265 -0
  40. package/dist/api/shared/display-profile.js +338 -0
  41. package/dist/api/shared/graphics-strategy.d.ts +29 -0
  42. package/dist/api/shared/graphics-strategy.js +11 -0
  43. package/dist/api/shared/hal-op-ir.d.ts +393 -0
  44. package/dist/api/shared/hal-op-ir.js +18 -0
  45. package/dist/api/shared/index.d.ts +26 -0
  46. package/dist/api/shared/index.js +21 -0
  47. package/dist/api/shared/ir-core.d.ts +363 -0
  48. package/dist/api/shared/ir-core.js +8 -0
  49. package/dist/api/shared/ir-declarations.d.ts +201 -0
  50. package/dist/api/shared/ir-declarations.js +26 -0
  51. package/dist/api/shared/ir.d.ts +85 -0
  52. package/dist/api/shared/ir.js +13 -0
  53. package/dist/api/shared/platform-strategy.d.ts +402 -0
  54. package/dist/api/shared/platform-strategy.js +14 -0
  55. package/dist/api/shared/polyfill-helper-registry.d.ts +11 -0
  56. package/dist/api/shared/polyfill-helper-registry.js +86 -0
  57. package/dist/api/shared/polyfill-types.d.ts +33 -0
  58. package/dist/api/shared/polyfill-types.js +76 -0
  59. package/dist/api/shared/promise-runtime.d.ts +10 -0
  60. package/dist/api/shared/promise-runtime.js +244 -0
  61. package/dist/api/shared/snprintf-types.d.ts +29 -0
  62. package/dist/api/shared/snprintf-types.js +8 -0
  63. package/dist/api/shared/string-method-registry.d.ts +53 -0
  64. package/dist/api/shared/string-method-registry.js +168 -0
  65. package/dist/api/shared/toolchain-types.d.ts +63 -0
  66. package/dist/api/shared/toolchain-types.js +71 -0
  67. package/dist/api/shared/types.d.ts +50 -0
  68. package/dist/api/shared/types.js +6 -0
  69. package/dist/ast/parse.d.ts +2 -0
  70. package/dist/ast/parse.js +4 -0
  71. package/dist/cache.d.ts +26 -0
  72. package/dist/cache.js +95 -0
  73. package/dist/cli-utils.d.ts +37 -0
  74. package/dist/cli-utils.js +250 -0
  75. package/dist/cli.d.ts +2 -0
  76. package/dist/cli.js +635 -0
  77. package/dist/config-loader.d.ts +78 -0
  78. package/dist/config-loader.js +508 -0
  79. package/dist/config-schema.d.ts +233 -0
  80. package/dist/config-schema.js +83 -0
  81. package/dist/create/board-checklist.d.ts +2 -0
  82. package/dist/create/board-checklist.js +52 -0
  83. package/dist/create/board-codegen.d.ts +9 -0
  84. package/dist/create/board-codegen.js +238 -0
  85. package/dist/create/board-generators.d.ts +12 -0
  86. package/dist/create/board-generators.js +652 -0
  87. package/dist/create/board-spec.d.ts +640 -0
  88. package/dist/create/board-spec.js +215 -0
  89. package/dist/create/eslint-rules-template.d.ts +2 -0
  90. package/dist/create/eslint-rules-template.js +672 -0
  91. package/dist/create/index.d.ts +11 -0
  92. package/dist/create/index.js +8 -0
  93. package/dist/create/init-scaffold.d.ts +27 -0
  94. package/dist/create/init-scaffold.js +150 -0
  95. package/dist/create/init-templates.d.ts +24 -0
  96. package/dist/create/init-templates.js +379 -0
  97. package/dist/create/init-wizard.d.ts +8 -0
  98. package/dist/create/init-wizard.js +168 -0
  99. package/dist/debug/breakpoint-loader.d.ts +24 -0
  100. package/dist/debug/breakpoint-loader.js +137 -0
  101. package/dist/debug/index.d.ts +3 -0
  102. package/dist/debug/index.js +7 -0
  103. package/dist/debug/preprocessor.d.ts +9 -0
  104. package/dist/debug/preprocessor.js +214 -0
  105. package/dist/debug/types.d.ts +32 -0
  106. package/dist/debug/types.js +6 -0
  107. package/dist/diagnostics/diagnostics-report.d.ts +51 -0
  108. package/dist/diagnostics/diagnostics-report.js +333 -0
  109. package/dist/diagnostics/json-schema.d.ts +138 -0
  110. package/dist/diagnostics/json-schema.js +27 -0
  111. package/dist/diagnostics/md-writer.d.ts +10 -0
  112. package/dist/diagnostics/md-writer.js +336 -0
  113. package/dist/diagnostics/mermaid-builder.d.ts +65 -0
  114. package/dist/diagnostics/mermaid-builder.js +681 -0
  115. package/dist/emit/cpp-emitter.d.ts +6 -0
  116. package/dist/emit/cpp-emitter.js +48 -0
  117. package/dist/emit/emitters/class-emitter.d.ts +2 -0
  118. package/dist/emit/emitters/class-emitter.js +523 -0
  119. package/dist/emit/emitters/emitter-context.d.ts +174 -0
  120. package/dist/emit/emitters/emitter-context.js +1 -0
  121. package/dist/emit/emitters/entrypoint-synthesizer.d.ts +2 -0
  122. package/dist/emit/emitters/entrypoint-synthesizer.js +175 -0
  123. package/dist/emit/emitters/function-emitter-impl.d.ts +19 -0
  124. package/dist/emit/emitters/function-emitter-impl.js +428 -0
  125. package/dist/emit/emitters/line-appender.d.ts +15 -0
  126. package/dist/emit/emitters/line-appender.js +344 -0
  127. package/dist/emit/emitters/namespace-emitter.d.ts +2 -0
  128. package/dist/emit/emitters/namespace-emitter.js +324 -0
  129. package/dist/emit/emitters/output-finalizer.d.ts +4 -0
  130. package/dist/emit/emitters/output-finalizer.js +267 -0
  131. package/dist/emit/emitters/setup.d.ts +3 -0
  132. package/dist/emit/emitters/setup.js +851 -0
  133. package/dist/emit/emitters/top-level-prep.d.ts +2 -0
  134. package/dist/emit/emitters/top-level-prep.js +706 -0
  135. package/dist/emit/emitters/type-decl-emitter.d.ts +2 -0
  136. package/dist/emit/emitters/type-decl-emitter.js +251 -0
  137. package/dist/emit/emitters/ui-emitter.d.ts +21 -0
  138. package/dist/emit/emitters/ui-emitter.js +564 -0
  139. package/dist/emit/enum-emitter.d.ts +1 -0
  140. package/dist/emit/enum-emitter.js +1 -0
  141. package/dist/emit/expression-renderer.d.ts +283 -0
  142. package/dist/emit/expression-renderer.js +1477 -0
  143. package/dist/emit/native-helpers-emitter.d.ts +11 -0
  144. package/dist/emit/native-helpers-emitter.js +34 -0
  145. package/dist/emit/route-hal-op.d.ts +5 -0
  146. package/dist/emit/route-hal-op.js +13 -0
  147. package/dist/emit/snprintf-helpers.d.ts +17 -0
  148. package/dist/emit/snprintf-helpers.js +462 -0
  149. package/dist/emit/statement-renderer.d.ts +189 -0
  150. package/dist/emit/statement-renderer.js +948 -0
  151. package/dist/emit/utils/async-state-machine.d.ts +42 -0
  152. package/dist/emit/utils/async-state-machine.js +343 -0
  153. package/dist/emit/utils/comment-helpers.d.ts +20 -0
  154. package/dist/emit/utils/comment-helpers.js +31 -0
  155. package/dist/emit/utils/cpp-helpers.d.ts +47 -0
  156. package/dist/emit/utils/cpp-helpers.js +85 -0
  157. package/dist/emit/utils/include-resolver.d.ts +58 -0
  158. package/dist/emit/utils/include-resolver.js +155 -0
  159. package/dist/emit/utils/index.d.ts +8 -0
  160. package/dist/emit/utils/index.js +12 -0
  161. package/dist/emit/utils/type-inference.d.ts +159 -0
  162. package/dist/emit/utils/type-inference.js +559 -0
  163. package/dist/eslint-check.d.ts +10 -0
  164. package/dist/eslint-check.js +102 -0
  165. package/dist/framework-package.d.ts +10 -0
  166. package/dist/framework-package.js +58 -0
  167. package/dist/framework-registry.d.ts +39 -0
  168. package/dist/framework-registry.js +30 -0
  169. package/dist/incremental-cache.d.ts +116 -0
  170. package/dist/incremental-cache.js +335 -0
  171. package/dist/ir/adc-range-validation.d.ts +11 -0
  172. package/dist/ir/adc-range-validation.js +250 -0
  173. package/dist/ir/ast-node-utils.d.ts +8 -0
  174. package/dist/ir/ast-node-utils.js +32 -0
  175. package/dist/ir/board-pin-utils.d.ts +13 -0
  176. package/dist/ir/board-pin-utils.js +65 -0
  177. package/dist/ir/board-resolver.d.ts +36 -0
  178. package/dist/ir/board-resolver.js +437 -0
  179. package/dist/ir/build-ir-state.d.ts +167 -0
  180. package/dist/ir/build-ir-state.js +306 -0
  181. package/dist/ir/build-ir.d.ts +2 -0
  182. package/dist/ir/build-ir.js +808 -0
  183. package/dist/ir/call-graph.d.ts +35 -0
  184. package/dist/ir/call-graph.js +194 -0
  185. package/dist/ir/compile-time-only.d.ts +2 -0
  186. package/dist/ir/compile-time-only.js +16 -0
  187. package/dist/ir/declaration-builders.d.ts +9 -0
  188. package/dist/ir/declaration-builders.js +608 -0
  189. package/dist/ir/entry-points.d.ts +30 -0
  190. package/dist/ir/entry-points.js +191 -0
  191. package/dist/ir/expression-to-ir.d.ts +5 -0
  192. package/dist/ir/expression-to-ir.js +2249 -0
  193. package/dist/ir/extract-property-chain.d.ts +10 -0
  194. package/dist/ir/extract-property-chain.js +30 -0
  195. package/dist/ir/feature-prescan.d.ts +3 -0
  196. package/dist/ir/feature-prescan.js +43 -0
  197. package/dist/ir/feature-registry.d.ts +30 -0
  198. package/dist/ir/feature-registry.js +816 -0
  199. package/dist/ir/filter.d.ts +7 -0
  200. package/dist/ir/filter.js +85 -0
  201. package/dist/ir/function-builder.d.ts +19 -0
  202. package/dist/ir/function-builder.js +670 -0
  203. package/dist/ir/hal/hal-emitter.d.ts +62 -0
  204. package/dist/ir/hal/hal-emitter.js +735 -0
  205. package/dist/ir/hal/hal-parser.d.ts +61 -0
  206. package/dist/ir/hal/hal-parser.js +473 -0
  207. package/dist/ir/hal/hal-plugins.d.ts +34 -0
  208. package/dist/ir/hal/hal-plugins.js +706 -0
  209. package/dist/ir/hal-resolver.d.ts +5 -0
  210. package/dist/ir/hal-resolver.js +5 -0
  211. package/dist/ir/heap-analysis.d.ts +8 -0
  212. package/dist/ir/heap-analysis.js +350 -0
  213. package/dist/ir/heap-array-validation.d.ts +24 -0
  214. package/dist/ir/heap-array-validation.js +29 -0
  215. package/dist/ir/identifier-collector.d.ts +18 -0
  216. package/dist/ir/identifier-collector.js +439 -0
  217. package/dist/ir/interrupt-analysis.d.ts +39 -0
  218. package/dist/ir/interrupt-analysis.js +467 -0
  219. package/dist/ir/memory-budget-validation.d.ts +10 -0
  220. package/dist/ir/memory-budget-validation.js +86 -0
  221. package/dist/ir/namespace-builder.d.ts +7 -0
  222. package/dist/ir/namespace-builder.js +152 -0
  223. package/dist/ir/ownership-analysis.d.ts +9 -0
  224. package/dist/ir/ownership-analysis.js +1207 -0
  225. package/dist/ir/peripheral-ownership.d.ts +3 -0
  226. package/dist/ir/peripheral-ownership.js +152 -0
  227. package/dist/ir/peripheral-symbols.d.ts +7 -0
  228. package/dist/ir/peripheral-symbols.js +57 -0
  229. package/dist/ir/peripheral-usage.d.ts +54 -0
  230. package/dist/ir/peripheral-usage.js +691 -0
  231. package/dist/ir/peripheral-validation.d.ts +8 -0
  232. package/dist/ir/peripheral-validation.js +77 -0
  233. package/dist/ir/pin-alias-conflict.d.ts +4 -0
  234. package/dist/ir/pin-alias-conflict.js +34 -0
  235. package/dist/ir/pin-capability-validation.d.ts +6 -0
  236. package/dist/ir/pin-capability-validation.js +413 -0
  237. package/dist/ir/pin-mode-validation.d.ts +10 -0
  238. package/dist/ir/pin-mode-validation.js +301 -0
  239. package/dist/ir/pin-safety.d.ts +11 -0
  240. package/dist/ir/pin-safety.js +58 -0
  241. package/dist/ir/program-analysis.d.ts +44 -0
  242. package/dist/ir/program-analysis.js +589 -0
  243. package/dist/ir/pulldown-validation.d.ts +7 -0
  244. package/dist/ir/pulldown-validation.js +49 -0
  245. package/dist/ir/pwm-timer-sharing.d.ts +4 -0
  246. package/dist/ir/pwm-timer-sharing.js +93 -0
  247. package/dist/ir/reachability.d.ts +68 -0
  248. package/dist/ir/reachability.js +224 -0
  249. package/dist/ir/register-decorators.d.ts +6 -0
  250. package/dist/ir/register-decorators.js +49 -0
  251. package/dist/ir/render-expr.d.ts +4 -0
  252. package/dist/ir/render-expr.js +127 -0
  253. package/dist/ir/resource-analysis.d.ts +19 -0
  254. package/dist/ir/resource-analysis.js +153 -0
  255. package/dist/ir/statement-to-ir.d.ts +23 -0
  256. package/dist/ir/statement-to-ir.js +349 -0
  257. package/dist/ir/symbol-table.d.ts +68 -0
  258. package/dist/ir/symbol-table.js +179 -0
  259. package/dist/ir/symbol-types.d.ts +56 -0
  260. package/dist/ir/symbol-types.js +107 -0
  261. package/dist/ir/timer0-pwm-timing-conflict.d.ts +4 -0
  262. package/dist/ir/timer0-pwm-timing-conflict.js +71 -0
  263. package/dist/ir/timing-validation.d.ts +7 -0
  264. package/dist/ir/timing-validation.js +95 -0
  265. package/dist/ir/transformers/array-methods.d.ts +8 -0
  266. package/dist/ir/transformers/array-methods.js +493 -0
  267. package/dist/ir/transformers/call-statement.d.ts +5 -0
  268. package/dist/ir/transformers/call-statement.js +758 -0
  269. package/dist/ir/transformers/callback-context-registry.d.ts +20 -0
  270. package/dist/ir/transformers/callback-context-registry.js +55 -0
  271. package/dist/ir/transformers/canvas-lowering.d.ts +42 -0
  272. package/dist/ir/transformers/canvas-lowering.js +249 -0
  273. package/dist/ir/transformers/control-flow.d.ts +8 -0
  274. package/dist/ir/transformers/control-flow.js +508 -0
  275. package/dist/ir/transformers/expressions.d.ts +7 -0
  276. package/dist/ir/transformers/expressions.js +406 -0
  277. package/dist/ir/transformers/hal-call-resolver.d.ts +29 -0
  278. package/dist/ir/transformers/hal-call-resolver.js +274 -0
  279. package/dist/ir/transformers/hal-emit-helpers.d.ts +14 -0
  280. package/dist/ir/transformers/hal-emit-helpers.js +63 -0
  281. package/dist/ir/transformers/namespace-methods.d.ts +20 -0
  282. package/dist/ir/transformers/namespace-methods.js +110 -0
  283. package/dist/ir/transformers/register-assignment.d.ts +5 -0
  284. package/dist/ir/transformers/register-assignment.js +56 -0
  285. package/dist/ir/transformers/ui-call-resolver.d.ts +149 -0
  286. package/dist/ir/transformers/ui-call-resolver.js +1136 -0
  287. package/dist/ir/transformers/ui-callback-lowering.d.ts +62 -0
  288. package/dist/ir/transformers/ui-callback-lowering.js +623 -0
  289. package/dist/ir/transformers/ui-mount.d.ts +20 -0
  290. package/dist/ir/transformers/ui-mount.js +35 -0
  291. package/dist/ir/transformers/ui-reactive.d.ts +68 -0
  292. package/dist/ir/transformers/ui-reactive.js +129 -0
  293. package/dist/ir/transformers/variables.d.ts +14 -0
  294. package/dist/ir/transformers/variables.js +1045 -0
  295. package/dist/ir/try-catch-validation.d.ts +26 -0
  296. package/dist/ir/try-catch-validation.js +128 -0
  297. package/dist/ir/type-resolution.d.ts +31 -0
  298. package/dist/ir/type-resolution.js +977 -0
  299. package/dist/ir/ui-element-auto-wire.d.ts +50 -0
  300. package/dist/ir/ui-element-auto-wire.js +218 -0
  301. package/dist/ir/unit-suspicion-validation.d.ts +12 -0
  302. package/dist/ir/unit-suspicion-validation.js +296 -0
  303. package/dist/ir/utils/walk-ir.d.ts +6 -0
  304. package/dist/ir/utils/walk-ir.js +162 -0
  305. package/dist/ir/validation-orchestrator.d.ts +4 -0
  306. package/dist/ir/validation-orchestrator.js +45 -0
  307. package/dist/libdef/base-class-resolver.d.ts +23 -0
  308. package/dist/libdef/base-class-resolver.js +50 -0
  309. package/dist/libdef/cpp-to-decl.d.ts +34 -0
  310. package/dist/libdef/cpp-to-decl.js +584 -0
  311. package/dist/libdef/header-parser.d.ts +53 -0
  312. package/dist/libdef/header-parser.js +269 -0
  313. package/dist/libdef/registry.d.ts +10 -0
  314. package/dist/libdef/registry.js +142 -0
  315. package/dist/mapping/peripheral-names.d.ts +23 -0
  316. package/dist/mapping/peripheral-names.js +63 -0
  317. package/dist/mapping/source-map.d.ts +46 -0
  318. package/dist/mapping/source-map.js +207 -0
  319. package/dist/orchestrator/dts-generator.d.ts +17 -0
  320. package/dist/orchestrator/dts-generator.js +83 -0
  321. package/dist/orchestrator/graph-builder.d.ts +18 -0
  322. package/dist/orchestrator/graph-builder.js +218 -0
  323. package/dist/orchestrator/semantic-facts-verifier.d.ts +38 -0
  324. package/dist/orchestrator/semantic-facts-verifier.js +121 -0
  325. package/dist/orchestrator/semantic-facts.d.ts +141 -0
  326. package/dist/orchestrator/semantic-facts.js +652 -0
  327. package/dist/orchestrator/type-checker.d.ts +39 -0
  328. package/dist/orchestrator/type-checker.js +760 -0
  329. package/dist/platform/async-runtime.d.ts +8 -0
  330. package/dist/platform/async-runtime.js +26 -0
  331. package/dist/platform/generic-strategy.d.ts +101 -0
  332. package/dist/platform/generic-strategy.js +289 -0
  333. package/dist/platform/index.d.ts +4 -0
  334. package/dist/platform/index.js +9 -0
  335. package/dist/platform/registry.d.ts +21 -0
  336. package/dist/platform/registry.js +42 -0
  337. package/dist/platform/toolchain.d.ts +4 -0
  338. package/dist/platform/toolchain.js +43 -0
  339. package/dist/preview/client.d.ts +1 -0
  340. package/dist/preview/client.js +137 -0
  341. package/dist/preview/server.d.ts +5 -0
  342. package/dist/preview/server.js +199 -0
  343. package/dist/profiler/index.d.ts +28 -0
  344. package/dist/profiler/index.js +28 -0
  345. package/dist/profiler/profiler.d.ts +95 -0
  346. package/dist/profiler/profiler.js +338 -0
  347. package/dist/profiler/types.d.ts +87 -0
  348. package/dist/profiler/types.js +12 -0
  349. package/dist/stores/display-profile-store.d.ts +16 -0
  350. package/dist/stores/display-profile-store.js +48 -0
  351. package/dist/stores/theme-store.d.ts +13 -0
  352. package/dist/stores/theme-store.js +30 -0
  353. package/dist/testing.d.ts +45 -0
  354. package/dist/testing.js +47 -0
  355. package/dist/transpile/resolution.d.ts +29 -0
  356. package/dist/transpile/resolution.js +282 -0
  357. package/dist/transpile.d.ts +3 -0
  358. package/dist/transpile.js +722 -0
  359. package/dist/types.d.ts +217 -0
  360. package/dist/types.js +1 -0
  361. package/dist/ui/ui-bridge.d.ts +4 -0
  362. package/dist/ui/ui-bridge.js +34 -0
  363. package/dist/ui-hook.d.ts +84 -0
  364. package/dist/ui-hook.js +45 -0
  365. package/dist/utils/cli.d.ts +3 -0
  366. package/dist/utils/cli.js +463 -0
  367. package/dist/utils/fs.d.ts +4 -0
  368. package/dist/utils/fs.js +23 -0
  369. package/dist/utils/logger.d.ts +2 -0
  370. package/dist/utils/logger.js +8 -0
  371. package/dist/utils/strings.d.ts +35 -0
  372. package/dist/utils/strings.js +142 -0
  373. package/dist/utils/ui.d.ts +66 -0
  374. package/dist/utils/ui.js +149 -0
  375. package/dist/watch.d.ts +35 -0
  376. package/dist/watch.js +111 -0
  377. package/package.json +127 -0
@@ -0,0 +1,672 @@
1
+ export function generateEslintRules(_options) {
2
+ return `// ---------------------------------------------------------------------------
3
+ // ESLint Custom Rules - Cuttlefish transpiler compatibility
4
+ //
5
+ // Context-sensitive checks that cannot be expressed as no-restricted-syntax
6
+ // selectors. These rules use AST analysis to detect patterns that the
7
+ // transpiler cannot handle or only approximates.
8
+ //
9
+ // Auto-generated by 'cuttlefish create'. Do not edit manually.
10
+ // ---------------------------------------------------------------------------
11
+
12
+ const MAP_LIKE_RE = /^[A-Z]/;
13
+
14
+ export default {
15
+ rules: {
16
+ "no-delete-non-map": {
17
+ meta: {
18
+ type: "problem",
19
+ docs: {
20
+ description:
21
+ "[transpiler] delete on non-map types is unsupported in C++.",
22
+ },
23
+ },
24
+ create(context) {
25
+ return {
26
+ "UnaryExpression[operator='delete']"(node) {
27
+ const arg = node.argument;
28
+ if (arg.type === "MemberExpression" && arg.computed) {
29
+ if (
30
+ arg.object.type === "Identifier" &&
31
+ (MAP_LIKE_RE.test(arg.object.name) ||
32
+ arg.object.name === "this")
33
+ ) {
34
+ return;
35
+ }
36
+ }
37
+ context.report({
38
+ node,
39
+ message:
40
+ "[transpiler] delete on non-map types is unsupported in C++. Use a Map and its .delete() method.",
41
+ });
42
+ },
43
+ };
44
+ },
45
+ },
46
+
47
+ "no-object-static-non-map": {
48
+ meta: {
49
+ type: "problem",
50
+ docs: {
51
+ description:
52
+ "[transpiler] Object.keys/values/entries on non-map types is unsupported.",
53
+ },
54
+ },
55
+ create(context) {
56
+ const METHODS = new Set(["keys", "values", "entries"]);
57
+ return {
58
+ CallExpression(node) {
59
+ const callee = node.callee;
60
+ if (
61
+ callee.type === "MemberExpression" &&
62
+ !callee.computed &&
63
+ callee.object.type === "Identifier" &&
64
+ callee.object.name === "Object" &&
65
+ callee.property.type === "Identifier" &&
66
+ METHODS.has(callee.property.name)
67
+ ) {
68
+ if (node.arguments.length > 0) {
69
+ const arg = node.arguments[0];
70
+ // Exempt a bare identifier whose name looks map-like (capitalized
71
+ // first letter) — the transpiler resolves it to std::map.
72
+ if (
73
+ arg.type === "Identifier" &&
74
+ MAP_LIKE_RE.test(arg.name) &&
75
+ arg.name !== "Object"
76
+ ) {
77
+ return;
78
+ }
79
+ // Exempt a member-access argument (this.field, obj.field). The
80
+ // transpiler resolves the field's declared type and emits the
81
+ // __tc_mapKeys/Values/Entries helper when it's a std::map.
82
+ if (
83
+ arg.type === "MemberExpression" &&
84
+ !arg.computed &&
85
+ arg.property.type === "Identifier"
86
+ ) {
87
+ return;
88
+ }
89
+ }
90
+ context.report({
91
+ node,
92
+ message:
93
+ "[transpiler] Object." +
94
+ callee.property.name +
95
+ " on non-map types is unsupported. Use a Map and iterate with .keys(), .values(), or .entries().",
96
+ });
97
+ }
98
+ },
99
+ };
100
+ },
101
+ },
102
+
103
+ "no-super-outside-method": {
104
+ meta: {
105
+ type: "problem",
106
+ docs: {
107
+ description:
108
+ "[transpiler] super keyword outside class method context has no valid C++ translation.",
109
+ },
110
+ },
111
+ create(context) {
112
+ return {
113
+ Super(node) {
114
+ let foundValid = false;
115
+ let current = node.parent;
116
+ while (current) {
117
+ if (
118
+ current.type === "MethodDefinition" ||
119
+ current.type === "FunctionExpression" ||
120
+ current.type === "StaticBlock"
121
+ ) {
122
+ let classBody = current.parent;
123
+ if (classBody && classBody.type === "MethodDefinition") {
124
+ classBody = classBody.parent;
125
+ }
126
+ if (classBody && classBody.type === "ClassBody") {
127
+ const classDecl = classBody.parent;
128
+ if (
129
+ classDecl &&
130
+ (classDecl.type === "ClassDeclaration" ||
131
+ classDecl.type === "ClassExpression") &&
132
+ classDecl.superClass
133
+ ) {
134
+ foundValid = true;
135
+ }
136
+ }
137
+ break;
138
+ }
139
+ if (
140
+ current.type === "ClassBody" ||
141
+ current.type === "ClassDeclaration" ||
142
+ current.type === "ClassExpression"
143
+ ) {
144
+ break;
145
+ }
146
+ current = current.parent;
147
+ }
148
+ if (!foundValid) {
149
+ context.report({
150
+ node,
151
+ message:
152
+ "[transpiler] super keyword outside of class method context has no valid C++ translation.",
153
+ });
154
+ }
155
+ },
156
+ };
157
+ },
158
+ },
159
+
160
+ "no-typeof-non-primitive": {
161
+ meta: {
162
+ type: "problem",
163
+ docs: {
164
+ description:
165
+ "[transpiler] typeof on non-primitive types returns an approximate type name in C++.",
166
+ },
167
+ },
168
+ create(context) {
169
+ return {
170
+ "UnaryExpression[operator='typeof']"(node) {
171
+ const arg = node.argument;
172
+ if (
173
+ arg.type === "MemberExpression" ||
174
+ arg.type === "CallExpression" ||
175
+ arg.type === "ObjectExpression"
176
+ ) {
177
+ context.report({
178
+ node,
179
+ message:
180
+ "[transpiler] typeof on non-primitive types returns an approximate type name in C++. Use type guards or instanceof instead.",
181
+ });
182
+ }
183
+ },
184
+ };
185
+ },
186
+ },
187
+
188
+ "no-destructured-without-init": {
189
+ meta: {
190
+ type: "problem",
191
+ docs: {
192
+ description:
193
+ "[transpiler] Destructuring declarations without initializers are unsupported.",
194
+ },
195
+ },
196
+ create(context) {
197
+ return {
198
+ VariableDeclarator(node) {
199
+ if (
200
+ (node.id.type === "ObjectPattern" ||
201
+ node.id.type === "ArrayPattern") &&
202
+ !node.init
203
+ ) {
204
+ context.report({
205
+ node,
206
+ message:
207
+ "[transpiler] Destructuring declaration without an initializer is unsupported in C++. Provide a default value or initializer.",
208
+ });
209
+ }
210
+ },
211
+ };
212
+ },
213
+ },
214
+
215
+ "no-fractional-to-number-type": {
216
+ meta: {
217
+ type: "problem",
218
+ docs: {
219
+ description:
220
+ "[transpiler] Fractional literals assigned to 'number'-typed variables/fields are truncated to integers in C++.",
221
+ },
222
+ },
223
+ create(context) {
224
+ function isNumberType(typeNode) {
225
+ if (!typeNode) return false;
226
+ if (typeNode.type === "TSNumberKeyword") return true;
227
+ if (typeNode.type === "TSTypeAnnotation" && typeNode.typeAnnotation) {
228
+ return isNumberType(typeNode.typeAnnotation);
229
+ }
230
+ return false;
231
+ }
232
+ function isFractionalLiteral(node) {
233
+ if (node.type === "Literal" && typeof node.value === "number") {
234
+ return !Number.isInteger(node.value);
235
+ }
236
+ if (node.type === "UnaryExpression" && node.operator === "-" && node.argument) {
237
+ return isFractionalLiteral(node.argument);
238
+ }
239
+ return false;
240
+ }
241
+ function checkFractionalInitializer(node, typeAnnotation, init) {
242
+ if (!typeAnnotation || !init) return;
243
+ if (!isNumberType(typeAnnotation)) return;
244
+ if (!isFractionalLiteral(init)) return;
245
+ context.report({
246
+ node,
247
+ message:
248
+ "[transpiler] Fractional value " + init.raw +
249
+ " is truncated when assigned to 'number' type. Use 'double' or 'float' to preserve fractional precision.",
250
+ });
251
+ }
252
+ return {
253
+ PropertyDefinition(node) {
254
+ if (node.typeAnnotation && node.value) {
255
+ checkFractionalInitializer(node, node.typeAnnotation, node.value);
256
+ }
257
+ },
258
+ VariableDeclarator(node) {
259
+ if (node.id.typeAnnotation && node.init) {
260
+ checkFractionalInitializer(node, node.id.typeAnnotation, node.init);
261
+ }
262
+ },
263
+ };
264
+ },
265
+ },
266
+
267
+ "no-array-param-content-mutation": {
268
+ meta: {
269
+ type: "problem",
270
+ docs: {
271
+ description:
272
+ "[transpiler] Mutating an array parameter's contents has no effect in C++ (the parameter is a by-value std::vector copy).",
273
+ },
274
+ },
275
+ create(context) {
276
+ return {};
277
+ },
278
+ },
279
+
280
+ "no-container-functional-methods": {
281
+ meta: {
282
+ type: "problem",
283
+ docs: {
284
+ description:
285
+ "[transpiler] Functional array methods (.forEach/.map/.filter/.reduce) are not lowered on Map/Set/Record.",
286
+ },
287
+ },
288
+ create(context) {
289
+ const FUNCTIONAL_METHODS = new Set([
290
+ "forEach", "map", "filter", "reduce", "reduceRight",
291
+ "find", "findIndex", "findLast", "some", "every", "flatMap",
292
+ ]);
293
+ const CONTAINER_TYPE_RE = /^(Map|Set|ReadonlyMap|ReadonlySet|Record|WeakMap|WeakSet)\\b/;
294
+ const containerVars = new Map();
295
+ function typeText(node) {
296
+ if (!node) return "";
297
+ if (node.type === "TSTypeAnnotation" && node.typeAnnotation) return typeText(node.typeAnnotation);
298
+ if (node.type === "TSTypeReference" && node.typeName) return node.typeName.type === "Identifier" ? node.typeName.name : typeText(node.typeName);
299
+ if (node.type === "TSMapLikeType") return "Map";
300
+ return "";
301
+ }
302
+ function isContainerVar(node) {
303
+ if (node.type === "Identifier" && containerVars.has(node.name)) return true;
304
+ if (node.type === "CallExpression" && node.callee.type === "MemberExpression" && node.callee.property.type === "Identifier" && FUNCTIONAL_METHODS.has(node.callee.property.name)) return true;
305
+ return false;
306
+ }
307
+ return {
308
+ VariableDeclarator(node) {
309
+ if (node.id.type !== "Identifier") return;
310
+ const name = node.id.name;
311
+ if (node.id.typeAnnotation) {
312
+ const t = typeText(node.id.typeAnnotation);
313
+ if (CONTAINER_TYPE_RE.test(t)) { containerVars.set(name, true); return; }
314
+ }
315
+ if (node.init && node.init.type === "NewExpression" && node.init.callee.type === "Identifier" && CONTAINER_TYPE_RE.test(node.init.callee.name)) {
316
+ containerVars.set(name, true);
317
+ }
318
+ },
319
+ CallExpression(node) {
320
+ const callee = node.callee;
321
+ if (callee.type !== "MemberExpression" || callee.computed || callee.property.type !== "Identifier" || !FUNCTIONAL_METHODS.has(callee.property.name)) return;
322
+ if (isContainerVar(callee.object)) {
323
+ context.report({ node, message: "[transpiler] ." + callee.property.name + "() is not lowered on Map/Set/Record. Iterate a parallel key array with for...of instead." });
324
+ }
325
+ },
326
+ };
327
+ },
328
+ },
329
+
330
+ "no-undefined-compare-on-get": {
331
+ meta: {
332
+ type: "problem",
333
+ docs: {
334
+ description:
335
+ "[transpiler] Comparing a .get() result to undefined/null does not lower to valid C++.",
336
+ },
337
+ },
338
+ create(context) {
339
+ const UNDEF_NULL_OPS = new Set(["==", "!=", "===", "!=="]);
340
+ function isUndefinedOrNull(node) {
341
+ if (node.type === "Identifier" && (node.name === "undefined" || node.name === "null")) return true;
342
+ if (node.type === "Literal" && node.value === null) return true;
343
+ return false;
344
+ }
345
+ function isGetCall(node) {
346
+ return node.type === "CallExpression" && node.callee.type === "MemberExpression" && !node.callee.computed && node.callee.property.type === "Identifier" && (node.callee.property.name === "get" || node.callee.property.name === "at");
347
+ }
348
+ return {
349
+ BinaryExpression(node) {
350
+ if (!UNDEF_NULL_OPS.has(node.operator)) return;
351
+ const leftUndef = isUndefinedOrNull(node.left);
352
+ const rightUndef = isUndefinedOrNull(node.right);
353
+ if (!leftUndef && !rightUndef) return;
354
+ const otherSide = leftUndef ? node.right : node.left;
355
+ if (isGetCall(otherSide)) {
356
+ context.report({ node, message: "[transpiler] Comparing ." + otherSide.callee.property.name + "() to undefined/null does not lower to valid C++. Guard with .has(key) before .get(key)." });
357
+ }
358
+ },
359
+ };
360
+ },
361
+ },
362
+
363
+ "no-map-struct-mutation": {
364
+ meta: {
365
+ type: "problem",
366
+ docs: {
367
+ description:
368
+ "[transpiler] Mutating a field of a value fetched via Map.get()/.at() is lost (or a compile error) in C++ — the value is a copy. Use a separate primitive Map and .set() back.",
369
+ },
370
+ },
371
+ create(context) {
372
+ const getBindings = new Set();
373
+ function isContainerGetCall(node) {
374
+ return node.type === "CallExpression" && node.callee.type === "MemberExpression" && !node.callee.computed && node.callee.property.type === "Identifier" && (node.callee.property.name === "get" || node.callee.property.name === "at");
375
+ }
376
+ function reportIfMutatingGetBinding(node, target) {
377
+ if (target.type !== "MemberExpression") return;
378
+ if (target.object.type === "Identifier" && getBindings.has(target.object.name)) {
379
+ const propName = target.property.type === "Identifier" ? target.property.name : "[...]";
380
+ context.report({ node, message: "[transpiler] '" + target.object.name + "' is a value fetched from a Map; mutating its '" + propName + "' field is lost in C++ (the binding is a copy). Use a separate primitive Map and .set() back, or erase + re-insert the struct." });
381
+ }
382
+ }
383
+ return {
384
+ VariableDeclarator(node) {
385
+ if (node.init && isContainerGetCall(node.init) && node.id.type === "Identifier") {
386
+ getBindings.add(node.id.name);
387
+ }
388
+ },
389
+ AssignmentExpression(node) { reportIfMutatingGetBinding(node, node.left); },
390
+ UpdateExpression(node) { reportIfMutatingGetBinding(node, node.argument); },
391
+ };
392
+ },
393
+ },
394
+
395
+ "no-undefined-compare-on-struct-field": {
396
+ meta: {
397
+ type: "problem",
398
+ docs: {
399
+ description:
400
+ "[transpiler] Comparing a struct/interface field to undefined/null does not lower to valid C++ (optional fields flatten to T). Use an explicit boolean flag.",
401
+ },
402
+ },
403
+ create(context) {
404
+ const UNDEF_NULL_OPS = new Set(["==", "!=", "===", "!=="]);
405
+ function isUndefinedOrNull(node) {
406
+ if (node.type === "Identifier" && (node.name === "undefined" || node.name === "null")) return true;
407
+ if (node.type === "Literal" && node.value === null) return true;
408
+ return false;
409
+ }
410
+ function isMemberAccess(node) {
411
+ return node.type === "MemberExpression" && !node.computed;
412
+ }
413
+ return {
414
+ BinaryExpression(node) {
415
+ if (!UNDEF_NULL_OPS.has(node.operator)) return;
416
+ const leftUndef = isUndefinedOrNull(node.left);
417
+ const rightUndef = isUndefinedOrNull(node.right);
418
+ if (!leftUndef && !rightUndef) return;
419
+ const otherSide = leftUndef ? node.right : node.left;
420
+ if (isMemberAccess(otherSide)) {
421
+ const propName = otherSide.property.type === "Identifier" ? otherSide.property.name : "<computed>";
422
+ context.report({ node, message: "[transpiler] Comparing ." + propName + " to undefined/null does not lower to valid C++ (optional struct/interface fields flatten to their value type). Use an explicit boolean flag on the interface instead of an optional field." });
423
+ }
424
+ },
425
+ };
426
+ },
427
+ },
428
+
429
+ "no-typed-array-param-length": {
430
+ meta: {
431
+ type: "problem",
432
+ docs: {
433
+ description:
434
+ "[transpiler] .length on a typed-array parameter does not lower to valid C++.",
435
+ },
436
+ },
437
+ create(context) {
438
+ const TYPED_ARRAYS = new Set(["Uint8Array", "Int8Array", "Uint16Array", "Int16Array", "Uint32Array", "Int32Array", "Float32Array", "Float64Array", "BigUint64Array", "BigInt64Array"]);
439
+ const typedArrayParams = new Set();
440
+ function isTypedArrayTypeAnnotation(typeAnnotation) {
441
+ if (!typeAnnotation) return false;
442
+ let t = typeAnnotation;
443
+ if (t.type === "TSTypeAnnotation") t = t.typeAnnotation;
444
+ if (t && t.type === "TSTypeReference" && t.typeName.type === "Identifier") return TYPED_ARRAYS.has(t.typeName.name);
445
+ return false;
446
+ }
447
+ function registerParams(params) {
448
+ for (const p of params) {
449
+ if (p.type === "Identifier" && isTypedArrayTypeAnnotation(p.typeAnnotation)) typedArrayParams.add(p.name);
450
+ }
451
+ }
452
+ return {
453
+ FunctionDeclaration: (node) => registerParams(node.params),
454
+ FunctionExpression: (node) => registerParams(node.params),
455
+ ArrowFunctionExpression: (node) => registerParams(node.params),
456
+ MemberExpression(node) {
457
+ if (!node.computed && node.object.type === "Identifier" && typedArrayParams.has(node.object.name) && node.property.type === "Identifier" && node.property.name === "length") {
458
+ context.report({ node, message: "[transpiler] ." + node.object.name + ".length on a typed-array parameter does not lower to valid C++. Pass the length explicitly." });
459
+ }
460
+ },
461
+ };
462
+ },
463
+ },
464
+
465
+ "no-typed-array-return": {
466
+ meta: {
467
+ type: "problem",
468
+ docs: {
469
+ description:
470
+ "[transpiler] Returning a typed array dangles (lowers to a pointer to a stack-local).",
471
+ },
472
+ },
473
+ create(context) {
474
+ const TYPED_ARRAYS = new Set(["Uint8Array", "Int8Array", "Uint16Array", "Int16Array", "Uint32Array", "Int32Array", "Float32Array", "Float64Array", "BigUint64Array", "BigInt64Array"]);
475
+ function isTypedArrayAnnotation(typeAnnotation) {
476
+ if (!typeAnnotation) return false;
477
+ let t = typeAnnotation;
478
+ if (t.type === "TSTypeAnnotation") t = t.typeAnnotation;
479
+ if (t && t.type === "TSTypeReference" && t.typeName.type === "Identifier") return TYPED_ARRAYS.has(t.typeName.name);
480
+ return false;
481
+ }
482
+ function checkReturnType(node) {
483
+ if (node.returnType && isTypedArrayAnnotation(node.returnType)) {
484
+ context.report({ node: node.returnType, message: "[transpiler] Returning a typed array dangles in C++. Use an out-parameter instead." });
485
+ }
486
+ }
487
+ return {
488
+ FunctionDeclaration: checkReturnType,
489
+ FunctionExpression: checkReturnType,
490
+ ArrowFunctionExpression: checkReturnType,
491
+ };
492
+ },
493
+ },
494
+
495
+ "no-typed-array-field": {
496
+ meta: {
497
+ type: "problem",
498
+ docs: {
499
+ description:
500
+ "[transpiler] A typed-array class field has no safe C++ lowering (pointer-like storage with no owned buffer).",
501
+ },
502
+ },
503
+ create(context) {
504
+ const TYPED_ARRAYS = new Set(["Uint8Array", "Int8Array", "Uint16Array", "Int16Array", "Uint32Array", "Int32Array", "Float32Array", "Float64Array", "BigUint64Array", "BigInt64Array"]);
505
+ function isTypedArrayAnnotation(typeAnnotation) {
506
+ if (!typeAnnotation) return false;
507
+ let t = typeAnnotation;
508
+ if (t.type === "TSTypeAnnotation") t = t.typeAnnotation;
509
+ if (t && t.type === "TSTypeReference" && t.typeName.type === "Identifier") return TYPED_ARRAYS.has(t.typeName.name);
510
+ return false;
511
+ }
512
+ return {
513
+ PropertyDefinition(node) {
514
+ if (node.typeAnnotation && isTypedArrayAnnotation(node.typeAnnotation)) {
515
+ context.report({ node: node.typeAnnotation, message: "[transpiler] A typed-array class field has no owned backing buffer in C++. Use a function-local typed array for a stack buffer, or store the data in a number[]/int8_t[] field (a std::vector) that owns its storage." });
516
+ }
517
+ },
518
+ };
519
+ },
520
+ },
521
+
522
+ "no-dynamic-property-access": {
523
+ meta: {
524
+ type: "problem",
525
+ docs: {
526
+ description:
527
+ "[transpiler] Dynamic string-key property access (obj[key]) on non-map types is not reliably lowered.",
528
+ },
529
+ },
530
+ create(context) {
531
+ function isNumericLiteral(node) {
532
+ return node.type === "Literal" && (typeof node.value === "number" || /^-?\\d+$/.test(String(node.value)));
533
+ }
534
+ function isStringLiteral(node) {
535
+ return node.type === "Literal" && typeof node.value === "string";
536
+ }
537
+ return {
538
+ "MemberExpression[computed=true]"(node) {
539
+ if (isNumericLiteral(node.property)) return;
540
+ if (!isStringLiteral(node.property)) return;
541
+ if (node.object.type === "Identifier" && (MAP_LIKE_RE.test(node.object.name) || node.object.name === "this")) return;
542
+ context.report({ node, message: "[transpiler] dynamic string-key access (obj[\\\"key\\\"]) on non-map types is not reliably lowered. Use a Map<string, T> for dynamic keys, or a numeric index for arrays." });
543
+ },
544
+ };
545
+ },
546
+ },
547
+
548
+ "no-mutating-method-on-const-collection": {
549
+ meta: {
550
+ type: "problem",
551
+ docs: {
552
+ description:
553
+ "[transpiler] A const-bound Map/Set mutated via .set()/.add()/.delete()/.clear() is demoted to non-const in C++. Prefer a let binding to express intent, or avoid mutating a collection you declared const.",
554
+ },
555
+ },
556
+ create(context) {
557
+ // const bindings whose declared type is Map/Set/ReadonlyMap/ReadonlySet.
558
+ const constCollections = new Map(); // name -> typeName
559
+ const COLLECTION_TYPES = new Set(["Map", "Set", "ReadonlyMap", "ReadonlySet"]);
560
+ const MUTATORS = new Set(["set", "add", "delete", "clear"]);
561
+ function collectionName(typeAnnotation) {
562
+ if (!typeAnnotation) return null;
563
+ let t = typeAnnotation;
564
+ if (t.type === "TSTypeAnnotation") t = t.typeAnnotation;
565
+ if (t && t.type === "TSTypeReference" && t.typeName.type === "Identifier" && COLLECTION_TYPES.has(t.typeName.name)) {
566
+ return t.typeName.name;
567
+ }
568
+ return null;
569
+ }
570
+ return {
571
+ VariableDeclarator(node) {
572
+ if (node.parent && node.parent.kind === "const" && node.id.type === "Identifier") {
573
+ const cName = collectionName(node.id.typeAnnotation);
574
+ if (cName) constCollections.set(node.id.name, cName);
575
+ }
576
+ },
577
+ CallExpression(node) {
578
+ const callee = node.callee;
579
+ if (callee.type !== "MemberExpression" || callee.computed) return;
580
+ if (callee.object.type !== "Identifier") return;
581
+ if (!constCollections.has(callee.object.name)) return;
582
+ if (callee.property.type !== "Identifier" || !MUTATORS.has(callee.property.name)) return;
583
+ context.report({ node, message: "[transpiler] '" + callee.object.name + "' is a const " + constCollections.get(callee.object.name) + " mutated via ." + callee.property.name + "() — the C++ binding is demoted to non-const. Declare it with a let binding to express the mutation intent, or avoid mutating a collection you declared const." });
584
+ },
585
+ };
586
+ },
587
+ },
588
+
589
+ // A const for/for-in loop variable mutated in the body is demoted to a
590
+ // non-const C++ reference (T&) by the transpiler. Surface it at lint time
591
+ // so the author can express the intent with a let binding. (demo #17 fix)
592
+ "no-readonly-loop-variable-mutation": {
593
+ meta: {
594
+ type: "problem",
595
+ docs: {
596
+ description:
597
+ "[transpiler] A const for/for-in loop variable mutated in the body is demoted to a non-const reference in C++. Prefer a let binding to express the mutation intent.",
598
+ },
599
+ },
600
+ create(context) {
601
+ // Stack of active const loop-variable names, scoped to each loop body.
602
+ const loopVarStack = [];
603
+ function baseIdentifierName(node) {
604
+ if (!node) return null;
605
+ if (node.type !== "MemberExpression") return null;
606
+ const obj = node.object;
607
+ if (obj.type === "Identifier") return obj.name;
608
+ return null;
609
+ }
610
+ function reportIfLoopVar(target, node) {
611
+ const name = baseIdentifierName(target);
612
+ if (!name) return;
613
+ const top = loopVarStack[loopVarStack.length - 1];
614
+ if (top && top.has(name)) {
615
+ context.report({ node, message: "[transpiler] '" + name + "' is a const loop variable mutated in the loop body — the C++ binding is demoted to a non-const reference (T&). Use a let binding to express the mutation intent." });
616
+ }
617
+ }
618
+ function pushLoopVars(node) {
619
+ const decl = node.left;
620
+ if (decl && decl.type === "VariableDeclaration" && decl.kind === "const") {
621
+ const names = new Set();
622
+ for (const d of decl.declarations) {
623
+ if (d.id && d.id.type === "Identifier") names.add(d.id.name);
624
+ }
625
+ loopVarStack.push(names);
626
+ } else {
627
+ loopVarStack.push(new Set());
628
+ }
629
+ }
630
+ return {
631
+ ForOfStatement(node) { pushLoopVars(node); },
632
+ "ForOfStatement:exit"() { loopVarStack.pop(); },
633
+ ForInStatement(node) { pushLoopVars(node); },
634
+ "ForInStatement:exit"() { loopVarStack.pop(); },
635
+ AssignmentExpression(node) { reportIfLoopVar(node.left, node); },
636
+ UpdateExpression(node) { reportIfLoopVar(node.argument, node); },
637
+ };
638
+ },
639
+ },
640
+
641
+ "no-this-in-free-function": {
642
+ meta: {
643
+ type: "problem",
644
+ docs: {
645
+ description:
646
+ "[transpiler] \`this\` in a free function has no fixed C++ this pointer to lower to.",
647
+ },
648
+ },
649
+ create(context) {
650
+ return {
651
+ ThisExpression(node) {
652
+ let current = node.parent;
653
+ while (current) {
654
+ if (current.type === "MethodDefinition") return;
655
+ if (current.type === "PropertyDefinition") return;
656
+ if (current.type === "StaticBlock") return;
657
+ if (current.type === "FunctionExpression" && current.parent && (current.parent.type === "MethodDefinition" || current.parent.type === "PropertyDefinition")) return;
658
+ if (current.type === "ArrowFunctionExpression") { current = current.parent; continue; }
659
+ if (current.type === "FunctionDeclaration" || current.type === "FunctionExpression") {
660
+ context.report({ node, message: "[transpiler] \`this\` in a free function has no fixed C++ this pointer to lower to. Move the code into a class method, or pass the value as a parameter." });
661
+ return;
662
+ }
663
+ current = current.parent;
664
+ }
665
+ },
666
+ };
667
+ },
668
+ },
669
+ },
670
+ };
671
+ `;
672
+ }
@@ -0,0 +1,11 @@
1
+ export { scaffoldProject, normalizeProjectName, KNOWN_TARGETS, KNOWN_BOARDS, registerKnownTarget, printInitNextSteps } from './init-scaffold.js';
2
+ export type { KnownTarget, KnownBoard, ScaffoldProjectResult } from './init-scaffold.js';
3
+ export { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateGitignore, generateEslintConfig, } from './init-templates.js';
4
+ export type { InitProjectOptions } from './init-templates.js';
5
+ export { runInitWizard } from './init-wizard.js';
6
+ export { scaffoldBoardPackages } from './board-codegen.js';
7
+ export type { ScaffoldBoardResult } from './board-codegen.js';
8
+ export { generateFrameworkChecklist } from './board-checklist.js';
9
+ export { parseBoardSpec, safeParseBoardSpec, stripJsonc, BoardSpecSchema } from './board-spec.js';
10
+ export type { BoardSpec } from './board-spec.js';
11
+ export * as BoardGenerators from './board-generators.js';