@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,301 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Pin Mode Configuration Validation
|
|
3
|
+
//
|
|
4
|
+
// Detects when GPIO I/O operations are used on pins without prior mode
|
|
5
|
+
// configuration. Generates warnings for reads and info for writes.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
import { scanNestedStatements } from './interrupt-analysis.js';
|
|
8
|
+
/** Methods that configure pin mode. */
|
|
9
|
+
const MODE_SET_METHODS = new Set([
|
|
10
|
+
'inputPullUp', 'inputPullDown', 'outputOpenDrain',
|
|
11
|
+
'asOutput', 'asInput', 'asInputPullUp',
|
|
12
|
+
]);
|
|
13
|
+
/** Read operations that require prior INPUT or INPUT_PULLUP mode. */
|
|
14
|
+
const READ_METHODS = new Set([
|
|
15
|
+
'read', 'isHigh', 'isLow', 'readAnalog', 'readVoltage',
|
|
16
|
+
]);
|
|
17
|
+
/** Write operations that implicitly set OUTPUT mode on Arduino. */
|
|
18
|
+
const WRITE_METHODS = new Set([
|
|
19
|
+
'write', 'high', 'low', 'toggle', 'pulse', 'pwm', 'tone',
|
|
20
|
+
]);
|
|
21
|
+
/** Receiver kinds that represent GPIO pins. */
|
|
22
|
+
const PIN_RECEIVER_KINDS = new Set([
|
|
23
|
+
'digital', 'pwm', 'analog-input', 'interrupt',
|
|
24
|
+
]);
|
|
25
|
+
/**
|
|
26
|
+
* Validate that GPIO I/O operations are preceded by mode configuration.
|
|
27
|
+
*
|
|
28
|
+
* - Read without prior mode → **warning** (undefined behavior on floating pin)
|
|
29
|
+
* - Write without prior mode → **info** (Arduino implicitly sets OUTPUT, but
|
|
30
|
+
* explicit configuration is recommended)
|
|
31
|
+
*/
|
|
32
|
+
export function validatePinModeConfig(program) {
|
|
33
|
+
const diagnostics = [];
|
|
34
|
+
// Track which receivers have had their mode explicitly set
|
|
35
|
+
const pinModeSet = new Set();
|
|
36
|
+
const checkCuttlefishCall = (receiver, receiverKind, method) => {
|
|
37
|
+
if (!receiverKind || !PIN_RECEIVER_KINDS.has(receiverKind))
|
|
38
|
+
return;
|
|
39
|
+
// Warn when analog pin is used as digital output — analog capability is lost
|
|
40
|
+
if (receiverKind === 'analog-input' && method === 'asOutput') {
|
|
41
|
+
diagnostics.push({
|
|
42
|
+
severity: 'warning',
|
|
43
|
+
message: `Analog pin '${receiver}' used as digital output. ` +
|
|
44
|
+
`Analog input capability (ADC) is lost while pin is in OUTPUT mode. ` +
|
|
45
|
+
`Call ${receiver}.asInput() to restore analog reading.`,
|
|
46
|
+
code: 'analog-pin-as-output',
|
|
47
|
+
source: 'pin-mode-validation',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (MODE_SET_METHODS.has(method)) {
|
|
51
|
+
pinModeSet.add(receiver);
|
|
52
|
+
}
|
|
53
|
+
else if (READ_METHODS.has(method) && !pinModeSet.has(receiver)) {
|
|
54
|
+
diagnostics.push({
|
|
55
|
+
severity: 'warning',
|
|
56
|
+
message: `Pin '${receiver}' read via '${method}()' without prior mode configuration. ` +
|
|
57
|
+
`Call ${receiver}.asInput() or ${receiver}.inputPullUp() first.`,
|
|
58
|
+
code: 'pin-mode-not-set',
|
|
59
|
+
source: 'pin-mode-validation',
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
else if (WRITE_METHODS.has(method) && !pinModeSet.has(receiver)) {
|
|
63
|
+
diagnostics.push({
|
|
64
|
+
severity: 'info',
|
|
65
|
+
message: `Pin '${receiver}' written via '${method}()' without explicit mode configuration. ` +
|
|
66
|
+
`Arduino implicitly sets OUTPUT, but explicit ${receiver}.asOutput() is recommended.`,
|
|
67
|
+
code: 'pin-mode-not-set',
|
|
68
|
+
source: 'pin-mode-validation',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Recursively scan an expression for cuttlefish-call nodes.
|
|
74
|
+
* Pin I/O can appear as expressions inside template literals, function args, etc.
|
|
75
|
+
*/
|
|
76
|
+
/** Infer the receiver kind from the method name. Analog/PWM methods imply
|
|
77
|
+
* their respective pin kinds; everything else defaults to digital. */
|
|
78
|
+
const inferReceiverKind = (method) => {
|
|
79
|
+
if (method === 'readAnalog' || method === 'readVoltage')
|
|
80
|
+
return 'analog-input';
|
|
81
|
+
if (method === 'pwm' || method === 'tone')
|
|
82
|
+
return 'pwm';
|
|
83
|
+
// Methods in the read/write/mode sets that aren't analog/pwm are digital.
|
|
84
|
+
if (READ_METHODS.has(method) || WRITE_METHODS.has(method) || MODE_SET_METHODS.has(method))
|
|
85
|
+
return 'digital';
|
|
86
|
+
return undefined;
|
|
87
|
+
};
|
|
88
|
+
/** Check a gpio HAL op for pin-mode issues. Used by both scanExpression
|
|
89
|
+
* (hal-expr, for reads used as values) and checkStatement (hal-op, for
|
|
90
|
+
* standalone writes/calls). */
|
|
91
|
+
const checkGpioHalOp = (op) => {
|
|
92
|
+
if (!op)
|
|
93
|
+
return;
|
|
94
|
+
const pinKey = `pin${op.pin}`;
|
|
95
|
+
if (op.operation === 'gpio.set_mode') {
|
|
96
|
+
pinModeSet.add(pinKey);
|
|
97
|
+
}
|
|
98
|
+
else if (op.operation === 'gpio.read' && !pinModeSet.has(pinKey)) {
|
|
99
|
+
diagnostics.push({
|
|
100
|
+
severity: 'warning',
|
|
101
|
+
message: `Pin ${op.pin} read without prior mode configuration. ` +
|
|
102
|
+
`Call asInput() or inputPullUp() first — reading a floating pin is undefined behavior.`,
|
|
103
|
+
code: 'pin-mode-not-set',
|
|
104
|
+
source: 'pin-mode-validation',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else if ((op.operation === 'gpio.write' || op.operation === 'gpio.toggle') && !pinModeSet.has(pinKey)) {
|
|
108
|
+
diagnostics.push({
|
|
109
|
+
severity: 'info',
|
|
110
|
+
message: `Pin ${op.pin} written without explicit mode configuration. ` +
|
|
111
|
+
`Arduino implicitly sets OUTPUT, but explicit asOutput() is recommended.`,
|
|
112
|
+
code: 'pin-mode-not-set',
|
|
113
|
+
source: 'pin-mode-validation',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const scanExpression = (expr) => {
|
|
118
|
+
if (!expr || typeof expr !== 'object')
|
|
119
|
+
return;
|
|
120
|
+
const e = expr;
|
|
121
|
+
if (!e.kind)
|
|
122
|
+
return;
|
|
123
|
+
// Method calls on pins: extract receiver + method and dispatch to
|
|
124
|
+
// checkCuttlefishCall (pre-HAL-resolution fallback path).
|
|
125
|
+
if (e.kind === 'method-call' && typeof e.callee === 'string') {
|
|
126
|
+
const callee = e.callee;
|
|
127
|
+
const dotIdx = callee.lastIndexOf('.');
|
|
128
|
+
if (dotIdx > 0) {
|
|
129
|
+
const receiver = callee.slice(0, dotIdx);
|
|
130
|
+
const method = callee.slice(dotIdx + 1);
|
|
131
|
+
const receiverKind = inferReceiverKind(method);
|
|
132
|
+
if (receiverKind) {
|
|
133
|
+
checkCuttlefishCall(receiver, receiverKind, method);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// HAL expression (read used as a value, e.g. `const v = D2.isHigh()`).
|
|
138
|
+
// After HAL resolution, pin reads become hal-expr nodes with a gpio.read
|
|
139
|
+
// operation — this is the common form at validation time.
|
|
140
|
+
if (e.kind === 'hal-expr' && e.operation) {
|
|
141
|
+
checkGpioHalOp(e.operation);
|
|
142
|
+
}
|
|
143
|
+
// Raw nodes: after full HAL resolution, some pin ops land as their C++ text
|
|
144
|
+
// (e.g. `digitalRead(2)`, `digitalWrite(2, 1)`) rather than structured
|
|
145
|
+
// hal-expr nodes. Extract the pin number and apply the same mode check.
|
|
146
|
+
// This mirrors how peripheral-usage.ts detects gpio via emitted text.
|
|
147
|
+
if (e.kind === 'raw' && typeof e.value === 'string') {
|
|
148
|
+
const readMatch = e.value.match(/digitalRead\((\d+)\)/);
|
|
149
|
+
const writeMatch = e.value.match(/digitalWrite\((\d+)/);
|
|
150
|
+
const toggleMatch = e.value.match(/digitalWrite\((\d+),\s*digitalRead/);
|
|
151
|
+
const pin = readMatch ? parseInt(readMatch[1], 10)
|
|
152
|
+
: writeMatch ? parseInt(writeMatch[1], 10)
|
|
153
|
+
: null;
|
|
154
|
+
if (pin !== null) {
|
|
155
|
+
const op = toggleMatch
|
|
156
|
+
? { operation: 'gpio.toggle', pin }
|
|
157
|
+
: readMatch ? { operation: 'gpio.read', pin }
|
|
158
|
+
: { operation: 'gpio.write', pin };
|
|
159
|
+
checkGpioHalOp(op);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Recurse into nested expressions
|
|
163
|
+
if (e.args && Array.isArray(e.args)) {
|
|
164
|
+
for (const arg of e.args)
|
|
165
|
+
scanExpression(arg);
|
|
166
|
+
}
|
|
167
|
+
if (e.left)
|
|
168
|
+
scanExpression(e.left);
|
|
169
|
+
if (e.right)
|
|
170
|
+
scanExpression(e.right);
|
|
171
|
+
if (e.operand)
|
|
172
|
+
scanExpression(e.operand);
|
|
173
|
+
if (e.condition && typeof e.condition === 'object')
|
|
174
|
+
scanExpression(e.condition);
|
|
175
|
+
if (e.whenTrue)
|
|
176
|
+
scanExpression(e.whenTrue);
|
|
177
|
+
if (e.whenFalse)
|
|
178
|
+
scanExpression(e.whenFalse);
|
|
179
|
+
if (e.object && typeof e.object === 'object')
|
|
180
|
+
scanExpression(e.object);
|
|
181
|
+
// Only recurse into .value when it's an object with a kind (an expression),
|
|
182
|
+
// not a primitive (number/string/boolean literals carry primitive values).
|
|
183
|
+
if (e.value && typeof e.value === 'object' && e.value.kind)
|
|
184
|
+
scanExpression(e.value);
|
|
185
|
+
if (e.inner)
|
|
186
|
+
scanExpression(e.inner);
|
|
187
|
+
if (e.elements && Array.isArray(e.elements)) {
|
|
188
|
+
for (const elem of e.elements)
|
|
189
|
+
scanExpression(elem);
|
|
190
|
+
}
|
|
191
|
+
if (e.fields && Array.isArray(e.fields)) {
|
|
192
|
+
for (const field of e.fields) {
|
|
193
|
+
if (field && field.value)
|
|
194
|
+
scanExpression(field.value);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Template literal: string_concat has a 'parts' array
|
|
198
|
+
if (e.parts && Array.isArray(e.parts)) {
|
|
199
|
+
for (const part of e.parts)
|
|
200
|
+
scanExpression(part);
|
|
201
|
+
}
|
|
202
|
+
// Template literal: template_string wraps an 'expression' (singular)
|
|
203
|
+
if (e.expression && typeof e.expression === 'object' && e.expression.kind)
|
|
204
|
+
scanExpression(e.expression);
|
|
205
|
+
// Callback expressions with nested statements
|
|
206
|
+
if (e.statements && Array.isArray(e.statements)) {
|
|
207
|
+
for (const stmt of e.statements)
|
|
208
|
+
checkStatement(stmt);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const checkStatement = (stmt) => {
|
|
212
|
+
if (!stmt || typeof stmt !== 'object')
|
|
213
|
+
return;
|
|
214
|
+
// HAL-op statements: track pin-mode state from gpio.set_mode and warn on
|
|
215
|
+
// gpio.read/write/toggle without prior mode configuration. After HAL
|
|
216
|
+
// resolution, pin method calls (D2.isHigh(), D2.high()) become these
|
|
217
|
+
// structured ops — the method-call form no longer exists at validation time.
|
|
218
|
+
if (stmt.kind === 'hal-op') {
|
|
219
|
+
checkGpioHalOp(stmt.operation);
|
|
220
|
+
}
|
|
221
|
+
// Scan expressions in other statement types for nested cuttlefish-calls
|
|
222
|
+
if (stmt.kind === 'assign') {
|
|
223
|
+
const a = stmt;
|
|
224
|
+
if (a.value)
|
|
225
|
+
scanExpression(a.value);
|
|
226
|
+
}
|
|
227
|
+
if (stmt.kind === 'var_decl') {
|
|
228
|
+
const v = stmt;
|
|
229
|
+
if (v.initializer)
|
|
230
|
+
scanExpression(v.initializer);
|
|
231
|
+
}
|
|
232
|
+
if (stmt.kind === 'return') {
|
|
233
|
+
const r = stmt;
|
|
234
|
+
if (r.value)
|
|
235
|
+
scanExpression(r.value);
|
|
236
|
+
}
|
|
237
|
+
if (stmt.kind === 'call') {
|
|
238
|
+
const c = stmt;
|
|
239
|
+
if (c.args && Array.isArray(c.args)) {
|
|
240
|
+
for (const arg of c.args)
|
|
241
|
+
scanExpression(arg);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (stmt.kind === 'if') {
|
|
245
|
+
const i = stmt;
|
|
246
|
+
if (i.condition)
|
|
247
|
+
scanExpression(i.condition);
|
|
248
|
+
}
|
|
249
|
+
if (stmt.kind === 'while' || stmt.kind === 'do_while') {
|
|
250
|
+
const w = stmt;
|
|
251
|
+
if (w.condition)
|
|
252
|
+
scanExpression(w.condition);
|
|
253
|
+
}
|
|
254
|
+
if (stmt.kind === 'for') {
|
|
255
|
+
const f = stmt;
|
|
256
|
+
if (f.condition)
|
|
257
|
+
scanExpression(f.condition);
|
|
258
|
+
if (f.initializer)
|
|
259
|
+
checkStatement(f.initializer);
|
|
260
|
+
if (f.increment)
|
|
261
|
+
checkStatement(f.increment);
|
|
262
|
+
}
|
|
263
|
+
if (stmt.kind === 'switch') {
|
|
264
|
+
const s = stmt;
|
|
265
|
+
if (s.expression)
|
|
266
|
+
scanExpression(s.expression);
|
|
267
|
+
}
|
|
268
|
+
// Recurse into nested statements (if branches, loop bodies, etc.)
|
|
269
|
+
scanNestedStatements(stmt, checkStatement);
|
|
270
|
+
};
|
|
271
|
+
// Scan all program locations
|
|
272
|
+
if (program.topLevelStatements) {
|
|
273
|
+
for (const stmt of program.topLevelStatements)
|
|
274
|
+
checkStatement(stmt);
|
|
275
|
+
}
|
|
276
|
+
if (program.functions) {
|
|
277
|
+
for (const fn of program.functions) {
|
|
278
|
+
if (fn.statements) {
|
|
279
|
+
for (const stmt of fn.statements)
|
|
280
|
+
checkStatement(stmt);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (program.classes) {
|
|
285
|
+
for (const cls of program.classes) {
|
|
286
|
+
if (cls.methods) {
|
|
287
|
+
for (const method of cls.methods) {
|
|
288
|
+
if (method.statements) {
|
|
289
|
+
for (const stmt of method.statements)
|
|
290
|
+
checkStatement(stmt);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (cls.constructor?.statements) {
|
|
295
|
+
for (const stmt of cls.constructor.statements)
|
|
296
|
+
checkStatement(stmt);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return diagnostics;
|
|
301
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PeripheralUsage } from './peripheral-usage.js';
|
|
2
|
+
import type { BoardConstants } from './board-resolver.js';
|
|
3
|
+
import type { Diagnostic } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Validate unsafe pin usage and generate warning diagnostics.
|
|
6
|
+
*
|
|
7
|
+
* @param usage - Peripheral usage analysis containing pinsUsed set
|
|
8
|
+
* @param boardConstants - Board constants containing pins.unsafe array
|
|
9
|
+
* @returns Array of diagnostic warnings for unsafe pin usage
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateUnsafePins(usage: PeripheralUsage, boardConstants: BoardConstants | undefined): Diagnostic[];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Pin Safety Validation
|
|
3
|
+
//
|
|
4
|
+
// Validates that unsafe pins are used with appropriate warnings.
|
|
5
|
+
// Generates diagnostics when pins marked as unsafe are used in the program.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
import { findBoardPinByName, formatPinReference } from './board-pin-utils.js';
|
|
8
|
+
function buildUnsafePinMessage(pinName, boardConstants) {
|
|
9
|
+
const boardName = boardConstants?.get('name');
|
|
10
|
+
const boardLabel = typeof boardName === 'string' && boardName.length > 0
|
|
11
|
+
? ` on ${boardName}`
|
|
12
|
+
: '';
|
|
13
|
+
const metadata = findBoardPinByName(pinName, boardConstants);
|
|
14
|
+
const pinReference = formatPinReference(pinName, metadata);
|
|
15
|
+
if (metadata?.warnings[0]) {
|
|
16
|
+
return `${pinReference} is marked as unsafe${boardLabel}. ${metadata.warnings[0]}.`;
|
|
17
|
+
}
|
|
18
|
+
if (metadata?.note) {
|
|
19
|
+
return `${pinReference} is marked as unsafe${boardLabel}. ${metadata.note}.`;
|
|
20
|
+
}
|
|
21
|
+
if (metadata && metadata.alternateFunctions.length > 0) {
|
|
22
|
+
return `${pinReference} is marked as unsafe${boardLabel}. It is also used for ${metadata.alternateFunctions.join(', ')}.`;
|
|
23
|
+
}
|
|
24
|
+
return `${pinReference} is marked as unsafe${boardLabel}. Use with caution - this pin may have special boot behavior or conflict with system functions.`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate unsafe pin usage and generate warning diagnostics.
|
|
28
|
+
*
|
|
29
|
+
* @param usage - Peripheral usage analysis containing pinsUsed set
|
|
30
|
+
* @param boardConstants - Board constants containing pins.unsafe array
|
|
31
|
+
* @returns Array of diagnostic warnings for unsafe pin usage
|
|
32
|
+
*/
|
|
33
|
+
export function validateUnsafePins(usage, boardConstants) {
|
|
34
|
+
const diagnostics = [];
|
|
35
|
+
if (!boardConstants)
|
|
36
|
+
return diagnostics;
|
|
37
|
+
if (!usage.pinsUsed || usage.pinsUsed.size === 0)
|
|
38
|
+
return diagnostics;
|
|
39
|
+
// Get unsafe pins list (stored as comma-separated string by board-resolver)
|
|
40
|
+
const unsafePinsStr = boardConstants.get('pins.unsafe');
|
|
41
|
+
if (!unsafePinsStr)
|
|
42
|
+
return diagnostics;
|
|
43
|
+
const unsafePins = unsafePinsStr.split(',').map(s => s.trim());
|
|
44
|
+
// Check each used pin against the unsafe list
|
|
45
|
+
for (const pinName of usage.pinsUsed) {
|
|
46
|
+
const boardPin = findBoardPinByName(pinName, boardConstants);
|
|
47
|
+
const canonicalPinName = boardPin?.name ?? pinName;
|
|
48
|
+
if (unsafePins.includes(canonicalPinName)) {
|
|
49
|
+
diagnostics.push({
|
|
50
|
+
severity: 'warning',
|
|
51
|
+
message: buildUnsafePinMessage(pinName, boardConstants),
|
|
52
|
+
code: 'unsafe-pin-usage',
|
|
53
|
+
source: 'pin-safety',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return diagnostics;
|
|
58
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combined program analysis - single-pass detection of multiple features.
|
|
3
|
+
*
|
|
4
|
+
* Instead of traversing the IR multiple times for different checks
|
|
5
|
+
* (hasConsoleCalls, hasArrayInObjectLiteral, hasThrowStatements, etc.),
|
|
6
|
+
* this module performs all checks in a single traversal.
|
|
7
|
+
*/
|
|
8
|
+
import { ProgramIR, PlatformStrategy } from "../api/index.js";
|
|
9
|
+
export interface ProgramAnalysisResult {
|
|
10
|
+
hasConsoleCalls: boolean;
|
|
11
|
+
hasArrayInObjectLiteral: boolean;
|
|
12
|
+
hasThrowStatements: boolean;
|
|
13
|
+
hasStdMathCalls: boolean;
|
|
14
|
+
usesVectorTypes: boolean;
|
|
15
|
+
usesStdString: boolean;
|
|
16
|
+
usesStdFunction: boolean;
|
|
17
|
+
declaredTypes: string[];
|
|
18
|
+
usedPolyfillHelpers: Set<string>;
|
|
19
|
+
usesStringConversion: boolean;
|
|
20
|
+
usesDateNow: boolean;
|
|
21
|
+
usesMillis: boolean;
|
|
22
|
+
usesNullish: boolean;
|
|
23
|
+
/** True when this file actually emits a cuttlefish_nullish/exists/is_nullish CALL
|
|
24
|
+
* (e.g. from a `??` lowering), as opposed to just referencing the
|
|
25
|
+
* CUTTLEFISH_UNDEFINED macro via a `null`/`undefined` literal. Used to decide
|
|
26
|
+
* whether non-entry headers need the full nullish shim block. */
|
|
27
|
+
usesNullishHelper: boolean;
|
|
28
|
+
usesNum: boolean;
|
|
29
|
+
usesTiming: boolean;
|
|
30
|
+
usesWDT: boolean;
|
|
31
|
+
usesStrPtr: boolean;
|
|
32
|
+
hasSerialBegin: boolean;
|
|
33
|
+
hasGenerators: boolean;
|
|
34
|
+
usesStdMap: boolean;
|
|
35
|
+
/** Number of setInterval/setTimeout call sites in the program. Used to size
|
|
36
|
+
* __tc_TimerRuntime::MAX_TIMERS to the observed count (floor 1) rather than
|
|
37
|
+
* a blind constant, so a one-timer program links one slot, not eight. */
|
|
38
|
+
timerCallCount: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Analyze a program IR in a single pass to detect all features.
|
|
42
|
+
* This replaces multiple separate traversals with one combined traversal.
|
|
43
|
+
*/
|
|
44
|
+
export declare function analyzeProgram(program: ProgramIR, strategy: PlatformStrategy): ProgramAnalysisResult;
|