@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.
- package/LICENSE +21 -0
- package/README.md +79 -0
- package/dist/api/board-types.d.ts +1 -0
- package/dist/api/board-types.js +4 -0
- package/dist/api/capabilities.d.ts +12 -0
- package/dist/api/capabilities.js +1 -0
- package/dist/api/config.d.ts +120 -0
- package/dist/api/config.js +7 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.js +2 -0
- package/dist/api/schema/builder.d.ts +14 -0
- package/dist/api/schema/builder.js +15 -0
- package/dist/api/schema/index.d.ts +2 -0
- package/dist/api/schema/index.js +1 -0
- package/dist/api/schema/types.d.ts +257 -0
- package/dist/api/schema/types.js +4 -0
- package/dist/api/shared/async-runtime-static.d.ts +8 -0
- package/dist/api/shared/async-runtime-static.js +201 -0
- package/dist/api/shared/async-types.d.ts +42 -0
- package/dist/api/shared/async-types.js +8 -0
- package/dist/api/shared/board-resolver.d.ts +12 -0
- package/dist/api/shared/board-resolver.js +7 -0
- package/dist/api/shared/cpp-type-ir.d.ts +229 -0
- package/dist/api/shared/cpp-type-ir.js +672 -0
- package/dist/api/shared/display-adapter.d.ts +12 -0
- package/dist/api/shared/display-adapter.js +145 -0
- package/dist/api/shared/display-adapters/eink-mono.d.ts +2 -0
- package/dist/api/shared/display-adapters/eink-mono.js +53 -0
- package/dist/api/shared/display-adapters/sdl.d.ts +2 -0
- package/dist/api/shared/display-adapters/sdl.js +452 -0
- package/dist/api/shared/display-adapters/ssd1309.d.ts +2 -0
- package/dist/api/shared/display-adapters/ssd1309.js +136 -0
- package/dist/api/shared/display-adapters/st7796.d.ts +2 -0
- package/dist/api/shared/display-adapters/st7796.js +132 -0
- package/dist/api/shared/display-capabilities.d.ts +45 -0
- package/dist/api/shared/display-capabilities.js +54 -0
- package/dist/api/shared/display-op-ir.d.ts +62 -0
- package/dist/api/shared/display-op-ir.js +19 -0
- package/dist/api/shared/display-profile.d.ts +265 -0
- package/dist/api/shared/display-profile.js +338 -0
- package/dist/api/shared/graphics-strategy.d.ts +29 -0
- package/dist/api/shared/graphics-strategy.js +11 -0
- package/dist/api/shared/hal-op-ir.d.ts +393 -0
- package/dist/api/shared/hal-op-ir.js +18 -0
- package/dist/api/shared/index.d.ts +26 -0
- package/dist/api/shared/index.js +21 -0
- package/dist/api/shared/ir-core.d.ts +363 -0
- package/dist/api/shared/ir-core.js +8 -0
- package/dist/api/shared/ir-declarations.d.ts +201 -0
- package/dist/api/shared/ir-declarations.js +26 -0
- package/dist/api/shared/ir.d.ts +85 -0
- package/dist/api/shared/ir.js +13 -0
- package/dist/api/shared/platform-strategy.d.ts +402 -0
- package/dist/api/shared/platform-strategy.js +14 -0
- package/dist/api/shared/polyfill-helper-registry.d.ts +11 -0
- package/dist/api/shared/polyfill-helper-registry.js +86 -0
- package/dist/api/shared/polyfill-types.d.ts +33 -0
- package/dist/api/shared/polyfill-types.js +76 -0
- package/dist/api/shared/promise-runtime.d.ts +10 -0
- package/dist/api/shared/promise-runtime.js +244 -0
- package/dist/api/shared/snprintf-types.d.ts +29 -0
- package/dist/api/shared/snprintf-types.js +8 -0
- package/dist/api/shared/string-method-registry.d.ts +53 -0
- package/dist/api/shared/string-method-registry.js +168 -0
- package/dist/api/shared/toolchain-types.d.ts +63 -0
- package/dist/api/shared/toolchain-types.js +71 -0
- package/dist/api/shared/types.d.ts +50 -0
- package/dist/api/shared/types.js +6 -0
- package/dist/ast/parse.d.ts +2 -0
- package/dist/ast/parse.js +4 -0
- package/dist/cache.d.ts +26 -0
- package/dist/cache.js +95 -0
- package/dist/cli-utils.d.ts +37 -0
- package/dist/cli-utils.js +250 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +635 -0
- package/dist/config-loader.d.ts +78 -0
- package/dist/config-loader.js +508 -0
- package/dist/config-schema.d.ts +233 -0
- package/dist/config-schema.js +83 -0
- package/dist/create/board-checklist.d.ts +2 -0
- package/dist/create/board-checklist.js +52 -0
- package/dist/create/board-codegen.d.ts +9 -0
- package/dist/create/board-codegen.js +238 -0
- package/dist/create/board-generators.d.ts +12 -0
- package/dist/create/board-generators.js +652 -0
- package/dist/create/board-spec.d.ts +640 -0
- package/dist/create/board-spec.js +215 -0
- package/dist/create/eslint-rules-template.d.ts +2 -0
- package/dist/create/eslint-rules-template.js +672 -0
- package/dist/create/index.d.ts +11 -0
- package/dist/create/index.js +8 -0
- package/dist/create/init-scaffold.d.ts +27 -0
- package/dist/create/init-scaffold.js +150 -0
- package/dist/create/init-templates.d.ts +24 -0
- package/dist/create/init-templates.js +379 -0
- package/dist/create/init-wizard.d.ts +8 -0
- package/dist/create/init-wizard.js +168 -0
- package/dist/debug/breakpoint-loader.d.ts +24 -0
- package/dist/debug/breakpoint-loader.js +137 -0
- package/dist/debug/index.d.ts +3 -0
- package/dist/debug/index.js +7 -0
- package/dist/debug/preprocessor.d.ts +9 -0
- package/dist/debug/preprocessor.js +214 -0
- package/dist/debug/types.d.ts +32 -0
- package/dist/debug/types.js +6 -0
- package/dist/diagnostics/diagnostics-report.d.ts +51 -0
- package/dist/diagnostics/diagnostics-report.js +333 -0
- package/dist/diagnostics/json-schema.d.ts +138 -0
- package/dist/diagnostics/json-schema.js +27 -0
- package/dist/diagnostics/md-writer.d.ts +10 -0
- package/dist/diagnostics/md-writer.js +336 -0
- package/dist/diagnostics/mermaid-builder.d.ts +65 -0
- package/dist/diagnostics/mermaid-builder.js +681 -0
- package/dist/emit/cpp-emitter.d.ts +6 -0
- package/dist/emit/cpp-emitter.js +48 -0
- package/dist/emit/emitters/class-emitter.d.ts +2 -0
- package/dist/emit/emitters/class-emitter.js +523 -0
- package/dist/emit/emitters/emitter-context.d.ts +174 -0
- package/dist/emit/emitters/emitter-context.js +1 -0
- package/dist/emit/emitters/entrypoint-synthesizer.d.ts +2 -0
- package/dist/emit/emitters/entrypoint-synthesizer.js +175 -0
- package/dist/emit/emitters/function-emitter-impl.d.ts +19 -0
- package/dist/emit/emitters/function-emitter-impl.js +428 -0
- package/dist/emit/emitters/line-appender.d.ts +15 -0
- package/dist/emit/emitters/line-appender.js +344 -0
- package/dist/emit/emitters/namespace-emitter.d.ts +2 -0
- package/dist/emit/emitters/namespace-emitter.js +324 -0
- package/dist/emit/emitters/output-finalizer.d.ts +4 -0
- package/dist/emit/emitters/output-finalizer.js +267 -0
- package/dist/emit/emitters/setup.d.ts +3 -0
- package/dist/emit/emitters/setup.js +851 -0
- package/dist/emit/emitters/top-level-prep.d.ts +2 -0
- package/dist/emit/emitters/top-level-prep.js +706 -0
- package/dist/emit/emitters/type-decl-emitter.d.ts +2 -0
- package/dist/emit/emitters/type-decl-emitter.js +251 -0
- package/dist/emit/emitters/ui-emitter.d.ts +21 -0
- package/dist/emit/emitters/ui-emitter.js +564 -0
- package/dist/emit/enum-emitter.d.ts +1 -0
- package/dist/emit/enum-emitter.js +1 -0
- package/dist/emit/expression-renderer.d.ts +283 -0
- package/dist/emit/expression-renderer.js +1477 -0
- package/dist/emit/native-helpers-emitter.d.ts +11 -0
- package/dist/emit/native-helpers-emitter.js +34 -0
- package/dist/emit/route-hal-op.d.ts +5 -0
- package/dist/emit/route-hal-op.js +13 -0
- package/dist/emit/snprintf-helpers.d.ts +17 -0
- package/dist/emit/snprintf-helpers.js +462 -0
- package/dist/emit/statement-renderer.d.ts +189 -0
- package/dist/emit/statement-renderer.js +948 -0
- package/dist/emit/utils/async-state-machine.d.ts +42 -0
- package/dist/emit/utils/async-state-machine.js +343 -0
- package/dist/emit/utils/comment-helpers.d.ts +20 -0
- package/dist/emit/utils/comment-helpers.js +31 -0
- package/dist/emit/utils/cpp-helpers.d.ts +47 -0
- package/dist/emit/utils/cpp-helpers.js +85 -0
- package/dist/emit/utils/include-resolver.d.ts +58 -0
- package/dist/emit/utils/include-resolver.js +155 -0
- package/dist/emit/utils/index.d.ts +8 -0
- package/dist/emit/utils/index.js +12 -0
- package/dist/emit/utils/type-inference.d.ts +159 -0
- package/dist/emit/utils/type-inference.js +559 -0
- package/dist/eslint-check.d.ts +10 -0
- package/dist/eslint-check.js +102 -0
- package/dist/framework-package.d.ts +10 -0
- package/dist/framework-package.js +58 -0
- package/dist/framework-registry.d.ts +39 -0
- package/dist/framework-registry.js +30 -0
- package/dist/incremental-cache.d.ts +116 -0
- package/dist/incremental-cache.js +335 -0
- package/dist/ir/adc-range-validation.d.ts +11 -0
- package/dist/ir/adc-range-validation.js +250 -0
- package/dist/ir/ast-node-utils.d.ts +8 -0
- package/dist/ir/ast-node-utils.js +32 -0
- package/dist/ir/board-pin-utils.d.ts +13 -0
- package/dist/ir/board-pin-utils.js +65 -0
- package/dist/ir/board-resolver.d.ts +36 -0
- package/dist/ir/board-resolver.js +437 -0
- package/dist/ir/build-ir-state.d.ts +167 -0
- package/dist/ir/build-ir-state.js +306 -0
- package/dist/ir/build-ir.d.ts +2 -0
- package/dist/ir/build-ir.js +808 -0
- package/dist/ir/call-graph.d.ts +35 -0
- package/dist/ir/call-graph.js +194 -0
- package/dist/ir/compile-time-only.d.ts +2 -0
- package/dist/ir/compile-time-only.js +16 -0
- package/dist/ir/declaration-builders.d.ts +9 -0
- package/dist/ir/declaration-builders.js +608 -0
- package/dist/ir/entry-points.d.ts +30 -0
- package/dist/ir/entry-points.js +191 -0
- package/dist/ir/expression-to-ir.d.ts +5 -0
- package/dist/ir/expression-to-ir.js +2249 -0
- package/dist/ir/extract-property-chain.d.ts +10 -0
- package/dist/ir/extract-property-chain.js +30 -0
- package/dist/ir/feature-prescan.d.ts +3 -0
- package/dist/ir/feature-prescan.js +43 -0
- package/dist/ir/feature-registry.d.ts +30 -0
- package/dist/ir/feature-registry.js +816 -0
- package/dist/ir/filter.d.ts +7 -0
- package/dist/ir/filter.js +85 -0
- package/dist/ir/function-builder.d.ts +19 -0
- package/dist/ir/function-builder.js +670 -0
- package/dist/ir/hal/hal-emitter.d.ts +62 -0
- package/dist/ir/hal/hal-emitter.js +735 -0
- package/dist/ir/hal/hal-parser.d.ts +61 -0
- package/dist/ir/hal/hal-parser.js +473 -0
- package/dist/ir/hal/hal-plugins.d.ts +34 -0
- package/dist/ir/hal/hal-plugins.js +706 -0
- package/dist/ir/hal-resolver.d.ts +5 -0
- package/dist/ir/hal-resolver.js +5 -0
- package/dist/ir/heap-analysis.d.ts +8 -0
- package/dist/ir/heap-analysis.js +350 -0
- package/dist/ir/heap-array-validation.d.ts +24 -0
- package/dist/ir/heap-array-validation.js +29 -0
- package/dist/ir/identifier-collector.d.ts +18 -0
- package/dist/ir/identifier-collector.js +439 -0
- package/dist/ir/interrupt-analysis.d.ts +39 -0
- package/dist/ir/interrupt-analysis.js +467 -0
- package/dist/ir/memory-budget-validation.d.ts +10 -0
- package/dist/ir/memory-budget-validation.js +86 -0
- package/dist/ir/namespace-builder.d.ts +7 -0
- package/dist/ir/namespace-builder.js +152 -0
- package/dist/ir/ownership-analysis.d.ts +9 -0
- package/dist/ir/ownership-analysis.js +1207 -0
- package/dist/ir/peripheral-ownership.d.ts +3 -0
- package/dist/ir/peripheral-ownership.js +152 -0
- package/dist/ir/peripheral-symbols.d.ts +7 -0
- package/dist/ir/peripheral-symbols.js +57 -0
- package/dist/ir/peripheral-usage.d.ts +54 -0
- package/dist/ir/peripheral-usage.js +691 -0
- package/dist/ir/peripheral-validation.d.ts +8 -0
- package/dist/ir/peripheral-validation.js +77 -0
- package/dist/ir/pin-alias-conflict.d.ts +4 -0
- package/dist/ir/pin-alias-conflict.js +34 -0
- package/dist/ir/pin-capability-validation.d.ts +6 -0
- package/dist/ir/pin-capability-validation.js +413 -0
- package/dist/ir/pin-mode-validation.d.ts +10 -0
- package/dist/ir/pin-mode-validation.js +301 -0
- package/dist/ir/pin-safety.d.ts +11 -0
- package/dist/ir/pin-safety.js +58 -0
- package/dist/ir/program-analysis.d.ts +44 -0
- package/dist/ir/program-analysis.js +589 -0
- package/dist/ir/pulldown-validation.d.ts +7 -0
- package/dist/ir/pulldown-validation.js +49 -0
- package/dist/ir/pwm-timer-sharing.d.ts +4 -0
- package/dist/ir/pwm-timer-sharing.js +93 -0
- package/dist/ir/reachability.d.ts +68 -0
- package/dist/ir/reachability.js +224 -0
- package/dist/ir/register-decorators.d.ts +6 -0
- package/dist/ir/register-decorators.js +49 -0
- package/dist/ir/render-expr.d.ts +4 -0
- package/dist/ir/render-expr.js +127 -0
- package/dist/ir/resource-analysis.d.ts +19 -0
- package/dist/ir/resource-analysis.js +153 -0
- package/dist/ir/statement-to-ir.d.ts +23 -0
- package/dist/ir/statement-to-ir.js +349 -0
- package/dist/ir/symbol-table.d.ts +68 -0
- package/dist/ir/symbol-table.js +179 -0
- package/dist/ir/symbol-types.d.ts +56 -0
- package/dist/ir/symbol-types.js +107 -0
- package/dist/ir/timer0-pwm-timing-conflict.d.ts +4 -0
- package/dist/ir/timer0-pwm-timing-conflict.js +71 -0
- package/dist/ir/timing-validation.d.ts +7 -0
- package/dist/ir/timing-validation.js +95 -0
- package/dist/ir/transformers/array-methods.d.ts +8 -0
- package/dist/ir/transformers/array-methods.js +493 -0
- package/dist/ir/transformers/call-statement.d.ts +5 -0
- package/dist/ir/transformers/call-statement.js +758 -0
- package/dist/ir/transformers/callback-context-registry.d.ts +20 -0
- package/dist/ir/transformers/callback-context-registry.js +55 -0
- package/dist/ir/transformers/canvas-lowering.d.ts +42 -0
- package/dist/ir/transformers/canvas-lowering.js +249 -0
- package/dist/ir/transformers/control-flow.d.ts +8 -0
- package/dist/ir/transformers/control-flow.js +508 -0
- package/dist/ir/transformers/expressions.d.ts +7 -0
- package/dist/ir/transformers/expressions.js +406 -0
- package/dist/ir/transformers/hal-call-resolver.d.ts +29 -0
- package/dist/ir/transformers/hal-call-resolver.js +274 -0
- package/dist/ir/transformers/hal-emit-helpers.d.ts +14 -0
- package/dist/ir/transformers/hal-emit-helpers.js +63 -0
- package/dist/ir/transformers/namespace-methods.d.ts +20 -0
- package/dist/ir/transformers/namespace-methods.js +110 -0
- package/dist/ir/transformers/register-assignment.d.ts +5 -0
- package/dist/ir/transformers/register-assignment.js +56 -0
- package/dist/ir/transformers/ui-call-resolver.d.ts +149 -0
- package/dist/ir/transformers/ui-call-resolver.js +1136 -0
- package/dist/ir/transformers/ui-callback-lowering.d.ts +62 -0
- package/dist/ir/transformers/ui-callback-lowering.js +623 -0
- package/dist/ir/transformers/ui-mount.d.ts +20 -0
- package/dist/ir/transformers/ui-mount.js +35 -0
- package/dist/ir/transformers/ui-reactive.d.ts +68 -0
- package/dist/ir/transformers/ui-reactive.js +129 -0
- package/dist/ir/transformers/variables.d.ts +14 -0
- package/dist/ir/transformers/variables.js +1045 -0
- package/dist/ir/try-catch-validation.d.ts +26 -0
- package/dist/ir/try-catch-validation.js +128 -0
- package/dist/ir/type-resolution.d.ts +31 -0
- package/dist/ir/type-resolution.js +977 -0
- package/dist/ir/ui-element-auto-wire.d.ts +50 -0
- package/dist/ir/ui-element-auto-wire.js +218 -0
- package/dist/ir/unit-suspicion-validation.d.ts +12 -0
- package/dist/ir/unit-suspicion-validation.js +296 -0
- package/dist/ir/utils/walk-ir.d.ts +6 -0
- package/dist/ir/utils/walk-ir.js +162 -0
- package/dist/ir/validation-orchestrator.d.ts +4 -0
- package/dist/ir/validation-orchestrator.js +45 -0
- package/dist/libdef/base-class-resolver.d.ts +23 -0
- package/dist/libdef/base-class-resolver.js +50 -0
- package/dist/libdef/cpp-to-decl.d.ts +34 -0
- package/dist/libdef/cpp-to-decl.js +584 -0
- package/dist/libdef/header-parser.d.ts +53 -0
- package/dist/libdef/header-parser.js +269 -0
- package/dist/libdef/registry.d.ts +10 -0
- package/dist/libdef/registry.js +142 -0
- package/dist/mapping/peripheral-names.d.ts +23 -0
- package/dist/mapping/peripheral-names.js +63 -0
- package/dist/mapping/source-map.d.ts +46 -0
- package/dist/mapping/source-map.js +207 -0
- package/dist/orchestrator/dts-generator.d.ts +17 -0
- package/dist/orchestrator/dts-generator.js +83 -0
- package/dist/orchestrator/graph-builder.d.ts +18 -0
- package/dist/orchestrator/graph-builder.js +218 -0
- package/dist/orchestrator/semantic-facts-verifier.d.ts +38 -0
- package/dist/orchestrator/semantic-facts-verifier.js +121 -0
- package/dist/orchestrator/semantic-facts.d.ts +141 -0
- package/dist/orchestrator/semantic-facts.js +652 -0
- package/dist/orchestrator/type-checker.d.ts +39 -0
- package/dist/orchestrator/type-checker.js +760 -0
- package/dist/platform/async-runtime.d.ts +8 -0
- package/dist/platform/async-runtime.js +26 -0
- package/dist/platform/generic-strategy.d.ts +101 -0
- package/dist/platform/generic-strategy.js +289 -0
- package/dist/platform/index.d.ts +4 -0
- package/dist/platform/index.js +9 -0
- package/dist/platform/registry.d.ts +21 -0
- package/dist/platform/registry.js +42 -0
- package/dist/platform/toolchain.d.ts +4 -0
- package/dist/platform/toolchain.js +43 -0
- package/dist/preview/client.d.ts +1 -0
- package/dist/preview/client.js +137 -0
- package/dist/preview/server.d.ts +5 -0
- package/dist/preview/server.js +199 -0
- package/dist/profiler/index.d.ts +28 -0
- package/dist/profiler/index.js +28 -0
- package/dist/profiler/profiler.d.ts +95 -0
- package/dist/profiler/profiler.js +338 -0
- package/dist/profiler/types.d.ts +87 -0
- package/dist/profiler/types.js +12 -0
- package/dist/stores/display-profile-store.d.ts +16 -0
- package/dist/stores/display-profile-store.js +48 -0
- package/dist/stores/theme-store.d.ts +13 -0
- package/dist/stores/theme-store.js +30 -0
- package/dist/testing.d.ts +45 -0
- package/dist/testing.js +47 -0
- package/dist/transpile/resolution.d.ts +29 -0
- package/dist/transpile/resolution.js +282 -0
- package/dist/transpile.d.ts +3 -0
- package/dist/transpile.js +722 -0
- package/dist/types.d.ts +217 -0
- package/dist/types.js +1 -0
- package/dist/ui/ui-bridge.d.ts +4 -0
- package/dist/ui/ui-bridge.js +34 -0
- package/dist/ui-hook.d.ts +84 -0
- package/dist/ui-hook.js +45 -0
- package/dist/utils/cli.d.ts +3 -0
- package/dist/utils/cli.js +463 -0
- package/dist/utils/fs.d.ts +4 -0
- package/dist/utils/fs.js +23 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +8 -0
- package/dist/utils/strings.d.ts +35 -0
- package/dist/utils/strings.js +142 -0
- package/dist/utils/ui.d.ts +66 -0
- package/dist/utils/ui.js +149 -0
- package/dist/watch.d.ts +35 -0
- package/dist/watch.js +111 -0
- 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,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
|
+
}
|