@typecad/cuttlefish 1.0.0-alpha.13 → 1.0.0-alpha.15
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/README.md +82 -79
- package/assets/editor-extensions/typecad-debug/README.md +141 -0
- package/assets/editor-extensions/typecad-debug/out/extension.js +347 -0
- package/assets/editor-extensions/typecad-debug/out/extension.js.map +1 -0
- package/assets/editor-extensions/typecad-debug/package.json +76 -0
- package/assets/editor-extensions/typecad-ui/LICENSE +27 -0
- package/assets/editor-extensions/typecad-ui/README.md +52 -0
- package/assets/editor-extensions/typecad-ui/file-icon-dark.png +0 -0
- package/assets/editor-extensions/typecad-ui/file-icon-light.png +0 -0
- package/assets/editor-extensions/typecad-ui/icon.png +0 -0
- package/assets/editor-extensions/typecad-ui/language-configuration.json +43 -0
- package/assets/editor-extensions/typecad-ui/package.json +54 -0
- package/assets/editor-extensions/typecad-ui/snippets/typecad-ui.json +80 -0
- package/assets/editor-extensions/typecad-ui/syntaxes/markdown-ui.json +45 -0
- package/assets/editor-extensions/typecad-ui/syntaxes/typecad-ui.tmLanguage.json +1269 -0
- package/dist/api/config.d.ts +30 -27
- package/dist/api/schema/types.d.ts +20 -3
- package/dist/api/shared/async-runtime-static.d.ts +1 -1
- package/dist/api/shared/async-runtime-static.js +5 -5
- package/dist/api/shared/async-types.d.ts +3 -2
- package/dist/api/shared/board-catalog.d.ts +2 -0
- package/dist/api/shared/board-catalog.js +6 -0
- package/dist/api/shared/board-resolver.d.ts +4 -7
- package/dist/api/shared/board-resolver.js +2 -1
- package/dist/api/shared/coop-scheduler.d.ts +1 -1
- package/dist/api/shared/coop-scheduler.js +1 -1
- package/dist/api/shared/cpp-type-ir.d.ts +1 -1
- package/dist/api/shared/cpp-type-ir.js +1 -1
- package/dist/api/shared/display-profile.d.ts +1 -1
- package/dist/api/shared/display-profile.js +3 -5
- package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
- package/dist/api/shared/framework-manifest-registry.js +0 -1
- package/dist/api/shared/framework-manifest.d.ts +65 -507
- package/dist/api/shared/framework-manifest.js +6 -11
- package/dist/api/shared/hal-op-ir.d.ts +294 -685
- package/dist/api/shared/hal-op-ir.js +31 -65
- package/dist/api/shared/index.d.ts +0 -4
- package/dist/api/shared/index.js +1 -7
- package/dist/api/shared/ir-core.d.ts +6 -0
- package/dist/api/shared/ir-declarations.d.ts +4 -0
- package/dist/api/shared/ir.d.ts +1 -3
- package/dist/api/shared/platform-strategy.d.ts +14 -37
- package/dist/api/shared/polyfill-helper-registry.js +0 -5
- package/dist/api/shared/polyfill-types.js +0 -27
- package/dist/api/shared/promise-runtime.js +3 -3
- package/dist/api/shared/spdx-licenses.d.ts +12 -10
- package/dist/api/shared/spdx-licenses.js +1 -1
- package/dist/api/shared/toolchain-types.d.ts +1 -1
- package/dist/api/shared/toolchain-types.js +3 -3
- package/dist/api/shared/types.d.ts +0 -3
- package/dist/api/shared/validate-framework-manifest.js +13 -33
- package/dist/board-catalog/dts-reader.d.ts +220 -0
- package/dist/board-catalog/dts-reader.js +1052 -0
- package/dist/board-catalog/index.d.ts +11 -0
- package/dist/board-catalog/index.js +12 -0
- package/dist/board-catalog/pinconfig.d.ts +48 -0
- package/dist/board-catalog/pinconfig.js +263 -0
- package/dist/board-catalog/sdk.d.ts +82 -0
- package/dist/board-catalog/sdk.js +180 -0
- package/dist/board-catalog/store.d.ts +196 -0
- package/dist/board-catalog/store.js +363 -0
- package/dist/board-catalog/types.d.ts +233 -0
- package/dist/board-catalog/types.js +7 -0
- package/dist/board-catalog/walker.d.ts +112 -0
- package/dist/board-catalog/walker.js +1101 -0
- package/dist/cli-utils.d.ts +2 -2
- package/dist/cli-utils.js +5 -5
- package/dist/cli.js +227 -244
- package/dist/config-loader.d.ts +14 -19
- package/dist/config-loader.js +242 -78
- package/dist/config-schema.d.ts +19 -227
- package/dist/config-schema.js +9 -8
- package/dist/contract/board-generator.d.ts +4 -4
- package/dist/contract/board-generator.js +16 -5
- package/dist/contract/contract-parser.d.ts +36 -127
- package/dist/contract/contract-parser.js +76 -0
- package/dist/contract/index.d.ts +1 -1
- package/dist/contract/index.js +70 -21
- package/dist/create/active-board-catalog.d.ts +9 -0
- package/dist/create/active-board-catalog.js +94 -0
- package/dist/create/board-catalog.generated.d.ts +96 -0
- package/dist/create/board-catalog.generated.js +128737 -0
- package/dist/create/board-search.d.ts +23 -0
- package/dist/create/board-search.js +88 -0
- package/dist/create/editor-integration.d.ts +32 -0
- package/dist/create/editor-integration.js +257 -0
- package/dist/create/eslint-rules-template.d.ts +2 -2
- package/dist/create/framework-catalog.d.ts +48 -8
- package/dist/create/framework-catalog.js +58 -44
- package/dist/create/index.d.ts +8 -13
- package/dist/create/index.js +5 -9
- package/dist/create/mcu-target.d.ts +39 -0
- package/dist/create/mcu-target.js +80 -0
- package/dist/create/pack-targets.d.ts +19 -0
- package/dist/create/pack-targets.js +56 -0
- package/dist/create/{init-scaffold.d.ts → scaffold.d.ts} +8 -11
- package/dist/create/{init-scaffold.js → scaffold.js} +28 -87
- package/dist/create/templates.d.ts +51 -0
- package/dist/create/{init-templates.js → templates.js} +135 -116
- package/dist/create/wizard.d.ts +19 -0
- package/dist/create/wizard.js +314 -0
- package/dist/debug/preprocessor.d.ts +5 -0
- package/dist/debug/preprocessor.js +31 -7
- package/dist/diagnostics/diagnostics-report.d.ts +1 -1
- package/dist/diagnostics/diagnostics-report.js +3 -11
- package/dist/diagnostics/json-schema.d.ts +1 -1
- package/dist/diagnostics/md-writer.js +2 -2
- package/dist/diagnostics/mermaid-builder.d.ts +1 -1
- package/dist/diagnostics/mermaid-builder.js +1 -1
- package/dist/emit/cpp-emitter.js +4 -1
- package/dist/emit/emitters/class-emitter.js +32 -4
- package/dist/emit/emitters/emitter-context.d.ts +11 -0
- package/dist/emit/emitters/entrypoint-synthesizer.js +1 -1
- package/dist/emit/emitters/function-emitter-impl.js +33 -17
- package/dist/emit/emitters/output-finalizer.d.ts +7 -0
- package/dist/emit/emitters/output-finalizer.js +31 -23
- package/dist/emit/emitters/setup.js +147 -63
- package/dist/emit/emitters/top-level-prep.js +1 -1
- package/dist/emit/emitters/type-decl-emitter.js +13 -8
- package/dist/emit/emitters/ui-emitter.js +1 -1
- package/dist/emit/expression-renderer.d.ts +3 -3
- package/dist/emit/expression-renderer.js +17 -7
- package/dist/emit/route-hal-op.js +17 -48
- package/dist/emit/snprintf-helpers.d.ts +1 -3
- package/dist/emit/snprintf-helpers.js +1 -39
- package/dist/emit/statement-renderer.d.ts +0 -4
- package/dist/emit/statement-renderer.js +54 -45
- package/dist/emit/utils/async-state-machine.d.ts +16 -9
- package/dist/emit/utils/async-state-machine.js +56 -54
- package/dist/emit/utils/comment-helpers.d.ts +0 -8
- package/dist/emit/utils/comment-helpers.js +1 -1
- package/dist/emit/utils/cpp-helpers.d.ts +2 -2
- package/dist/emit/utils/cpp-helpers.js +2 -2
- package/dist/emit/utils/hal-op-cpp-type.js +4 -6
- package/dist/emit/utils/index.d.ts +3 -3
- package/dist/emit/utils/index.js +3 -3
- package/dist/emit/utils/type-inference.d.ts +1 -29
- package/dist/emit/utils/type-inference.js +0 -75
- package/dist/framework-package.d.ts +3 -0
- package/dist/framework-package.js +23 -6
- package/dist/framework-registry.d.ts +5 -5
- package/dist/frameworks/native/graphics/terminal-preview.d.ts +5 -0
- package/dist/frameworks/native/graphics/terminal-preview.js +33 -0
- package/dist/frameworks/native/index.d.ts +3 -0
- package/dist/frameworks/native/index.js +15 -0
- package/dist/frameworks/native/native-compile.d.ts +17 -0
- package/dist/frameworks/native/native-compile.js +170 -0
- package/dist/frameworks/native/native-config.d.ts +41 -0
- package/dist/frameworks/native/native-config.js +7 -0
- package/dist/frameworks/native/strategy.d.ts +97 -0
- package/dist/frameworks/native/strategy.js +664 -0
- package/dist/ir/board-resolver.d.ts +18 -23
- package/dist/ir/board-resolver.js +43 -401
- package/dist/ir/build-ir-state.d.ts +3 -0
- package/dist/ir/build-ir-state.js +42 -0
- package/dist/ir/build-ir.d.ts +1 -1
- package/dist/ir/build-ir.js +64 -45
- package/dist/ir/declaration-builders.js +1 -0
- package/dist/ir/expression-to-ir.js +17 -10
- package/dist/ir/hal/hal-emitter.d.ts +0 -2
- package/dist/ir/hal/hal-emitter.js +92 -41
- package/dist/ir/hal/hal-parser.d.ts +5 -5
- package/dist/ir/hal/hal-parser.js +128 -36
- package/dist/ir/hal/hal-plugins.d.ts +0 -1
- package/dist/ir/hal/hal-plugins.js +425 -716
- package/dist/ir/heap-analysis.js +2 -41
- package/dist/ir/identifier-collector.js +32 -20
- package/dist/ir/network-validation.js +7 -11
- package/dist/ir/ownership-analysis.js +75 -13
- package/dist/ir/peripheral-usage.d.ts +8 -2
- package/dist/ir/peripheral-usage.js +78 -149
- package/dist/ir/peripheral-validation.js +23 -3
- package/dist/ir/pin-capability-validation.d.ts +12 -0
- package/dist/ir/pin-capability-validation.js +61 -97
- package/dist/ir/pin-mode-validation.js +5 -5
- package/dist/ir/program-analysis.d.ts +8 -15
- package/dist/ir/program-analysis.js +140 -323
- package/dist/ir/pulldown-validation.js +11 -4
- package/dist/ir/resource-analysis.js +15 -3
- package/dist/ir/statement-to-ir.js +0 -6
- package/dist/ir/timing-validation.js +1 -1
- package/dist/ir/transformers/array-methods.js +11 -5
- package/dist/ir/transformers/call-statement.js +20 -87
- package/dist/ir/transformers/callback-context-registry.d.ts +1 -1
- package/dist/ir/transformers/callback-context-registry.js +8 -16
- package/dist/ir/transformers/control-flow.js +0 -13
- package/dist/ir/transformers/expressions.js +10 -9
- package/dist/ir/transformers/hal-call-resolver.d.ts +2 -2
- package/dist/ir/transformers/hal-call-resolver.js +24 -10
- package/dist/ir/transformers/hal-emit-helpers.d.ts +2 -2
- package/dist/ir/transformers/hal-emit-helpers.js +2 -2
- package/dist/ir/transformers/namespace-methods.js +1 -1
- package/dist/ir/transformers/ui-callback-lowering.d.ts +0 -2
- package/dist/ir/transformers/ui-callback-lowering.js +0 -24
- package/dist/ir/transformers/variables.js +338 -42
- package/dist/ir/try-catch-validation.js +4 -3
- package/dist/ir/type-resolution.js +15 -4
- package/dist/ir/validation-orchestrator.js +0 -9
- package/dist/libdef/cpp-to-decl.d.ts +0 -9
- package/dist/libdef/cpp-to-decl.js +0 -72
- package/dist/libdef/registry.d.ts +0 -1
- package/dist/libdef/registry.js +1 -24
- package/dist/library/catalog.d.ts +35 -0
- package/dist/library/catalog.js +67 -0
- package/dist/library/cli.d.ts +2 -0
- package/dist/library/cli.js +168 -0
- package/dist/library/init.d.ts +25 -0
- package/dist/library/init.js +397 -0
- package/dist/library/install.d.ts +9 -0
- package/dist/library/install.js +80 -0
- package/dist/library/registry-search.d.ts +34 -0
- package/dist/library/registry-search.js +50 -0
- package/dist/library/validate.d.ts +17 -0
- package/dist/library/validate.js +175 -0
- package/dist/library-packages.d.ts +95 -0
- package/dist/library-packages.js +275 -0
- package/dist/mapping/peripheral-names.js +9 -4
- package/dist/mapping/source-map.d.ts +3 -4
- package/dist/mapping/source-map.js +12 -18
- package/dist/orchestrator/graph-builder.d.ts +3 -3
- package/dist/orchestrator/graph-builder.js +29 -12
- package/dist/orchestrator/type-checker.d.ts +3 -3
- package/dist/orchestrator/type-checker.js +3 -3
- package/dist/platform/async-runtime.js +1 -1
- package/dist/platform/coop-scheduler-runtime.js +2 -2
- package/dist/platform/generic-debug-codegen.d.ts +36 -0
- package/dist/platform/generic-debug-codegen.js +185 -0
- package/dist/platform/generic-strategy.d.ts +3 -4
- package/dist/platform/generic-strategy.js +5 -80
- package/dist/platform/index.js +1 -1
- package/dist/platform/registry.d.ts +2 -2
- package/dist/platform/registry.js +2 -2
- package/dist/preview/client.js +17 -3
- package/dist/safety/asil-decorators.d.ts +32 -0
- package/dist/safety/asil-decorators.js +32 -0
- package/dist/safety/authoring.d.ts +85 -0
- package/dist/safety/authoring.js +61 -0
- package/dist/safety/engine.d.ts +3 -0
- package/dist/safety/engine.js +83 -0
- package/dist/safety/hal/ops.d.ts +48 -0
- package/dist/safety/hal/ops.js +46 -0
- package/dist/safety/iso26262/analyze.d.ts +13 -0
- package/dist/safety/iso26262/analyze.js +29 -0
- package/dist/safety/iso26262/asil.d.ts +10 -0
- package/dist/safety/iso26262/asil.js +22 -0
- package/dist/safety/iso26262/collect.d.ts +14 -0
- package/dist/safety/iso26262/collect.js +137 -0
- package/dist/safety/iso26262/goto-checker.d.ts +10 -0
- package/dist/safety/iso26262/goto-checker.js +72 -0
- package/dist/safety/iso26262/heap-checker.d.ts +7 -0
- package/dist/safety/iso26262/heap-checker.js +57 -0
- package/dist/safety/iso26262/init-checker.d.ts +13 -0
- package/dist/safety/iso26262/init-checker.js +127 -0
- package/dist/safety/iso26262/loop-checker.d.ts +7 -0
- package/dist/safety/iso26262/loop-checker.js +86 -0
- package/dist/safety/iso26262/recursion-checker.d.ts +9 -0
- package/dist/safety/iso26262/recursion-checker.js +134 -0
- package/dist/safety/iso26262/sidecar-writer.d.ts +25 -0
- package/dist/safety/iso26262/sidecar-writer.js +13 -0
- package/dist/safety/passes/pinMode-intercept.d.ts +3 -0
- package/dist/safety/passes/pinMode-intercept.js +60 -0
- package/dist/safety/runtime/mode-table.d.ts +5 -0
- package/dist/safety/runtime/mode-table.js +55 -0
- package/dist/safety/runtime/polyfills.d.ts +6 -0
- package/dist/safety/runtime/polyfills.js +12 -0
- package/dist/safety/runtime/result-struct.d.ts +11 -0
- package/dist/safety/runtime/result-struct.js +98 -0
- package/dist/safety/runtime/safe-int.d.ts +33 -0
- package/dist/safety/runtime/safe-int.js +170 -0
- package/dist/safety/runtime/safe-traits.d.ts +4 -0
- package/dist/safety/runtime/safe-traits.js +95 -0
- package/dist/safety/runtime/safe-variable.d.ts +39 -0
- package/dist/safety/runtime/safe-variable.js +226 -0
- package/dist/safety/runtime/vote.d.ts +8 -0
- package/dist/safety/runtime/vote.js +92 -0
- package/dist/safety/runtime/write-verify.d.ts +8 -0
- package/dist/safety/runtime/write-verify.js +71 -0
- package/dist/safety/safe-int-types.d.ts +45 -0
- package/dist/safety/safe-int-types.js +25 -0
- package/dist/safety/safe-variable-types.d.ts +29 -0
- package/dist/safety/safe-variable-types.js +19 -0
- package/dist/safety/safety-bridge.d.ts +5 -6
- package/dist/safety/safety-bridge.js +15 -28
- package/dist/safety/sidecar-bridge.d.ts +1 -3
- package/dist/safety/sidecar-bridge.js +3 -20
- package/dist/safety/specifiers.d.ts +6 -0
- package/dist/safety/specifiers.js +14 -0
- package/dist/safety-hook.d.ts +8 -7
- package/dist/safety-hook.js +12 -13
- package/dist/testing.d.ts +5 -6
- package/dist/testing.js +5 -5
- package/dist/transpile/resolution.d.ts +1 -1
- package/dist/transpile/resolution.js +18 -9
- package/dist/transpile/test-pins.d.ts +18 -0
- package/dist/transpile/test-pins.js +142 -0
- package/dist/transpile.d.ts +1 -2
- package/dist/transpile.js +90 -29
- package/dist/types.d.ts +45 -26
- package/dist/ui-hook.d.ts +1 -1
- package/dist/utils/cli.d.ts +2 -2
- package/dist/utils/cli.js +160 -157
- package/dist/utils/fs.d.ts +3 -4
- package/dist/utils/fs.js +4 -5
- package/dist/utils/strings.d.ts +0 -1
- package/dist/utils/strings.js +0 -8
- package/dist/utils/ui.d.ts +5 -2
- package/dist/utils/ui.js +13 -3
- package/package.json +158 -149
- package/dist/add-preset.d.ts +0 -4
- package/dist/add-preset.js +0 -74
- package/dist/api/shared/async-symbol-detector.d.ts +0 -11
- package/dist/api/shared/async-symbol-detector.js +0 -140
- package/dist/api/shared/native-display-op-resolver.d.ts +0 -10
- package/dist/api/shared/native-display-op-resolver.js +0 -64
- package/dist/create/board-checklist.d.ts +0 -2
- package/dist/create/board-checklist.js +0 -52
- package/dist/create/board-codegen.d.ts +0 -9
- package/dist/create/board-codegen.js +0 -238
- package/dist/create/board-generators.d.ts +0 -12
- package/dist/create/board-generators.js +0 -651
- package/dist/create/board-spec.d.ts +0 -637
- package/dist/create/board-spec.js +0 -214
- package/dist/create/init-templates.d.ts +0 -28
- package/dist/create/init-wizard.d.ts +0 -8
- package/dist/create/init-wizard.js +0 -182
- package/dist/install/framework-catalog.d.ts +0 -53
- package/dist/install/framework-catalog.js +0 -107
- package/dist/install/handle-install.d.ts +0 -35
- package/dist/install/handle-install.js +0 -177
- package/dist/install/index.d.ts +0 -4
- package/dist/install/index.js +0 -3
- package/dist/ir/pin-state-tracking.d.ts +0 -58
- package/dist/ir/pin-state-tracking.js +0 -182
- package/dist/ir/pwm-timer-sharing.d.ts +0 -4
- package/dist/ir/pwm-timer-sharing.js +0 -94
- package/dist/ir/timer0-pwm-timing-conflict.d.ts +0 -4
- package/dist/ir/timer0-pwm-timing-conflict.js +0 -72
- package/dist/libdef/component-decls.d.ts +0 -2
- package/dist/libdef/component-decls.js +0 -6
- package/dist/libdef/component-discovery.d.ts +0 -43
- package/dist/libdef/component-discovery.js +0 -83
- package/dist/theme-tokens.d.ts +0 -22
- package/dist/theme-tokens.js +0 -172
|
@@ -2,17 +2,116 @@
|
|
|
2
2
|
* Combined program analysis - single-pass detection of multiple features.
|
|
3
3
|
*
|
|
4
4
|
* Instead of traversing the IR multiple times for different checks
|
|
5
|
-
* (
|
|
5
|
+
* (hasArrayInObjectLiteral, hasThrowStatements, etc.),
|
|
6
6
|
* this module performs all checks in a single traversal.
|
|
7
7
|
*/
|
|
8
8
|
import { POLYFILL_HELPER_MAP } from "../api/shared/index.js";
|
|
9
9
|
import { parseCppType } from "../api/shared/cpp-type-ir.js";
|
|
10
|
-
import { loweredConsoleInCallback } from "./transformers/ui-callback-lowering.js";
|
|
11
10
|
import { watchPinSpecs, clickHandlers } from "./transformers/ui-call-resolver.js";
|
|
12
11
|
import { canvasBindings } from "./transformers/canvas-lowering.js";
|
|
13
12
|
import { getInputBindings, getListBindings } from "./transformers/ui-reactive.js";
|
|
13
|
+
import { getTranspileResolvedHalOps } from "./build-ir-state.js";
|
|
14
|
+
/**
|
|
15
|
+
* Map one HAL op name onto the peripheral usage flags its lowering requires.
|
|
16
|
+
* Called from three places: the hal-expr expression case, the hal-op statement
|
|
17
|
+
* case, and analyzeProgram's merge of transpile-resolved ops (ops baked into
|
|
18
|
+
* another HAL method's emit lines never appear as IR nodes, so without the
|
|
19
|
+
* merge their peripheral's init block + include were dropped — e.g.
|
|
20
|
+
* `sense.readMillivolts()` inside `USB0.writeLine(...)` compiled against a
|
|
21
|
+
* missing adc.h). Keep in sync with the per-strategy gating in the frameworks.
|
|
22
|
+
*/
|
|
23
|
+
function applyHalOpUsageFlags(opName, result) {
|
|
24
|
+
if (opName.startsWith("display.")) {
|
|
25
|
+
result.usesGPIO = true;
|
|
26
|
+
result.usesDisplay = true;
|
|
27
|
+
}
|
|
28
|
+
if (opName.startsWith("gpio."))
|
|
29
|
+
result.usesGPIO = true;
|
|
30
|
+
if (opName === "gpio.read")
|
|
31
|
+
result.usesDigitalRead = true;
|
|
32
|
+
if (opName.startsWith("pwm."))
|
|
33
|
+
result.usesPWM = true;
|
|
34
|
+
if (opName.startsWith("rmt."))
|
|
35
|
+
result.usesRmt = true;
|
|
36
|
+
if (opName.startsWith("adc."))
|
|
37
|
+
result.usesADC = true;
|
|
38
|
+
if (opName.startsWith("dac."))
|
|
39
|
+
result.usesDAC = true;
|
|
40
|
+
if (opName.startsWith("wdt."))
|
|
41
|
+
result.usesWdt = true;
|
|
42
|
+
if (opName.startsWith("spi."))
|
|
43
|
+
result.usesSPI = true;
|
|
44
|
+
if (opName.startsWith("i2c."))
|
|
45
|
+
result.usesI2C = true;
|
|
46
|
+
if (opName.startsWith("uart."))
|
|
47
|
+
result.usesUart = true;
|
|
48
|
+
if (opName.startsWith("usb."))
|
|
49
|
+
result.usesUsb = true;
|
|
50
|
+
// Safety HAL ops (@typecad/safety) — map each op to the __tc_safety_*
|
|
51
|
+
// polyfill helper it triggers, so the mode-table and voter polyfills
|
|
52
|
+
// survive tree-shaking when actually used. Matches the resolveSafetyOp
|
|
53
|
+
// output naming. Cast through string because the HALOpIR operation union is
|
|
54
|
+
// closed and doesn't include safety.* ops (those are owned by the optional
|
|
55
|
+
// @typecad/safety package).
|
|
56
|
+
const safetyOpName = opName;
|
|
57
|
+
if (safetyOpName === "safety.record_pin_mode") {
|
|
58
|
+
result.usedPolyfillHelpers.add("__tc_safety_record_pin_mode");
|
|
59
|
+
}
|
|
60
|
+
if (safetyOpName === "safety.read_safe") {
|
|
61
|
+
result.usedPolyfillHelpers.add("__tc_safety_read_safe");
|
|
62
|
+
}
|
|
63
|
+
if (safetyOpName === "safety.write_verify") {
|
|
64
|
+
result.usedPolyfillHelpers.add("__tc_safety_write_verify");
|
|
65
|
+
}
|
|
66
|
+
if (opName.startsWith("interrupt."))
|
|
67
|
+
result.usesInterrupts = true;
|
|
68
|
+
if (opName.startsWith("pulse."))
|
|
69
|
+
result.usesPulse = true;
|
|
70
|
+
if (opName.startsWith("shift."))
|
|
71
|
+
result.usesShift = true;
|
|
72
|
+
if (opName.startsWith("wifi.")) {
|
|
73
|
+
result.usesWifi = true;
|
|
74
|
+
if (opName === "wifi.join" || opName === "wifi.connect_start" || opName === "wifi.disconnect") {
|
|
75
|
+
result.usesWifiConnect = true;
|
|
76
|
+
if (opName === "wifi.join")
|
|
77
|
+
result.usesWifiConnectBlocking = true;
|
|
78
|
+
}
|
|
79
|
+
else if (opName.startsWith("wifi.scan"))
|
|
80
|
+
result.usesWifiScan = true;
|
|
81
|
+
else if (opName === "wifi.is_connected" || opName === "wifi.local_ip" || opName === "wifi.rssi" || opName === "wifi.mac")
|
|
82
|
+
result.usesWifiQuery = true;
|
|
83
|
+
else if (opName === "wifi.on_event")
|
|
84
|
+
result.usesWifiConfig = true;
|
|
85
|
+
}
|
|
86
|
+
if (opName.startsWith("http."))
|
|
87
|
+
result.usesHttp = true;
|
|
88
|
+
if (opName.startsWith("ble."))
|
|
89
|
+
result.usesBle = true;
|
|
90
|
+
if (opName.startsWith("preferences."))
|
|
91
|
+
result.usesPreferences = true;
|
|
92
|
+
if (opName.startsWith("random."))
|
|
93
|
+
result.usesRandom = true;
|
|
94
|
+
if (opName.startsWith("fs."))
|
|
95
|
+
result.usesFS = true;
|
|
96
|
+
if (opName.startsWith("mdns."))
|
|
97
|
+
result.usesMdns = true;
|
|
98
|
+
if (opName.startsWith("mqtt."))
|
|
99
|
+
result.usesMqtt = true;
|
|
100
|
+
if (opName.startsWith("ota."))
|
|
101
|
+
result.usesOta = true;
|
|
102
|
+
if (opName.startsWith("temp."))
|
|
103
|
+
result.usesTemp = true;
|
|
104
|
+
if (opName.startsWith("sensor."))
|
|
105
|
+
result.usesSensor = true;
|
|
106
|
+
if (opName.startsWith("hwtimer.") || opName.startsWith("counter."))
|
|
107
|
+
result.usesHwtimer = true;
|
|
108
|
+
if (opName.startsWith("capacitive."))
|
|
109
|
+
result.usesCapacitive = true;
|
|
110
|
+
}
|
|
14
111
|
// Regex for std:: math calls
|
|
15
|
-
|
|
112
|
+
// Both the lowered form (std::<fn>) and the source form (Math.<fn>) — the
|
|
113
|
+
// analysis can see either depending on when expressions render.
|
|
114
|
+
const MATH_PATTERN = /\b(?:std::|Math\.)(floor|ceil|round|trunc|sqrt|pow|sin|cos|tan|asin|acos|atan|abs|max|min)\b/;
|
|
16
115
|
/**
|
|
17
116
|
* Analyze an expression for all features in a single pass.
|
|
18
117
|
*/
|
|
@@ -38,20 +137,6 @@ function analyzeExpression(expr, result, strategy) {
|
|
|
38
137
|
}
|
|
39
138
|
}
|
|
40
139
|
}
|
|
41
|
-
// Timer polyfill sizing — Timing.setInterval/Timing.setTimeout in
|
|
42
|
-
// expression position (e.g. `const id = Timing.setInterval(...)`) lower to
|
|
43
|
-
// a raw expression whose value contains `__tc_setInterval(...)`. The
|
|
44
|
-
// callee-based counter in the "call" case only fires for bare timer
|
|
45
|
-
// calls; without this the timer_methods polyfill is gated off and the
|
|
46
|
-
// link fails: "'__tc_setInterval' was not declared in this scope".
|
|
47
|
-
{
|
|
48
|
-
const intervals = expr.value.match(/__tc_setInterval\s*\(/g);
|
|
49
|
-
if (intervals)
|
|
50
|
-
result.timerCallCount += intervals.length;
|
|
51
|
-
const timeouts = expr.value.match(/__tc_setTimeout\s*\(/g);
|
|
52
|
-
if (timeouts)
|
|
53
|
-
result.timerCallCount += timeouts.length;
|
|
54
|
-
}
|
|
55
140
|
if (/\bString\s*\(/.test(expr.value)) {
|
|
56
141
|
result.usesStringConversion = true;
|
|
57
142
|
}
|
|
@@ -106,9 +191,6 @@ function analyzeExpression(expr, result, strategy) {
|
|
|
106
191
|
}
|
|
107
192
|
break;
|
|
108
193
|
case "method-call":
|
|
109
|
-
if (strategy.isConsoleCall(expr.callee)) {
|
|
110
|
-
result.hasConsoleCalls = true;
|
|
111
|
-
}
|
|
112
194
|
if (/\bmillis\b/.test(expr.callee) || /\bdelay\b/.test(expr.callee) || /\bmicros\b/.test(expr.callee)) {
|
|
113
195
|
result.usesMillis = true;
|
|
114
196
|
}
|
|
@@ -150,7 +232,7 @@ function analyzeExpression(expr, result, strategy) {
|
|
|
150
232
|
result.usesWDT = true;
|
|
151
233
|
}
|
|
152
234
|
// Native AVR peripheral usage from namespace-prefixed method calls
|
|
153
|
-
// (Serial.* / SPI.* / Wire.*
|
|
235
|
+
// (Serial.* / SPI.* / Wire.*). The HAL resolver lowers these
|
|
154
236
|
// to structured hal-ops (detected in analyzeStatement) OR to bare
|
|
155
237
|
// lowered calls; these checks cover the pre-lowering and direct forms.
|
|
156
238
|
if (expr.callee.startsWith("Serial.") || expr.callee === "Serial") {
|
|
@@ -162,9 +244,6 @@ function analyzeExpression(expr, result, strategy) {
|
|
|
162
244
|
if (expr.callee.startsWith("Wire.") || expr.callee === "Wire") {
|
|
163
245
|
result.usesI2C = true;
|
|
164
246
|
}
|
|
165
|
-
if (expr.callee.startsWith("EEPROM.") || expr.callee === "EEPROM") {
|
|
166
|
-
result.usesEEPROM = true;
|
|
167
|
-
}
|
|
168
247
|
// map()/constrain() Arduino-API calls appear as method-call exprs
|
|
169
248
|
// (callee "map"/"constrain"). framework-avr lowers these to _native_map/
|
|
170
249
|
// _native_constrain via symbol aliases, so the helpers are dead code
|
|
@@ -173,12 +252,6 @@ function analyzeExpression(expr, result, strategy) {
|
|
|
173
252
|
result.usesMap = true;
|
|
174
253
|
if (expr.callee === "constrain")
|
|
175
254
|
result.usesConstrain = true;
|
|
176
|
-
// Count setInterval/setTimeout call sites (post-rename callee names) so
|
|
177
|
-
// __tc_TimerRuntime::MAX_TIMERS can be sized to the observed count.
|
|
178
|
-
if (expr.callee === "__tc_setInterval" || expr.callee === "__tc_setTimeout"
|
|
179
|
-
|| expr.callee === "setInterval" || expr.callee === "setTimeout") {
|
|
180
|
-
result.timerCallCount++;
|
|
181
|
-
}
|
|
182
255
|
for (const arg of expr.args) {
|
|
183
256
|
analyzeExpression(arg, result, strategy);
|
|
184
257
|
}
|
|
@@ -271,98 +344,11 @@ function analyzeExpression(expr, result, strategy) {
|
|
|
271
344
|
// a value-returning HAL op used in a var-init or expression context fails
|
|
272
345
|
// to set its analysis flag — the framework then drops the matching init
|
|
273
346
|
// block + forced includes (e.g. __tc_adc_read was emitted but the
|
|
274
|
-
// CUTTLEFISH_ADC init block and adc_oneshot.h include were not).
|
|
275
|
-
//
|
|
347
|
+
// CUTTLEFISH_ADC init block and adc_oneshot.h include were not). Both
|
|
348
|
+
// this case and the hal-op statement case delegate to
|
|
349
|
+
// applyHalOpUsageFlags, which also covers transpile-resolved ops.
|
|
276
350
|
if (expr.operation && typeof expr.operation.operation === "string") {
|
|
277
|
-
|
|
278
|
-
if (opName.startsWith("display.")) {
|
|
279
|
-
result.usesGPIO = true;
|
|
280
|
-
result.usesDisplay = true;
|
|
281
|
-
}
|
|
282
|
-
if (opName.startsWith("gpio."))
|
|
283
|
-
result.usesGPIO = true;
|
|
284
|
-
if (opName === "gpio.read")
|
|
285
|
-
result.usesDigitalRead = true;
|
|
286
|
-
if (opName.startsWith("pwm."))
|
|
287
|
-
result.usesPWM = true;
|
|
288
|
-
if (opName.startsWith("rmt."))
|
|
289
|
-
result.usesRmt = true;
|
|
290
|
-
if (opName.startsWith("adc."))
|
|
291
|
-
result.usesADC = true;
|
|
292
|
-
if (opName.startsWith("dac."))
|
|
293
|
-
result.usesDAC = true;
|
|
294
|
-
if (opName.startsWith("power."))
|
|
295
|
-
result.usesPower = true;
|
|
296
|
-
if (opName.startsWith("wdt."))
|
|
297
|
-
result.usesWdt = true;
|
|
298
|
-
// Safety HAL ops (@typecad/safety) — map each op to the
|
|
299
|
-
// __tc_safety_* polyfill helper it triggers, so the mode-table and
|
|
300
|
-
// voter polyfills survive tree-shaking when actually used. Matches
|
|
301
|
-
// the resolveSafetyOp output naming. Cast through string because the
|
|
302
|
-
// HALOpIR operation union is closed and doesn't include safety.* ops
|
|
303
|
-
// (those are owned by the optional @typecad/safety package).
|
|
304
|
-
const safetyOpName = opName;
|
|
305
|
-
if (safetyOpName === "safety.record_pin_mode") {
|
|
306
|
-
result.usedPolyfillHelpers.add("__tc_safety_record_pin_mode");
|
|
307
|
-
}
|
|
308
|
-
if (safetyOpName === "safety.read_safe") {
|
|
309
|
-
result.usedPolyfillHelpers.add("__tc_safety_read_safe");
|
|
310
|
-
}
|
|
311
|
-
if (safetyOpName === "safety.write_verify") {
|
|
312
|
-
result.usedPolyfillHelpers.add("__tc_safety_write_verify");
|
|
313
|
-
}
|
|
314
|
-
if (opName.startsWith("interrupt."))
|
|
315
|
-
result.usesInterrupts = true;
|
|
316
|
-
if (opName.startsWith("pulse."))
|
|
317
|
-
result.usesPulse = true;
|
|
318
|
-
if (opName.startsWith("shift."))
|
|
319
|
-
result.usesShift = true;
|
|
320
|
-
if (opName.startsWith("tone."))
|
|
321
|
-
result.usesTone = true;
|
|
322
|
-
if (opName.startsWith("i2c."))
|
|
323
|
-
result.usesI2C = true;
|
|
324
|
-
if (opName.startsWith("spi."))
|
|
325
|
-
result.usesSPI = true;
|
|
326
|
-
if (opName.startsWith("uart."))
|
|
327
|
-
result.usesUart = true;
|
|
328
|
-
if (opName.startsWith("wifi.")) {
|
|
329
|
-
result.usesWifi = true;
|
|
330
|
-
if (opName === "wifi.connect" || opName === "wifi.connect_start" || opName === "wifi.disconnect") {
|
|
331
|
-
result.usesWifiConnect = true;
|
|
332
|
-
if (opName === "wifi.connect")
|
|
333
|
-
result.usesWifiConnectBlocking = true;
|
|
334
|
-
}
|
|
335
|
-
else if (opName.startsWith("wifi.scan"))
|
|
336
|
-
result.usesWifiScan = true;
|
|
337
|
-
else if (opName === "wifi.status" || opName === "wifi.local_ip" || opName === "wifi.rssi" || opName === "wifi.mac")
|
|
338
|
-
result.usesWifiQuery = true;
|
|
339
|
-
else if (opName === "wifi.set_hostname")
|
|
340
|
-
result.usesWifiConfig = true;
|
|
341
|
-
}
|
|
342
|
-
if (opName.startsWith("http."))
|
|
343
|
-
result.usesHttp = true;
|
|
344
|
-
if (opName.startsWith("ble."))
|
|
345
|
-
result.usesBle = true;
|
|
346
|
-
if (opName.startsWith("preferences."))
|
|
347
|
-
result.usesPreferences = true;
|
|
348
|
-
if (opName.startsWith("random."))
|
|
349
|
-
result.usesRandom = true;
|
|
350
|
-
if (opName.startsWith("fs."))
|
|
351
|
-
result.usesFS = true;
|
|
352
|
-
if (opName.startsWith("mdns."))
|
|
353
|
-
result.usesMdns = true;
|
|
354
|
-
if (opName.startsWith("mqtt."))
|
|
355
|
-
result.usesMqtt = true;
|
|
356
|
-
if (opName.startsWith("ota."))
|
|
357
|
-
result.usesOta = true;
|
|
358
|
-
if (opName.startsWith("temp."))
|
|
359
|
-
result.usesTemp = true;
|
|
360
|
-
if (opName.startsWith("hwtimer."))
|
|
361
|
-
result.usesHwtimer = true;
|
|
362
|
-
if (opName.startsWith("capacitive."))
|
|
363
|
-
result.usesCapacitive = true;
|
|
364
|
-
if (opName.startsWith("worker."))
|
|
365
|
-
result.usesWorker = true;
|
|
351
|
+
applyHalOpUsageFlags(expr.operation.operation, result);
|
|
366
352
|
}
|
|
367
353
|
break;
|
|
368
354
|
}
|
|
@@ -376,9 +362,6 @@ function analyzeStatement(statement, result, strategy) {
|
|
|
376
362
|
}
|
|
377
363
|
switch (statement.kind) {
|
|
378
364
|
case "call":
|
|
379
|
-
if (strategy.isConsoleCall(statement.callee)) {
|
|
380
|
-
result.hasConsoleCalls = true;
|
|
381
|
-
}
|
|
382
365
|
if (statement.callee === "Serial.begin" || statement.callee.endsWith(".begin")) {
|
|
383
366
|
result.hasSerialBegin = true;
|
|
384
367
|
}
|
|
@@ -403,6 +386,17 @@ function analyzeStatement(statement, result, strategy) {
|
|
|
403
386
|
if (statement.callee === "__tc_print" || statement.callee === "__tc_println") {
|
|
404
387
|
result.usedPolyfillHelpers.add(statement.callee);
|
|
405
388
|
}
|
|
389
|
+
// emit()/rawCpp() statements (__EMIT__) carry verbatim C++ in string
|
|
390
|
+
// args — the raw-text regex below never sees them (the arg is a string
|
|
391
|
+
// IR node, not raw text). Scan them for the printf family so a debug
|
|
392
|
+
// build (or any rawCpp'd stdio call) pulls in <cstdio>.
|
|
393
|
+
if (statement.callee === "__EMIT__") {
|
|
394
|
+
for (const arg of statement.args) {
|
|
395
|
+
if (arg.kind === "string" && /\b(printf|fprintf|sprintf|snprintf|getchar|putchar|puts)\s*\(/.test(arg.value)) {
|
|
396
|
+
result.usesCstdio = true;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
406
400
|
// Namespace-qualified polyfill entry points used as bare call statements
|
|
407
401
|
// (e.g. `Timing.delay(5);`). The expression-level analyzer (case
|
|
408
402
|
// "method-call") already checks these prefixes, but a statement-form call
|
|
@@ -419,15 +413,10 @@ function analyzeStatement(statement, result, strategy) {
|
|
|
419
413
|
if (statement.callee.startsWith("WDT.") || statement.callee === "WDT") {
|
|
420
414
|
result.usesWDT = true;
|
|
421
415
|
}
|
|
422
|
-
// Native AVR peripheral usage from statement-form calls.
|
|
423
|
-
//
|
|
424
|
-
//
|
|
425
|
-
|
|
426
|
-
result.usesTone = true;
|
|
427
|
-
}
|
|
428
|
-
// console.* is NOT UART: on ESP-IDF it lowers to printf, on Arduino to
|
|
429
|
-
// Serial via hasConsoleCalls. Only real UART HAL / Serial peripheral
|
|
430
|
-
// usage should gate the uart shim (avoids unused __tc_uart*_init).
|
|
416
|
+
// Native AVR peripheral usage from statement-form calls. Serial.* drives
|
|
417
|
+
// UART; the namespace prefixes mirror the method-call checks above.
|
|
418
|
+
// Only real UART HAL / Serial peripheral usage should gate the uart shim
|
|
419
|
+
// (avoids unused __tc_uart*_init).
|
|
431
420
|
if (statement.callee.startsWith("_uart_")) {
|
|
432
421
|
result.usesUart = true;
|
|
433
422
|
}
|
|
@@ -440,26 +429,11 @@ function analyzeStatement(statement, result, strategy) {
|
|
|
440
429
|
if (statement.callee.startsWith("Wire.") || statement.callee === "Wire") {
|
|
441
430
|
result.usesI2C = true;
|
|
442
431
|
}
|
|
443
|
-
if (statement.callee.startsWith("EEPROM.") || statement.callee === "EEPROM") {
|
|
444
|
-
result.usesEEPROM = true;
|
|
445
|
-
}
|
|
446
432
|
// Statement-form map()/constrain() mirror the method-call checks above.
|
|
447
433
|
if (statement.callee === "map")
|
|
448
434
|
result.usesMap = true;
|
|
449
435
|
if (statement.callee === "constrain")
|
|
450
436
|
result.usesConstrain = true;
|
|
451
|
-
// Statement-form setInterval/setTimeout mirror the expression-level
|
|
452
|
-
// timer-count (analyzeExpression). A top-level `setInterval(...)` call
|
|
453
|
-
// stays a `call` statement (never becomes a method-call expression — see
|
|
454
|
-
// the comment above re: Timing./Num./WDT.), so without this mirror the
|
|
455
|
-
// timer polyfill gate (timerCallCount) stays 0 and __tc_setInterval is
|
|
456
|
-
// emitted as a call but never defined (demo: "'__tc_setInterval' was not
|
|
457
|
-
// declared in this scope"). The arrow-callback hoister renames the callee
|
|
458
|
-
// to __tc_setInterval/__tc_setTimeout, so check both pre- and post-rename.
|
|
459
|
-
if (statement.callee === "setInterval" || statement.callee === "setTimeout"
|
|
460
|
-
|| statement.callee === "__tc_setInterval" || statement.callee === "__tc_setTimeout") {
|
|
461
|
-
result.timerCallCount++;
|
|
462
|
-
}
|
|
463
437
|
// The HAL resolver lowers WDT.*/Timing.* namespace calls to bare AVR
|
|
464
438
|
// library functions (WDT.reset() → wdt_reset(), Timing.delay() → delay(),
|
|
465
439
|
// Timing.millis() → millis()). When that happens the `WDT.`/`Timing.`
|
|
@@ -487,27 +461,6 @@ function analyzeStatement(statement, result, strategy) {
|
|
|
487
461
|
}
|
|
488
462
|
}
|
|
489
463
|
}
|
|
490
|
-
// Timer polyfill sizing for __EMIT__ statements (callee "__EMIT__"):
|
|
491
|
-
// Timing.setInterval/Timing.setTimeout can lower to an __EMIT__ call whose
|
|
492
|
-
// single string arg is the raw C++ payload, e.g.
|
|
493
|
-
// `return __tc_setInterval(<cb>, 500)`. The callee-based timer counter
|
|
494
|
-
// above only fires for bare setInterval/__tc_setInterval calls, so without
|
|
495
|
-
// this the timer_methods polyfill is gated off and the link fails:
|
|
496
|
-
// "'__tc_setInterval' was not declared in this scope". Count call sites
|
|
497
|
-
// embedded in the raw payload. (The hal-op raw-code path has a parallel
|
|
498
|
-
// counter below.)
|
|
499
|
-
if (statement.callee === "__EMIT__") {
|
|
500
|
-
for (const arg of statement.args) {
|
|
501
|
-
if (arg && arg.kind === "string" && typeof arg.value === "string") {
|
|
502
|
-
const matches = arg.value.match(/__tc_setInterval\s*\(/g);
|
|
503
|
-
if (matches)
|
|
504
|
-
result.timerCallCount += matches.length;
|
|
505
|
-
const timeouts = arg.value.match(/__tc_setTimeout\s*\(/g);
|
|
506
|
-
if (timeouts)
|
|
507
|
-
result.timerCallCount += timeouts.length;
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
464
|
for (const arg of statement.args) {
|
|
512
465
|
analyzeExpression(arg, result, strategy);
|
|
513
466
|
}
|
|
@@ -612,116 +565,7 @@ function analyzeStatement(statement, result, strategy) {
|
|
|
612
565
|
// always be emitted. Same blind spot the wdt.* fix below the raw-code
|
|
613
566
|
// block addresses for the watchdog.
|
|
614
567
|
if (statement.operation && typeof statement.operation.operation === "string") {
|
|
615
|
-
|
|
616
|
-
if (opName.startsWith("spi."))
|
|
617
|
-
result.usesSPI = true;
|
|
618
|
-
if (opName.startsWith("i2c."))
|
|
619
|
-
result.usesI2C = true;
|
|
620
|
-
if (opName.startsWith("tone."))
|
|
621
|
-
result.usesTone = true;
|
|
622
|
-
if (opName.startsWith("uart."))
|
|
623
|
-
result.usesUart = true;
|
|
624
|
-
// Display HAL ops (display.init from ui.mount, display.flush per frame)
|
|
625
|
-
// always imply GPIO usage (CS/DC/RST pins). Native SPI/I2C display
|
|
626
|
-
// adapters emit their own transport #includes (driver/spi_master.h,
|
|
627
|
-
// driver/i2c_master.h) — we don't force usesSPI/usesI2C here because
|
|
628
|
-
// that would pull headers even for non-display SPI/I2C code, and the
|
|
629
|
-
// display's transport type can't be determined from the op alone.
|
|
630
|
-
if (opName.startsWith("display.")) {
|
|
631
|
-
result.usesGPIO = true;
|
|
632
|
-
result.usesDisplay = true;
|
|
633
|
-
}
|
|
634
|
-
// ESP32 peripheral usage — framework-esp32 gates IDF driver blocks
|
|
635
|
-
// and forced includes on these. No-op for other frameworks (their
|
|
636
|
-
// shimLines emit no CUTTLEFISH_* blocks with these marker names).
|
|
637
|
-
if (opName.startsWith("gpio."))
|
|
638
|
-
result.usesGPIO = true;
|
|
639
|
-
if (opName === "gpio.read")
|
|
640
|
-
result.usesDigitalRead = true;
|
|
641
|
-
if (opName.startsWith("pwm."))
|
|
642
|
-
result.usesPWM = true;
|
|
643
|
-
if (opName.startsWith("rmt."))
|
|
644
|
-
result.usesRmt = true;
|
|
645
|
-
if (opName.startsWith("adc."))
|
|
646
|
-
result.usesADC = true;
|
|
647
|
-
if (opName.startsWith("dac."))
|
|
648
|
-
result.usesDAC = true;
|
|
649
|
-
if (opName.startsWith("power."))
|
|
650
|
-
result.usesPower = true;
|
|
651
|
-
if (opName.startsWith("wdt."))
|
|
652
|
-
result.usesWdt = true;
|
|
653
|
-
// Safety HAL ops (@typecad/safety) — map each op to the
|
|
654
|
-
// __tc_safety_* polyfill helper it triggers, so the mode-table and
|
|
655
|
-
// voter polyfills survive tree-shaking when actually used. Matches
|
|
656
|
-
// the resolveSafetyOp output naming. Cast through string because the
|
|
657
|
-
// HALOpIR operation union is closed and doesn't include safety.* ops
|
|
658
|
-
// (those are owned by the optional @typecad/safety package).
|
|
659
|
-
const safetyOpName = opName;
|
|
660
|
-
if (safetyOpName === "safety.record_pin_mode") {
|
|
661
|
-
result.usedPolyfillHelpers.add("__tc_safety_record_pin_mode");
|
|
662
|
-
}
|
|
663
|
-
if (safetyOpName === "safety.read_safe") {
|
|
664
|
-
result.usedPolyfillHelpers.add("__tc_safety_read_safe");
|
|
665
|
-
}
|
|
666
|
-
if (safetyOpName === "safety.write_verify") {
|
|
667
|
-
result.usedPolyfillHelpers.add("__tc_safety_write_verify");
|
|
668
|
-
}
|
|
669
|
-
if (opName.startsWith("interrupt."))
|
|
670
|
-
result.usesInterrupts = true;
|
|
671
|
-
if (opName.startsWith("pulse."))
|
|
672
|
-
result.usesPulse = true;
|
|
673
|
-
if (opName.startsWith("shift."))
|
|
674
|
-
result.usesShift = true;
|
|
675
|
-
if (opName.startsWith("wifi.")) {
|
|
676
|
-
result.usesWifi = true;
|
|
677
|
-
if (opName === "wifi.connect" || opName === "wifi.connect_start" || opName === "wifi.disconnect") {
|
|
678
|
-
result.usesWifiConnect = true;
|
|
679
|
-
if (opName === "wifi.connect")
|
|
680
|
-
result.usesWifiConnectBlocking = true;
|
|
681
|
-
}
|
|
682
|
-
else if (opName.startsWith("wifi.scan"))
|
|
683
|
-
result.usesWifiScan = true;
|
|
684
|
-
else if (opName === "wifi.status" || opName === "wifi.local_ip" || opName === "wifi.rssi" || opName === "wifi.mac")
|
|
685
|
-
result.usesWifiQuery = true;
|
|
686
|
-
else if (opName === "wifi.set_hostname")
|
|
687
|
-
result.usesWifiConfig = true;
|
|
688
|
-
}
|
|
689
|
-
if (opName.startsWith("http."))
|
|
690
|
-
result.usesHttp = true;
|
|
691
|
-
if (opName.startsWith("ble."))
|
|
692
|
-
result.usesBle = true;
|
|
693
|
-
if (opName.startsWith("preferences."))
|
|
694
|
-
result.usesPreferences = true;
|
|
695
|
-
if (opName.startsWith("random."))
|
|
696
|
-
result.usesRandom = true;
|
|
697
|
-
if (opName.startsWith("fs."))
|
|
698
|
-
result.usesFS = true;
|
|
699
|
-
if (opName.startsWith("mdns."))
|
|
700
|
-
result.usesMdns = true;
|
|
701
|
-
if (opName.startsWith("mqtt."))
|
|
702
|
-
result.usesMqtt = true;
|
|
703
|
-
if (opName.startsWith("ota."))
|
|
704
|
-
result.usesOta = true;
|
|
705
|
-
if (opName.startsWith("temp."))
|
|
706
|
-
result.usesTemp = true;
|
|
707
|
-
if (opName.startsWith("hwtimer."))
|
|
708
|
-
result.usesHwtimer = true;
|
|
709
|
-
if (opName.startsWith("capacitive."))
|
|
710
|
-
result.usesCapacitive = true;
|
|
711
|
-
if (opName.startsWith("worker."))
|
|
712
|
-
result.usesWorker = true;
|
|
713
|
-
// Timing HAL ops (timing.delay/millis/micros) carry a typed operation
|
|
714
|
-
// name, not raw code, so the regex scans below miss them. Mirror the
|
|
715
|
-
// raw-code timing detection here so usesMillis/usesTiming (and thus
|
|
716
|
-
// usesNativeTiming) fire for `delay()`/`millis()` on AVR.
|
|
717
|
-
if (opName === "timing.delay" || opName === "timing.delay_microseconds"
|
|
718
|
-
|| opName === "timing.millis" || opName === "timing.micros") {
|
|
719
|
-
result.usesTiming = true;
|
|
720
|
-
result.usesMillis = true;
|
|
721
|
-
}
|
|
722
|
-
if (opName === "timing.millis" || opName === "timing.micros") {
|
|
723
|
-
result.usesWallClock = true;
|
|
724
|
-
}
|
|
568
|
+
applyHalOpUsageFlags(statement.operation.operation, result);
|
|
725
569
|
}
|
|
726
570
|
// Scan raw C++ code in HAL ops for polyfill helper usage
|
|
727
571
|
if (statement.operation && statement.operation.operation === "raw" && typeof statement.operation.code === "string") {
|
|
@@ -759,29 +603,8 @@ function analyzeStatement(statement, result, strategy) {
|
|
|
759
603
|
if (code.includes("__tc_print(")) {
|
|
760
604
|
result.usedPolyfillHelpers.add("__tc_print");
|
|
761
605
|
}
|
|
762
|
-
//
|
|
763
|
-
//
|
|
764
|
-
// rawCpp body and emits a raw hal-op whose code is e.g.
|
|
765
|
-
// `return __tc_setInterval(<cb>, 500)`. The callee-based counter below
|
|
766
|
-
// (statement.callee === "__tc_setInterval") never fires for these — the
|
|
767
|
-
// statement is a hal-op, not a bare timer call — so without counting
|
|
768
|
-
// here the timer_methods polyfill is gated off (timerCallCount == 0)
|
|
769
|
-
// and the link fails: "'__tc_setInterval' was not declared in this
|
|
770
|
-
// scope". Count each __tc_setInterval/__tc_setTimeout call site in the
|
|
771
|
-
// raw code. The optional `return ` prefix is emitted by value-returning
|
|
772
|
-
// HAL methods (statement context), so match with or without it.
|
|
773
|
-
const intervalSites = code.match(/__tc_setInterval\s*\(/g);
|
|
774
|
-
if (intervalSites)
|
|
775
|
-
result.timerCallCount += intervalSites.length;
|
|
776
|
-
const timeoutSites = code.match(/__tc_setTimeout\s*\(/g);
|
|
777
|
-
if (timeoutSites)
|
|
778
|
-
result.timerCallCount += timeoutSites.length;
|
|
779
|
-
// Native AVR peripheral usage inside raw hal-op code (e.g. the
|
|
780
|
-
// EEPROM namespace lowers to `EEPROM.write(...)` in a raw hal-op;
|
|
781
|
-
// Serial/SPI/Wire may appear as lowered library calls too).
|
|
782
|
-
if (/\bEEPROM\b/.test(code) || /\beeprom_(read|write|update)_byte\b/.test(code)) {
|
|
783
|
-
result.usesEEPROM = true;
|
|
784
|
-
}
|
|
606
|
+
// Native AVR peripheral usage inside raw hal-op code (Serial/SPI/Wire
|
|
607
|
+
// may appear as lowered library calls).
|
|
785
608
|
if (/\bSerial\b/.test(code)) {
|
|
786
609
|
result.usesUart = true;
|
|
787
610
|
}
|
|
@@ -820,7 +643,6 @@ function analyzeStatement(statement, result, strategy) {
|
|
|
820
643
|
*/
|
|
821
644
|
export function analyzeProgram(program, strategy) {
|
|
822
645
|
const result = {
|
|
823
|
-
hasConsoleCalls: false,
|
|
824
646
|
hasArrayInObjectLiteral: false,
|
|
825
647
|
hasThrowStatements: false,
|
|
826
648
|
hasStdMathCalls: false,
|
|
@@ -840,23 +662,20 @@ export function analyzeProgram(program, strategy) {
|
|
|
840
662
|
usesWDT: false,
|
|
841
663
|
usesStrPtr: false,
|
|
842
664
|
usesUart: false,
|
|
665
|
+
usesUsb: false,
|
|
843
666
|
usesSPI: false,
|
|
844
667
|
usesI2C: false,
|
|
845
|
-
usesEEPROM: false,
|
|
846
|
-
usesTone: false,
|
|
847
668
|
usesMap: false,
|
|
848
669
|
usesConstrain: false,
|
|
849
670
|
usesNativeTiming: false,
|
|
850
671
|
hasSerialBegin: false,
|
|
851
672
|
hasGenerators: false,
|
|
852
673
|
usesStdMap: false,
|
|
853
|
-
timerCallCount: 0,
|
|
854
674
|
usesGPIO: false,
|
|
855
675
|
usesPWM: false,
|
|
856
676
|
usesRmt: false,
|
|
857
677
|
usesADC: false,
|
|
858
678
|
usesDAC: false,
|
|
859
|
-
usesPower: false,
|
|
860
679
|
usesWdt: false,
|
|
861
680
|
usesInterrupts: false,
|
|
862
681
|
usesPulse: false,
|
|
@@ -876,9 +695,9 @@ export function analyzeProgram(program, strategy) {
|
|
|
876
695
|
usesMqtt: false,
|
|
877
696
|
usesOta: false,
|
|
878
697
|
usesTemp: false,
|
|
698
|
+
usesSensor: false,
|
|
879
699
|
usesHwtimer: false,
|
|
880
700
|
usesCapacitive: false,
|
|
881
|
-
usesWorker: false,
|
|
882
701
|
hasAsync: false,
|
|
883
702
|
usesSet: false,
|
|
884
703
|
usesAlgorithm: false,
|
|
@@ -1003,7 +822,7 @@ export function analyzeProgram(program, strategy) {
|
|
|
1003
822
|
// Analyze UI callback bodies that live outside program.functions
|
|
1004
823
|
// (onClick / watchPin / drawCanvas / bindInput / bindList). They now carry
|
|
1005
824
|
// StatementIR[] from the main lowerStatementList pipeline, so console /
|
|
1006
|
-
// helper usage is visible here the same way
|
|
825
|
+
// helper usage is visible here the same way nested-function bodies are.
|
|
1007
826
|
for (const wp of watchPinSpecs()) {
|
|
1008
827
|
for (const stmt of wp.bodyStatements ?? [])
|
|
1009
828
|
analyzeStatement(stmt, result, strategy);
|
|
@@ -1028,27 +847,25 @@ export function analyzeProgram(program, strategy) {
|
|
|
1028
847
|
for (const stmt of spec.tapStatements ?? [])
|
|
1029
848
|
analyzeStatement(stmt, result, strategy);
|
|
1030
849
|
}
|
|
1031
|
-
//
|
|
1032
|
-
//
|
|
1033
|
-
//
|
|
1034
|
-
//
|
|
1035
|
-
//
|
|
1036
|
-
|
|
1037
|
-
result
|
|
850
|
+
// HAL ops the transpiler resolved to C++ text while inlining one HAL method
|
|
851
|
+
// inside another (e.g. `sense.readMillivolts()` in a USB0.writeLine template)
|
|
852
|
+
// never appear as hal-op/hal-expr IR nodes, so the walks above can't see
|
|
853
|
+
// them. The lowering seams record every op they resolve; merge their
|
|
854
|
+
// peripheral flags here.
|
|
855
|
+
for (const opName of getTranspileResolvedHalOps()) {
|
|
856
|
+
applyHalOpUsageFlags(opName, result);
|
|
1038
857
|
}
|
|
1039
858
|
// Derive the comprehensive native-timing gate for the AVR millis() Timer0
|
|
1040
859
|
// ISR. The ISR is needed whenever the program touches the soft clock
|
|
1041
|
-
// directly (millis/delay/micros) OR has a hidden consumer:
|
|
1042
|
-
//
|
|
1043
|
-
//
|
|
1044
|
-
//
|
|
1045
|
-
//
|
|
1046
|
-
// ISR even when it never uses timing.
|
|
860
|
+
// directly (millis/delay/micros) OR has a hidden consumer: async functions
|
|
861
|
+
// (the runtime polls millis). The per-frame UI tick is injected by the
|
|
862
|
+
// emitter, not present in user source — the setup emitter ORs entryHasUI()
|
|
863
|
+
// in at the consume site. Without this gate, every AVR program pulled in
|
|
864
|
+
// the Timer0 ISR even when it never uses timing.
|
|
1047
865
|
const hasAsync = program.functions.some(fn => fn.isAsync);
|
|
1048
866
|
result.hasAsync = hasAsync;
|
|
1049
867
|
result.usesNativeTiming = result.usesMillis
|
|
1050
868
|
|| result.usesTiming
|
|
1051
|
-
|| result.timerCallCount > 0
|
|
1052
869
|
|| hasAsync;
|
|
1053
870
|
return result;
|
|
1054
871
|
}
|