@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,608 @@
1
+ import ts from "typescript";
2
+ import { extractNodeComments, makeSourceSpan } from "./ast-node-utils.js";
3
+ import { typeNodeToCppType, extractOwnershipKindFromTypeNode } from "./type-resolution.js";
4
+ import { getBitsRange, getRegisterAddress } from "./register-decorators.js";
5
+ import { registerFieldMap, setActiveExtendsClass, discriminatedUnionVariantNames, requiredIncludes } from "./build-ir-state.js";
6
+ import { getCurrentIrTypeScope } from "./symbol-types.js";
7
+ import { expressionToIR } from "./expression-to-ir.js";
8
+ import { lowerStatementList } from "./statement-to-ir.js";
9
+ /**
10
+ * Format an `ExpressionWithTypeArguments` (a heritage-clause type) as a C++
11
+ * base-class specifier, resolving each type argument through `typeNodeToCppType`.
12
+ * `extends Registry<string, number>` → `Registry<std::string, double>`.
13
+ * Without this, `.expression.getText()` drops the type arguments and leaves
14
+ * the base as an unsubstituted template.
15
+ */
16
+ function formatHeritageType(heritage, typeAliasNodes) {
17
+ const baseName = heritage.expression.getText();
18
+ if (!heritage.typeArguments || heritage.typeArguments.length === 0) {
19
+ return baseName;
20
+ }
21
+ const args = heritage.typeArguments.map(ta => typeNodeToCppType(ta, typeAliasNodes));
22
+ return `${baseName}<${args.join(", ")}>`;
23
+ }
24
+ export function classDeclarationToIR(node, fileName, sourceText, diagnostics, functionReturnTypes, typeAliasNodes, registerClasses, pointerVars = new Map(), scopePrefix) {
25
+ if (!node.name) {
26
+ return undefined;
27
+ }
28
+ const className = node.name.text;
29
+ const regAddr = getRegisterAddress(node);
30
+ if (regAddr !== undefined) {
31
+ const classComments = extractNodeComments(node, sourceText);
32
+ const bitFields = [];
33
+ for (const member of node.members) {
34
+ if (ts.isPropertyDeclaration(member) && member.name && ts.isIdentifier(member.name)) {
35
+ const range = getBitsRange(member);
36
+ if (range) {
37
+ bitFields.push({
38
+ name: member.name.text,
39
+ hi: range.hi,
40
+ lo: range.lo,
41
+ width: range.hi - range.lo + 1,
42
+ });
43
+ }
44
+ }
45
+ }
46
+ const regIR = {
47
+ name: className,
48
+ address: regAddr,
49
+ bitFields,
50
+ sourceSpan: makeSourceSpan(node, fileName, sourceText),
51
+ leadingComments: classComments.leadingComments,
52
+ trailingComments: classComments.trailingComments,
53
+ };
54
+ registerClasses.push(regIR);
55
+ const fieldMap = new Map();
56
+ for (const bf of bitFields) {
57
+ fieldMap.set(bf.name, { hi: bf.hi, lo: bf.lo, width: bf.width });
58
+ }
59
+ registerFieldMap.set(className, fieldMap);
60
+ return undefined;
61
+ }
62
+ const isAbstract = node.modifiers?.some(m => m.kind === ts.SyntaxKind.AbstractKeyword) ?? false;
63
+ // Render the extends-clause type, INCLUDING type arguments, so a subclass of
64
+ // a generic base (`extends Registry<string, number>`) lowers to
65
+ // `: public Registry<std::string, double>` rather than dropping the
66
+ // instantiation (which would leave the base as an unsubstituted template).
67
+ const extendsHeritage = node.heritageClauses
68
+ ?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)
69
+ ?.types[0];
70
+ const extendsClass = extendsHeritage ? formatHeritageType(extendsHeritage, typeAliasNodes) : undefined;
71
+ const implementsInterfaces = node.heritageClauses
72
+ ?.find((clause) => clause.token === ts.SyntaxKind.ImplementsKeyword)
73
+ ?.types.map(t => t.expression?.getText())
74
+ .filter((name) => name !== undefined);
75
+ const classComments = extractNodeComments(node, sourceText);
76
+ const fields = [];
77
+ const methods = [];
78
+ const getters = [];
79
+ const setters = [];
80
+ let ctor;
81
+ const qualifiedName = scopePrefix ? `${scopePrefix}.${className}` : className;
82
+ const staticBlockStatements = [];
83
+ const preScannedFieldTypes = new Map();
84
+ for (const member of node.members) {
85
+ if (ts.isPropertyDeclaration(member) && member.name) {
86
+ const fName = ts.isIdentifier(member.name) ? member.name.text
87
+ : member.name.kind === ts.SyntaxKind.PrivateIdentifier ? `__priv_${member.name.text.substring(1)}` : null;
88
+ if (fName) {
89
+ const fType = typeNodeToCppType(member.type, typeAliasNodes);
90
+ preScannedFieldTypes.set(`this->${fName}`, fType);
91
+ getCurrentIrTypeScope()?.classFields.set(`this->${fName}`, fType);
92
+ }
93
+ }
94
+ }
95
+ for (const member of node.members) {
96
+ if (ts.isClassStaticBlockDeclaration?.(member) || member.kind === ts.SyntaxKind.ClassStaticBlockDeclaration) {
97
+ const block = member;
98
+ if (block.body) {
99
+ const stmts = lowerStatementList(block.body.statements, fileName, sourceText, diagnostics, functionReturnTypes, new Map(), `${qualifiedName}.staticBlock`, typeAliasNodes, pointerVars);
100
+ staticBlockStatements.push(...stmts);
101
+ }
102
+ continue;
103
+ }
104
+ if (ts.isConstructorDeclaration(member)) {
105
+ const ctorParams = [];
106
+ const ctorLocalTypes = new Map();
107
+ const paramPropertyNames = [];
108
+ for (const param of member.parameters) {
109
+ if (ts.isIdentifier(param.name)) {
110
+ const paramType = typeNodeToCppType(param.type, typeAliasNodes);
111
+ ctorLocalTypes.set(param.name.text, paramType);
112
+ const paramOwnershipKind = extractOwnershipKindFromTypeNode(param.type, typeAliasNodes);
113
+ ctorParams.push({
114
+ name: param.name.text,
115
+ cppType: (paramType === "void" ? "auto" : paramType),
116
+ defaultValue: param.initializer
117
+ ? expressionToIR(param.initializer, sourceText, diagnostics, pointerVars)
118
+ : undefined,
119
+ isRest: !!param.dotDotDotToken,
120
+ ...(paramOwnershipKind ? { ownershipKind: paramOwnershipKind } : {}),
121
+ });
122
+ const hasVisibility = param.modifiers?.some(m => m.kind === ts.SyntaxKind.PublicKeyword ||
123
+ m.kind === ts.SyntaxKind.PrivateKeyword ||
124
+ m.kind === ts.SyntaxKind.ProtectedKeyword);
125
+ if (hasVisibility) {
126
+ const visibility = param.modifiers.some(m => m.kind === ts.SyntaxKind.PrivateKeyword)
127
+ ? "private"
128
+ : param.modifiers.some(m => m.kind === ts.SyntaxKind.ProtectedKeyword)
129
+ ? "protected"
130
+ : "public";
131
+ fields.push({
132
+ name: param.name.text,
133
+ cppType: (paramType === "void" ? "auto" : paramType),
134
+ visibility,
135
+ initializer: param.initializer
136
+ ? expressionToIR(param.initializer, sourceText, diagnostics, pointerVars)
137
+ : undefined,
138
+ });
139
+ paramPropertyNames.push(param.name.text);
140
+ }
141
+ }
142
+ }
143
+ const ctorBody = member.body
144
+ ? lowerStatementList(member.body.statements, fileName, sourceText, diagnostics, functionReturnTypes, ctorLocalTypes, `${qualifiedName}.constructor`, typeAliasNodes, pointerVars)
145
+ : [];
146
+ const syntheticSpan = { filePath: fileName, startOffset: 0, endOffset: 0, startLine: 0, startColumn: 0, endLine: 0, endColumn: 0 };
147
+ const paramPropertyAssignments = paramPropertyNames.map(name => ({
148
+ kind: "assign",
149
+ sourceSpan: syntheticSpan,
150
+ target: `this->${name}`,
151
+ operator: "=",
152
+ value: { kind: "identifier", value: name },
153
+ }));
154
+ ctor = { parameters: ctorParams, statements: [...paramPropertyAssignments, ...ctorBody, ...staticBlockStatements] };
155
+ continue;
156
+ }
157
+ if (ts.isPropertyDeclaration(member) && member.name) {
158
+ if (member.modifiers?.some(m => m.kind === ts.SyntaxKind.AbstractKeyword)) {
159
+ continue;
160
+ }
161
+ let fieldName;
162
+ let fieldVisibility;
163
+ if (member.name.kind === ts.SyntaxKind.PrivateIdentifier) {
164
+ fieldName = `__priv_${member.name.text.substring(1)}`;
165
+ fieldVisibility = "private";
166
+ }
167
+ else if (ts.isIdentifier(member.name)) {
168
+ fieldName = member.name.text;
169
+ fieldVisibility = member.modifiers?.some(m => m.kind === ts.SyntaxKind.PrivateKeyword)
170
+ ? "private"
171
+ : member.modifiers?.some(m => m.kind === ts.SyntaxKind.ProtectedKeyword)
172
+ ? "protected"
173
+ : "public";
174
+ }
175
+ else {
176
+ continue;
177
+ }
178
+ const fieldType = typeNodeToCppType(member.type, typeAliasNodes);
179
+ fields.push({
180
+ name: fieldName,
181
+ cppType: (fieldType === "void" ? "auto" : fieldType),
182
+ visibility: fieldVisibility,
183
+ initializer: member.initializer
184
+ ? expressionToIR(member.initializer, sourceText, diagnostics, pointerVars)
185
+ : undefined,
186
+ isStatic: member.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) ?? false,
187
+ });
188
+ continue;
189
+ }
190
+ if (ts.isMethodDeclaration(member) && member.name) {
191
+ let methodName;
192
+ let methodVisibility;
193
+ if (member.name.kind === ts.SyntaxKind.PrivateIdentifier) {
194
+ methodName = `__priv_${member.name.text.substring(1)}`;
195
+ methodVisibility = "private";
196
+ }
197
+ else if (ts.isIdentifier(member.name)) {
198
+ methodName = member.name.text;
199
+ methodVisibility = member.modifiers?.some(m => m.kind === ts.SyntaxKind.PrivateKeyword)
200
+ ? "private"
201
+ : member.modifiers?.some(m => m.kind === ts.SyntaxKind.ProtectedKeyword)
202
+ ? "protected"
203
+ : "public";
204
+ }
205
+ else {
206
+ continue;
207
+ }
208
+ const isStatic = member.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) ?? false;
209
+ const isMethodAbstract = member.modifiers?.some(m => m.kind === ts.SyntaxKind.AbstractKeyword) ?? false;
210
+ const isOverride = member.modifiers?.some(m => m.kind === ts.SyntaxKind.OverrideKeyword) ?? false;
211
+ if (extendsClass && !isStatic) {
212
+ setActiveExtendsClass(extendsClass);
213
+ }
214
+ // Resolve this method's declared return type and register it under the
215
+ // same qualified key used as functionNameForDiagnostics below, so that
216
+ // return statements inside the body get the enclosing return type
217
+ // annotated on the ReturnIR (used by the emitter to lower
218
+ // `return null`/`undefined` to `return {};` for struct returns — demo
219
+ // #14 Finding A). Top-level functions get this via buildFunctionReturnTypeMap;
220
+ // methods do not, so we add it here.
221
+ const methodQualifiedKey = `${qualifiedName}.${methodName}`;
222
+ const preMethodReturnType = typeNodeToCppType(member.type, typeAliasNodes);
223
+ if (preMethodReturnType && preMethodReturnType !== "void") {
224
+ functionReturnTypes.set(methodQualifiedKey, preMethodReturnType);
225
+ }
226
+ const methodParams = [];
227
+ const methodLocalTypes = new Map(preScannedFieldTypes);
228
+ for (const param of member.parameters) {
229
+ if (ts.isIdentifier(param.name)) {
230
+ const paramType = typeNodeToCppType(param.type, typeAliasNodes);
231
+ methodLocalTypes.set(param.name.text, paramType);
232
+ const paramOwnershipKind = extractOwnershipKindFromTypeNode(param.type, typeAliasNodes);
233
+ methodParams.push({
234
+ name: param.name.text,
235
+ cppType: (paramType === "void" ? "auto" : paramType),
236
+ defaultValue: param.initializer
237
+ ? expressionToIR(param.initializer, sourceText, diagnostics, pointerVars)
238
+ : undefined,
239
+ isRest: !!param.dotDotDotToken,
240
+ ...(paramOwnershipKind ? { ownershipKind: paramOwnershipKind } : {}),
241
+ });
242
+ }
243
+ }
244
+ const methodBody = member.body
245
+ ? lowerStatementList(member.body.statements, fileName, sourceText, diagnostics, functionReturnTypes, methodLocalTypes, `${qualifiedName}.${methodName}`, typeAliasNodes, pointerVars)
246
+ : [];
247
+ const methodReturnType = typeNodeToCppType(member.type, typeAliasNodes);
248
+ setActiveExtendsClass(undefined);
249
+ methods.push({
250
+ name: methodName,
251
+ returnType: (member.type?.kind === ts.SyntaxKind.ThisType
252
+ ? `${className}*`
253
+ : (methodReturnType === className ? `${className}*` : (methodReturnType === "void" ? "void" : methodReturnType))),
254
+ parameters: methodParams,
255
+ statements: methodBody,
256
+ visibility: methodVisibility,
257
+ isStatic,
258
+ isAbstract: isMethodAbstract,
259
+ isOverride,
260
+ ...(member.typeParameters && member.typeParameters.length > 0
261
+ ? { typeParameters: member.typeParameters.map(tp => tp.name.text) }
262
+ : {}),
263
+ });
264
+ }
265
+ if (ts.isGetAccessorDeclaration(member) && member.name && ts.isIdentifier(member.name)) {
266
+ const visibility = member.modifiers?.some(m => m.kind === ts.SyntaxKind.PrivateKeyword)
267
+ ? "private"
268
+ : member.modifiers?.some(m => m.kind === ts.SyntaxKind.ProtectedKeyword)
269
+ ? "protected"
270
+ : "public";
271
+ if (extendsClass) {
272
+ const isStatic = member.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) ?? false;
273
+ if (!isStatic)
274
+ setActiveExtendsClass(extendsClass);
275
+ }
276
+ const accessorLocalTypes = new Map();
277
+ const accessorBody = member.body
278
+ ? lowerStatementList(member.body.statements, fileName, sourceText, diagnostics, functionReturnTypes, accessorLocalTypes, `${qualifiedName}.get:${member.name.text}`, typeAliasNodes, pointerVars)
279
+ : [];
280
+ setActiveExtendsClass(undefined);
281
+ getters.push({
282
+ name: member.name.text,
283
+ returnType: typeNodeToCppType(member.type, typeAliasNodes),
284
+ statements: accessorBody,
285
+ visibility,
286
+ isStatic: member.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) ?? false,
287
+ });
288
+ }
289
+ if (ts.isSetAccessorDeclaration(member) && member.name && ts.isIdentifier(member.name)) {
290
+ const visibility = member.modifiers?.some(m => m.kind === ts.SyntaxKind.PrivateKeyword)
291
+ ? "private"
292
+ : member.modifiers?.some(m => m.kind === ts.SyntaxKind.ProtectedKeyword)
293
+ ? "protected"
294
+ : "public";
295
+ const setParams = [];
296
+ const setterLocalTypes = new Map();
297
+ for (const param of member.parameters) {
298
+ if (ts.isIdentifier(param.name)) {
299
+ const paramType = typeNodeToCppType(param.type, typeAliasNodes);
300
+ setterLocalTypes.set(param.name.text, paramType);
301
+ setParams.push({
302
+ name: param.name.text,
303
+ cppType: (paramType === "void" ? "auto" : paramType),
304
+ isRest: !!param.dotDotDotToken,
305
+ });
306
+ }
307
+ }
308
+ if (extendsClass) {
309
+ const isStatic = member.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) ?? false;
310
+ if (!isStatic)
311
+ setActiveExtendsClass(extendsClass);
312
+ }
313
+ const accessorBody = member.body
314
+ ? lowerStatementList(member.body.statements, fileName, sourceText, diagnostics, functionReturnTypes, setterLocalTypes, `${qualifiedName}.set:${member.name.text}`, typeAliasNodes, pointerVars)
315
+ : [];
316
+ setActiveExtendsClass(undefined);
317
+ setters.push({
318
+ name: member.name.text,
319
+ parameter: setParams[0] ?? { name: "value", cppType: "auto", isRest: false },
320
+ statements: accessorBody,
321
+ visibility,
322
+ isStatic: member.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) ?? false,
323
+ });
324
+ }
325
+ }
326
+ if (!ctor && staticBlockStatements.length > 0) {
327
+ ctor = { parameters: [], statements: [...staticBlockStatements] };
328
+ }
329
+ const classDecorators = node.decorators
330
+ ? node.decorators
331
+ .map((d) => {
332
+ if (d.expression && ts.isIdentifier(d.expression))
333
+ return d.expression.text;
334
+ if (d.expression && ts.isCallExpression(d.expression) && ts.isIdentifier(d.expression.expression))
335
+ return d.expression.expression.text;
336
+ return undefined;
337
+ })
338
+ .filter((d) => d !== undefined)
339
+ : undefined;
340
+ const classTypeParams = node.typeParameters
341
+ ? node.typeParameters.map(tp => tp.name.text)
342
+ : undefined;
343
+ return {
344
+ name: className,
345
+ extendsClass,
346
+ implementsInterfaces,
347
+ isAbstract,
348
+ sourceSpan: makeSourceSpan(node, fileName, sourceText),
349
+ leadingComments: classComments.leadingComments,
350
+ trailingComments: classComments.trailingComments,
351
+ fields,
352
+ methods,
353
+ constructor: ctor,
354
+ getters,
355
+ setters,
356
+ ...(classTypeParams && classTypeParams.length > 0 ? { typeParameters: classTypeParams } : {}),
357
+ ...(classDecorators && classDecorators.length > 0 ? { decorators: classDecorators } : {}),
358
+ };
359
+ }
360
+ function evaluateConstExpr(expr, memberMap, sourceText) {
361
+ if (ts.isNumericLiteral(expr)) {
362
+ return Number(expr.text);
363
+ }
364
+ if (ts.isPrefixUnaryExpression(expr)) {
365
+ const operand = evaluateConstExpr(expr.operand, memberMap, sourceText);
366
+ if (operand === undefined)
367
+ return undefined;
368
+ switch (expr.operator) {
369
+ case ts.SyntaxKind.MinusToken: return -operand;
370
+ case ts.SyntaxKind.PlusToken: return +operand;
371
+ case ts.SyntaxKind.TildeToken: return ~operand;
372
+ case ts.SyntaxKind.ExclamationToken: return operand ? 0 : 1;
373
+ default: return undefined;
374
+ }
375
+ }
376
+ if (ts.isBinaryExpression(expr)) {
377
+ const left = evaluateConstExpr(expr.left, memberMap, sourceText);
378
+ const right = evaluateConstExpr(expr.right, memberMap, sourceText);
379
+ if (left === undefined || right === undefined)
380
+ return undefined;
381
+ switch (expr.operatorToken.kind) {
382
+ case ts.SyntaxKind.PlusToken: return left + right;
383
+ case ts.SyntaxKind.MinusToken: return left - right;
384
+ case ts.SyntaxKind.AsteriskToken: return left * right;
385
+ case ts.SyntaxKind.SlashToken: return Math.trunc(left / right);
386
+ case ts.SyntaxKind.PercentToken: return left % right;
387
+ case ts.SyntaxKind.BarToken: return left | right;
388
+ case ts.SyntaxKind.AmpersandToken: return left & right;
389
+ case ts.SyntaxKind.CaretToken: return left ^ right;
390
+ case ts.SyntaxKind.LessThanLessThanToken: return left << right;
391
+ case ts.SyntaxKind.GreaterThanGreaterThanToken: return left >> right;
392
+ case ts.SyntaxKind.BarBarToken: return left || right;
393
+ case ts.SyntaxKind.AmpersandAmpersandToken: return left && right;
394
+ default: return undefined;
395
+ }
396
+ }
397
+ if (ts.isIdentifier(expr)) {
398
+ return memberMap.get(expr.text);
399
+ }
400
+ if (ts.isPropertyAccessExpression(expr)) {
401
+ if (ts.isIdentifier(expr.expression)) {
402
+ const enumPrefix = expr.expression.text;
403
+ const memberName = expr.name.text;
404
+ const qualifiedKey = `${enumPrefix}.${memberName}`;
405
+ return memberMap.get(qualifiedKey) ?? memberMap.get(memberName);
406
+ }
407
+ }
408
+ if (ts.isParenthesizedExpression(expr)) {
409
+ return evaluateConstExpr(expr.expression, memberMap, sourceText);
410
+ }
411
+ return undefined;
412
+ }
413
+ export function enumDeclarationToIR(node, fileName, sourceText) {
414
+ if (!node.name) {
415
+ return undefined;
416
+ }
417
+ const enumName = node.name.text;
418
+ const enumComments = extractNodeComments(node, sourceText);
419
+ const isConst = node.modifiers?.some(m => m.kind === ts.SyntaxKind.ConstKeyword) ?? false;
420
+ const members = [];
421
+ const memberMap = new Map();
422
+ let nextValue = 0;
423
+ for (const member of node.members) {
424
+ if (ts.isIdentifier(member.name)) {
425
+ let value;
426
+ if (member.initializer) {
427
+ value = evaluateConstExpr(member.initializer, memberMap, sourceText);
428
+ if (value === undefined) {
429
+ if (ts.isNumericLiteral(member.initializer)) {
430
+ value = Number(member.initializer.text);
431
+ }
432
+ else if (ts.isPrefixUnaryExpression(member.initializer) &&
433
+ member.initializer.operator === ts.SyntaxKind.MinusToken &&
434
+ ts.isNumericLiteral(member.initializer.operand)) {
435
+ value = -Number(member.initializer.operand.text);
436
+ }
437
+ else if (ts.isStringLiteral(member.initializer)) {
438
+ value = member.initializer.text;
439
+ }
440
+ }
441
+ if (value !== undefined && typeof value === "number") {
442
+ nextValue = value + 1;
443
+ }
444
+ else {
445
+ nextValue++;
446
+ }
447
+ }
448
+ else {
449
+ value = nextValue;
450
+ nextValue++;
451
+ }
452
+ if (value !== undefined && typeof value === "number") {
453
+ memberMap.set(member.name.text, value);
454
+ memberMap.set(`${enumName}.${member.name.text}`, value);
455
+ }
456
+ members.push({
457
+ name: member.name.text,
458
+ value,
459
+ });
460
+ }
461
+ }
462
+ return {
463
+ name: node.name.text,
464
+ sourceSpan: makeSourceSpan(node, fileName, sourceText),
465
+ leadingComments: enumComments.leadingComments,
466
+ trailingComments: enumComments.trailingComments,
467
+ members,
468
+ isConst,
469
+ };
470
+ }
471
+ export function interfaceDeclarationToIR(node, fileName, sourceText, typeAliasNodes) {
472
+ if (!node.name) {
473
+ return undefined;
474
+ }
475
+ const interfaceComments = extractNodeComments(node, sourceText);
476
+ const interfaceName = node.name.text;
477
+ const extendsInterfaces = node.heritageClauses
478
+ ?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)
479
+ ?.types.map(t => t.expression?.getText())
480
+ .filter((name) => name !== undefined);
481
+ const fields = [];
482
+ const methods = [];
483
+ let indexSignature;
484
+ for (const member of node.members) {
485
+ if (ts.isPropertySignature(member) && member.name && ts.isIdentifier(member.name)) {
486
+ const propName = member.name.text;
487
+ const isOptional = !!member.questionToken;
488
+ const propType = typeNodeToCppType(member.type, typeAliasNodes);
489
+ fields.push({
490
+ name: propName,
491
+ cppType: propType,
492
+ isOptional,
493
+ });
494
+ continue;
495
+ }
496
+ if (ts.isMethodSignature(member) && member.name && ts.isIdentifier(member.name)) {
497
+ const methodName = member.name.text;
498
+ const returnType = typeNodeToCppType(member.type, typeAliasNodes);
499
+ const params = [];
500
+ for (const param of member.parameters) {
501
+ if (ts.isIdentifier(param.name)) {
502
+ const paramType = typeNodeToCppType(param.type, typeAliasNodes);
503
+ params.push({
504
+ name: param.name.text,
505
+ cppType: (paramType === "void" ? "auto" : paramType),
506
+ isRest: !!param.dotDotDotToken,
507
+ });
508
+ }
509
+ }
510
+ methods.push({
511
+ name: methodName,
512
+ returnType,
513
+ parameters: params,
514
+ });
515
+ continue;
516
+ }
517
+ if (ts.isIndexSignatureDeclaration(member)) {
518
+ let keyType = "string";
519
+ if (member.parameters.length > 0 && ts.isIdentifier(member.parameters[0].name)) {
520
+ const paramType = member.parameters[0].type;
521
+ if (paramType && ts.isTypeNode(paramType)) {
522
+ keyType = typeNodeToCppType(paramType, typeAliasNodes);
523
+ }
524
+ }
525
+ const valueType = typeNodeToCppType(member.type, typeAliasNodes);
526
+ indexSignature = { keyType, valueType };
527
+ }
528
+ }
529
+ return {
530
+ name: interfaceName,
531
+ sourceSpan: makeSourceSpan(node, fileName, sourceText),
532
+ leadingComments: interfaceComments.leadingComments,
533
+ trailingComments: interfaceComments.trailingComments,
534
+ extendsInterfaces,
535
+ fields,
536
+ methods,
537
+ indexSignature,
538
+ };
539
+ }
540
+ export function typeAliasDeclarationToIR(node, fileName, sourceText, typeAliasNodes) {
541
+ const aliasComments = extractNodeComments(node, sourceText);
542
+ const aliasTypeParams = node.typeParameters
543
+ ? node.typeParameters.map(tp => tp.name.text)
544
+ : undefined;
545
+ const resolved = node.type;
546
+ if (ts.isUnionTypeNode(resolved)) {
547
+ const variantStructs = extractDiscriminatedUnionVariants(resolved, typeAliasNodes, node.name.text);
548
+ if (variantStructs) {
549
+ const variantNames = variantStructs.map(v => v.name);
550
+ discriminatedUnionVariantNames.set(node.name.text, variantNames);
551
+ return {
552
+ name: node.name.text,
553
+ sourceSpan: makeSourceSpan(node, fileName, sourceText),
554
+ leadingComments: aliasComments.leadingComments,
555
+ trailingComments: aliasComments.trailingComments,
556
+ cppType: `std::variant<${variantNames.join(", ")}>`,
557
+ variantStructs,
558
+ ...(aliasTypeParams && aliasTypeParams.length > 0 ? { typeParameters: aliasTypeParams } : {}),
559
+ };
560
+ // std::variant requires <variant>; register the include so the header
561
+ // compiles (demo #9 Finding A — was emitting `std::variant<...>` with
562
+ // no include, giving "'variant' is not a member of 'std'").
563
+ if (variantNames.length > 0) {
564
+ requiredIncludes.add("<variant>");
565
+ }
566
+ }
567
+ }
568
+ const cppType = typeNodeToCppType(node.type, typeAliasNodes);
569
+ let structFields;
570
+ if (ts.isTypeLiteralNode(resolved)) {
571
+ structFields = resolved.members
572
+ .filter(ts.isPropertySignature)
573
+ .filter(m => ts.isIdentifier(m.name))
574
+ .map(m => ({
575
+ name: m.name.text,
576
+ cppType: typeNodeToCppType(m.type, typeAliasNodes),
577
+ }));
578
+ }
579
+ return {
580
+ name: node.name.text,
581
+ sourceSpan: makeSourceSpan(node, fileName, sourceText),
582
+ leadingComments: aliasComments.leadingComments,
583
+ trailingComments: aliasComments.trailingComments,
584
+ cppType,
585
+ structFields,
586
+ ...(aliasTypeParams && aliasTypeParams.length > 0 ? { typeParameters: aliasTypeParams } : {}),
587
+ };
588
+ }
589
+ function extractDiscriminatedUnionVariants(unionNode, typeAliasNodes, aliasName) {
590
+ const typeLiterals = unionNode.types.filter(ts.isTypeLiteralNode);
591
+ if (typeLiterals.length === 0 || typeLiterals.length !== unionNode.types.length) {
592
+ return null;
593
+ }
594
+ const variants = [];
595
+ for (let i = 0; i < typeLiterals.length; i++) {
596
+ const literal = typeLiterals[i];
597
+ const variantName = `_${aliasName}_Variant_${i}`;
598
+ const fields = literal.members
599
+ .filter(ts.isPropertySignature)
600
+ .filter(m => ts.isIdentifier(m.name))
601
+ .map(m => ({
602
+ name: m.name.text,
603
+ cppType: typeNodeToCppType(m.type, typeAliasNodes),
604
+ }));
605
+ variants.push({ name: variantName, fields });
606
+ }
607
+ return variants;
608
+ }
@@ -0,0 +1,30 @@
1
+ import { ProgramIR } from "../api/index.js";
2
+ /**
3
+ * Configuration for entry point detection
4
+ */
5
+ export interface EntryPointConfig {
6
+ /** Default entry points when none are explicitly provided */
7
+ defaultEntryPoints: string[];
8
+ /** Additional custom entry points */
9
+ customEntryPoints: string[];
10
+ }
11
+ /**
12
+ * Detect entry points for a program.
13
+ *
14
+ * @param program The IR program to analyze
15
+ * @param config Entry point configuration
16
+ * @param entryPointNames Explicit entry point names (overrides config defaults).
17
+ * Derived from the platform strategy's `entrypointFunctionName()`
18
+ * and `requiresLoopFunction()` at the call site.
19
+ */
20
+ export declare function detectEntryPoints(program: ProgramIR, config?: Partial<EntryPointConfig>, entryPointNames?: string[]): Set<string>;
21
+ /**
22
+ * Detect symbols in a program that are imported by other files in the project.
23
+ * These become additional entry points for tree-shaking so they aren't
24
+ * eliminated as "unused" when they are only used externally.
25
+ *
26
+ * @param program The IR for one file
27
+ * @param importedByOtherFiles Symbol names that other files import from this one
28
+ * @returns Set of symbol names that should be treated as entry points
29
+ */
30
+ export declare function detectExportedEntryPoints(program: ProgramIR, importedByOtherFiles: Set<string>): Set<string>;