@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,439 @@
1
+ /**
2
+ * Shared utility for collecting identifiers from IR nodes.
3
+ * This consolidates duplicate logic that was previously in:
4
+ * - transpile.ts (collectExpressionIdentifiers, collectStatementIdentifiers)
5
+ * - call-graph.ts (collectExpressionIdentifiers, collectStatementIdentifiers)
6
+ * - build-ir.ts (similar traversal logic)
7
+ */
8
+ /**
9
+ * Collect all identifiers from an expression IR node.
10
+ * Returns a Set of identifier names found.
11
+ */
12
+ export function collectExpressionIdentifiers(expr) {
13
+ const identifiers = new Set();
14
+ // Safety check
15
+ if (!expr || typeof expr !== "object" || !expr.kind) {
16
+ return identifiers;
17
+ }
18
+ switch (expr.kind) {
19
+ case "identifier":
20
+ identifiers.add(expr.value);
21
+ break;
22
+ case "raw": {
23
+ // Extract identifiers from raw expressions
24
+ const matches = expr.value.match(/[A-Za-z_][A-Za-z0-9_]*/g);
25
+ if (matches) {
26
+ for (const match of matches) {
27
+ identifiers.add(match);
28
+ }
29
+ }
30
+ break;
31
+ }
32
+ case "await":
33
+ for (const id of collectExpressionIdentifiers(expr.value)) {
34
+ identifiers.add(id);
35
+ }
36
+ break;
37
+ case "ternary":
38
+ for (const id of collectExpressionIdentifiers(expr.condition)) {
39
+ identifiers.add(id);
40
+ }
41
+ for (const id of collectExpressionIdentifiers(expr.whenTrue)) {
42
+ identifiers.add(id);
43
+ }
44
+ for (const id of collectExpressionIdentifiers(expr.whenFalse)) {
45
+ identifiers.add(id);
46
+ }
47
+ break;
48
+ case "array":
49
+ for (const element of expr.elements) {
50
+ for (const id of collectExpressionIdentifiers(element)) {
51
+ identifiers.add(id);
52
+ }
53
+ }
54
+ break;
55
+ case "object":
56
+ for (const field of expr.fields) {
57
+ for (const id of collectExpressionIdentifiers(field.value)) {
58
+ identifiers.add(id);
59
+ }
60
+ }
61
+ break;
62
+ case "instanceof":
63
+ for (const id of collectExpressionIdentifiers(expr.object)) {
64
+ identifiers.add(id);
65
+ }
66
+ identifiers.add(expr.className);
67
+ break;
68
+ case "spread_array":
69
+ for (const id of collectExpressionIdentifiers(expr.spreadExpr)) {
70
+ identifiers.add(id);
71
+ }
72
+ for (const element of expr.additionalElements) {
73
+ for (const id of collectExpressionIdentifiers(element)) {
74
+ identifiers.add(id);
75
+ }
76
+ }
77
+ break;
78
+ case "binary":
79
+ for (const id of collectExpressionIdentifiers(expr.left)) {
80
+ identifiers.add(id);
81
+ }
82
+ for (const id of collectExpressionIdentifiers(expr.right)) {
83
+ identifiers.add(id);
84
+ }
85
+ break;
86
+ case "unary":
87
+ for (const id of collectExpressionIdentifiers(expr.operand)) {
88
+ identifiers.add(id);
89
+ }
90
+ break;
91
+ case "property-access":
92
+ for (const id of collectExpressionIdentifiers(expr.object)) {
93
+ identifiers.add(id);
94
+ }
95
+ break;
96
+ case "element-access":
97
+ for (const id of collectExpressionIdentifiers(expr.object)) {
98
+ identifiers.add(id);
99
+ }
100
+ for (const id of collectExpressionIdentifiers(expr.index)) {
101
+ identifiers.add(id);
102
+ }
103
+ break;
104
+ case "template_string":
105
+ for (const id of collectExpressionIdentifiers(expr.expression)) {
106
+ identifiers.add(id);
107
+ }
108
+ break;
109
+ case "string_concat":
110
+ for (const part of expr.parts) {
111
+ for (const id of collectExpressionIdentifiers(part)) {
112
+ identifiers.add(id);
113
+ }
114
+ }
115
+ break;
116
+ case "callback":
117
+ // Callbacks have nested statements
118
+ for (const stmt of expr.statements) {
119
+ for (const id of collectStatementIdentifiers(stmt)) {
120
+ identifiers.add(id);
121
+ }
122
+ }
123
+ break;
124
+ case "method-call": {
125
+ const calleeParts = expr.callee.split(/->|::|\./);
126
+ for (const part of calleeParts) {
127
+ if (part.length > 0) {
128
+ identifiers.add(part);
129
+ }
130
+ }
131
+ for (const arg of expr.args) {
132
+ for (const id of collectExpressionIdentifiers(arg)) {
133
+ identifiers.add(id);
134
+ }
135
+ }
136
+ break;
137
+ }
138
+ // Parenthesized expression — recurse into the inner expression. The `paren`
139
+ // IR node exists to preserve explicit TS grouping (e.g. `(a + b) * c`), and
140
+ // any free-function call nested inside parens (such as `!fn(x)` inside an
141
+ // `(cond && !fn(x))` clause) MUST be visible to the call-graph/reachability
142
+ // pass, or the function is tree-shaken and g++ reports "not declared in
143
+ // this scope". Demo #22 Finding B — the root cause was the absence of this
144
+ // case, not a forward-declaration or return-type gap.
145
+ case "paren":
146
+ for (const id of collectExpressionIdentifiers(expr.inner)) {
147
+ identifiers.add(id);
148
+ }
149
+ break;
150
+ // Tuple element access `std::get<N>(object)` — the object may reference a
151
+ // reachable symbol.
152
+ case "tuple-access":
153
+ for (const id of collectExpressionIdentifiers(expr.object)) {
154
+ identifiers.add(id);
155
+ }
156
+ break;
157
+ // Arrow/lambda expression used as a value — walk its body for captured
158
+ // identifiers (the call graph must see free functions/vars a lambda uses).
159
+ case "lambda":
160
+ for (const param of expr.params) {
161
+ identifiers.add(param.name);
162
+ }
163
+ for (const stmt of expr.body) {
164
+ for (const id of collectStatementIdentifiers(stmt)) {
165
+ identifiers.add(id);
166
+ }
167
+ }
168
+ break;
169
+ // HAL operation used as an expression — delegate to the HAL identifier
170
+ // collector (same logic as the hal-op statement case).
171
+ case "hal-expr":
172
+ for (const id of collectHALOpIdentifiers(expr.operation)) {
173
+ identifiers.add(id);
174
+ }
175
+ break;
176
+ // number, string, boolean have no identifiers
177
+ }
178
+ return identifiers;
179
+ }
180
+ /**
181
+ * Collect all identifiers from a statement IR node.
182
+ * Returns a Set of identifier names found.
183
+ */
184
+ export function collectStatementIdentifiers(statement) {
185
+ const identifiers = new Set();
186
+ // Safety check
187
+ if (!statement || typeof statement !== "object" || !statement.kind) {
188
+ return identifiers;
189
+ }
190
+ switch (statement.kind) {
191
+ case "call":
192
+ // Extract function/method name from callee
193
+ const calleeParts = statement.callee.split(/->|::|[.(]/);
194
+ identifiers.add(calleeParts[0]);
195
+ // Add EVERY callee part, not just the first. A `call` statement's callee
196
+ // can be a lowered raw wrapper (`__RAW_STMT__out.push_back(glyphFor(op))`,
197
+ // produced by ir/transformers/call-statement.ts when an outer call wraps
198
+ // an inner free-function call). Only adding `calleeParts[0]` left the
199
+ // inner callee (`glyphFor`) invisible to the call graph, so a free
200
+ // function called only as a nested argument was tree-shaken and g++
201
+ // reported it "not declared in this scope". Demo #28 Finding C.
202
+ for (const part of calleeParts) {
203
+ if (part.length > 0) {
204
+ identifiers.add(part);
205
+ }
206
+ }
207
+ // Also add the full callee (e.g. "Serial.begin") for polyfill detection
208
+ identifiers.add(statement.callee);
209
+ // Demo #31 Finding A — a `__RAW_STMT__` callee carries a fully-formed
210
+ // C++ expression in its raw text (e.g. `parts.push_back(ONES_TEENS[i])`
211
+ // or `__tc_pop(map[k])`), and the split on `/->|::|[.(]/` does NOT fully
212
+ // tokenize it: it stops splitting once it hits `]` or `)`, so an indexed
213
+ // identifier like `ONES_TEENS` survives glued to its suffix
214
+ // (`"ONES_TEENS[i])"`) and is never added. The result: a top-level
215
+ // variable referenced ONLY through `arr.push(globalArr[i])` from a class
216
+ // method is tree-shaken, then g++ reports it "not declared in this
217
+ // scope" from the inline method body. Same blind-spot family as demo
218
+ // #22 B / demo #28 C, but in a DIFFERENT shape: those missed a free
219
+ // FUNCTION buried in raw/paren text; this misses a free VARIABLE buried
220
+ // in raw text behind an index. Fix: when the callee is a raw wrapper,
221
+ // scan its raw text with the SAME identifier regex the `raw` expression
222
+ // case uses (`case "raw"` above), so EVERY identifier in the embedded
223
+ // expression is collected regardless of bracket/paren structure.
224
+ if (statement.callee.startsWith("__RAW_STMT__")) {
225
+ const matches = statement.callee.match(/[A-Za-z_][A-Za-z0-9_]*/g);
226
+ if (matches) {
227
+ for (const match of matches) {
228
+ identifiers.add(match);
229
+ }
230
+ }
231
+ }
232
+ for (const arg of statement.args) {
233
+ // Special case: if this is an __EMIT__ call, scan string literals for identifiers
234
+ if (statement.callee === "__EMIT__" && arg.kind === "string") {
235
+ const matches = arg.value.match(/[A-Za-z_][A-Za-z0-9_]*/g);
236
+ if (matches) {
237
+ for (const match of matches) {
238
+ identifiers.add(match);
239
+ }
240
+ }
241
+ }
242
+ for (const id of collectExpressionIdentifiers(arg)) {
243
+ identifiers.add(id);
244
+ }
245
+ }
246
+ break;
247
+ case "var_decl":
248
+ identifiers.add(statement.name);
249
+ if (statement.initializer) {
250
+ for (const id of collectExpressionIdentifiers(statement.initializer)) {
251
+ identifiers.add(id);
252
+ }
253
+ }
254
+ break;
255
+ case "assign":
256
+ identifiers.add(statement.target);
257
+ for (const id of collectExpressionIdentifiers(statement.value)) {
258
+ identifiers.add(id);
259
+ }
260
+ break;
261
+ case "update":
262
+ identifiers.add(statement.target);
263
+ break;
264
+ case "return":
265
+ if (statement.value) {
266
+ for (const id of collectExpressionIdentifiers(statement.value)) {
267
+ identifiers.add(id);
268
+ }
269
+ }
270
+ break;
271
+ case "while":
272
+ case "do_while":
273
+ for (const id of collectExpressionIdentifiers(statement.condition)) {
274
+ identifiers.add(id);
275
+ }
276
+ for (const nested of statement.body) {
277
+ for (const id of collectStatementIdentifiers(nested)) {
278
+ identifiers.add(id);
279
+ }
280
+ }
281
+ break;
282
+ case "if":
283
+ for (const id of collectExpressionIdentifiers(statement.condition)) {
284
+ identifiers.add(id);
285
+ }
286
+ for (const nested of statement.thenBranch) {
287
+ for (const id of collectStatementIdentifiers(nested)) {
288
+ identifiers.add(id);
289
+ }
290
+ }
291
+ for (const nested of statement.elseBranch ?? []) {
292
+ for (const id of collectStatementIdentifiers(nested)) {
293
+ identifiers.add(id);
294
+ }
295
+ }
296
+ break;
297
+ case "for":
298
+ if (statement.initializer) {
299
+ for (const id of collectStatementIdentifiers(statement.initializer)) {
300
+ identifiers.add(id);
301
+ }
302
+ }
303
+ if (statement.condition) {
304
+ for (const id of collectExpressionIdentifiers(statement.condition)) {
305
+ identifiers.add(id);
306
+ }
307
+ }
308
+ if (statement.increment) {
309
+ for (const id of collectStatementIdentifiers(statement.increment)) {
310
+ identifiers.add(id);
311
+ }
312
+ }
313
+ for (const nested of statement.body) {
314
+ for (const id of collectStatementIdentifiers(nested)) {
315
+ identifiers.add(id);
316
+ }
317
+ }
318
+ break;
319
+ case "for_of":
320
+ for (const id of collectStatementIdentifiers(statement.variable)) {
321
+ identifiers.add(id);
322
+ }
323
+ for (const id of collectExpressionIdentifiers(statement.iterable)) {
324
+ identifiers.add(id);
325
+ }
326
+ for (const nested of statement.body) {
327
+ for (const id of collectStatementIdentifiers(nested)) {
328
+ identifiers.add(id);
329
+ }
330
+ }
331
+ break;
332
+ case "for_in":
333
+ for (const id of collectStatementIdentifiers(statement.variable)) {
334
+ identifiers.add(id);
335
+ }
336
+ for (const id of collectExpressionIdentifiers(statement.object)) {
337
+ identifiers.add(id);
338
+ }
339
+ for (const nested of statement.body) {
340
+ for (const id of collectStatementIdentifiers(nested)) {
341
+ identifiers.add(id);
342
+ }
343
+ }
344
+ break;
345
+ case "switch":
346
+ for (const id of collectExpressionIdentifiers(statement.expression)) {
347
+ identifiers.add(id);
348
+ }
349
+ for (const caseClause of statement.cases) {
350
+ if (caseClause.value) {
351
+ for (const id of collectExpressionIdentifiers(caseClause.value)) {
352
+ identifiers.add(id);
353
+ }
354
+ }
355
+ for (const nested of caseClause.body) {
356
+ for (const id of collectStatementIdentifiers(nested)) {
357
+ identifiers.add(id);
358
+ }
359
+ }
360
+ }
361
+ break;
362
+ case "try":
363
+ if (statement.catchParam) {
364
+ identifiers.add(statement.catchParam);
365
+ }
366
+ for (const nested of statement.tryBlock) {
367
+ for (const id of collectStatementIdentifiers(nested)) {
368
+ identifiers.add(id);
369
+ }
370
+ }
371
+ for (const nested of statement.catchBlock ?? []) {
372
+ for (const id of collectStatementIdentifiers(nested)) {
373
+ identifiers.add(id);
374
+ }
375
+ }
376
+ if (statement.finallyBlock) {
377
+ for (const nested of statement.finallyBlock) {
378
+ for (const id of collectStatementIdentifiers(nested)) {
379
+ identifiers.add(id);
380
+ }
381
+ }
382
+ }
383
+ break;
384
+ case "throw":
385
+ for (const id of collectExpressionIdentifiers(statement.value)) {
386
+ identifiers.add(id);
387
+ }
388
+ break;
389
+ case "labeled":
390
+ identifiers.add(statement.label);
391
+ for (const nested of statement.body) {
392
+ for (const id of collectStatementIdentifiers(nested)) {
393
+ identifiers.add(id);
394
+ }
395
+ }
396
+ break;
397
+ case "block":
398
+ for (const nested of statement.body) {
399
+ for (const id of collectStatementIdentifiers(nested)) {
400
+ identifiers.add(id);
401
+ }
402
+ }
403
+ break;
404
+ // break, continue have no identifiers
405
+ case "hal-op":
406
+ for (const id of collectHALOpIdentifiers(statement.operation)) {
407
+ identifiers.add(id);
408
+ }
409
+ break;
410
+ // break, continue have no identifiers
411
+ }
412
+ return identifiers;
413
+ }
414
+ /**
415
+ * Extract identifier names from a HAL operation's string fields.
416
+ * This ensures the call graph tracks function references embedded in
417
+ * semantic HAL ops (e.g. the handler name in interrupt.attach).
418
+ */
419
+ function collectHALOpIdentifiers(op) {
420
+ const identifiers = new Set();
421
+ switch (op.operation) {
422
+ case "interrupt.attach":
423
+ // handler is a resolved C++ function name (e.g. "myIsr" or a placeholder)
424
+ identifiers.add(op.handler);
425
+ break;
426
+ case "raw": {
427
+ // Raw C++ code may reference user-defined identifiers
428
+ const matches = op.code.match(/[A-Za-z_][A-Za-z0-9_]*/g);
429
+ if (matches) {
430
+ for (const match of matches) {
431
+ identifiers.add(match);
432
+ }
433
+ }
434
+ break;
435
+ }
436
+ // Other HAL ops have only numeric/literal fields — no identifier references
437
+ }
438
+ return identifiers;
439
+ }
@@ -0,0 +1,39 @@
1
+ import type { ProgramIR } from '../api/index.js';
2
+ import type { PeripheralUsage } from './peripheral-usage.js';
3
+ import type { Diagnostic } from '../types.js';
4
+ export { walkNestedStatements as scanNestedStatements } from './utils/walk-ir.js';
5
+ /** ISR-unsafe operation entry. */
6
+ export interface IsrUnsafeOp {
7
+ reason: string;
8
+ severity: 'warning' | 'info';
9
+ }
10
+ /**
11
+ * Track interrupt handlers attached to pins.
12
+ * Maps pin name to the number of handlers attached.
13
+ */
14
+ export interface InterruptHandlerInfo {
15
+ pinName: string;
16
+ attachCount: number;
17
+ }
18
+ /**
19
+ * Analyze a program for interrupt handler issues.
20
+ *
21
+ * @param program - The program IR to analyze
22
+ * @param usage - Peripheral usage information
23
+ * @param isrUnsafeOps - Platform-specific ISR-unsafe operations map (from strategy)
24
+ * @returns Array of diagnostics for interrupt-related issues
25
+ */
26
+ export declare function analyzeInterruptSafety(program: ProgramIR, usage: PeripheralUsage, isrUnsafeOps?: Map<string, IsrUnsafeOp>): Diagnostic[];
27
+ /**
28
+ * Infer `volatile` for global variables shared between ISR callbacks and main
29
+ * code. Mutates the IR (sets isVolatile=true on qualifying var_decls) and
30
+ * emits an info diagnostic for each promotion. A variable qualifies when it is
31
+ * a global (top-level) that is assigned inside an isInterruptHandler callback
32
+ * AND read from non-ISR code (setup/loop/main/functions).
33
+ */
34
+ export declare function inferVolatileForIsrSharedVars(program: ProgramIR, diagnostics: Diagnostic[]): void;
35
+ /**
36
+ * Detect functions called from both ISR callbacks and main-thread code.
37
+ * Emits a warning for each reentrancy-risk function.
38
+ */
39
+ export declare function detectReentrancyRisk(program: ProgramIR, diagnostics: Diagnostic[]): void;