@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,344 @@
|
|
|
1
|
+
import { cloneEmissionScopeState, recordVariableType } from "../snprintf-helpers.js";
|
|
2
|
+
import { emitCommentLines } from "../utils/index.js";
|
|
3
|
+
import { escapeCppKeyword } from "../../utils/strings.js";
|
|
4
|
+
export function appendSourceLine(ctx, line, entry) {
|
|
5
|
+
ctx.sourceLines.push(line);
|
|
6
|
+
if (!entry)
|
|
7
|
+
return;
|
|
8
|
+
const generatedLine = ctx.sourceLines.length;
|
|
9
|
+
ctx.sourceMapEntries.push({
|
|
10
|
+
generatedStartLine: generatedLine,
|
|
11
|
+
generatedStartColumn: 1,
|
|
12
|
+
generatedEndLine: generatedLine,
|
|
13
|
+
generatedEndColumn: Math.max(1, line.length + 1),
|
|
14
|
+
tsSpan: entry.tsSpan,
|
|
15
|
+
nodeKind: entry.nodeKind,
|
|
16
|
+
symbolName: entry.symbolName,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export function appendHeaderLine(ctx, line, entry) {
|
|
20
|
+
ctx.headerLines.push(line);
|
|
21
|
+
if (!entry)
|
|
22
|
+
return;
|
|
23
|
+
const generatedLine = ctx.headerLines.length;
|
|
24
|
+
ctx.headerMapEntries.push({
|
|
25
|
+
generatedStartLine: generatedLine,
|
|
26
|
+
generatedStartColumn: 1,
|
|
27
|
+
generatedEndLine: generatedLine,
|
|
28
|
+
generatedEndColumn: Math.max(1, line.length + 1),
|
|
29
|
+
tsSpan: entry.tsSpan,
|
|
30
|
+
nodeKind: entry.nodeKind,
|
|
31
|
+
symbolName: entry.symbolName,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export function appendRenderedStatement(ctx, statement, indent, scopeState) {
|
|
35
|
+
const { statementRenderer, exprRenderer, fixPointerFieldAccess, reservedNames } = ctx;
|
|
36
|
+
emitCommentLines(statement.leadingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
37
|
+
if (statement.kind === "while") {
|
|
38
|
+
const { prelude, statement: rendered } = statementRenderer.renderWithPrelude(statement, false, fixPointerFieldAccess, scopeState.knownVariableTypes);
|
|
39
|
+
for (const line of prelude)
|
|
40
|
+
appendSourceLine(ctx, `${indent}${line}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
41
|
+
appendSourceLine(ctx, `${indent}${rendered}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
42
|
+
appendSourceLine(ctx, `${indent}{`);
|
|
43
|
+
const nestedScope = cloneEmissionScopeState(scopeState);
|
|
44
|
+
for (const nested of statement.body)
|
|
45
|
+
appendRenderedStatement(ctx, nested, `${indent} `, nestedScope);
|
|
46
|
+
appendSourceLine(ctx, `${indent}}`);
|
|
47
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (statement.kind === "if") {
|
|
51
|
+
const { prelude, statement: rendered } = statementRenderer.renderWithPrelude(statement, false, fixPointerFieldAccess, scopeState.knownVariableTypes);
|
|
52
|
+
for (const line of prelude)
|
|
53
|
+
appendSourceLine(ctx, `${indent}${line}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
54
|
+
appendSourceLine(ctx, `${indent}${rendered}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
55
|
+
appendSourceLine(ctx, `${indent}{`);
|
|
56
|
+
const thenScope = cloneEmissionScopeState(scopeState);
|
|
57
|
+
for (const nested of statement.thenBranch)
|
|
58
|
+
appendRenderedStatement(ctx, nested, `${indent} `, thenScope);
|
|
59
|
+
appendSourceLine(ctx, `${indent}}`);
|
|
60
|
+
if (statement.elseBranch && statement.elseBranch.length > 0) {
|
|
61
|
+
appendSourceLine(ctx, `${indent}else {`);
|
|
62
|
+
const elseScope = cloneEmissionScopeState(scopeState);
|
|
63
|
+
for (const nested of statement.elseBranch)
|
|
64
|
+
appendRenderedStatement(ctx, nested, `${indent} `, elseScope);
|
|
65
|
+
appendSourceLine(ctx, `${indent}}`);
|
|
66
|
+
}
|
|
67
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (statement.kind === "for" || statement.kind === "for_of" || statement.kind === "for_in") {
|
|
71
|
+
if (statement.kind === "for" && statement.initializer?.kind === "var_decl" && statement.initializer.storage === "var") {
|
|
72
|
+
recordVariableType(statement.initializer, scopeState);
|
|
73
|
+
}
|
|
74
|
+
const { prelude, statement: rendered } = statementRenderer.renderWithPrelude(statement, false, fixPointerFieldAccess, scopeState.knownVariableTypes);
|
|
75
|
+
for (const line of prelude)
|
|
76
|
+
appendSourceLine(ctx, `${indent}${line}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
77
|
+
appendSourceLine(ctx, `${indent}${rendered}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
78
|
+
appendSourceLine(ctx, `${indent}{`);
|
|
79
|
+
const nestedScope = cloneEmissionScopeState(scopeState);
|
|
80
|
+
// Register the loop variable's type in the nested scope so the body can
|
|
81
|
+
// infer property-access types on it (e.g. for-of element field types).
|
|
82
|
+
if ((statement.kind === "for_of" || statement.kind === "for_in") && statement.variable.kind === "var_decl") {
|
|
83
|
+
recordVariableType(statement.variable, nestedScope);
|
|
84
|
+
}
|
|
85
|
+
if (statement.kind === "for_in" && statement.keys && statement.keys.length > 0 && statement.variable.kind === "var_decl") {
|
|
86
|
+
const objName = statement.object.kind === "identifier" ? statement.object.value : "_obj";
|
|
87
|
+
const idxVar = `_ki_${objName}`;
|
|
88
|
+
const safeName = escapeCppKeyword(statement.variable.name, reservedNames);
|
|
89
|
+
appendSourceLine(ctx, `${indent} const char* ${safeName} = ${idxVar}_keys[${idxVar}];`);
|
|
90
|
+
}
|
|
91
|
+
for (const nested of statement.body)
|
|
92
|
+
appendRenderedStatement(ctx, nested, `${indent} `, nestedScope);
|
|
93
|
+
appendSourceLine(ctx, `${indent}}`);
|
|
94
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (statement.kind === "do_while") {
|
|
98
|
+
appendSourceLine(ctx, `${indent}do`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
99
|
+
appendSourceLine(ctx, `${indent}{`);
|
|
100
|
+
const nestedScope = cloneEmissionScopeState(scopeState);
|
|
101
|
+
for (const nested of statement.body)
|
|
102
|
+
appendRenderedStatement(ctx, nested, `${indent} `, nestedScope);
|
|
103
|
+
const renderedCondition = exprRenderer.render(statement.condition, ctx.fixPointerFieldAccess, scopeState.knownVariableTypes);
|
|
104
|
+
appendSourceLine(ctx, `${indent}} while (${renderedCondition});`);
|
|
105
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (statement.kind === "switch") {
|
|
109
|
+
const switchExpr = statement.expression;
|
|
110
|
+
const isStringSwitch = (switchExpr.kind === "identifier" &&
|
|
111
|
+
scopeState.knownVariableTypes?.get(switchExpr.value) != null &&
|
|
112
|
+
ctx.strategy.isStringLikeType(scopeState.knownVariableTypes.get(switchExpr.value).cppType)) ||
|
|
113
|
+
statement.cases.some(c => c.value?.kind === "string");
|
|
114
|
+
const isBooleanSwitch = switchExpr.kind === "boolean" && switchExpr.value === true;
|
|
115
|
+
const hasNonConstantCase = statement.cases.some(c => c.value !== undefined &&
|
|
116
|
+
c.value.kind !== "number" &&
|
|
117
|
+
c.value.kind !== "boolean" &&
|
|
118
|
+
c.value.kind !== "string");
|
|
119
|
+
if (isStringSwitch || isBooleanSwitch || hasNonConstantCase) {
|
|
120
|
+
let switchVar = exprRenderer.render(switchExpr, undefined, scopeState.knownVariableTypes);
|
|
121
|
+
// Wrap the discriminant in std::string(...) ONLY when it is genuinely a
|
|
122
|
+
// bare string-like value that needs promoting for a correct `==`
|
|
123
|
+
// comparison. A bare `const char*` identifier compares by pointer, not
|
|
124
|
+
// by contents, so it must be wrapped; a `std::string`, an enum, or a
|
|
125
|
+
// number already compares correctly and wrapping a non-string is a hard
|
|
126
|
+
// g++ error (demo #16 gap #1: `std::string(enumValue)` is ill-formed).
|
|
127
|
+
// Resolve the discriminant's real type and wrap iff string-like; when
|
|
128
|
+
// the type is unknown, default to NO wrap (always valid C++).
|
|
129
|
+
const discCppType = exprRenderer.inferCppType?.(switchExpr, scopeState.knownVariableTypes);
|
|
130
|
+
const needsStringWrap = switchExpr.kind === "identifier"
|
|
131
|
+
? (() => { const vi = scopeState.knownVariableTypes?.get(switchExpr.value); return vi && vi.cppType === "const char*"; })()
|
|
132
|
+
: switchExpr.kind === "property-access"
|
|
133
|
+
? ctx.strategy.isStringLikeType(discCppType ?? "")
|
|
134
|
+
: false;
|
|
135
|
+
if (needsStringWrap) {
|
|
136
|
+
switchVar = `std::string(${switchVar})`;
|
|
137
|
+
}
|
|
138
|
+
let isFirst = true;
|
|
139
|
+
// Demo #30 Finding D — handle TS switch fall-through into a shared body.
|
|
140
|
+
// `case A: case B: default: { body }` parses as three clauses where A
|
|
141
|
+
// and B have EMPTY bodies and `default` carries the shared body. A naive
|
|
142
|
+
// `if/else if` chain would emit `if (x==A) {} else if (x==B) {} else
|
|
143
|
+
// { body }`, so x==A and x==B run NOTHING — semantically wrong (TS
|
|
144
|
+
// falls through A and B into the shared body). The faithful lowering
|
|
145
|
+
// groups consecutive fall-through cases (empty-body cases) with the
|
|
146
|
+
// next clause that HAS a body, joining their conditions with `||`. A
|
|
147
|
+
// `default` in a group makes the whole group the catch-all `else`. This
|
|
148
|
+
// is the general fix for the `case X: default:` idiom AND for chained
|
|
149
|
+
// `case A: case B: body` (which a bare-identifier or empty-body case
|
|
150
|
+
// also represents).
|
|
151
|
+
//
|
|
152
|
+
// A case body whose only statement is a `break` also counts as empty
|
|
153
|
+
// (it terminates with no real work) — that is the canonical fall-through
|
|
154
|
+
// terminator. `stripBreaks` already removes breaks, so after stripping
|
|
155
|
+
// such a body is empty too.
|
|
156
|
+
const stripBreaks = (stmts) => stmts.filter((s) => s.kind !== "break").map((s) => {
|
|
157
|
+
if (s.kind === "block") {
|
|
158
|
+
return { ...s, body: stripBreaks(s.body) };
|
|
159
|
+
}
|
|
160
|
+
return s;
|
|
161
|
+
});
|
|
162
|
+
const groups = [];
|
|
163
|
+
let pendingConditions = [];
|
|
164
|
+
let pendingHasDefault = false;
|
|
165
|
+
let pendingLeadingComments = [];
|
|
166
|
+
const flushGroup = (terminatingClause, body) => {
|
|
167
|
+
groups.push({
|
|
168
|
+
conditions: pendingConditions,
|
|
169
|
+
hasDefault: pendingHasDefault,
|
|
170
|
+
body,
|
|
171
|
+
leadingComments: pendingLeadingComments,
|
|
172
|
+
trailingComments: terminatingClause.trailingComments ?? [],
|
|
173
|
+
});
|
|
174
|
+
pendingConditions = [];
|
|
175
|
+
pendingHasDefault = false;
|
|
176
|
+
pendingLeadingComments = [];
|
|
177
|
+
};
|
|
178
|
+
for (const caseClause of statement.cases) {
|
|
179
|
+
const bodyWithoutBreak = stripBreaks(caseClause.body);
|
|
180
|
+
const isEmpty = bodyWithoutBreak.length === 0;
|
|
181
|
+
if (caseClause.value !== undefined) {
|
|
182
|
+
// Named case. Accumulate its condition; if its body is empty it
|
|
183
|
+
// falls through to the next clause, otherwise it terminates a run.
|
|
184
|
+
if (pendingLeadingComments.length === 0) {
|
|
185
|
+
pendingLeadingComments = caseClause.leadingComments ?? [];
|
|
186
|
+
}
|
|
187
|
+
const renderedValue = exprRenderer.render(caseClause.value, undefined, scopeState.knownVariableTypes);
|
|
188
|
+
pendingConditions.push(isBooleanSwitch ? renderedValue : `${switchVar} == ${renderedValue}`);
|
|
189
|
+
if (!isEmpty) {
|
|
190
|
+
flushGroup(caseClause, bodyWithoutBreak);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
// Default clause. If it has a body it terminates the run (the body
|
|
195
|
+
// is shared with all accumulated fall-through conditions); if not,
|
|
196
|
+
// it itself falls through (rare, but `default: case X: body`).
|
|
197
|
+
pendingHasDefault = true;
|
|
198
|
+
if (pendingLeadingComments.length === 0) {
|
|
199
|
+
pendingLeadingComments = caseClause.leadingComments ?? [];
|
|
200
|
+
}
|
|
201
|
+
if (!isEmpty) {
|
|
202
|
+
flushGroup(caseClause, bodyWithoutBreak);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Emit each group as one branch of the if/else-if/else chain.
|
|
207
|
+
for (const group of groups) {
|
|
208
|
+
emitCommentLines(group.leadingComments, `${indent} `, (line) => appendSourceLine(ctx, line));
|
|
209
|
+
if (group.hasDefault && group.conditions.length === 0) {
|
|
210
|
+
// Pure default (no fall-through into it): the final `else`.
|
|
211
|
+
appendSourceLine(ctx, `${indent}} else`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
212
|
+
appendSourceLine(ctx, `${indent}{`);
|
|
213
|
+
}
|
|
214
|
+
else if (group.hasDefault) {
|
|
215
|
+
// `case X: default: body` — X OR anything-else runs the body, which
|
|
216
|
+
// is equivalent to "always run the body". Emit it as a final else
|
|
217
|
+
// (the catch-all), which is both correct and the simplest form.
|
|
218
|
+
appendSourceLine(ctx, `${indent}} else`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
219
|
+
appendSourceLine(ctx, `${indent}{`);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
// One or more named conditions sharing a body. Join with `||`.
|
|
223
|
+
const condition = group.conditions.join(" || ");
|
|
224
|
+
const keyword = isFirst ? "if" : "} else if";
|
|
225
|
+
appendSourceLine(ctx, `${indent}${keyword} (${condition})`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
226
|
+
appendSourceLine(ctx, `${indent}{`);
|
|
227
|
+
}
|
|
228
|
+
isFirst = false;
|
|
229
|
+
const nestedScope = cloneEmissionScopeState(scopeState);
|
|
230
|
+
for (const nested of group.body)
|
|
231
|
+
appendRenderedStatement(ctx, nested, `${indent} `, nestedScope);
|
|
232
|
+
emitCommentLines(group.trailingComments, `${indent} `, (line) => appendSourceLine(ctx, line));
|
|
233
|
+
}
|
|
234
|
+
if (!isFirst) {
|
|
235
|
+
appendSourceLine(ctx, `${indent}}`);
|
|
236
|
+
}
|
|
237
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const { prelude, statement: rendered } = statementRenderer.renderWithPrelude(statement, false, fixPointerFieldAccess, scopeState.knownVariableTypes);
|
|
241
|
+
for (const line of prelude)
|
|
242
|
+
appendSourceLine(ctx, `${indent}${line}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
243
|
+
appendSourceLine(ctx, `${indent}${rendered}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
244
|
+
appendSourceLine(ctx, `${indent}{`);
|
|
245
|
+
for (const caseClause of statement.cases) {
|
|
246
|
+
emitCommentLines(caseClause.leadingComments, `${indent} `, (line) => appendSourceLine(ctx, line));
|
|
247
|
+
if (caseClause.value !== undefined) {
|
|
248
|
+
const renderedValue = exprRenderer.render(caseClause.value, undefined, scopeState.knownVariableTypes);
|
|
249
|
+
appendSourceLine(ctx, `${indent} case ${renderedValue}:`);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
appendSourceLine(ctx, `${indent} default:`);
|
|
253
|
+
}
|
|
254
|
+
const nestedScope = cloneEmissionScopeState(scopeState);
|
|
255
|
+
for (const nested of caseClause.body)
|
|
256
|
+
appendRenderedStatement(ctx, nested, `${indent} `, nestedScope);
|
|
257
|
+
emitCommentLines(caseClause.trailingComments, `${indent} `, (line) => appendSourceLine(ctx, line));
|
|
258
|
+
}
|
|
259
|
+
appendSourceLine(ctx, `${indent}}`);
|
|
260
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (statement.kind === "labeled") {
|
|
264
|
+
emitCommentLines(statement.leadingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
265
|
+
appendSourceLine(ctx, `${indent}${statement.label}:`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
266
|
+
const nestedScope = cloneEmissionScopeState(scopeState);
|
|
267
|
+
for (let i = 0; i < statement.body.length; i++) {
|
|
268
|
+
appendRenderedStatement(ctx, statement.body[i], indent, nestedScope);
|
|
269
|
+
}
|
|
270
|
+
// Emit a no-op statement (`;`) after the label so it is never the last
|
|
271
|
+
// token before a closing brace. Without this, g++ warns "label at end of
|
|
272
|
+
// compound statement only available with '-std=c++23'" and (when the label
|
|
273
|
+
// is unused in a particular code path) "label defined but not used".
|
|
274
|
+
// The __attribute__((unused)) suppresses the -Wunused-label false
|
|
275
|
+
// positive (the label IS a goto target from the labelled break, but the
|
|
276
|
+
// compiler may prove the goto unreachable on some code paths).
|
|
277
|
+
appendSourceLine(ctx, `${indent}__attribute__((unused)) __break_${statement.label}: ;`);
|
|
278
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (statement.kind === "block") {
|
|
282
|
+
appendSourceLine(ctx, `${indent}{`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
283
|
+
const nestedScope = cloneEmissionScopeState(scopeState);
|
|
284
|
+
for (const nested of statement.body)
|
|
285
|
+
appendRenderedStatement(ctx, nested, `${indent} `, nestedScope);
|
|
286
|
+
appendSourceLine(ctx, `${indent}}`);
|
|
287
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
if (statement.kind === "yield") {
|
|
291
|
+
const { prelude, statement: rendered } = statementRenderer.renderWithPrelude(statement, false, fixPointerFieldAccess, scopeState.knownVariableTypes);
|
|
292
|
+
for (const line of prelude)
|
|
293
|
+
appendSourceLine(ctx, `${indent}${line}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
294
|
+
appendSourceLine(ctx, `${indent}${rendered}`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (statement.kind === "try") {
|
|
298
|
+
appendSourceLine(ctx, `${indent}try`, { tsSpan: statement.sourceSpan, nodeKind: statement.kind });
|
|
299
|
+
appendSourceLine(ctx, `${indent}{`);
|
|
300
|
+
const tryScope = cloneEmissionScopeState(scopeState);
|
|
301
|
+
for (const nested of statement.tryBlock)
|
|
302
|
+
appendRenderedStatement(ctx, nested, `${indent} `, tryScope);
|
|
303
|
+
appendSourceLine(ctx, `${indent}}`);
|
|
304
|
+
if (statement.catchBlock) {
|
|
305
|
+
// TS `catch (e)` catches ANY thrown value (not just std::exception).
|
|
306
|
+
// Emit `catch (...)` (catch-all) so thrown pointers/values of non-
|
|
307
|
+
// std::exception types are caught. If the catch param is named, bind it
|
|
308
|
+
// via a rethrow-and-cast pattern OR just use catch(...) and leave the
|
|
309
|
+
// param unbound (accessing `.message` on an `unknown` catch value isn't
|
|
310
|
+
// type-safe in C++ anyway). Demo #11 Finding E — was `catch (const
|
|
311
|
+
// std::exception& e)` which missed a thrown `RegionError*`.
|
|
312
|
+
const catchDecl = `catch (...) {`;
|
|
313
|
+
appendSourceLine(ctx, `${indent}${catchDecl}`);
|
|
314
|
+
const catchScope = cloneEmissionScopeState(scopeState);
|
|
315
|
+
for (const nested of statement.catchBlock)
|
|
316
|
+
appendRenderedStatement(ctx, nested, `${indent} `, catchScope);
|
|
317
|
+
appendSourceLine(ctx, `${indent}}`);
|
|
318
|
+
}
|
|
319
|
+
// Render finally block inline immediately after catch (matching TypeScript semantics),
|
|
320
|
+
// instead of using an RAII guard that would defer execution to scope exit.
|
|
321
|
+
if (statement.finallyBlock && statement.finallyBlock.length > 0) {
|
|
322
|
+
const finallyScope = cloneEmissionScopeState(scopeState);
|
|
323
|
+
for (const nested of statement.finallyBlock)
|
|
324
|
+
appendRenderedStatement(ctx, nested, `${indent}`, finallyScope);
|
|
325
|
+
}
|
|
326
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
const { prelude, statement: rendered } = statementRenderer.renderWithPrelude(statement, false, fixPointerFieldAccess, scopeState.knownVariableTypes);
|
|
330
|
+
for (const preludeLine of prelude) {
|
|
331
|
+
appendSourceLine(ctx, `${indent}${preludeLine}`, {
|
|
332
|
+
tsSpan: statement.sourceSpan,
|
|
333
|
+
nodeKind: statement.kind,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
appendSourceLine(ctx, `${indent}${rendered}`, {
|
|
337
|
+
tsSpan: statement.sourceSpan,
|
|
338
|
+
nodeKind: statement.kind,
|
|
339
|
+
});
|
|
340
|
+
if (statement.kind === "var_decl") {
|
|
341
|
+
recordVariableType(statement, scopeState);
|
|
342
|
+
}
|
|
343
|
+
emitCommentLines(statement.trailingComments, indent, (line) => appendSourceLine(ctx, line));
|
|
344
|
+
}
|