@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
package/dist/ir/heap-analysis.js
CHANGED
|
@@ -6,36 +6,7 @@
|
|
|
6
6
|
// optimizations and runtime behavior.
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import { parseCppType, renderCppType, bareType } from "../api/shared/cpp-type-ir.js";
|
|
9
|
-
/** Type sizes for common C++ types on
|
|
10
|
-
const AVR_TYPE_SIZES = {
|
|
11
|
-
bool: 1,
|
|
12
|
-
char: 1,
|
|
13
|
-
"unsigned char": 1,
|
|
14
|
-
"signed char": 1,
|
|
15
|
-
uint8_t: 1,
|
|
16
|
-
int8_t: 1,
|
|
17
|
-
byte: 1,
|
|
18
|
-
short: 2,
|
|
19
|
-
"unsigned short": 2,
|
|
20
|
-
int16_t: 2,
|
|
21
|
-
uint16_t: 2,
|
|
22
|
-
int: 2,
|
|
23
|
-
"unsigned int": 2,
|
|
24
|
-
int32_t: 4,
|
|
25
|
-
uint32_t: 4,
|
|
26
|
-
long: 4,
|
|
27
|
-
"unsigned long": 4,
|
|
28
|
-
int64_t: 8,
|
|
29
|
-
uint64_t: 8,
|
|
30
|
-
float: 4,
|
|
31
|
-
double: 4,
|
|
32
|
-
"long long": 8,
|
|
33
|
-
size_t: 2,
|
|
34
|
-
ptrdiff_t: 2,
|
|
35
|
-
pointer: 2,
|
|
36
|
-
"char*": 2,
|
|
37
|
-
"const char*": 2,
|
|
38
|
-
};
|
|
9
|
+
/** Type sizes for common C++ types on 32-bit targets */
|
|
39
10
|
const ESP32_TYPE_SIZES = {
|
|
40
11
|
bool: 1,
|
|
41
12
|
char: 1,
|
|
@@ -69,14 +40,6 @@ const ESP32_TYPE_SIZES = {
|
|
|
69
40
|
* Determine the type size table based on the target architecture.
|
|
70
41
|
*/
|
|
71
42
|
function getTypeSizes(architecture) {
|
|
72
|
-
const arch = (architecture ?? "").toLowerCase();
|
|
73
|
-
if (arch === "avr" || arch === "atmega328p" || arch === "atmega2560") {
|
|
74
|
-
return AVR_TYPE_SIZES;
|
|
75
|
-
}
|
|
76
|
-
if (arch === "esp32" || arch === "esp32s3" || arch === "esp32c3" || arch === "esp32c6" || arch === "xtensa" || arch === "riscv32") {
|
|
77
|
-
return ESP32_TYPE_SIZES;
|
|
78
|
-
}
|
|
79
|
-
// Default to ESP32 sizes (more conservative for 32-bit targets)
|
|
80
43
|
return ESP32_TYPE_SIZES;
|
|
81
44
|
}
|
|
82
45
|
/**
|
|
@@ -335,9 +298,7 @@ export function analyzeHeapUsage(program, architecture, callGraphNodes) {
|
|
|
335
298
|
// Add notes about approximations
|
|
336
299
|
notes.push("Heap estimate is static only — dynamic allocations (malloc/new) are not tracked.");
|
|
337
300
|
notes.push("String literals may be deduplicated by the compiler/linker.");
|
|
338
|
-
notes.push(
|
|
339
|
-
? "AVR sizes: int=2 bytes, pointer=2 bytes, float=4 bytes."
|
|
340
|
-
: `Default sizes: int=${typeSizes.int ?? "?"} bytes, pointer=${typeSizes.pointer ?? "?"} bytes, float=${typeSizes.float ?? "?"} bytes.`);
|
|
301
|
+
notes.push(`Default sizes: int=${typeSizes.int ?? "?"} bytes, pointer=${typeSizes.pointer ?? "?"} bytes, float=${typeSizes.float ?? "?"} bytes.`);
|
|
341
302
|
return {
|
|
342
303
|
globalVariables,
|
|
343
304
|
structSizes,
|
|
@@ -252,14 +252,20 @@ export function collectStatementIdentifiers(statement) {
|
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
break;
|
|
255
|
-
case "assign":
|
|
255
|
+
case "assign": {
|
|
256
256
|
identifiers.add(statement.target);
|
|
257
|
+
// An element-access target (`buf[i] = x`) references the base array;
|
|
258
|
+
// extract it so the buffer's var_decl survives tree-shaking (the raw
|
|
259
|
+
// `buf[i]` string never matches a declaration named `buf`).
|
|
260
|
+
addElementAccessBase(statement.target, identifiers);
|
|
257
261
|
for (const id of collectExpressionIdentifiers(statement.value)) {
|
|
258
262
|
identifiers.add(id);
|
|
259
263
|
}
|
|
260
264
|
break;
|
|
265
|
+
}
|
|
261
266
|
case "update":
|
|
262
267
|
identifiers.add(statement.target);
|
|
268
|
+
addElementAccessBase(statement.target, identifiers);
|
|
263
269
|
break;
|
|
264
270
|
case "return":
|
|
265
271
|
if (statement.value) {
|
|
@@ -414,12 +420,18 @@ export function collectStatementIdentifiers(statement) {
|
|
|
414
420
|
/**
|
|
415
421
|
* Extract identifier names from a HAL operation's string fields.
|
|
416
422
|
* This ensures the call graph tracks function references embedded in
|
|
417
|
-
* semantic HAL ops (e.g. the handler name in interrupt.
|
|
423
|
+
* semantic HAL ops (e.g. the handler name in interrupt.attach_flags).
|
|
418
424
|
*/
|
|
425
|
+
/** Record the base identifier of an element-access lvalue (`buf[i]` → `buf`). */
|
|
426
|
+
function addElementAccessBase(target, identifiers) {
|
|
427
|
+
const base = /^([A-Za-z_][A-Za-z0-9_]*)\s*\[/.exec(target);
|
|
428
|
+
if (base)
|
|
429
|
+
identifiers.add(base[1]);
|
|
430
|
+
}
|
|
419
431
|
function collectHALOpIdentifiers(op) {
|
|
420
432
|
const identifiers = new Set();
|
|
421
433
|
switch (op.operation) {
|
|
422
|
-
case "interrupt.
|
|
434
|
+
case "interrupt.attach_flags":
|
|
423
435
|
// handler is a resolved C++ function name (e.g. "myIsr" or a placeholder)
|
|
424
436
|
identifiers.add(op.handler);
|
|
425
437
|
break;
|
|
@@ -427,7 +439,7 @@ function collectHALOpIdentifiers(op) {
|
|
|
427
439
|
// handler is the user's onMessage callback name (callback() resolves it to
|
|
428
440
|
// a string). Without this the tree-shaker drops the function declaration —
|
|
429
441
|
// the mqtt.on_message op only carries the name, so the function has no
|
|
430
|
-
// other reference and looks unreachable. Same shape as interrupt.
|
|
442
|
+
// other reference and looks unreachable. Same shape as interrupt.attach_flags.
|
|
431
443
|
identifiers.add(op.handler);
|
|
432
444
|
break;
|
|
433
445
|
case "wifi.on_event":
|
|
@@ -451,22 +463,22 @@ function collectHALOpIdentifiers(op) {
|
|
|
451
463
|
}
|
|
452
464
|
// Other HAL ops have only numeric/literal fields — no identifier references
|
|
453
465
|
}
|
|
454
|
-
//
|
|
455
|
-
//
|
|
456
|
-
//
|
|
457
|
-
//
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
466
|
+
// HAL ops can carry resolved C++ expression texts in their string fields —
|
|
467
|
+
// not just wifi/http/mqtt (e.g. wifi.connect ssid: `WIFI_SSID`, a top-level
|
|
468
|
+
// const) but also peripheral lowerings that inline a user buffer into the
|
|
469
|
+
// emitted code (spi.transceive rx: `static_cast<const void*>(id)`). Scan
|
|
470
|
+
// every string field of every op for identifiers so referenced variables
|
|
471
|
+
// survive tree-shaking; quoted literals are skipped. Over-matching is safe
|
|
472
|
+
// (the reachability set just keeps a name no var_decl uses).
|
|
473
|
+
for (const value of Object.values(op)) {
|
|
474
|
+
if (typeof value !== "string" || value === op.operation)
|
|
475
|
+
continue;
|
|
476
|
+
if (/^".*"$/.test(value.trim()))
|
|
477
|
+
continue;
|
|
478
|
+
const matches = value.match(/[A-Za-z_][A-Za-z0-9_]*/g);
|
|
479
|
+
if (matches) {
|
|
480
|
+
for (const match of matches) {
|
|
481
|
+
identifiers.add(match);
|
|
470
482
|
}
|
|
471
483
|
}
|
|
472
484
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// wifi-blocking-in-loop (warning) blocking WiFi.connect()/scan() or
|
|
12
12
|
// Http send inside loop() — stalls every
|
|
13
13
|
// iteration; use async/await instead.
|
|
14
|
-
// wifi-ap-password-short (error)
|
|
14
|
+
// wifi-ap-password-short (error) WiFiAP with a literal WPA2
|
|
15
15
|
// password shorter than 8 characters —
|
|
16
16
|
// esp_wifi rejects it at runtime.
|
|
17
17
|
// http-max-body-large (warning) Http maxBody() above 64 KB — the
|
|
@@ -23,20 +23,16 @@
|
|
|
23
23
|
import { walkProgramIR, walkNestedStatements } from "./utils/walk-ir.js";
|
|
24
24
|
/** Architectures with no WiFi radio. Driven by the `architecture` board
|
|
25
25
|
* constant (from the MCU package); absent data emits nothing. */
|
|
26
|
-
const NO_RADIO_ARCHITECTURES = new Set(
|
|
26
|
+
const NO_RADIO_ARCHITECTURES = new Set();
|
|
27
27
|
/** Ops that bring the WiFi link (STA or AP) up. */
|
|
28
28
|
const LINK_UP_OPS = new Set([
|
|
29
|
-
"wifi.
|
|
29
|
+
"wifi.join",
|
|
30
30
|
"wifi.connect_start",
|
|
31
|
-
"wifi.connect_saved",
|
|
32
31
|
"wifi.ap_start",
|
|
33
32
|
]);
|
|
34
33
|
/** Blocking waits that stall loop() for their full duration. */
|
|
35
34
|
const BLOCKING_LOOP_OPS = new Set([
|
|
36
|
-
"wifi.
|
|
37
|
-
"wifi.connect_saved",
|
|
38
|
-
"wifi.wait_connected",
|
|
39
|
-
"wifi.wait_disconnected",
|
|
35
|
+
"wifi.join",
|
|
40
36
|
"wifi.scan",
|
|
41
37
|
"http.send",
|
|
42
38
|
]);
|
|
@@ -117,7 +113,7 @@ export function validateNetworkUsage(program, boardConstants) {
|
|
|
117
113
|
severity: "error",
|
|
118
114
|
code: "wifi-no-radio",
|
|
119
115
|
message: `WiFi/HTTP APIs are used but the target board's architecture ('${archName}') has no WiFi radio.`,
|
|
120
|
-
hint: "Target a WiFi-capable board (e.g.
|
|
116
|
+
hint: "Target a WiFi-capable board (e.g. esp32_devkitc/esp32/procpu) or remove the WiFi/HTTP calls.",
|
|
121
117
|
}));
|
|
122
118
|
// No point piling on the remaining checks for a board that can't radio.
|
|
123
119
|
return diagnostics;
|
|
@@ -128,7 +124,7 @@ export function validateNetworkUsage(program, boardConstants) {
|
|
|
128
124
|
severity: "warning",
|
|
129
125
|
code: "http-without-wifi",
|
|
130
126
|
message: "HTTP requests are made but the program never brings the WiFi link up — every request will fail at runtime.",
|
|
131
|
-
hint: "
|
|
127
|
+
hint: "Join a network first — new WiFi(ssid, { psk}).join() (or a WiFiAP) — before sending HTTP requests.",
|
|
132
128
|
}));
|
|
133
129
|
}
|
|
134
130
|
// ── wifi-blocking-in-loop ────────────────────────────────────────────────
|
|
@@ -161,7 +157,7 @@ export function validateNetworkUsage(program, boardConstants) {
|
|
|
161
157
|
diagnostics.push(diagAt(stmt, {
|
|
162
158
|
severity: "error",
|
|
163
159
|
code: "wifi-ap-password-short",
|
|
164
|
-
message: `
|
|
160
|
+
message: `WiFiAP password is ${password.length} characters — WPA2 requires at least 8, and the driver rejects shorter ones at runtime.`,
|
|
165
161
|
hint: "Use a password of 8+ characters, or omit the password entirely for an open access point.",
|
|
166
162
|
}));
|
|
167
163
|
}
|
|
@@ -811,6 +811,18 @@ function validateConstSuggestions(program, diagnostics) {
|
|
|
811
811
|
// Set.add() -> insert, Map/Set.delete() -> erase (demo #15 fix C)
|
|
812
812
|
'insert', 'erase',
|
|
813
813
|
]);
|
|
814
|
+
// Safety wrapper types (SafeVariable/SafeInt) mutate only through method
|
|
815
|
+
// calls — the C++ members are non-const by design. Kept separate from
|
|
816
|
+
// MUTATING_METHODS because these names ('set', 'add', ...) are matched
|
|
817
|
+
// ONLY against receivers whose declared cppType is a safety wrapper, so
|
|
818
|
+
// unrelated user classes with same-named methods are unaffected.
|
|
819
|
+
const SAFETY_WRAPPER_MUTATING_METHODS = new Set([
|
|
820
|
+
// SafeVariable<T>
|
|
821
|
+
'set',
|
|
822
|
+
// SafeInt<T> mutating chain
|
|
823
|
+
'add', 'sub', 'mul', 'divide', 'mod', 'negate', 'absValue', 'reset',
|
|
824
|
+
]);
|
|
825
|
+
const isSafetyWrapperCppType = (cppType) => typeof cppType === 'string' && (cppType.startsWith('SafeInt') || cppType.startsWith('SafeVariable'));
|
|
814
826
|
// Every lexical statement body in the program. Demotion (const-content-
|
|
815
827
|
// mutated) and the suggest-const global-assignment scan must reach class
|
|
816
828
|
// methods, getters, setters, constructors, and namespace-scoped functions —
|
|
@@ -852,6 +864,14 @@ function validateConstSuggestions(program, diagnostics) {
|
|
|
852
864
|
};
|
|
853
865
|
for (const ns of program.namespaces)
|
|
854
866
|
collectNamespaceBodies(ns);
|
|
867
|
+
// Callbacks registered out-of-band (interrupt handlers, Thread.start,
|
|
868
|
+
// watchPin / drawCanvas bodies) carry their statements on the callback
|
|
869
|
+
// expression rather than in a function body. A top-level `let` mutated
|
|
870
|
+
// only inside one must not be const-suggested — the emitted `const`
|
|
871
|
+
// makes g++ reject the assignment.
|
|
872
|
+
for (const rc of program.registeredCallbacks ?? []) {
|
|
873
|
+
allStatementBodies.push(rc.callbackIR.statements);
|
|
874
|
+
}
|
|
855
875
|
// Collect every plain-identifier assignment / update target across the whole
|
|
856
876
|
// program. A `let` declared in one scope may be reassigned by a *different*
|
|
857
877
|
// function that closes over it (e.g. a top-level `let counter` reassigned in
|
|
@@ -1031,6 +1051,32 @@ function validateConstSuggestions(program, diagnostics) {
|
|
|
1031
1051
|
});
|
|
1032
1052
|
}
|
|
1033
1053
|
}
|
|
1054
|
+
// Safety wrapper mutation: match on the LEADING identifier of the
|
|
1055
|
+
// callee — chained calls arrive as partially-rendered callees
|
|
1056
|
+
// (e.g. `count.add(5).mul`) whose receiver segment is not a bare
|
|
1057
|
+
// identifier — and gate on the receiver's declared safety cppType
|
|
1058
|
+
// so same-named methods on non-safety types are untouched.
|
|
1059
|
+
if (SAFETY_WRAPPER_MUTATING_METHODS.has(method)) {
|
|
1060
|
+
const baseDot = callee.indexOf('.');
|
|
1061
|
+
const base = baseDot > 0 ? callee.slice(0, baseDot) : receiver;
|
|
1062
|
+
const letEntry = letVars.get(base);
|
|
1063
|
+
if (letEntry && isSafetyWrapperCppType(letEntry.stmt.cppType)) {
|
|
1064
|
+
letEntry.everAssigned = true;
|
|
1065
|
+
}
|
|
1066
|
+
const constEntry = constVars.get(base);
|
|
1067
|
+
if (constEntry && constEntry.stmt.storage === 'const' && isSafetyWrapperCppType(constEntry.stmt.cppType)) {
|
|
1068
|
+
constEntry.stmt.storage = 'let';
|
|
1069
|
+
diagnostics.push({
|
|
1070
|
+
severity: 'info',
|
|
1071
|
+
message: `'${base}' is declared 'const' but is mutated via .${method}() — demoted to non-const in C++ so the mutation compiles.`,
|
|
1072
|
+
line: constEntry.span.startLine,
|
|
1073
|
+
column: constEntry.span.startColumn,
|
|
1074
|
+
filePath: constEntry.span.filePath,
|
|
1075
|
+
code: 'ownership-const-content-mutated',
|
|
1076
|
+
source: 'ownership-analysis',
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1034
1080
|
}
|
|
1035
1081
|
}
|
|
1036
1082
|
// Recurse into nested statements (shares this scope's maps — a nested
|
|
@@ -1045,24 +1091,40 @@ function validateConstSuggestions(program, diagnostics) {
|
|
|
1045
1091
|
// Promote `let` bindings that are never reassigned (in this scope or any
|
|
1046
1092
|
// other) to `const` in the emitted C++. The transpiler's whole-program
|
|
1047
1093
|
// reassignment analysis proves the binding is never written after init —
|
|
1048
|
-
// information
|
|
1094
|
+
// information the compiler cannot recover across translation units. Emitting
|
|
1049
1095
|
// `const` lets the compiler place the value in flash/ROM and enables
|
|
1050
1096
|
// constant folding. The inverse demotion (const→let when a member is
|
|
1051
1097
|
// mutated) already mutates `.storage` the same way (see above), so the
|
|
1052
1098
|
// emit path already handles both directions.
|
|
1053
1099
|
for (const entry of letVars.values()) {
|
|
1054
|
-
if (
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1100
|
+
if (entry.everAssigned || globallyAssignedNames.has(entry.name))
|
|
1101
|
+
continue;
|
|
1102
|
+
// Safety wrapper declarations mutate exclusively through method calls
|
|
1103
|
+
// (.set/.add/...), and chained mutating calls render as callee text the
|
|
1104
|
+
// reassignment walk cannot fully parse — non-mutation cannot be proven
|
|
1105
|
+
// for these types, so they are never promoted (a promoted `const
|
|
1106
|
+
// SafeVariable` / `const SafeInt` rejects every mutating member in g++).
|
|
1107
|
+
if (isSafetyWrapperCppType(entry.stmt.cppType))
|
|
1108
|
+
continue;
|
|
1109
|
+
// A typed-array buffer (`const id = new Uint8Array(N)`, forced to let at
|
|
1110
|
+
// IR build) lowers with a pointer cppType + array initializer. HAL fills
|
|
1111
|
+
// write through it opaquely — the lowered C++ embeds the buffer name in
|
|
1112
|
+
// hal-op text (e.g. spi.transceive's rx), which the reassignment walk
|
|
1113
|
+
// above cannot see. Promoting it to const would make the HAL fill
|
|
1114
|
+
// undefined behavior and disagree with the array-shaped definition.
|
|
1115
|
+
const bufferInit = entry.stmt.initializer;
|
|
1116
|
+
if (bufferInit?.kind === 'array' && /\*\s*$/.test(entry.stmt.cppType ?? ''))
|
|
1117
|
+
continue;
|
|
1118
|
+
entry.stmt.storage = 'const';
|
|
1119
|
+
diagnostics.push({
|
|
1120
|
+
severity: 'info',
|
|
1121
|
+
message: `'${entry.name}' is never reassigned — emitted as \`const\` so the C++ compiler can place it in ROM and fold it.`,
|
|
1122
|
+
line: entry.span.startLine,
|
|
1123
|
+
column: entry.span.startColumn,
|
|
1124
|
+
filePath: entry.span.filePath,
|
|
1125
|
+
code: 'ownership-suggest-const',
|
|
1126
|
+
source: 'ownership-analysis',
|
|
1127
|
+
});
|
|
1066
1128
|
}
|
|
1067
1129
|
};
|
|
1068
1130
|
for (const body of allStatementBodies)
|
|
@@ -9,8 +9,6 @@ export interface PeripheralUsage {
|
|
|
9
9
|
pwm: boolean;
|
|
10
10
|
/** External interrupts are used (attachInterrupt on D2, D3) */
|
|
11
11
|
externalInterrupts: boolean;
|
|
12
|
-
/** Timer0-based timing is used (millis, micros) */
|
|
13
|
-
timer0: boolean;
|
|
14
12
|
/** I2C bus is used */
|
|
15
13
|
i2c: boolean;
|
|
16
14
|
/** SPI bus is used */
|
|
@@ -31,6 +29,14 @@ export interface PeripheralUsage {
|
|
|
31
29
|
inputPulldownPins: Set<number>;
|
|
32
30
|
/** Specific I2C bus instances used (0 for I2C0, 1 for I2C1, etc.) */
|
|
33
31
|
i2cInstancesUsed: Set<number>;
|
|
32
|
+
/** DT-bound sensor parts used (generic catalog, hal/sensor.ts) */
|
|
33
|
+
sensor: boolean;
|
|
34
|
+
/** Distinct sensors used: `${part}|${busInstance}|${address}` keys — feeds
|
|
35
|
+
* the framework's per-sensor DT node + device-handle emission. */
|
|
36
|
+
sensorPartsUsed: Set<string>;
|
|
37
|
+
/** Distinct thin SPI targets used: `${bus}|${cs}|${hz}|${mode}` keys —
|
|
38
|
+
* feeds the per-target DT child node + spi_dt_spec emission. */
|
|
39
|
+
spiTargetsUsed: Set<string>;
|
|
34
40
|
/** Specific SPI bus instances used (0 for SPI0, 1 for SPI1, etc.) */
|
|
35
41
|
spiInstancesUsed: Set<number>;
|
|
36
42
|
/** Specific UART instances used (0 for UART0/Serial, 1 for UART1/Serial1, etc.) */
|