@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,48 @@
1
+ import { buildEmitterContext } from "./emitters/setup.js";
2
+ import { emitPreamble } from "./emitters/output-finalizer.js";
3
+ import { runTopLevelPreprocessing } from "./emitters/top-level-prep.js";
4
+ import { synthesizeEntrypoints } from "./emitters/entrypoint-synthesizer.js";
5
+ import { emitTypeDeclarations } from "./emitters/type-decl-emitter.js";
6
+ import { emitNamespaces } from "./emitters/namespace-emitter.js";
7
+ import { emitClasses } from "./emitters/class-emitter.js";
8
+ import { emitPostClassDeclarations, emitCallbackFunctions, emitFunctions, emitFunctionForwardDeclarations } from "./emitters/function-emitter-impl.js";
9
+ import { emitUIRuntime } from "./emitters/ui-emitter.js";
10
+ import { finalizeOutput } from "./emitters/output-finalizer.js";
11
+ const globalEnumNames = new Set();
12
+ const globalLargeEnumNames = new Set();
13
+ export function registerAllEnumNames(enums) {
14
+ for (const e of enums) {
15
+ globalEnumNames.add(e.name);
16
+ if (e.members && e.members.some((m) => m.value !== undefined && (m.value > 32767 || m.value < -32768))) {
17
+ globalLargeEnumNames.add(e.name);
18
+ }
19
+ }
20
+ }
21
+ export function emitCpp(program, options) {
22
+ // 1. Build shared emitter context (strategy, renderers, analysis, etc.)
23
+ const ctx = buildEmitterContext(program, options);
24
+ // 2. Emit preamble (includes, polyfills, async task classes, shims)
25
+ emitPreamble(ctx);
26
+ // 2.5. Emit UI runtime (header structs + static tables) — entry file only,
27
+ // when a UI is mounted. File-scope, must precede any function using it.
28
+ emitUIRuntime(ctx);
29
+ // 3. Run top-level preprocessing (timing promotion, ISR extraction, pointer tracking)
30
+ runTopLevelPreprocessing(ctx);
31
+ // 4. Synthesize entrypoint functions (setup/main/loop)
32
+ synthesizeEntrypoints(ctx);
33
+ // 5. Emit type declarations (enums, type aliases, interfaces, top-level constants)
34
+ emitTypeDeclarations(ctx);
35
+ // 6. Emit namespaces
36
+ emitNamespaces(ctx);
37
+ // 6.5. Emit function forward declarations (split mode — must precede class definitions)
38
+ emitFunctionForwardDeclarations(ctx);
39
+ // 7. Emit classes
40
+ emitClasses(ctx);
41
+ // 8. Emit post-class declarations (runtime vars, promoted vars, object literal structs)
42
+ emitPostClassDeclarations(ctx);
43
+ // 9. Emit callbacks + forward declarations + function definitions
44
+ emitCallbackFunctions(ctx);
45
+ emitFunctions(ctx);
46
+ // 10. Finalize output (write files, source maps, post-processing)
47
+ return finalizeOutput(ctx);
48
+ }
@@ -0,0 +1,2 @@
1
+ import type { EmitterContext } from "./emitter-context.js";
2
+ export declare function emitClasses(ctx: EmitterContext): void;
@@ -0,0 +1,523 @@
1
+ import { emitCommentLines } from "../utils/index.js";
2
+ import { appendSourceLine, appendRenderedStatement } from "./line-appender.js";
3
+ import { createChildEmissionScope } from "../snprintf-helpers.js";
4
+ import { escapeCppKeyword } from "../../utils/strings.js";
5
+ import { accessorGetterName, accessorSetterName } from "../utils/cpp-helpers.js";
6
+ import { parseCppType, parsedIsPointer, parsedIsVector, isStaticArray } from "../../api/shared/cpp-type-ir.js";
7
+ export function emitClasses(ctx) {
8
+ const { program, strategy, effectiveEmitMode, reservedNames, mappedFunctions, topLevelScope, exprRenderer, statementRenderer, isEntryFile } = ctx;
9
+ if (effectiveEmitMode === "split") {
10
+ const _swapLines = ctx.sourceLines;
11
+ ctx.sourceLines = ctx.headerLines;
12
+ ctx.headerLines = _swapLines;
13
+ const _swapMaps = ctx.sourceMapEntries;
14
+ ctx.sourceMapEntries = ctx.headerMapEntries;
15
+ ctx.headerMapEntries = _swapMaps;
16
+ }
17
+ const normalizeCppTypeForTarget = (cppType) => strategy.normalizeCppType(cppType);
18
+ const renderExpression = (expr, calleeTransformer) => exprRenderer.render(expr, calleeTransformer);
19
+ const renderParameters = (params, forHeader = false) => statementRenderer.renderParameters(params, forHeader);
20
+ const renderTypedName = (cppType, name) => statementRenderer.renderTypedName(cppType, name);
21
+ // Forward-declare locally-defined base classes
22
+ const localClassNames = new Set(program.classes.map(c => c.name));
23
+ const baseClassesNeeded = new Set();
24
+ for (const classDef of program.classes) {
25
+ if (classDef.extendsClass && !localClassNames.has(classDef.extendsClass)) {
26
+ // Base class from import — header handles it
27
+ }
28
+ else if (classDef.extendsClass && localClassNames.has(classDef.extendsClass)) {
29
+ baseClassesNeeded.add(classDef.extendsClass);
30
+ }
31
+ }
32
+ for (const classDef of program.classes) {
33
+ if (classDef.extendsClass && baseClassesNeeded.has(classDef.extendsClass)) {
34
+ const baseIdx = program.classes.findIndex(c => c.name === classDef.extendsClass);
35
+ const derivedIdx = program.classes.findIndex(c => c.name === classDef.name);
36
+ if (derivedIdx < baseIdx) {
37
+ appendSourceLine(ctx, `class ${classDef.extendsClass};`);
38
+ }
39
+ }
40
+ }
41
+ // Track static member names per class
42
+ const classStaticMembers = new Map();
43
+ for (const classDef of program.classes) {
44
+ const statics = new Set();
45
+ for (const method of classDef.methods) {
46
+ if (method.isStatic)
47
+ statics.add(method.name);
48
+ }
49
+ for (const field of classDef.fields) {
50
+ if (field.isStatic)
51
+ statics.add(field.name);
52
+ }
53
+ for (const getter of classDef.getters) {
54
+ if (getter.isStatic)
55
+ statics.add(getter.name);
56
+ }
57
+ for (const setter of classDef.setters) {
58
+ if (setter.isStatic)
59
+ statics.add(setter.name);
60
+ }
61
+ if (statics.size > 0) {
62
+ classStaticMembers.set(classDef.name, statics);
63
+ }
64
+ }
65
+ // String-typed variable tracking + C-array variable tracking
66
+ const stringVarTypes = new Set();
67
+ ctx.cArrayVarNames = new Set();
68
+ const fnCArrayVarNames = new Map();
69
+ const addCArrayIfNotMutable = (name, normalizedType, target) => {
70
+ if (!normalizedType.startsWith("StaticArray<")) {
71
+ target.add(name);
72
+ }
73
+ };
74
+ // Note: this intentionally matches only const char*/char*/String, NOT
75
+ // std::string — the latter is tracked separately as a "managed" string var.
76
+ const isStringLikeType = (t) => t === "const char*" || t === "char*" || t === "String";
77
+ for (const stmt of program.topLevelStatements) {
78
+ if (stmt.kind === "var_decl") {
79
+ const normalizedType = normalizeCppTypeForTarget(stmt.cppType);
80
+ if (isStringLikeType(normalizedType)) {
81
+ stringVarTypes.add(stmt.name);
82
+ }
83
+ if (stmt.initializer?.kind === "array") {
84
+ if (!parsedIsVector(normalizedType) || !strategy.needsStdVector()) {
85
+ addCArrayIfNotMutable(stmt.name, normalizedType, ctx.cArrayVarNames);
86
+ }
87
+ }
88
+ if (stmt.initializer?.kind === "spread_array") {
89
+ addCArrayIfNotMutable(stmt.name, normalizedType, ctx.cArrayVarNames);
90
+ }
91
+ }
92
+ }
93
+ for (let fi = 0; fi < mappedFunctions.length; fi++) {
94
+ const fn = mappedFunctions[fi];
95
+ const fnSet = new Set();
96
+ for (const stmt of fn.statements) {
97
+ if (stmt.kind === "var_decl") {
98
+ const normalizedType = normalizeCppTypeForTarget(stmt.cppType);
99
+ if (isStringLikeType(normalizedType)) {
100
+ stringVarTypes.add(stmt.name);
101
+ }
102
+ if (stmt.initializer?.kind === "array") {
103
+ if (!parsedIsVector(normalizedType) || !strategy.needsStdVector()) {
104
+ addCArrayIfNotMutable(stmt.name, normalizedType, fnSet);
105
+ }
106
+ }
107
+ if (stmt.initializer?.kind === "spread_array") {
108
+ addCArrayIfNotMutable(stmt.name, normalizedType, fnSet);
109
+ }
110
+ // Demo #17 Finding A — `new Uint8Array([...])` / `new Int8Array(N)`
111
+ // lowers to a raw C array var_decl whose cppType is a staticArray
112
+ // (e.g. `uint8_t[5]`) but whose initializer is NOT `kind: "array"`
113
+ // (it's a raw/text initializer). The `stmt.initializer?.kind === "array"`
114
+ // gate above therefore misses it, so `.length` on the buffer fell
115
+ // through to the invalid `buf.size()` (avr-g++: "request for member
116
+ // 'size' in 'buf', which is of non-class type 'uint8_t [5]'").
117
+ // Detect by cppType shape: a staticArray on a no-std::vector target is
118
+ // a raw C array → sizeof. (StaticArray<T,N> — the mutable promoted
119
+ // form — is excluded by addCArrayIfNotMutable and keeps its .size().)
120
+ if (!strategy.needsStdVector() && isStaticArray(parseCppType(normalizedType))) {
121
+ addCArrayIfNotMutable(stmt.name, normalizedType, fnSet);
122
+ }
123
+ }
124
+ }
125
+ fnCArrayVarNames.set(String(fi), fnSet);
126
+ }
127
+ ctx.fnCArrayVarNames = fnCArrayVarNames;
128
+ // Build class accessor name map
129
+ const classAccessorNames = new Map();
130
+ for (const classDef of program.classes) {
131
+ const accessors = new Map();
132
+ for (const g of classDef.getters) {
133
+ accessors.set(g.name, accessors.has(g.name) ? "both" : "getter");
134
+ }
135
+ for (const s of classDef.setters) {
136
+ accessors.set(s.name, accessors.has(s.name) ? "both" : "setter");
137
+ }
138
+ if (accessors.size > 0) {
139
+ classAccessorNames.set(classDef.name, accessors);
140
+ }
141
+ }
142
+ // Build variable → accessor map. NOTE: the variable/parameter registration
143
+ // now lives in setup.ts so it runs before any emit pass. The classAccessorNames
144
+ // map built here is still used below for the per-method "this" registration.
145
+ // See SUPPORT_MATRIX §4.3 (demo #4 fix).
146
+ // Build virtual/override maps for inherited methods
147
+ const classMethodNames = new Map();
148
+ for (const cls of program.classes) {
149
+ const names = new Set(cls.methods
150
+ .filter(m => !m.isStatic && !m.isAbstract)
151
+ .map(m => m.name));
152
+ classMethodNames.set(cls.name, names);
153
+ }
154
+ const virtualMethodNames = new Map();
155
+ for (const cls of program.classes) {
156
+ if (cls.extendsClass) {
157
+ const baseMethods = classMethodNames.get(cls.extendsClass);
158
+ if (baseMethods) {
159
+ for (const method of cls.methods) {
160
+ if (!method.isStatic && !method.isAbstract && baseMethods.has(method.name)) {
161
+ if (!virtualMethodNames.has(cls.extendsClass)) {
162
+ virtualMethodNames.set(cls.extendsClass, new Set());
163
+ }
164
+ virtualMethodNames.get(cls.extendsClass).add(method.name);
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+ const collectAllFields = (classDef) => {
171
+ const fields = [...classDef.fields];
172
+ if (classDef.extendsClass) {
173
+ const parent = program.classes.find((c) => c.name === classDef.extendsClass);
174
+ if (parent)
175
+ fields.push(...collectAllFields(parent));
176
+ }
177
+ return fields;
178
+ };
179
+ const addClassFieldsToScope = (classDef, scope) => {
180
+ for (const f of collectAllFields(classDef)) {
181
+ const normalizedFieldType = strategy.normalizeCppType(f.cppType);
182
+ scope.knownVariableTypes.set(f.name, { cppType: normalizedFieldType });
183
+ }
184
+ };
185
+ const withThisAccessors = (classDef, isStatic, fn) => {
186
+ const classAccessors = classAccessorNames.get(classDef.name);
187
+ if (classAccessors && !isStatic)
188
+ ctx.varAccessorNames.set("this", classAccessors);
189
+ fn();
190
+ if (classAccessors && !isStatic)
191
+ ctx.varAccessorNames.delete("this");
192
+ };
193
+ // Emit each class
194
+ for (const classDef of program.classes) {
195
+ emitCommentLines(classDef.leadingComments, "", (line) => appendSourceLine(ctx, line));
196
+ const inheritanceParts = [];
197
+ if (classDef.extendsClass) {
198
+ inheritanceParts.push(`public ${classDef.extendsClass}`);
199
+ }
200
+ const inheritanceClause = inheritanceParts.length > 0 ? ` : ${inheritanceParts.join(", ")}` : "";
201
+ if (classDef.isAbstract) {
202
+ appendSourceLine(ctx, `// Abstract class - contains pure virtual methods`);
203
+ }
204
+ if (classDef.decorators && classDef.decorators.length > 0) {
205
+ for (const dec of classDef.decorators) {
206
+ if (dec === "sealed")
207
+ appendSourceLine(ctx, `// @sealed → class marked final`);
208
+ else if (dec === "deprecated")
209
+ appendSourceLine(ctx, `[[deprecated]]`);
210
+ else if (dec === "nodiscard")
211
+ appendSourceLine(ctx, `[[nodiscard]]`);
212
+ }
213
+ }
214
+ if (classDef.decorators && classDef.decorators.includes("sealed")) {
215
+ if (classDef.typeParameters && classDef.typeParameters.length > 0) {
216
+ appendSourceLine(ctx, `template<typename ${classDef.typeParameters.join(", typename ")}>`);
217
+ }
218
+ appendSourceLine(ctx, `class ${classDef.name}${inheritanceClause} final {`);
219
+ }
220
+ else {
221
+ if (classDef.typeParameters && classDef.typeParameters.length > 0) {
222
+ appendSourceLine(ctx, `template<typename ${classDef.typeParameters.join(", typename ")}>`);
223
+ }
224
+ appendSourceLine(ctx, `class ${classDef.name}${inheritanceClause} {`);
225
+ }
226
+ const publicFields = classDef.fields.filter(f => f.visibility === "public");
227
+ const privateFields = classDef.fields.filter(f => f.visibility === "private");
228
+ const protectedFields = classDef.fields.filter(f => f.visibility === "protected");
229
+ const publicMethods = classDef.methods.filter(m => m.visibility === "public");
230
+ const privateMethods = classDef.methods.filter(m => m.visibility === "private");
231
+ const protectedMethods = classDef.methods.filter(m => m.visibility === "protected");
232
+ const publicGetters = classDef.getters.filter(g => g.visibility === "public");
233
+ const publicSetters = classDef.setters.filter(s => s.visibility === "public");
234
+ const privateGetters = classDef.getters.filter(g => g.visibility === "private");
235
+ const privateSetters = classDef.setters.filter(s => s.visibility === "private");
236
+ const protectedGetters = classDef.getters.filter(g => g.visibility === "protected");
237
+ const protectedSetters = classDef.setters.filter(s => s.visibility === "protected");
238
+ const classPointerFieldNames = classDef.fields
239
+ .filter(f => parsedIsPointer(f.cppType))
240
+ .map(f => f.name);
241
+ ctx.currentClassPointerFields = classPointerFieldNames.length > 0 ? classPointerFieldNames : undefined;
242
+ const classPointerFieldTypes = new Map();
243
+ for (const f of classDef.fields) {
244
+ if (parsedIsPointer(f.cppType)) {
245
+ classPointerFieldTypes.set(f.name, f.cppType);
246
+ }
247
+ }
248
+ ctx.currentClassPointerFieldTypes = classPointerFieldTypes.size > 0 ? classPointerFieldTypes : undefined;
249
+ const needsPublicSection = publicFields.length > 0 || publicMethods.length > 0 || publicGetters.length > 0 || publicSetters.length > 0 || classDef.constructor || ctx.callbackFunctions.length > 0;
250
+ if (needsPublicSection) {
251
+ appendSourceLine(ctx, "public:");
252
+ if (ctx.callbackFunctions.length > 0) {
253
+ for (const callback of ctx.callbackFunctions) {
254
+ // Friend declaration must match the synthesized callback's actual
255
+ // signature (void name() for ISRs, or R name(args) for typed
256
+ // std::function-callback lambdas). See renderCallbackSignature in
257
+ // function-emitter-impl.ts.
258
+ const fret = callback.returnType && callback.returnType !== "void" ? callback.returnType : "void";
259
+ const fparams = (callback.typedParams ?? []).map((p) => `${p.cppType} ${p.name}`).join(", ");
260
+ appendSourceLine(ctx, ` friend ${fret} ${callback.name}(${fparams});`);
261
+ }
262
+ appendSourceLine(ctx, "");
263
+ }
264
+ if (classDef.constructor) {
265
+ const ctorParamsMapped = classDef.constructor.parameters.map(p => ({
266
+ ...p,
267
+ cppType: normalizeCppTypeForTarget(p.cppType)
268
+ }));
269
+ const ctorParams = renderParameters(ctorParamsMapped);
270
+ let ctorInitializer = "";
271
+ let ctorStatements = classDef.constructor.statements;
272
+ const firstCtorStatement = ctorStatements[0];
273
+ if (classDef.extendsClass && firstCtorStatement && firstCtorStatement.kind === "super_call") {
274
+ const baseArgs = firstCtorStatement.args.map((arg) => renderExpression(arg, ctx.fixPointerFieldAccess)).join(", ");
275
+ ctorInitializer = ` : ${classDef.extendsClass}(${baseArgs})`;
276
+ ctorStatements = ctorStatements.slice(1);
277
+ }
278
+ appendSourceLine(ctx, ` ${classDef.name}(${ctorParams})${ctorInitializer} {`);
279
+ const ctorScope = createChildEmissionScope(topLevelScope, classDef.constructor.parameters);
280
+ addClassFieldsToScope(classDef, ctorScope);
281
+ const classAccessors = classAccessorNames.get(classDef.name);
282
+ if (classAccessors)
283
+ ctx.varAccessorNames.set("this", classAccessors);
284
+ for (const stmt of ctorStatements) {
285
+ appendRenderedStatement(ctx, stmt, " ", ctorScope);
286
+ }
287
+ if (classAccessors)
288
+ ctx.varAccessorNames.delete("this");
289
+ appendSourceLine(ctx, " }");
290
+ appendSourceLine(ctx, "");
291
+ }
292
+ // Class-typed fields are references, not implicitly owned allocations.
293
+ // Deleting every pointer field here double-frees borrowed constructor
294
+ // parameters and breaks aliasing. Only bases used polymorphically need a
295
+ // generated destructor, and the default destructor is sufficient.
296
+ if (program.classes.some((candidate) => candidate.extendsClass === classDef.name)) {
297
+ appendSourceLine(ctx, ` virtual ~${classDef.name}() = default;`);
298
+ appendSourceLine(ctx, "");
299
+ }
300
+ for (const field of publicFields) {
301
+ const initSuffix = field.initializer ? ` = ${renderExpression(field.initializer, undefined)}` : "";
302
+ const fieldType = strategy.overrideClassFieldType(field.name, normalizeCppTypeForTarget(field.cppType));
303
+ // `static inline` lets an initialized static field live entirely in the
304
+ // header (C++17) — required because this transpiler emits class bodies
305
+ // inline rather than splitting decl/defn across .h/.cpp.
306
+ const staticPrefix = field.isStatic ? "static inline " : "";
307
+ appendSourceLine(ctx, ` ${staticPrefix}${renderTypedName(fieldType, field.name)}${initSuffix};`);
308
+ }
309
+ if (publicFields.length > 0)
310
+ appendSourceLine(ctx, "");
311
+ for (const method of publicMethods) {
312
+ const methodParams = renderParameters(method.parameters);
313
+ const staticPrefix = method.isStatic ? "static " : "";
314
+ const returnType = normalizeCppTypeForTarget(method.returnType);
315
+ if (method.isAbstract) {
316
+ appendSourceLine(ctx, ` virtual ${returnType} ${escapeCppKeyword(method.name, reservedNames)}(${methodParams}) = 0;`);
317
+ appendSourceLine(ctx, "");
318
+ continue;
319
+ }
320
+ const virtualSet = virtualMethodNames.get(classDef.name);
321
+ const isVirtual = !method.isStatic && virtualSet?.has(method.name);
322
+ const virtualPrefix = isVirtual ? "virtual " : "";
323
+ const baseMethods = classDef.extendsClass ? classMethodNames.get(classDef.extendsClass) : undefined;
324
+ const isOverrideMethod = !method.isStatic && (method.isOverride || baseMethods?.has(method.name));
325
+ const overrideSuffix = isOverrideMethod ? " override" : "";
326
+ if (method.typeParameters && method.typeParameters.length > 0) {
327
+ appendSourceLine(ctx, ` template<typename ${method.typeParameters.join(", typename ")}>`);
328
+ }
329
+ appendSourceLine(ctx, ` ${virtualPrefix}${staticPrefix}${returnType} ${escapeCppKeyword(method.name, reservedNames)}(${methodParams})${overrideSuffix} {`);
330
+ const methodScope = createChildEmissionScope(topLevelScope, method.parameters);
331
+ addClassFieldsToScope(classDef, methodScope);
332
+ const classAccessors = classAccessorNames.get(classDef.name);
333
+ if (classAccessors && !method.isStatic)
334
+ ctx.varAccessorNames.set("this", classAccessors);
335
+ for (const stmt of method.statements) {
336
+ appendRenderedStatement(ctx, stmt, " ", methodScope);
337
+ }
338
+ if (classAccessors && !method.isStatic)
339
+ ctx.varAccessorNames.delete("this");
340
+ appendSourceLine(ctx, " }");
341
+ appendSourceLine(ctx, "");
342
+ }
343
+ for (const getter of publicGetters) {
344
+ const staticPrefix = getter.isStatic ? "static " : "";
345
+ const returnType = normalizeCppTypeForTarget(getter.returnType);
346
+ const getterName = accessorGetterName(getter.name);
347
+ // A `const` cv-qualifier is illegal on a static member function
348
+ // (g++: "static member function ... cannot have cv-qualifier"). Only
349
+ // add `const` for instance getters.
350
+ const constQualifier = getter.isStatic ? "" : " const";
351
+ appendSourceLine(ctx, ` ${staticPrefix}${returnType} ${getterName}()${constQualifier} {`);
352
+ const getterScope = createChildEmissionScope(topLevelScope, []);
353
+ addClassFieldsToScope(classDef, getterScope);
354
+ withThisAccessors(classDef, getter.isStatic, () => {
355
+ for (const stmt of getter.statements) {
356
+ appendRenderedStatement(ctx, stmt, " ", getterScope);
357
+ }
358
+ });
359
+ appendSourceLine(ctx, " }");
360
+ appendSourceLine(ctx, "");
361
+ }
362
+ for (const setter of publicSetters) {
363
+ const staticPrefix = setter.isStatic ? "static " : "";
364
+ const paramType = normalizeCppTypeForTarget(setter.parameter.cppType);
365
+ const setterName = accessorSetterName(setter.name);
366
+ appendSourceLine(ctx, ` ${staticPrefix}void ${setterName}(${paramType} ${setter.parameter.name}) {`);
367
+ const setterScope = createChildEmissionScope(topLevelScope, [setter.parameter]);
368
+ addClassFieldsToScope(classDef, setterScope);
369
+ withThisAccessors(classDef, setter.isStatic, () => {
370
+ for (const stmt of setter.statements) {
371
+ appendRenderedStatement(ctx, stmt, " ", setterScope);
372
+ }
373
+ });
374
+ appendSourceLine(ctx, " }");
375
+ appendSourceLine(ctx, "");
376
+ }
377
+ }
378
+ // Private section
379
+ if (privateFields.length > 0 || privateMethods.length > 0 || privateGetters.length > 0 || privateSetters.length > 0) {
380
+ appendSourceLine(ctx, "private:");
381
+ for (const field of privateFields) {
382
+ const initSuffix = field.initializer ? ` = ${renderExpression(field.initializer, undefined)}` : "";
383
+ const fieldType = strategy.overrideClassFieldType(field.name, normalizeCppTypeForTarget(field.cppType));
384
+ const staticPrefix = field.isStatic ? "static inline " : "";
385
+ appendSourceLine(ctx, ` ${staticPrefix}${renderTypedName(fieldType, field.name)}${initSuffix};`);
386
+ }
387
+ if (privateFields.length > 0)
388
+ appendSourceLine(ctx, "");
389
+ for (const method of privateMethods) {
390
+ const methodParams = renderParameters(method.parameters);
391
+ const staticPrefix = method.isStatic ? "static " : "";
392
+ const virtualSet = virtualMethodNames.get(classDef.name);
393
+ const isVirtual = !method.isStatic && virtualSet?.has(method.name);
394
+ const virtualPrefix = isVirtual ? "virtual " : "";
395
+ const baseMethods = classDef.extendsClass ? classMethodNames.get(classDef.extendsClass) : undefined;
396
+ const isOverrideMethod = !method.isStatic && (method.isOverride || baseMethods?.has(method.name));
397
+ const overrideSuffix = isOverrideMethod ? " override" : "";
398
+ if (method.typeParameters && method.typeParameters.length > 0) {
399
+ appendSourceLine(ctx, ` template<typename ${method.typeParameters.join(", typename ")}>`);
400
+ }
401
+ appendSourceLine(ctx, ` ${virtualPrefix}${staticPrefix}${normalizeCppTypeForTarget(method.returnType)} ${escapeCppKeyword(method.name, reservedNames)}(${methodParams})${overrideSuffix} {`);
402
+ const methodScope = createChildEmissionScope(topLevelScope, method.parameters);
403
+ addClassFieldsToScope(classDef, methodScope);
404
+ withThisAccessors(classDef, method.isStatic, () => {
405
+ for (const stmt of method.statements) {
406
+ appendRenderedStatement(ctx, stmt, " ", methodScope);
407
+ }
408
+ });
409
+ appendSourceLine(ctx, " }");
410
+ appendSourceLine(ctx, "");
411
+ }
412
+ for (const getter of privateGetters) {
413
+ const staticPrefix = getter.isStatic ? "static " : "";
414
+ const returnType = normalizeCppTypeForTarget(getter.returnType);
415
+ const getterName = accessorGetterName(getter.name);
416
+ const constQualifier = getter.isStatic ? "" : " const";
417
+ appendSourceLine(ctx, ` ${staticPrefix}${returnType} ${getterName}()${constQualifier} {`);
418
+ const getterScope = createChildEmissionScope(topLevelScope, []);
419
+ addClassFieldsToScope(classDef, getterScope);
420
+ withThisAccessors(classDef, getter.isStatic, () => {
421
+ for (const stmt of getter.statements) {
422
+ appendRenderedStatement(ctx, stmt, " ", getterScope);
423
+ }
424
+ });
425
+ appendSourceLine(ctx, " }");
426
+ appendSourceLine(ctx, "");
427
+ }
428
+ for (const setter of privateSetters) {
429
+ const staticPrefix = setter.isStatic ? "static " : "";
430
+ const paramType = normalizeCppTypeForTarget(setter.parameter.cppType);
431
+ const setterName = accessorSetterName(setter.name);
432
+ appendSourceLine(ctx, ` ${staticPrefix}void ${setterName}(${paramType} ${setter.parameter.name}) {`);
433
+ const setterScope = createChildEmissionScope(topLevelScope, [setter.parameter]);
434
+ addClassFieldsToScope(classDef, setterScope);
435
+ withThisAccessors(classDef, setter.isStatic, () => {
436
+ for (const stmt of setter.statements) {
437
+ appendRenderedStatement(ctx, stmt, " ", setterScope);
438
+ }
439
+ });
440
+ appendSourceLine(ctx, " }");
441
+ appendSourceLine(ctx, "");
442
+ }
443
+ }
444
+ // Protected section
445
+ if (protectedFields.length > 0 || protectedMethods.length > 0 || protectedGetters.length > 0 || protectedSetters.length > 0) {
446
+ appendSourceLine(ctx, "protected:");
447
+ for (const field of protectedFields) {
448
+ const initSuffix = field.initializer ? ` = ${renderExpression(field.initializer, undefined)}` : "";
449
+ const fieldType = strategy.overrideClassFieldType(field.name, normalizeCppTypeForTarget(field.cppType));
450
+ const staticPrefix = field.isStatic ? "static inline " : "";
451
+ appendSourceLine(ctx, ` ${staticPrefix}${renderTypedName(fieldType, field.name)}${initSuffix};`);
452
+ }
453
+ if (protectedFields.length > 0)
454
+ appendSourceLine(ctx, "");
455
+ for (const method of protectedMethods) {
456
+ const methodParams = renderParameters(method.parameters);
457
+ const staticPrefix = method.isStatic ? "static " : "";
458
+ const virtualSet = virtualMethodNames.get(classDef.name);
459
+ const isVirtual = !method.isStatic && virtualSet?.has(method.name);
460
+ const virtualPrefix = isVirtual ? "virtual " : "";
461
+ const baseMethods = classDef.extendsClass ? classMethodNames.get(classDef.extendsClass) : undefined;
462
+ const isOverrideMethod = !method.isStatic && (method.isOverride || baseMethods?.has(method.name));
463
+ const overrideSuffix = isOverrideMethod ? " override" : "";
464
+ if (method.typeParameters && method.typeParameters.length > 0) {
465
+ appendSourceLine(ctx, ` template<typename ${method.typeParameters.join(", typename ")}>`);
466
+ }
467
+ appendSourceLine(ctx, ` ${virtualPrefix}${staticPrefix}${normalizeCppTypeForTarget(method.returnType)} ${escapeCppKeyword(method.name, reservedNames)}(${methodParams})${overrideSuffix} {`);
468
+ const methodScope = createChildEmissionScope(topLevelScope, method.parameters);
469
+ addClassFieldsToScope(classDef, methodScope);
470
+ withThisAccessors(classDef, method.isStatic, () => {
471
+ for (const stmt of method.statements) {
472
+ appendRenderedStatement(ctx, stmt, " ", methodScope);
473
+ }
474
+ });
475
+ appendSourceLine(ctx, " }");
476
+ appendSourceLine(ctx, "");
477
+ }
478
+ for (const getter of protectedGetters) {
479
+ const staticPrefix = getter.isStatic ? "static " : "";
480
+ const returnType = normalizeCppTypeForTarget(getter.returnType);
481
+ const getterName = accessorGetterName(getter.name);
482
+ appendSourceLine(ctx, ` ${staticPrefix}${returnType} ${getterName}() const {`);
483
+ const getterScope = createChildEmissionScope(topLevelScope, []);
484
+ addClassFieldsToScope(classDef, getterScope);
485
+ withThisAccessors(classDef, getter.isStatic, () => {
486
+ for (const stmt of getter.statements) {
487
+ appendRenderedStatement(ctx, stmt, " ", getterScope);
488
+ }
489
+ });
490
+ appendSourceLine(ctx, " }");
491
+ appendSourceLine(ctx, "");
492
+ }
493
+ for (const setter of protectedSetters) {
494
+ const staticPrefix = setter.isStatic ? "static " : "";
495
+ const paramType = normalizeCppTypeForTarget(setter.parameter.cppType);
496
+ const setterName = accessorSetterName(setter.name);
497
+ appendSourceLine(ctx, ` ${staticPrefix}void ${setterName}(${paramType} ${setter.parameter.name}) {`);
498
+ const setterScope = createChildEmissionScope(topLevelScope, [setter.parameter]);
499
+ addClassFieldsToScope(classDef, setterScope);
500
+ withThisAccessors(classDef, setter.isStatic, () => {
501
+ for (const stmt of setter.statements) {
502
+ appendRenderedStatement(ctx, stmt, " ", setterScope);
503
+ }
504
+ });
505
+ appendSourceLine(ctx, " }");
506
+ appendSourceLine(ctx, "");
507
+ }
508
+ }
509
+ appendSourceLine(ctx, "};");
510
+ emitCommentLines(classDef.trailingComments, "", (line) => appendSourceLine(ctx, line));
511
+ appendSourceLine(ctx, "");
512
+ ctx.currentClassPointerFields = undefined;
513
+ ctx.currentClassPointerFieldTypes = undefined;
514
+ }
515
+ if (effectiveEmitMode === "split") {
516
+ const _swapLines = ctx.sourceLines;
517
+ ctx.sourceLines = ctx.headerLines;
518
+ ctx.headerLines = _swapLines;
519
+ const _swapMaps = ctx.sourceMapEntries;
520
+ ctx.sourceMapEntries = ctx.headerMapEntries;
521
+ ctx.headerMapEntries = _swapMaps;
522
+ }
523
+ }