@typecad/cuttlefish 1.0.0-alpha.7 → 1.0.0-alpha.8
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/dist/api/config.d.ts +32 -0
- package/dist/api/index.d.ts +1 -1
- package/dist/api/schema/types.d.ts +15 -0
- package/dist/api/shared/async-runtime-static.d.ts +12 -1
- package/dist/api/shared/async-runtime-static.js +69 -24
- package/dist/api/shared/async-symbol-detector.d.ts +11 -0
- package/dist/api/shared/async-symbol-detector.js +140 -0
- package/dist/api/shared/async-types.d.ts +24 -0
- package/dist/api/shared/coop-scheduler.d.ts +60 -0
- package/dist/api/shared/coop-scheduler.js +149 -0
- package/dist/api/shared/display-adapter.d.ts +2 -2
- package/dist/api/shared/display-adapter.js +9 -119
- package/dist/api/shared/display-adapters/sdl.js +29 -29
- package/dist/api/shared/display-profile.d.ts +38 -33
- package/dist/api/shared/display-profile.js +22 -170
- package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
- package/dist/api/shared/framework-manifest-registry.js +8 -6
- package/dist/api/shared/framework-manifest.d.ts +147 -28
- package/dist/api/shared/framework-manifest.js +35 -2
- package/dist/api/shared/graphics-strategy.d.ts +15 -6
- package/dist/api/shared/hal-op-ir.d.ts +340 -3
- package/dist/api/shared/hal-op-ir.js +34 -0
- package/dist/api/shared/index.d.ts +9 -1
- package/dist/api/shared/index.js +11 -1
- package/dist/api/shared/ir-core.d.ts +4 -0
- package/dist/api/shared/ir-declarations.d.ts +6 -0
- package/dist/api/shared/platform-strategy.d.ts +104 -2
- package/dist/api/shared/polyfill-helper-registry.js +18 -1
- package/dist/api/shared/promise-runtime.d.ts +1 -1
- package/dist/api/shared/promise-runtime.js +17 -13
- package/dist/api/shared/toolchain-types.d.ts +17 -0
- package/dist/api/shared/validate-framework-manifest.js +77 -0
- package/dist/api/shared/worker-runtime-polyfill.d.ts +22 -0
- package/dist/api/shared/worker-runtime-polyfill.js +34 -0
- package/dist/api/shared/worker-runtime.d.ts +69 -0
- package/dist/api/shared/worker-runtime.js +163 -0
- package/dist/cli.js +120 -121
- package/dist/config-loader.d.ts +7 -2
- package/dist/config-loader.js +20 -19
- package/dist/config-schema.d.ts +107 -65
- package/dist/config-schema.js +14 -0
- package/dist/contract/board-generator.d.ts +17 -0
- package/dist/contract/board-generator.js +57 -0
- package/dist/contract/contract-parser.d.ts +217 -0
- package/dist/contract/contract-parser.js +224 -0
- package/dist/contract/index.d.ts +22 -0
- package/dist/contract/index.js +68 -0
- package/dist/create/board-codegen.js +4 -4
- package/dist/create/board-generators.js +4 -5
- package/dist/create/board-spec.d.ts +74 -77
- package/dist/create/board-spec.js +0 -1
- package/dist/create/init-scaffold.d.ts +7 -3
- package/dist/create/init-scaffold.js +0 -62
- package/dist/create/init-templates.js +62 -16
- package/dist/create/init-wizard.js +32 -27
- package/dist/debug/preprocessor.js +178 -39
- package/dist/debug/types.d.ts +23 -0
- package/dist/diagnostics/mermaid-builder.d.ts +1 -1
- package/dist/diagnostics/mermaid-builder.js +34 -24
- package/dist/emit/compliance/arxml-writer.d.ts +11 -0
- package/dist/emit/compliance/arxml-writer.js +34 -0
- package/dist/emit/compliance/compliance-context.d.ts +57 -0
- package/dist/emit/compliance/compliance-context.js +113 -0
- package/dist/emit/compliance/deviation-ledger.d.ts +27 -0
- package/dist/emit/compliance/deviation-ledger.js +47 -0
- package/dist/emit/compliance/deviation-writer.d.ts +30 -0
- package/dist/emit/compliance/deviation-writer.js +37 -0
- package/dist/emit/compliance/index.d.ts +7 -0
- package/dist/emit/compliance/index.js +6 -0
- package/dist/emit/compliance/rule-engine.d.ts +13 -0
- package/dist/emit/compliance/rule-engine.js +101 -0
- package/dist/emit/compliance/rules.d.ts +16 -0
- package/dist/emit/compliance/rules.js +191 -0
- package/dist/emit/compliance/types.d.ts +59 -0
- package/dist/emit/compliance/types.js +8 -0
- package/dist/emit/emitters/class-emitter.js +6 -1
- package/dist/emit/emitters/emitter-context.d.ts +23 -1
- package/dist/emit/emitters/function-emitter-impl.js +96 -6
- package/dist/emit/emitters/line-appender.js +19 -0
- package/dist/emit/emitters/line-marker.d.ts +38 -0
- package/dist/emit/emitters/line-marker.js +39 -0
- package/dist/emit/emitters/output-finalizer.js +80 -1
- package/dist/emit/emitters/setup.d.ts +17 -0
- package/dist/emit/emitters/setup.js +217 -36
- package/dist/emit/emitters/top-level-prep.js +6 -0
- package/dist/emit/emitters/type-decl-emitter.js +28 -3
- package/dist/emit/emitters/ui-emitter.js +17 -8
- package/dist/emit/expression-renderer.d.ts +1 -1
- package/dist/emit/expression-renderer.js +81 -5
- package/dist/emit/route-hal-op.js +18 -5
- package/dist/emit/snprintf-helpers.js +7 -4
- package/dist/emit/statement-renderer.d.ts +10 -0
- package/dist/emit/statement-renderer.js +21 -5
- package/dist/emit/utils/async-state-machine.js +39 -12
- package/dist/framework-package.js +2 -0
- package/dist/framework-registry.d.ts +17 -0
- package/dist/ir/adc-range-validation.js +14 -1
- package/dist/ir/build-ir-state.d.ts +1 -0
- package/dist/ir/build-ir-state.js +14 -0
- package/dist/ir/build-ir.js +4 -4
- package/dist/ir/call-graph.js +16 -0
- package/dist/ir/expression-to-ir.js +150 -0
- package/dist/ir/function-builder.js +22 -0
- package/dist/ir/hal/hal-emitter.js +10 -6
- package/dist/ir/hal/hal-parser.js +16 -9
- package/dist/ir/hal/hal-plugins.js +164 -3
- package/dist/ir/identifier-collector.js +21 -4
- package/dist/ir/interrupt-analysis.d.ts +5 -1
- package/dist/ir/interrupt-analysis.js +8 -16
- package/dist/ir/ownership-analysis.js +6 -0
- package/dist/ir/pin-capability-validation.js +37 -0
- package/dist/ir/pin-mode-validation.d.ts +2 -2
- package/dist/ir/pin-mode-validation.js +49 -18
- package/dist/ir/program-analysis.d.ts +42 -0
- package/dist/ir/program-analysis.js +243 -6
- package/dist/ir/render-expr.js +11 -0
- package/dist/ir/timing-validation.js +11 -2
- package/dist/ir/transformers/call-statement.js +105 -0
- package/dist/ir/transformers/expressions.js +4 -0
- package/dist/ir/transformers/hal-call-resolver.js +21 -0
- package/dist/ir/transformers/namespace-methods.js +17 -12
- package/dist/ir/transformers/ui-reactive.js +2 -2
- package/dist/ir/transformers/variables.js +51 -0
- package/dist/ir/type-resolution.js +18 -0
- package/dist/ir/ui-element-auto-wire.js +7 -5
- package/dist/ir/utils/map-statements.d.ts +4 -0
- package/dist/ir/utils/map-statements.js +79 -0
- package/dist/ir/validation-orchestrator.js +6 -1
- package/dist/ir/worker-analysis.d.ts +10 -0
- package/dist/ir/worker-analysis.js +261 -0
- package/dist/orchestrator/graph-builder.js +8 -7
- package/dist/platform/coop-scheduler-runtime.d.ts +19 -0
- package/dist/platform/coop-scheduler-runtime.js +41 -0
- package/dist/platform/generic-strategy.d.ts +15 -3
- package/dist/platform/generic-strategy.js +49 -4
- package/dist/safety/safety-bridge.d.ts +11 -0
- package/dist/safety/safety-bridge.js +48 -0
- package/dist/safety/sidecar-bridge.d.ts +5 -0
- package/dist/safety/sidecar-bridge.js +22 -0
- package/dist/safety-hook.d.ts +79 -0
- package/dist/safety-hook.js +35 -0
- package/dist/stores/display-profile-store.d.ts +0 -1
- package/dist/stores/display-profile-store.js +0 -1
- package/dist/testing.d.ts +4 -0
- package/dist/testing.js +5 -0
- package/dist/transpile.js +124 -35
- package/dist/types.d.ts +13 -2
- package/dist/ui-hook.d.ts +0 -2
- package/dist/utils/cli.js +51 -3
- package/package.json +20 -5
- package/dist/api/shared/display-adapters/eink-mono.d.ts +0 -2
- package/dist/api/shared/display-adapters/eink-mono.js +0 -53
- package/dist/api/shared/display-adapters/ssd1309.d.ts +0 -2
- package/dist/api/shared/display-adapters/ssd1309.js +0 -136
- package/dist/api/shared/display-adapters/st7796.d.ts +0 -2
- package/dist/api/shared/display-adapters/st7796.js +0 -132
- package/dist/libdef/idf-discovery.d.ts +0 -7
- package/dist/libdef/idf-discovery.js +0 -59
- package/dist/licenses.d.ts +0 -185
- package/dist/licenses.js +0 -963
|
@@ -42,10 +42,14 @@ export class GenericStrategy {
|
|
|
42
42
|
// ── Type normalisation ──────────────────────────────────────────────────
|
|
43
43
|
normalizeCppType(typeName) {
|
|
44
44
|
if (typeName === "auto")
|
|
45
|
-
return
|
|
45
|
+
return this.defaultNumericType();
|
|
46
46
|
return typeName;
|
|
47
47
|
}
|
|
48
|
-
defaultNumericType() {
|
|
48
|
+
defaultNumericType(compliance) {
|
|
49
|
+
// A3-9-1: fixed-width integers under AUTOSAR. Legacy 'int' spelling
|
|
50
|
+
// preserved when autosar is off so default output is byte-identical.
|
|
51
|
+
return compliance?.isBanned("A3-9-1") ? "int32_t" : "int";
|
|
52
|
+
}
|
|
49
53
|
mapReturnType(_functionName, returnType) {
|
|
50
54
|
return this.normalizeCppType(returnType);
|
|
51
55
|
}
|
|
@@ -185,17 +189,23 @@ export class GenericStrategy {
|
|
|
185
189
|
helpers.push(asyncRuntime);
|
|
186
190
|
return helpers;
|
|
187
191
|
}
|
|
188
|
-
asyncLoopInjection(
|
|
192
|
+
asyncLoopInjection(taskVarNames, configOrBool) {
|
|
189
193
|
let hasPromiseRuntime;
|
|
190
|
-
if (typeof configOrBool ===
|
|
194
|
+
if (typeof configOrBool === "boolean") {
|
|
191
195
|
hasPromiseRuntime = configOrBool;
|
|
192
196
|
}
|
|
193
197
|
else {
|
|
194
198
|
hasPromiseRuntime = configOrBool.hasPromiseRuntime;
|
|
195
199
|
}
|
|
200
|
+
// Drive every async state-machine task once per driver-function iteration.
|
|
201
|
+
// Task globals auto-start on their first .run() (STATE_0 runs
|
|
202
|
+
// unconditionally); the state machine no-ops in its terminal/cyclic state.
|
|
196
203
|
const lines = [];
|
|
197
204
|
if (hasPromiseRuntime)
|
|
198
205
|
lines.push(" cuttlefish_pump_microtasks();");
|
|
206
|
+
for (const n of taskVarNames) {
|
|
207
|
+
lines.push(` ${n}.run();`);
|
|
208
|
+
}
|
|
199
209
|
return lines;
|
|
200
210
|
}
|
|
201
211
|
asyncDriverFunctionName() { return "main"; }
|
|
@@ -213,6 +223,9 @@ export class GenericStrategy {
|
|
|
213
223
|
enumApiGuard(_enumName) { return undefined; }
|
|
214
224
|
getStdLibSupport(_architecture) { return DEFAULT_STDLIB_SUPPORT; }
|
|
215
225
|
// ── Debug code generation ─────────────────────────────────────────────────
|
|
226
|
+
debugMode(_target) {
|
|
227
|
+
return 'printf';
|
|
228
|
+
}
|
|
216
229
|
generateDebugInitCode() {
|
|
217
230
|
return [
|
|
218
231
|
'// === DEBUG: Initialize ===',
|
|
@@ -286,4 +299,36 @@ export class GenericStrategy {
|
|
|
286
299
|
nodeStorage: "flash",
|
|
287
300
|
};
|
|
288
301
|
}
|
|
302
|
+
// ── HAL (generic fallback) ──────────────────────────────────────────────
|
|
303
|
+
// The generic/host target has no GPIO or timing hardware. These return
|
|
304
|
+
// documented no-op stubs so emit stays deterministic rather than throwing
|
|
305
|
+
// mid-codegen. Host tests that exercise pin-polling paths use a mock
|
|
306
|
+
// PlatformStrategy (see tests/packages/cuttlefish/async-runtime-static.test.ts).
|
|
307
|
+
readDigitalPin(_pin) {
|
|
308
|
+
return "/* gpio unavailable on generic target */ 0";
|
|
309
|
+
}
|
|
310
|
+
readAnalogPin(_pin) {
|
|
311
|
+
return "/* adc unavailable on generic target */ 0";
|
|
312
|
+
}
|
|
313
|
+
writeDigitalPin(_pin, _val) {
|
|
314
|
+
return "/* gpio unavailable on generic target */";
|
|
315
|
+
}
|
|
316
|
+
setPinMode(_pin, _mode) {
|
|
317
|
+
return "/* gpio unavailable on generic target */";
|
|
318
|
+
}
|
|
319
|
+
delayMs(_ms) {
|
|
320
|
+
return "/* delay unavailable on generic target */";
|
|
321
|
+
}
|
|
322
|
+
delayMicroseconds(_us) {
|
|
323
|
+
return "/* delay unavailable on generic target */";
|
|
324
|
+
}
|
|
325
|
+
halCallNames() {
|
|
326
|
+
return new Set();
|
|
327
|
+
}
|
|
328
|
+
isHalCall(_name) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
analogReadCallNames() {
|
|
332
|
+
return new Set();
|
|
333
|
+
}
|
|
289
334
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Dynamically load @typecad/safety/engine and register the hook.
|
|
2
|
+
* Called by transpile.ts at the start of each transpile run.
|
|
3
|
+
* Safe to call when @typecad/safety is absent (hook stays null). */
|
|
4
|
+
export declare function loadSafetyEngine(): Promise<void>;
|
|
5
|
+
/** Reset the safety bridge: forget a load was attempted and clear the hook.
|
|
6
|
+
* Mirrors resetUIEngine() so each transpile run / test starts clean. */
|
|
7
|
+
export declare function resetSafetyEngine(): void;
|
|
8
|
+
/** Test-only: force the bridge into the "no @typecad/safety" state — mark the
|
|
9
|
+
* load as already attempted and leave the hook null, exactly as if the
|
|
10
|
+
* dynamic import had failed because the package is not installed. */
|
|
11
|
+
export declare function __simulateSafetyAbsentForTest(): void;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Safety bridge — loads the safety engine from @typecad/safety and registers it.
|
|
3
|
+
//
|
|
4
|
+
// transpile.ts calls loadSafetyEngine() at the start of transpileFile(). If
|
|
5
|
+
// @typecad/safety is not installed, the import fails gracefully and the hook
|
|
6
|
+
// stays null — cuttlefish works as a pure TS→C++ transpiler with no safety
|
|
7
|
+
// support.
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
import { setSafetyHook } from "../safety-hook.js";
|
|
10
|
+
let loaded = false;
|
|
11
|
+
/** Dynamically load @typecad/safety/engine and register the hook.
|
|
12
|
+
* Called by transpile.ts at the start of each transpile run.
|
|
13
|
+
* Safe to call when @typecad/safety is absent (hook stays null). */
|
|
14
|
+
export async function loadSafetyEngine() {
|
|
15
|
+
if (loaded)
|
|
16
|
+
return;
|
|
17
|
+
loaded = true;
|
|
18
|
+
try {
|
|
19
|
+
// Dynamic import — @typecad/safety is optional. The module specifier is
|
|
20
|
+
// routed through a variable (rather than a string literal) so tsc types
|
|
21
|
+
// the result as `any` and never resolves @typecad/safety's declaration
|
|
22
|
+
// files while type-checking this file. A literal specifier would make tsc
|
|
23
|
+
// load safety's dist/engine-index.d.ts, which imports back
|
|
24
|
+
// @typecad/cuttlefish/safety-hook-types — a self-referencing package path
|
|
25
|
+
// that resolves into this package's own dist/ output and causes TS5055
|
|
26
|
+
// ("would overwrite input file") on every rebuild where dist/ exists.
|
|
27
|
+
const safetyEnginePath = "@typecad/safety/engine";
|
|
28
|
+
const engine = await import(safetyEnginePath);
|
|
29
|
+
const hook = engine.registerSafetyEngine();
|
|
30
|
+
setSafetyHook(hook);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// @typecad/safety is not installed — cuttlefish works without safety.
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Reset the safety bridge: forget a load was attempted and clear the hook.
|
|
37
|
+
* Mirrors resetUIEngine() so each transpile run / test starts clean. */
|
|
38
|
+
export function resetSafetyEngine() {
|
|
39
|
+
loaded = false;
|
|
40
|
+
setSafetyHook(null);
|
|
41
|
+
}
|
|
42
|
+
/** Test-only: force the bridge into the "no @typecad/safety" state — mark the
|
|
43
|
+
* load as already attempted and leave the hook null, exactly as if the
|
|
44
|
+
* dynamic import had failed because the package is not installed. */
|
|
45
|
+
export function __simulateSafetyAbsentForTest() {
|
|
46
|
+
loaded = true;
|
|
47
|
+
setSafetyHook(null);
|
|
48
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SafetyMetadata } from "../safety-hook.js";
|
|
2
|
+
/** Dynamically import the safety package's sidecar renderer.
|
|
3
|
+
* Uses a variable-held specifier so tsc doesn't try to resolve the
|
|
4
|
+
* @typecad/safety types at build time (avoids circular dependency). */
|
|
5
|
+
export declare function renderSafetySidecar(metadata: SafetyMetadata, toolVersion: string): Promise<string>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Dynamically import the safety package's sidecar renderer.
|
|
2
|
+
* Uses a variable-held specifier so tsc doesn't try to resolve the
|
|
3
|
+
* @typecad/safety types at build time (avoids circular dependency). */
|
|
4
|
+
export async function renderSafetySidecar(metadata, toolVersion) {
|
|
5
|
+
const spec = "@typecad/safety/iso26262/sidecar-writer";
|
|
6
|
+
try {
|
|
7
|
+
const mod = await import(spec);
|
|
8
|
+
return mod.renderSafetySidecar(metadata, toolVersion);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
// Fallback: inline the renderer so the sidecar is produced even if
|
|
12
|
+
// the subpath export isn't configured.
|
|
13
|
+
return JSON.stringify({
|
|
14
|
+
schemaVersion: "1.0.0",
|
|
15
|
+
standard: "ISO 26262 Part 6",
|
|
16
|
+
tool: "cuttlefish (@typecad/safety)",
|
|
17
|
+
toolVersion,
|
|
18
|
+
generatedAt: new Date().toISOString(),
|
|
19
|
+
safetyFunctions: metadata.functions,
|
|
20
|
+
}, null, 2);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { HALOpIR, ProgramIR, RuntimePolyfillIR, Diagnostic } from "./api/shared/index.js";
|
|
2
|
+
/** Context handed to transformIR. */
|
|
3
|
+
export interface SafetyTransformContext {
|
|
4
|
+
/** True iff the entry file imports `safe` from @typecad/safety. The pass
|
|
5
|
+
* uses this as a fast no-op guard. */
|
|
6
|
+
readonly safetyInUse: boolean;
|
|
7
|
+
/** Build target (e.g. "esp32", "avr"). Strategies still resolve the
|
|
8
|
+
* underlying pinMode/digitalRead symbols; the safety package is target-
|
|
9
|
+
* agnostic. */
|
|
10
|
+
readonly target: string;
|
|
11
|
+
}
|
|
12
|
+
/** Capabilities cuttlefish core needs from the safety engine.
|
|
13
|
+
*
|
|
14
|
+
* Part A uses transformIR + resolveSafetyOp + resolveSemanticCall.
|
|
15
|
+
* Part B (ISO 26262 Part 6 rules) adds analyzeIR; Part C (sidecar) will
|
|
16
|
+
* add collectSafetyMetadata. Both reuse this same seam with no new core
|
|
17
|
+
* machinery. */
|
|
18
|
+
export interface TranspilerSafetyHook {
|
|
19
|
+
/** Post-build IR transform. Must return a (possibly new) ProgramIR. Part A
|
|
20
|
+
* uses this to inject safety.record_pin_mode companions after every
|
|
21
|
+
* gpio.pin_mode / safety.pin_mode op. Called only when hasSafetyHook(). */
|
|
22
|
+
transformIR(program: ProgramIR, ctx: SafetyTransformContext): ProgramIR;
|
|
23
|
+
/** Resolve a safety.* HAL op to C++ code or expression. Called from the
|
|
24
|
+
* extended routeHALOp() for any op whose `operation` starts with "safety.".
|
|
25
|
+
* NEVER delegated to a per-target strategy. Returns undefined if the op
|
|
26
|
+
* is not recognized (caller emits an unhandled-op warning). */
|
|
27
|
+
resolveSafetyOp(op: HALOpIR): {
|
|
28
|
+
code?: string;
|
|
29
|
+
expression?: string;
|
|
30
|
+
} | undefined;
|
|
31
|
+
/** Lower a safe.* TS call to a HAL op. Called from an extension point in
|
|
32
|
+
* tryResolveSemanticCall (hal-plugins.ts) when the callee resolves to the
|
|
33
|
+
* @typecad/safety package. Returns undefined if not a safety call. */
|
|
34
|
+
resolveSemanticCall?(callee: string, args: readonly unknown[]): HALOpIR | undefined;
|
|
35
|
+
/** Provide safety runtime polyfills (mode table + voter). Called from
|
|
36
|
+
* buildEmitterContext so the polyfills participate in tree-shaking.
|
|
37
|
+
* Returns [] when safety is not in use. */
|
|
38
|
+
buildPolyfills?(): RuntimePolyfillIR[];
|
|
39
|
+
/** Part B: read-only ISO 26262 Part 6 software-rule analysis. Called
|
|
40
|
+
* after transformIR completes, on the final transformed IR. Returns
|
|
41
|
+
* diagnostics that flow into the build's diagnostic list. Diagnostics
|
|
42
|
+
* with severity "error" abort the build (via throwIfFatalDiagnostics);
|
|
43
|
+
* "warning"/"info" are logged but the build succeeds. */
|
|
44
|
+
analyzeIR?(program: ProgramIR, ctx: SafetyTransformContext): Diagnostic[];
|
|
45
|
+
/** Part C: collect safety metadata for sidecar artifact generation.
|
|
46
|
+
* Called after analyzeIR completes. Returns structured metadata about
|
|
47
|
+
* each safety-critical function (ASIL level, mechanisms, rule results)
|
|
48
|
+
* that the caller writes to a sidecar JSON file. */
|
|
49
|
+
collectSafetyMetadata?(program: ProgramIR, ctx: SafetyTransformContext): SafetyMetadata[];
|
|
50
|
+
}
|
|
51
|
+
/** Set the safety hook. Called by transpile.ts after dynamically loading
|
|
52
|
+
* @typecad/safety/engine. Passing null clears it. */
|
|
53
|
+
export declare function setSafetyHook(hook: TranspilerSafetyHook | null): void;
|
|
54
|
+
/** Get the current safety hook, or null if @typecad/safety is not loaded. */
|
|
55
|
+
export declare function getSafetyHook(): TranspilerSafetyHook | null;
|
|
56
|
+
/** Returns true if the safety hook is registered (i.e. @typecad/safety loaded). */
|
|
57
|
+
export declare function hasSafetyHook(): boolean;
|
|
58
|
+
/** Get the safety hook, throwing if it's not set. Use only inside
|
|
59
|
+
* `if (hasSafetyHook())` guards. */
|
|
60
|
+
export declare function requireSafetyHook(): TranspilerSafetyHook;
|
|
61
|
+
export type { Diagnostic };
|
|
62
|
+
/** Metadata about one safety-critical function, collected for Part C. */
|
|
63
|
+
export interface SafetyFunctionMetadata {
|
|
64
|
+
name: string;
|
|
65
|
+
asilLevel: string;
|
|
66
|
+
source?: {
|
|
67
|
+
tsFile: string;
|
|
68
|
+
tsLine: number;
|
|
69
|
+
};
|
|
70
|
+
mechanisms: string[];
|
|
71
|
+
rules: Record<string, "pass" | {
|
|
72
|
+
severity: string;
|
|
73
|
+
message: string;
|
|
74
|
+
}>;
|
|
75
|
+
}
|
|
76
|
+
/** Result of Part C's metadata collection. */
|
|
77
|
+
export interface SafetyMetadata {
|
|
78
|
+
functions: SafetyFunctionMetadata[];
|
|
79
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Safety hook — the contract cuttlefish core uses to talk to the optional
|
|
3
|
+
// @typecad/safety package. Modeled on ui-hook.ts.
|
|
4
|
+
//
|
|
5
|
+
// @typecad/safety is an optional peer dependency. When it is installed and
|
|
6
|
+
// imported by a sketch, transpile.ts calls loadSafetyEngine() which dynamic-
|
|
7
|
+
// imports @typecad/safety/engine and calls registerSafetyEngine() to push an
|
|
8
|
+
// implementation of this interface into the registry. When absent, every
|
|
9
|
+
// hasSafetyHook() guard returns false and cuttlefish behaves as before.
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// ── Module-level hook state ────────────────────────────────────────────────
|
|
12
|
+
let safetyHook = null;
|
|
13
|
+
/** Set the safety hook. Called by transpile.ts after dynamically loading
|
|
14
|
+
* @typecad/safety/engine. Passing null clears it. */
|
|
15
|
+
export function setSafetyHook(hook) {
|
|
16
|
+
safetyHook = hook;
|
|
17
|
+
}
|
|
18
|
+
/** Get the current safety hook, or null if @typecad/safety is not loaded. */
|
|
19
|
+
export function getSafetyHook() {
|
|
20
|
+
return safetyHook;
|
|
21
|
+
}
|
|
22
|
+
/** Returns true if the safety hook is registered (i.e. @typecad/safety loaded). */
|
|
23
|
+
export function hasSafetyHook() {
|
|
24
|
+
return safetyHook !== null;
|
|
25
|
+
}
|
|
26
|
+
/** Get the safety hook, throwing if it's not set. Use only inside
|
|
27
|
+
* `if (hasSafetyHook())` guards. */
|
|
28
|
+
export function requireSafetyHook() {
|
|
29
|
+
if (!safetyHook) {
|
|
30
|
+
throw new Error("Safety hook is not registered. This code path requires @typecad/safety " +
|
|
31
|
+
"to be installed and loaded. This should not happen — the hook is set " +
|
|
32
|
+
"at the start of transpileFile() when safety is detected.");
|
|
33
|
+
}
|
|
34
|
+
return safetyHook;
|
|
35
|
+
}
|
|
@@ -9,7 +9,6 @@ export declare function setDisplayProfile(profile: DisplayProfile, wiring: {
|
|
|
9
9
|
address?: number;
|
|
10
10
|
reset?: number;
|
|
11
11
|
buildTarget?: string;
|
|
12
|
-
psram?: boolean;
|
|
13
12
|
}): void;
|
|
14
13
|
/** Get the current display profile, or a default if none set. */
|
|
15
14
|
export declare function getDisplayProfile(): ResolvedDisplay;
|
|
@@ -20,7 +20,6 @@ export function setDisplayProfile(profile, wiring) {
|
|
|
20
20
|
_mountAddress: wiring.address ?? 0x3C,
|
|
21
21
|
_mountReset: wiring.reset ?? -1,
|
|
22
22
|
_buildTarget: wiring.buildTarget,
|
|
23
|
-
_psram: wiring.psram,
|
|
24
23
|
};
|
|
25
24
|
}
|
|
26
25
|
/** Get the current display profile, or a default if none set. */
|
package/dist/testing.d.ts
CHANGED
|
@@ -12,9 +12,13 @@ export { inferSnprintfArg, createEmissionScopeState, escapeCppStringLiteral } fr
|
|
|
12
12
|
export { setLoadedFramework } from "./framework-registry.js";
|
|
13
13
|
export { registerPlatformStrategy, resolveStrategy, clearAllProfileCaches } from "./platform/registry.js";
|
|
14
14
|
export type { EmitMode, GeneratedOutputs, TargetProfile, PlatformContext } from "./types.js";
|
|
15
|
+
export { ComplianceContext, runSelfCheck, renderRegistryJson } from "./emit/compliance/index.js";
|
|
16
|
+
export type { ComplianceMode, SelfCheckFinding, Deviation } from "./emit/compliance/index.js";
|
|
15
17
|
export { findConfigFile, parseConfigFile, loadCuttlefishConfig, generateVirtualTypeDeclaration, } from "./config-loader.js";
|
|
16
18
|
export { transpileFile } from "./transpile.js";
|
|
17
19
|
export { resetUIEngine, __simulateUIAbsentForTest } from "./ui/ui-bridge.js";
|
|
20
|
+
export { resetSafetyEngine, __simulateSafetyAbsentForTest } from "./safety/safety-bridge.js";
|
|
21
|
+
export { setSafetyHook, hasSafetyHook } from "./safety-hook.js";
|
|
18
22
|
export { scaffoldProject, normalizeProjectName, KNOWN_BOARDS, generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, runInitWizard, } from "./create/index.js";
|
|
19
23
|
export type { InitProjectOptions } from "./create/index.js";
|
|
20
24
|
export { scaffoldBoardPackages, parseBoardSpec, safeParseBoardSpec, stripJsonc, } from "./create/index.js";
|
package/dist/testing.js
CHANGED
|
@@ -11,12 +11,17 @@ export { analyzePeripheralUsage, createEmptyPeripheralUsage } from "./ir/periphe
|
|
|
11
11
|
export { inferSnprintfArg, createEmissionScopeState, escapeCppStringLiteral } from "./emit/snprintf-helpers.js";
|
|
12
12
|
export { setLoadedFramework } from "./framework-registry.js";
|
|
13
13
|
export { registerPlatformStrategy, resolveStrategy, clearAllProfileCaches } from "./platform/registry.js";
|
|
14
|
+
// ── AUTOSAR compliance module (test-visible) ───────────────────────────────
|
|
15
|
+
export { ComplianceContext, runSelfCheck, renderRegistryJson } from "./emit/compliance/index.js";
|
|
14
16
|
// ── Config loader ───────────────────────────────────────────────────────────
|
|
15
17
|
export { findConfigFile, parseConfigFile, loadCuttlefishConfig, generateVirtualTypeDeclaration, } from "./config-loader.js";
|
|
16
18
|
// ── Transpiler internal API ─────────────────────────────────────────────────
|
|
17
19
|
export { transpileFile } from "./transpile.js";
|
|
18
20
|
// ── UI bridge (optional @typecad/ui) ─────────────────────────────────────────
|
|
19
21
|
export { resetUIEngine, __simulateUIAbsentForTest } from "./ui/ui-bridge.js";
|
|
22
|
+
// ── Safety bridge (optional @typecad/safety) ────────────────────────────────
|
|
23
|
+
export { resetSafetyEngine, __simulateSafetyAbsentForTest } from "./safety/safety-bridge.js";
|
|
24
|
+
export { setSafetyHook, hasSafetyHook } from "./safety-hook.js";
|
|
20
25
|
// ── Project scaffolding ──────────────────────────────────────────────────────
|
|
21
26
|
export { scaffoldProject, normalizeProjectName, KNOWN_BOARDS, generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, runInitWizard, } from "./create/index.js";
|
|
22
27
|
// ── Board codegen (`cuttlefish board add`) ───────────────────────────────────
|
package/dist/transpile.js
CHANGED
|
@@ -3,15 +3,33 @@ import path from "node:path";
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import ts from "typescript";
|
|
6
|
+
// Read once at module load. Used to populate the AUTOSAR deviation sidecar's
|
|
7
|
+
// `toolVersion` field. Falls back to "unknown" if the read fails (e.g. tests
|
|
8
|
+
// that import the module from an unexpected location).
|
|
9
|
+
const CUTTLEFISH_VERSION = (() => {
|
|
10
|
+
try {
|
|
11
|
+
const require_ = createRequire(import.meta.url);
|
|
12
|
+
// transpile.ts lives in src/, compiled to dist/transpile.js. The package
|
|
13
|
+
// root is one level up from dist/, so from dist/ the path is ../package.json.
|
|
14
|
+
// From src/ (TypeScript source used by tests) it's also ../package.json.
|
|
15
|
+
const pkg = require_("../package.json");
|
|
16
|
+
return pkg.version ?? "unknown";
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return "unknown";
|
|
20
|
+
}
|
|
21
|
+
})();
|
|
6
22
|
import { buildProgramIR } from "./ir/build-ir.js";
|
|
7
23
|
import { classDeclarationToIR } from "./ir/declaration-builders.js";
|
|
8
24
|
import { clickHandlers } from "./ir/transformers/ui-call-resolver.js";
|
|
9
25
|
import { requireUIHook, hasUIHook } from "./ui-hook.js";
|
|
10
26
|
import { loadUIEngine } from "./ui/ui-bridge.js";
|
|
27
|
+
import { hasSafetyHook, requireSafetyHook } from "./safety-hook.js";
|
|
28
|
+
import { loadSafetyEngine } from "./safety/safety-bridge.js";
|
|
11
29
|
import { setDisplayProfile, resetDisplayProfile } from "./stores/display-profile-store.js";
|
|
12
30
|
import { setThemeCss, resetThemeCss, setThemeClass } from "./stores/theme-store.js";
|
|
13
31
|
import { emitCpp, registerAllEnumNames } from "./emit/cpp-emitter.js";
|
|
14
|
-
import { readText } from "./utils/fs.js";
|
|
32
|
+
import { readText, writeText } from "./utils/fs.js";
|
|
15
33
|
import { debug as logDebug, info } from "./utils/logger.js";
|
|
16
34
|
import { loadLibraryDefinitions, generateLibdefStubs } from "./libdef/registry.js";
|
|
17
35
|
import { buildCallGraph } from "./ir/call-graph.js";
|
|
@@ -60,6 +78,18 @@ function cleanOutput(_entryDir, outDir) {
|
|
|
60
78
|
* Also tries to generate declarations for framework libraries.
|
|
61
79
|
* Returns list of generated files.
|
|
62
80
|
*/
|
|
81
|
+
/**
|
|
82
|
+
* True iff the program imports `@typecad/safety` anywhere. The safety
|
|
83
|
+
* transform pass uses this as its fast no-op guard — when no file imports
|
|
84
|
+
* safety, the pass returns the program unchanged.
|
|
85
|
+
*/
|
|
86
|
+
function entryImportsSafety(program) {
|
|
87
|
+
for (const imp of program.imports) {
|
|
88
|
+
if (imp.moduleSpecifier === "@typecad/safety")
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
63
93
|
/**
|
|
64
94
|
* Apply tree-shaking to program IR if enabled
|
|
65
95
|
*/
|
|
@@ -136,7 +166,11 @@ function formatFatalDiagnostics(entries) {
|
|
|
136
166
|
`Transpilation aborted because ${errors.length} unsupported pattern${errors.length === 1 ? "" : "s"} were found.`,
|
|
137
167
|
];
|
|
138
168
|
for (const { filePath, diagnostic } of errors) {
|
|
139
|
-
|
|
169
|
+
// Prefer diagnostic.filePath (set explicitly by the emitter, e.g. AUTOSAR
|
|
170
|
+
// diagnostics that map a C++ line back to TS) over the wrapper's filePath
|
|
171
|
+
// (the TS source file being processed, which may not be the right pointer
|
|
172
|
+
// for emit-stage diagnostics).
|
|
173
|
+
const resolvedFile = diagnostic.filePath ?? filePath;
|
|
140
174
|
const locationBase = resolvedFile
|
|
141
175
|
? path.relative(process.cwd(), resolvedFile) || resolvedFile
|
|
142
176
|
: diagnostic.source ?? "user code";
|
|
@@ -215,6 +249,10 @@ export async function transpileFile(options) {
|
|
|
215
249
|
// requireUIHook() works throughout this transpile run. Gracefully no-ops
|
|
216
250
|
// when @typecad/ui is absent (pure TS→C++ transpile).
|
|
217
251
|
await loadUIEngine();
|
|
252
|
+
// Load the safety engine from @typecad/safety (if installed). Sets up the
|
|
253
|
+
// hook so requireSafetyHook() works throughout this transpile run.
|
|
254
|
+
// Gracefully no-ops when @typecad/safety is absent.
|
|
255
|
+
await loadSafetyEngine();
|
|
218
256
|
const entryFile = path.resolve(options.inputFile);
|
|
219
257
|
const entryDir = path.dirname(entryFile);
|
|
220
258
|
const sourceDir = entryDir;
|
|
@@ -236,41 +274,29 @@ export async function transpileFile(options) {
|
|
|
236
274
|
const configDisplay = options.display;
|
|
237
275
|
if (configDisplay) {
|
|
238
276
|
const { resolveDisplayProfile } = await import("./api/shared/display-profile.js");
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
: null;
|
|
257
|
-
for (const mod of [profileMod, fallbackMod]) {
|
|
258
|
-
if (mod?.BUILT_IN_PROFILES) {
|
|
259
|
-
for (const [k, v] of Object.entries(mod.BUILT_IN_PROFILES)) {
|
|
260
|
-
registry.set(k, v);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
277
|
+
// Build the named-profile registry. Prefer the strategy's hook (per-framework
|
|
278
|
+
// canonical profiles — Arduino returns its BUILT_IN_PROFILES, Zephyr returns
|
|
279
|
+
// its DT-binding profiles). Fall back to the legacy dynamic import of the
|
|
280
|
+
// framework's displays/ili9341-spi module when the strategy provides none.
|
|
281
|
+
// The registry maps a config `profile` name (e.g. "st7796-zephyr") to its
|
|
282
|
+
// DisplayProfile; an empty registry makes resolveDisplayProfile fall back to
|
|
283
|
+
// the bare default driver (config.driver ?? "ili9341") when no profile name
|
|
284
|
+
// is set, or throw "Unknown display profile" when one is.
|
|
285
|
+
let registry = new Map();
|
|
286
|
+
if (strategy.getProfileRegistry) {
|
|
287
|
+
registry = strategy.getProfileRegistry();
|
|
288
|
+
}
|
|
289
|
+
else if (options.frameworkPackage) {
|
|
290
|
+
const profileMod = await import(options.frameworkPackage + "/displays/ili9341-spi").catch(() => null);
|
|
291
|
+
if (profileMod?.BUILT_IN_PROFILES) {
|
|
292
|
+
for (const [k, v] of Object.entries(profileMod.BUILT_IN_PROFILES)) {
|
|
293
|
+
registry.set(k, v);
|
|
263
294
|
}
|
|
264
295
|
}
|
|
265
|
-
const resolved = resolveDisplayProfile(configDisplay, registry);
|
|
266
|
-
const buildTarget = options.platformContext?.frameworkData?.buildTarget;
|
|
267
|
-
const psramRaw = options.platformContext?.frameworkData?.psram;
|
|
268
|
-
const psram = psramRaw === 'opi' || psramRaw === 'quad';
|
|
269
|
-
setDisplayProfile(resolved.profile, { cs: resolved.cs, dc: resolved.dc, rst: resolved.rst, bus: resolved.bus, address: resolved.address, reset: resolved.reset, buildTarget, psram });
|
|
270
|
-
}
|
|
271
|
-
catch {
|
|
272
|
-
// Fall back to default profile — not fatal
|
|
273
296
|
}
|
|
297
|
+
const resolved = resolveDisplayProfile(configDisplay, registry);
|
|
298
|
+
const buildTarget = options.platformContext?.frameworkData?.buildTarget;
|
|
299
|
+
setDisplayProfile(resolved.profile, { cs: resolved.cs, dc: resolved.dc, rst: resolved.rst, bus: resolved.bus, address: resolved.address, reset: resolved.reset, buildTarget });
|
|
274
300
|
// Apply theme CSS override if specified.
|
|
275
301
|
if (configDisplay.themeCss) {
|
|
276
302
|
setThemeCss(configDisplay.themeCss);
|
|
@@ -478,7 +504,13 @@ export async function transpileFile(options) {
|
|
|
478
504
|
}
|
|
479
505
|
sourceText = preprocess(sourceText, filePath);
|
|
480
506
|
}
|
|
481
|
-
|
|
507
|
+
// Printf instrumentation runs only in printf debug mode. In gdb mode
|
|
508
|
+
// (e.g. ESP32-S3), --debug emits #line markers at the emit stage and
|
|
509
|
+
// uses VS Code native breakpoints; the printf preprocessor is skipped
|
|
510
|
+
// so the source reaches IR/emit unmodified.
|
|
511
|
+
const buildTarget = options.platformContext?.frameworkData?.buildTarget;
|
|
512
|
+
const debugMode = strategy.debugMode?.(buildTarget) ?? 'printf';
|
|
513
|
+
if (options.debug && breakpoints && debugMode === 'printf') {
|
|
482
514
|
const instrumented = debugPreprocess({
|
|
483
515
|
fileName: filePath,
|
|
484
516
|
breakpoints,
|
|
@@ -665,6 +697,60 @@ export async function transpileFile(options) {
|
|
|
665
697
|
profiler.startTimer("emit:register-enums");
|
|
666
698
|
registerAllEnumNames(allEnumIRs);
|
|
667
699
|
profiler.endTimer("emit:register-enums");
|
|
700
|
+
// ── Phase D: safety transform pass ──────────────────────────────────────
|
|
701
|
+
// When @typecad/safety is in use, run its post-build IR transform to inject
|
|
702
|
+
// safety ops (e.g. companion safety.record_pin_mode after every
|
|
703
|
+
// gpio.pin_mode). Produces new IR per file; no-op when safety is off or
|
|
704
|
+
// absent.
|
|
705
|
+
if (hasSafetyHook()) {
|
|
706
|
+
profiler.startTimer("safety:transform");
|
|
707
|
+
const hook = requireSafetyHook();
|
|
708
|
+
for (const [filePath, item] of preBuilt) {
|
|
709
|
+
const newIR = hook.transformIR(item.programIR, {
|
|
710
|
+
safetyInUse: entryImportsSafety(item.programIR),
|
|
711
|
+
target: options.target,
|
|
712
|
+
});
|
|
713
|
+
preBuilt.set(filePath, { ...item, programIR: newIR });
|
|
714
|
+
}
|
|
715
|
+
profiler.endTimer("safety:transform");
|
|
716
|
+
// Part B: ISO 26262 Part 6 read-only IR analysis. Runs after transformIR
|
|
717
|
+
// so it sees the final IR (including injected safety ops). Returned
|
|
718
|
+
// diagnostics flow into the build's diagnostic list; error-severity
|
|
719
|
+
// diagnostics abort via throwIfFatalDiagnostics.
|
|
720
|
+
if (hook.analyzeIR) {
|
|
721
|
+
profiler.startTimer("safety:analyze");
|
|
722
|
+
for (const [, item] of preBuilt) {
|
|
723
|
+
const irDiags = hook.analyzeIR(item.programIR, {
|
|
724
|
+
safetyInUse: entryImportsSafety(item.programIR),
|
|
725
|
+
target: options.target,
|
|
726
|
+
});
|
|
727
|
+
if (irDiags.length > 0) {
|
|
728
|
+
diagnostics.push(...irDiags);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
profiler.endTimer("safety:analyze");
|
|
732
|
+
}
|
|
733
|
+
// Part C: collect safety metadata and write sidecar artifact.
|
|
734
|
+
if (hook.collectSafetyMetadata) {
|
|
735
|
+
profiler.startTimer("safety:collect");
|
|
736
|
+
for (const [filePath, item] of preBuilt) {
|
|
737
|
+
if (!entryImportsSafety(item.programIR))
|
|
738
|
+
continue;
|
|
739
|
+
const metadata = hook.collectSafetyMetadata(item.programIR, {
|
|
740
|
+
safetyInUse: true,
|
|
741
|
+
target: options.target,
|
|
742
|
+
});
|
|
743
|
+
if (metadata.length > 0 && metadata[0].functions.length > 0) {
|
|
744
|
+
const { renderSafetySidecar } = await import("./safety/sidecar-bridge.js");
|
|
745
|
+
const toolVersion = CUTTLEFISH_VERSION;
|
|
746
|
+
const sidecarPath = path.join(outDir, path.basename(filePath).replace(/\.\w+$/, ".safety-sidecar.json"));
|
|
747
|
+
const sidecarJson = await renderSafetySidecar(metadata[0], toolVersion);
|
|
748
|
+
writeText(sidecarPath, sidecarJson);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
profiler.endTimer("safety:collect");
|
|
752
|
+
}
|
|
753
|
+
}
|
|
668
754
|
// ── Pass 2: emit (only for files that needed retranspilation) ─────────────
|
|
669
755
|
profiler.startTimer("emit:all");
|
|
670
756
|
profiler.captureMemorySnapshot("emit:pre");
|
|
@@ -689,6 +775,9 @@ export async function transpileFile(options) {
|
|
|
689
775
|
crossModuleEnumNames: allEnumNames,
|
|
690
776
|
crossModuleStringEnumNames: allStringEnumNames,
|
|
691
777
|
crossModuleVariableTypes: allVariableTypes,
|
|
778
|
+
autosar: options.autosar,
|
|
779
|
+
toolVersion: CUTTLEFISH_VERSION,
|
|
780
|
+
autosarArxml: options.autosarArxml,
|
|
692
781
|
};
|
|
693
782
|
// Pass the already-resolved strategy (framework-loaded or target-based)
|
|
694
783
|
emitOptions.strategy = strategy;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { TargetProfile as CoreTargetProfile, PlatformContext as CorePlatformContext, SourceSpan as CoreSourceSpan, Diagnostic as CoreDiagnostic } from "./api/shared/index.js";
|
|
2
2
|
export type EmitMode = "cpp" | "split";
|
|
3
|
+
export type ComplianceMode = "off" | "warn" | "strict";
|
|
3
4
|
export type TargetProfile = CoreTargetProfile;
|
|
4
5
|
export type PlatformContext = CorePlatformContext;
|
|
5
6
|
export type SourceSpan = CoreSourceSpan;
|
|
@@ -95,6 +96,10 @@ export interface TranspileOptions {
|
|
|
95
96
|
diagnostics?: boolean;
|
|
96
97
|
/** Display profile config from cuttlefish.config.ts */
|
|
97
98
|
display?: import("./api/shared/display-profile.js").DisplayConfig;
|
|
99
|
+
/** AUTOSAR C++14 compliance mode for emitted code (default: "off"). */
|
|
100
|
+
autosar?: ComplianceMode;
|
|
101
|
+
/** When true (and autosar is warn/strict), also emit the .autosar-deviations.arxml sidecar. */
|
|
102
|
+
autosarArxml?: boolean;
|
|
98
103
|
}
|
|
99
104
|
export interface LibraryDefinitionCondition {
|
|
100
105
|
target?: TargetProfile;
|
|
@@ -134,8 +139,10 @@ export interface CommandLineOptions {
|
|
|
134
139
|
monitor: boolean;
|
|
135
140
|
/** Serial port for upload and monitor (e.g. COM4 or /dev/ttyACM0) */
|
|
136
141
|
port?: string;
|
|
137
|
-
/** Baud rate for monitor
|
|
138
|
-
|
|
142
|
+
/** Baud rate for monitor. Undefined when --baud is absent so the consumer
|
|
143
|
+
* can fall back to config.console.baudRate (the framework monitor default
|
|
144
|
+
* applies only when neither is set). */
|
|
145
|
+
baud?: number;
|
|
139
146
|
platformContext?: PlatformContext;
|
|
140
147
|
mapFile?: string;
|
|
141
148
|
cppFile?: string;
|
|
@@ -168,6 +175,10 @@ export interface CommandLineOptions {
|
|
|
168
175
|
expectFile?: string;
|
|
169
176
|
/** Generate diagnostics.md and diagnostics.json reports */
|
|
170
177
|
diagnostics?: boolean;
|
|
178
|
+
/** AUTOSAR C++14 compliance mode for emitted code (default: "off"). */
|
|
179
|
+
autosar?: ComplianceMode;
|
|
180
|
+
/** When true (and autosar is warn/strict), also emit the .autosar-deviations.arxml sidecar. */
|
|
181
|
+
autosarArxml?: boolean;
|
|
171
182
|
/** Config file for preview command */
|
|
172
183
|
configPath?: string;
|
|
173
184
|
/** Project root (dir of cuttlefish.config.ts); passed to transpileFile for the ESLint gate. */
|
package/dist/ui-hook.d.ts
CHANGED
|
@@ -9,7 +9,6 @@ export interface LoweredUI {
|
|
|
9
9
|
screenCount: number;
|
|
10
10
|
imageTables: string;
|
|
11
11
|
keyframeTables: string;
|
|
12
|
-
scrollMemoryDiagnostics: Diagnostic[];
|
|
13
12
|
diagnostics: Diagnostic[];
|
|
14
13
|
}
|
|
15
14
|
export interface UIModule {
|
|
@@ -83,7 +82,6 @@ export interface TranspilerUIHook {
|
|
|
83
82
|
error: Error;
|
|
84
83
|
}>;
|
|
85
84
|
};
|
|
86
|
-
analyzeScrollMemory(styled: unknown, budget: number): Diagnostic[];
|
|
87
85
|
}
|
|
88
86
|
/** Set the UI hook. Called by transpile.ts after dynamically loading
|
|
89
87
|
* @typecad/ui/engine. Passing null clears it (end of transpile run). */
|