@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,584 @@
1
+ /**
2
+ * C++ to TypeScript Declaration Generator
3
+ *
4
+ * Parses simple C++ class definitions and generates .d.ts declaration files
5
+ * for use with TypeCAD's native module support.
6
+ */
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import { parseHeader } from "./header-parser.js";
10
+ import { buildClassIndex, BaseClassResolver } from "./base-class-resolver.js";
11
+ /**
12
+ * Maps C++ types to TypeScript types
13
+ */
14
+ function mapCppTypeToTs(cppType) {
15
+ const trimmed = cppType.trim();
16
+ // Remove const qualifier
17
+ const withoutConst = trimmed.replace(/^const\s+/, "");
18
+ // Basic type mappings
19
+ const typeMap = {
20
+ "int": "number",
21
+ "unsigned int": "number",
22
+ "uint8_t": "number",
23
+ "uint16_t": "number",
24
+ "uint32_t": "number",
25
+ "int8_t": "number",
26
+ "int16_t": "number",
27
+ "int32_t": "number",
28
+ "float": "number",
29
+ "double": "number",
30
+ "bool": "boolean",
31
+ "void": "void",
32
+ "char": "string",
33
+ "char*": "string",
34
+ "const char*": "string",
35
+ "std::string": "string",
36
+ "String": "string",
37
+ };
38
+ // Check direct mapping
39
+ if (typeMap[withoutConst]) {
40
+ return typeMap[withoutConst];
41
+ }
42
+ // Handle pointers (treat as number for simplicity)
43
+ if (withoutConst.endsWith("*")) {
44
+ return "number";
45
+ }
46
+ // Handle references
47
+ if (withoutConst.endsWith("&")) {
48
+ const baseType = withoutConst.slice(0, -1).trim();
49
+ return mapCppTypeToTs(baseType);
50
+ }
51
+ // Default to any for unknown types
52
+ return "any";
53
+ }
54
+ /**
55
+ * Extracts the parameter list from a function signature
56
+ */
57
+ function parseParameters(paramString) {
58
+ if (!paramString.trim()) {
59
+ return [];
60
+ }
61
+ const params = [];
62
+ const parts = paramString.split(",");
63
+ for (const part of parts) {
64
+ const trimmed = part.trim();
65
+ if (!trimmed)
66
+ continue;
67
+ // Handle default values (remove them for the declaration)
68
+ const withoutDefault = trimmed.split("=")[0].trim();
69
+ // Split into tokens to find type and name
70
+ const tokens = withoutDefault.split(/\s+/);
71
+ if (tokens.length >= 2) {
72
+ // C++ lets pointer/reference markers attach to either the type
73
+ // (`char* label`) or the name (`char *label`), and arrays appear as a
74
+ // trailing `[]` on the name. Peel leading `*`/`&` and trailing `[]`
75
+ // off the name token back onto the type, so the emitted name is a
76
+ // valid TS identifier and the type still routes through
77
+ // mapCppTypeToTs (which maps pointers/refs appropriately).
78
+ let name = tokens[tokens.length - 1];
79
+ const typeParts = tokens.slice(0, -1);
80
+ const prefix = [];
81
+ while (/^[*&]/.test(name)) {
82
+ prefix.push(name[0]);
83
+ name = name.slice(1);
84
+ }
85
+ let arrayMarker = "";
86
+ if (/\[\]$/.test(name)) {
87
+ arrayMarker = "*";
88
+ name = name.replace(/\[\]$/, "");
89
+ }
90
+ if (prefix.length > 0 || arrayMarker) {
91
+ typeParts.push(prefix.join("") + arrayMarker);
92
+ }
93
+ const type = typeParts.join(" ").trim();
94
+ params.push({ type: mapCppTypeToTs(type), name });
95
+ }
96
+ else if (tokens.length === 1) {
97
+ // Just a type (unnamed parameter)
98
+ params.push({ type: mapCppTypeToTs(tokens[0]), name: "" });
99
+ }
100
+ }
101
+ return params;
102
+ }
103
+ /**
104
+ * Parses a C++ class definition
105
+ */
106
+ function parseCppClass(content) {
107
+ const result = {
108
+ classes: [],
109
+ constants: [],
110
+ };
111
+ // Parse top-level constants: const int NAME = value;
112
+ const constRegex = /const\s+(\w+)\s+(\w+)\s*=\s*([^;]+);/g;
113
+ let constMatch;
114
+ while ((constMatch = constRegex.exec(content)) !== null) {
115
+ result.constants.push({
116
+ type: mapCppTypeToTs(constMatch[1]),
117
+ name: constMatch[2],
118
+ value: constMatch[3].trim(),
119
+ });
120
+ }
121
+ // Parse methods with scope resolution (ClassName::methodName) - for .cpp implementation files
122
+ // This handles cases where the class is defined in a header but implemented in .cpp
123
+ const scopeResolutionRegex = /(?:^|\n)\s*(?:(\w+(?:\s*[*&])?)\s+)?(\w+)::(\w+)\s*\(([^)]*)\)\s*(?:const\s*)?(?:\{|;)/g;
124
+ let scopeMatch;
125
+ const classesFromImpl = new Map();
126
+ while ((scopeMatch = scopeResolutionRegex.exec(content)) !== null) {
127
+ const returnType = scopeMatch[1]?.trim();
128
+ const className = scopeMatch[2];
129
+ const methodName = scopeMatch[3];
130
+ const params = scopeMatch[4];
131
+ // Skip if this looks like a namespace (e.g., std::something)
132
+ if (!returnType && className.toLowerCase() === className) {
133
+ continue;
134
+ }
135
+ if (!classesFromImpl.has(className)) {
136
+ classesFromImpl.set(className, {
137
+ name: className,
138
+ methods: [],
139
+ constructors: [],
140
+ source: "cpp",
141
+ });
142
+ }
143
+ const cppClass = classesFromImpl.get(className);
144
+ // Check if this is a constructor (method name matches class name)
145
+ if (methodName === className) {
146
+ cppClass.constructors.push({
147
+ parameters: parseParameters(params),
148
+ });
149
+ }
150
+ else if (returnType) {
151
+ cppClass.methods.push({
152
+ returnType: mapCppTypeToTs(returnType),
153
+ name: methodName,
154
+ parameters: parseParameters(params),
155
+ isPublic: true, // Assume public for implementation files
156
+ });
157
+ }
158
+ }
159
+ // Add inferred classes to result
160
+ for (const cppClass of classesFromImpl.values()) {
161
+ result.classes.push(cppClass);
162
+ }
163
+ // Parse class definitions - handle nested braces properly
164
+ // Find class keyword and then find matching closing brace
165
+ const classStartRegex = /\bclass\s+(\w+)\s*\{/g;
166
+ let classStartMatch;
167
+ while ((classStartMatch = classStartRegex.exec(content)) !== null) {
168
+ const className = classStartMatch[1];
169
+ const startIndex = classStartMatch.index + classStartMatch[0].length;
170
+ // Find matching closing brace
171
+ let braceCount = 1;
172
+ let endIndex = startIndex;
173
+ for (let i = startIndex; i < content.length && braceCount > 0; i++) {
174
+ if (content[i] === '{')
175
+ braceCount++;
176
+ if (content[i] === '}')
177
+ braceCount--;
178
+ endIndex = i;
179
+ }
180
+ const classBody = content.slice(startIndex, endIndex);
181
+ const cppClass = {
182
+ name: className,
183
+ methods: [],
184
+ constructors: [],
185
+ source: "cpp",
186
+ };
187
+ // Track current access level
188
+ let isPublic = false;
189
+ // Parse declarations within the class body
190
+ // Match constructors and methods: type name(params) or name(params)
191
+ // Need to handle multi-line declarations
192
+ // First, normalize whitespace
193
+ const normalizedBody = classBody.replace(/\s+/g, ' ');
194
+ // Split by method/constructor definitions (look for patterns ending with { or ;)
195
+ // Pattern: type name(params) { body } or type name(params);
196
+ const methodRegex = /(\w+(?:\s*[*&])?)\s+(\w+)\s*\(([^)]*)\)\s*(?:const\s*)?(?:\{|;)/g;
197
+ let methodMatch;
198
+ // Also look for access specifiers
199
+ const accessRegex = /(public|private|protected)\s*:/g;
200
+ // Process the class body by scanning for declarations
201
+ let lastIndex = 0;
202
+ const segments = [];
203
+ let currentIsPublic = false;
204
+ // Split by access specifiers
205
+ const bodyWithAccess = normalizedBody.split(/(public:|private:|protected:)/);
206
+ for (let i = 0; i < bodyWithAccess.length; i++) {
207
+ const segment = bodyWithAccess[i].trim();
208
+ if (segment === 'public:') {
209
+ currentIsPublic = true;
210
+ }
211
+ else if (segment === 'private:' || segment === 'protected:') {
212
+ currentIsPublic = false;
213
+ }
214
+ else if (segment) {
215
+ segments.push({ text: segment, isPublic: currentIsPublic });
216
+ }
217
+ }
218
+ // Process each segment for methods and constructors
219
+ for (const segment of segments) {
220
+ // Match methods with return type: type name(params)
221
+ const methodMatches = segment.text.matchAll(/(\w+(?:\s*[*&])?)\s+(\w+)\s*\(([^)]*)\)\s*(?:const\s*)?(?:\{|;)/g);
222
+ for (const match of methodMatches) {
223
+ const returnType = match[1].trim();
224
+ const name = match[2].trim();
225
+ const params = match[3];
226
+ // Check if this is a constructor (name matches class name)
227
+ if (name === className) {
228
+ cppClass.constructors.push({
229
+ parameters: parseParameters(params),
230
+ });
231
+ }
232
+ else {
233
+ cppClass.methods.push({
234
+ returnType: mapCppTypeToTs(returnType),
235
+ name,
236
+ parameters: parseParameters(params),
237
+ isPublic: segment.isPublic,
238
+ });
239
+ }
240
+ }
241
+ // Also match constructors without return type: ClassName(params)
242
+ const ctorRegex = new RegExp(`\\b(${className})\\s*\\(([^)]*)\\)\\s*(?:\\{|;)`, 'g');
243
+ const ctorMatches = segment.text.matchAll(ctorRegex);
244
+ for (const match of ctorMatches) {
245
+ const params = match[2];
246
+ // Check if we already have this constructor (avoid duplicates)
247
+ const existingCtor = cppClass.constructors.find(c => c.parameters.length === parseParameters(params).length);
248
+ if (!existingCtor) {
249
+ cppClass.constructors.push({
250
+ parameters: parseParameters(params),
251
+ });
252
+ }
253
+ }
254
+ }
255
+ result.classes.push(cppClass);
256
+ }
257
+ return result;
258
+ }
259
+ /**
260
+ * Generates TypeScript declaration content from parsed C++
261
+ */
262
+ function generateDeclaration(parsed, moduleDocstring) {
263
+ const lines = [];
264
+ // Add docstring if provided
265
+ if (moduleDocstring) {
266
+ lines.push(`/** ${moduleDocstring} */`);
267
+ }
268
+ // Export constants
269
+ for (const constant of parsed.constants) {
270
+ lines.push(`export declare const ${constant.name}: ${constant.type};`);
271
+ }
272
+ if (parsed.constants.length > 0 && parsed.classes.length > 0) {
273
+ lines.push("");
274
+ }
275
+ // Export classes
276
+ for (const cppClass of parsed.classes) {
277
+ const extendsClause = cppClass.baseClass ? ` extends ${cppClass.baseClass}` : "";
278
+ lines.push(`export declare class ${cppClass.name}${extendsClause} {`);
279
+ // Add constructors
280
+ for (const ctor of cppClass.constructors) {
281
+ const params = ctor.parameters
282
+ .filter(p => p.name)
283
+ .map(p => `${p.name}: ${p.type}`)
284
+ .join(", ");
285
+ lines.push(` constructor(${params});`);
286
+ }
287
+ // Add public methods
288
+ const publicMethods = cppClass.methods.filter(m => m.isPublic);
289
+ for (const method of publicMethods) {
290
+ const params = method.parameters
291
+ .filter(p => p.name)
292
+ .map(p => `${p.name}: ${p.type}`)
293
+ .join(", ");
294
+ lines.push(` ${method.name}(${params}): ${method.returnType};`);
295
+ }
296
+ lines.push("}");
297
+ }
298
+ return lines.join("\n") + "\n";
299
+ }
300
+ /**
301
+ * Backward-compat wrapper — delegates to generateDecl so legacy callers
302
+ * (e.g. cli.ts) keep resolving while the richer .h/.cpp merge lives in
303
+ * generateDecl.
304
+ */
305
+ export function generateDeclFromCpp(cppFilePath, outputPath) {
306
+ return generateDecl(cppFilePath, outputPath);
307
+ }
308
+ /**
309
+ * Scans a directory for .h and .cpp files and generates .d.ts files.
310
+ *
311
+ * Two passes:
312
+ * 1. Build a class-name → header-path index from all .h under dir.
313
+ * 2. For each .h (and .cpp with no sibling .h), parse + merge + emit with
314
+ * cross-file base resolution.
315
+ */
316
+ export function generateDeclsForDirectory(dir, recursive = true) {
317
+ const created = [];
318
+ if (!fs.existsSync(dir)) {
319
+ return created;
320
+ }
321
+ const index = buildClassIndex(dir);
322
+ const resolver = new BaseClassResolver(index);
323
+ const walk = (d) => {
324
+ const entries = fs.readdirSync(d, { withFileTypes: true });
325
+ for (const entry of entries) {
326
+ const full = path.join(d, entry.name);
327
+ if (entry.isDirectory() && recursive) {
328
+ walk(full);
329
+ continue;
330
+ }
331
+ if (!entry.isFile())
332
+ continue;
333
+ const lower = entry.name.toLowerCase();
334
+ if (lower.endsWith(".h")) {
335
+ const r = generateDeclWithResolver(full, resolver);
336
+ if (r)
337
+ created.push(r);
338
+ }
339
+ else if (lower.endsWith(".cpp")) {
340
+ // Skip .cpp files that have a sibling .h — the .h drives emission.
341
+ const cppBase = path.basename(full, ".cpp");
342
+ const siblingH = path.join(path.dirname(full), cppBase + ".h");
343
+ if (!fs.existsSync(siblingH)) {
344
+ const r = generateDeclWithResolver(full, resolver);
345
+ if (r)
346
+ created.push(r);
347
+ }
348
+ }
349
+ }
350
+ };
351
+ walk(dir);
352
+ return created;
353
+ }
354
+ /**
355
+ * Generates a .d.ts from a .h OR .cpp file.
356
+ *
357
+ * - For .h: parses the header; if a sibling .cpp exists, merges its
358
+ * impl-only methods (ClassName::method) into the header's classes.
359
+ * - For .cpp: if a sibling .h exists, parses the header and merges; else
360
+ * behaves as the legacy flattened path.
361
+ *
362
+ * Does NOT resolve cross-file base classes — bases from other headers are
363
+ * left as bare `extends Foo` (no import). Cross-file resolution is added in
364
+ * a later step for the directory-scan path.
365
+ */
366
+ export function generateDecl(filePath, outputPath) {
367
+ if (!fs.existsSync(filePath)) {
368
+ return null;
369
+ }
370
+ const ext = path.extname(filePath).toLowerCase();
371
+ const dir = path.dirname(filePath);
372
+ const baseNoExt = path.basename(filePath, ext);
373
+ let headerPath;
374
+ let cppPath;
375
+ if (ext === ".h") {
376
+ headerPath = filePath;
377
+ const siblingCpp = path.join(dir, baseNoExt + ".cpp");
378
+ cppPath = fs.existsSync(siblingCpp) ? siblingCpp : undefined;
379
+ }
380
+ else if (ext === ".cpp") {
381
+ cppPath = filePath;
382
+ const siblingH = path.join(dir, baseNoExt + ".h");
383
+ headerPath = fs.existsSync(siblingH) ? siblingH : undefined;
384
+ }
385
+ else {
386
+ return null;
387
+ }
388
+ let headerClasses = [];
389
+ if (headerPath) {
390
+ headerClasses = parseHeader(fs.readFileSync(headerPath, "utf8"));
391
+ }
392
+ let cppResult = { classes: [], constants: [] };
393
+ if (cppPath) {
394
+ cppResult = parseCppClass(fs.readFileSync(cppPath, "utf8"));
395
+ }
396
+ const merged = [];
397
+ const byName = new Map();
398
+ for (const h of headerClasses) {
399
+ const cls = {
400
+ name: h.name,
401
+ methods: [...h.methods],
402
+ constructors: [...h.constructors],
403
+ baseClass: h.baseClass,
404
+ source: "header",
405
+ };
406
+ byName.set(h.name, cls);
407
+ merged.push(cls);
408
+ }
409
+ for (const c of cppResult.classes) {
410
+ const existing = byName.get(c.name);
411
+ if (existing) {
412
+ for (const m of c.methods) {
413
+ if (!existing.methods.some(em => em.name === m.name)) {
414
+ existing.methods.push(m);
415
+ }
416
+ }
417
+ }
418
+ else if (!headerPath) {
419
+ // No sibling header: keep .cpp-inferred classes (legacy flattened path).
420
+ // When a header IS present, drop .cpp-only classes — they belong to
421
+ // other headers and would otherwise create false "same-file" bases
422
+ // (e.g. Adafruit_SPITFT inferred from Adafruit_ILI9341.cpp's
423
+ // Adafruit_SPITFT::readcommand8 scope resolution).
424
+ merged.push({ ...c, source: "cpp" });
425
+ }
426
+ }
427
+ if (merged.length === 0 && cppResult.constants.length === 0) {
428
+ return null;
429
+ }
430
+ // Single-file mode: no resolver → all cross-file bases are "external" →
431
+ // emitted as empty stubs so the .d.ts still compiles standalone.
432
+ const declaration = generateDeclarationWithResolver({ classes: merged, constants: cppResult.constants }, new BaseClassResolver(new Map()), filePath);
433
+ const outPath = outputPath || path.join(dir, baseNoExt + ".d.ts");
434
+ if (!fs.existsSync(outPath) || fs.readFileSync(outPath, "utf8") !== declaration) {
435
+ fs.writeFileSync(outPath, declaration, "utf8");
436
+ }
437
+ return outPath;
438
+ }
439
+ /**
440
+ * Like generateDeclaration, but resolves base classes against `resolver` and
441
+ * the emitting file path (for computing relative import paths).
442
+ *
443
+ * Emission order: imports → constants → stubs → classes.
444
+ */
445
+ function generateDeclarationWithResolver(parsed, resolver, emittingFilePath) {
446
+ const lines = [];
447
+ const importingFrom = new Map(); // baseName → POSIX import path
448
+ const stubs = new Set(); // unresolved base names
449
+ const classNames = new Set(parsed.classes.map(c => c.name));
450
+ // Classify each base.
451
+ for (const cls of parsed.classes) {
452
+ if (!cls.baseClass)
453
+ continue;
454
+ if (classNames.has(cls.baseClass))
455
+ continue; // same-file base
456
+ const r = resolver.resolve(cls.baseClass);
457
+ if (r.kind === "found") {
458
+ const targetDts = r.headerPath.replace(/\.h$/i, ".d.ts");
459
+ const rel = path.relative(path.dirname(emittingFilePath), path.dirname(targetDts));
460
+ const targetBase = path.basename(targetDts, ".d.ts");
461
+ const relPosix = (rel || ".").replace(/\\/g, "/");
462
+ const importPath = relPosix === "." ? `./${targetBase}` : `${relPosix}/${targetBase}`;
463
+ importingFrom.set(cls.baseClass, importPath);
464
+ }
465
+ else {
466
+ stubs.add(cls.baseClass);
467
+ }
468
+ }
469
+ // Imports.
470
+ for (const [baseName, importPath] of importingFrom) {
471
+ lines.push(`import type { ${baseName} } from "${importPath}";`);
472
+ }
473
+ if (importingFrom.size > 0)
474
+ lines.push("");
475
+ // Constants.
476
+ for (const constant of parsed.constants) {
477
+ lines.push(`export declare const ${constant.name}: ${constant.type};`);
478
+ }
479
+ if (parsed.constants.length > 0 && parsed.classes.length > 0)
480
+ lines.push("");
481
+ // Stubs for unresolved bases.
482
+ for (const stub of stubs) {
483
+ lines.push(`declare class ${stub} {}`);
484
+ }
485
+ if (stubs.size > 0)
486
+ lines.push("");
487
+ // Classes.
488
+ for (const cppClass of parsed.classes) {
489
+ const extendsClause = cppClass.baseClass ? ` extends ${cppClass.baseClass}` : "";
490
+ lines.push(`export declare class ${cppClass.name}${extendsClause} {`);
491
+ for (const ctor of cppClass.constructors) {
492
+ const params = ctor.parameters
493
+ .filter(p => p.name)
494
+ .map(p => `${p.name}: ${p.type}`)
495
+ .join(", ");
496
+ lines.push(` constructor(${params});`);
497
+ }
498
+ const publicMethods = cppClass.methods.filter(m => m.isPublic);
499
+ for (const method of publicMethods) {
500
+ const params = method.parameters
501
+ .filter(p => p.name)
502
+ .map(p => `${p.name}: ${p.type}`)
503
+ .join(", ");
504
+ lines.push(` ${method.name}(${params}): ${method.returnType};`);
505
+ }
506
+ lines.push("}");
507
+ }
508
+ return lines.join("\n") + "\n";
509
+ }
510
+ /**
511
+ * Like generateDecl, but resolves base classes against `resolver`: cross-file
512
+ * bases become `import type`; unresolved bases become empty stubs.
513
+ */
514
+ function generateDeclWithResolver(filePath, resolver) {
515
+ if (!fs.existsSync(filePath)) {
516
+ return null;
517
+ }
518
+ const ext = path.extname(filePath).toLowerCase();
519
+ const dir = path.dirname(filePath);
520
+ const baseNoExt = path.basename(filePath, ext);
521
+ let headerPath;
522
+ let cppPath;
523
+ if (ext === ".h") {
524
+ headerPath = filePath;
525
+ const siblingCpp = path.join(dir, baseNoExt + ".cpp");
526
+ cppPath = fs.existsSync(siblingCpp) ? siblingCpp : undefined;
527
+ }
528
+ else if (ext === ".cpp") {
529
+ cppPath = filePath;
530
+ const siblingH = path.join(dir, baseNoExt + ".h");
531
+ headerPath = fs.existsSync(siblingH) ? siblingH : undefined;
532
+ }
533
+ else {
534
+ return null;
535
+ }
536
+ let headerClasses = [];
537
+ if (headerPath) {
538
+ headerClasses = parseHeader(fs.readFileSync(headerPath, "utf8"));
539
+ }
540
+ let cppResult = { classes: [], constants: [] };
541
+ if (cppPath) {
542
+ cppResult = parseCppClass(fs.readFileSync(cppPath, "utf8"));
543
+ }
544
+ const merged = [];
545
+ const byName = new Map();
546
+ for (const h of headerClasses) {
547
+ const cls = {
548
+ name: h.name,
549
+ methods: [...h.methods],
550
+ constructors: [...h.constructors],
551
+ baseClass: h.baseClass,
552
+ source: "header",
553
+ };
554
+ byName.set(h.name, cls);
555
+ merged.push(cls);
556
+ }
557
+ for (const c of cppResult.classes) {
558
+ const existing = byName.get(c.name);
559
+ if (existing) {
560
+ for (const m of c.methods) {
561
+ if (!existing.methods.some(em => em.name === m.name)) {
562
+ existing.methods.push(m);
563
+ }
564
+ }
565
+ }
566
+ else if (!headerPath) {
567
+ // No sibling header: keep .cpp-inferred classes (legacy flattened path).
568
+ // When a header IS present, drop .cpp-only classes — they belong to
569
+ // other headers and would otherwise create false "same-file" bases
570
+ // (e.g. Adafruit_SPITFT inferred from Adafruit_ILI9341.cpp's
571
+ // Adafruit_SPITFT::readcommand8 scope resolution).
572
+ merged.push({ ...c, source: "cpp" });
573
+ }
574
+ }
575
+ if (merged.length === 0 && cppResult.constants.length === 0) {
576
+ return null;
577
+ }
578
+ const declaration = generateDeclarationWithResolver({ classes: merged, constants: cppResult.constants }, resolver, filePath);
579
+ const outPath = path.join(dir, baseNoExt + ".d.ts");
580
+ if (!fs.existsSync(outPath) || fs.readFileSync(outPath, "utf8") !== declaration) {
581
+ fs.writeFileSync(outPath, declaration, "utf8");
582
+ }
583
+ return outPath;
584
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Header parser for gen-decls.
3
+ *
4
+ * Parses C++ class declarations from .h files, capturing inheritance
5
+ * (`class X : public Y`) and stripping #if/#ifdef/#ifndef preprocessor
6
+ * blocks before parsing. See
7
+ * docs/superpowers/specs/2026-06-20-gen-decls-inheritance-design.md.
8
+ */
9
+ /** A single method/constructor signature. */
10
+ export interface ClassMethod {
11
+ name: string;
12
+ returnType: string;
13
+ parameters: {
14
+ type: string;
15
+ name: string;
16
+ }[];
17
+ isPublic: boolean;
18
+ }
19
+ /** A parsed C++ class with optional base class. */
20
+ export interface ParsedClass {
21
+ name: string;
22
+ methods: ClassMethod[];
23
+ constructors: {
24
+ parameters: {
25
+ type: string;
26
+ name: string;
27
+ }[];
28
+ }[];
29
+ baseClass?: string;
30
+ source: "header" | "cpp";
31
+ }
32
+ /**
33
+ * Normalizes C++ preprocessor directives so the class parser can see the
34
+ * declarations. Semantics:
35
+ *
36
+ * - Include guards (`#ifndef X` immediately followed by `#define X`, and
37
+ * `#pragma once`): directives dropped, all guarded content kept.
38
+ * - `#if` / `#ifdef` / `#ifndef` ... `#else` / `#elif` ... `#endif`: the
39
+ * FIRST branch's content is kept; `#else` / `#elif` branch content is
40
+ * dropped; all directives themselves are dropped. This preserves classes
41
+ * that real-world headers gate behind target conditionals (e.g.
42
+ * Adafruit_SPITFT wraps its whole class in `#if !defined(__AVR_ATtiny85__)`),
43
+ * at the cost of possibly emitting declarations from a branch that isn't
44
+ * active on the user's target. That's acceptable for .d.ts generation,
45
+ * where a slightly wider API surface beats no API surface.
46
+ */
47
+ export declare function stripPreprocessorBlocks(content: string): string;
48
+ /**
49
+ * Parses a header source string into ParsedClass[]. Strips #if blocks first,
50
+ * then finds `class Name [: access Base] { ... }` blocks and extracts public
51
+ * methods + constructors.
52
+ */
53
+ export declare function parseHeader(content: string): ParsedClass[];