@typecad/cuttlefish 1.0.0-alpha.10 → 1.0.0-alpha.12
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 +11 -3
- package/dist/api/shared/framework-manifest.d.ts +85 -78
- package/dist/api/shared/framework-manifest.js +1 -0
- package/dist/api/shared/index.d.ts +2 -0
- package/dist/api/shared/index.js +1 -0
- package/dist/api/shared/spdx-licenses.d.ts +139 -0
- package/dist/api/shared/spdx-licenses.js +385 -0
- package/dist/cli.js +6 -0
- package/dist/config-loader.d.ts +8 -0
- package/dist/config-loader.js +192 -48
- package/dist/config-schema.d.ts +96 -89
- package/dist/config-schema.js +3 -0
- package/dist/create/board-spec.d.ts +122 -122
- package/dist/create/eslint-rules-template.js +6 -3
- package/dist/create/init-templates.js +9 -1
- package/dist/emit/compliance/rules.js +34 -0
- package/dist/emit/emitters/setup.js +15 -2
- package/dist/ir/feature-registry.js +22 -6
- package/dist/ir/program-analysis.d.ts +4 -2
- package/dist/ir/program-analysis.js +2 -4
- package/dist/platform/async-runtime.d.ts +1 -1
- package/dist/platform/async-runtime.js +12 -3
- package/dist/platform/generic-strategy.js +1 -1
- package/dist/transpile.js +55 -7
- package/dist/utils/cli.js +3 -2
- package/dist/utils/fs.d.ts +2 -0
- package/dist/utils/fs.js +16 -0
- package/package.json +5 -4
|
@@ -44,10 +44,10 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
44
44
|
instance: number;
|
|
45
45
|
role: string;
|
|
46
46
|
}[] | undefined;
|
|
47
|
+
notes?: string | undefined;
|
|
47
48
|
alt?: string[] | undefined;
|
|
48
49
|
warnings?: string[] | undefined;
|
|
49
50
|
unsafe?: boolean | undefined;
|
|
50
|
-
notes?: string | undefined;
|
|
51
51
|
onboardLed?: boolean | undefined;
|
|
52
52
|
}, {
|
|
53
53
|
gpio: number;
|
|
@@ -57,10 +57,10 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
57
57
|
instance: number;
|
|
58
58
|
role: string;
|
|
59
59
|
}[] | undefined;
|
|
60
|
+
notes?: string | undefined;
|
|
60
61
|
alt?: string[] | undefined;
|
|
61
62
|
warnings?: string[] | undefined;
|
|
62
63
|
unsafe?: boolean | undefined;
|
|
63
|
-
notes?: string | undefined;
|
|
64
64
|
onboardLed?: boolean | undefined;
|
|
65
65
|
}>, "many">;
|
|
66
66
|
unsafe: z.ZodArray<z.ZodString, "many">;
|
|
@@ -75,21 +75,21 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
75
75
|
tx: z.ZodOptional<z.ZodString>;
|
|
76
76
|
rx: z.ZodOptional<z.ZodString>;
|
|
77
77
|
}, "strict", z.ZodTypeAny, {
|
|
78
|
-
|
|
79
|
-
scl?: string | undefined;
|
|
78
|
+
cs?: string | undefined;
|
|
80
79
|
mosi?: string | undefined;
|
|
81
|
-
miso?: string | undefined;
|
|
82
80
|
sck?: string | undefined;
|
|
83
|
-
|
|
81
|
+
miso?: string | undefined;
|
|
82
|
+
sda?: string | undefined;
|
|
83
|
+
scl?: string | undefined;
|
|
84
84
|
tx?: string | undefined;
|
|
85
85
|
rx?: string | undefined;
|
|
86
86
|
}, {
|
|
87
|
-
|
|
88
|
-
scl?: string | undefined;
|
|
87
|
+
cs?: string | undefined;
|
|
89
88
|
mosi?: string | undefined;
|
|
90
|
-
miso?: string | undefined;
|
|
91
89
|
sck?: string | undefined;
|
|
92
|
-
|
|
90
|
+
miso?: string | undefined;
|
|
91
|
+
sda?: string | undefined;
|
|
92
|
+
scl?: string | undefined;
|
|
93
93
|
tx?: string | undefined;
|
|
94
94
|
rx?: string | undefined;
|
|
95
95
|
}>>;
|
|
@@ -103,21 +103,21 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
103
103
|
tx: z.ZodOptional<z.ZodString>;
|
|
104
104
|
rx: z.ZodOptional<z.ZodString>;
|
|
105
105
|
}, "strict", z.ZodTypeAny, {
|
|
106
|
-
|
|
107
|
-
scl?: string | undefined;
|
|
106
|
+
cs?: string | undefined;
|
|
108
107
|
mosi?: string | undefined;
|
|
109
|
-
miso?: string | undefined;
|
|
110
108
|
sck?: string | undefined;
|
|
111
|
-
|
|
109
|
+
miso?: string | undefined;
|
|
110
|
+
sda?: string | undefined;
|
|
111
|
+
scl?: string | undefined;
|
|
112
112
|
tx?: string | undefined;
|
|
113
113
|
rx?: string | undefined;
|
|
114
114
|
}, {
|
|
115
|
-
|
|
116
|
-
scl?: string | undefined;
|
|
115
|
+
cs?: string | undefined;
|
|
117
116
|
mosi?: string | undefined;
|
|
118
|
-
miso?: string | undefined;
|
|
119
117
|
sck?: string | undefined;
|
|
120
|
-
|
|
118
|
+
miso?: string | undefined;
|
|
119
|
+
sda?: string | undefined;
|
|
120
|
+
scl?: string | undefined;
|
|
121
121
|
tx?: string | undefined;
|
|
122
122
|
rx?: string | undefined;
|
|
123
123
|
}>>;
|
|
@@ -131,21 +131,21 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
131
131
|
tx: z.ZodOptional<z.ZodString>;
|
|
132
132
|
rx: z.ZodOptional<z.ZodString>;
|
|
133
133
|
}, "strict", z.ZodTypeAny, {
|
|
134
|
-
|
|
135
|
-
scl?: string | undefined;
|
|
134
|
+
cs?: string | undefined;
|
|
136
135
|
mosi?: string | undefined;
|
|
137
|
-
miso?: string | undefined;
|
|
138
136
|
sck?: string | undefined;
|
|
139
|
-
|
|
137
|
+
miso?: string | undefined;
|
|
138
|
+
sda?: string | undefined;
|
|
139
|
+
scl?: string | undefined;
|
|
140
140
|
tx?: string | undefined;
|
|
141
141
|
rx?: string | undefined;
|
|
142
142
|
}, {
|
|
143
|
-
|
|
144
|
-
scl?: string | undefined;
|
|
143
|
+
cs?: string | undefined;
|
|
145
144
|
mosi?: string | undefined;
|
|
146
|
-
miso?: string | undefined;
|
|
147
145
|
sck?: string | undefined;
|
|
148
|
-
|
|
146
|
+
miso?: string | undefined;
|
|
147
|
+
sda?: string | undefined;
|
|
148
|
+
scl?: string | undefined;
|
|
149
149
|
tx?: string | undefined;
|
|
150
150
|
rx?: string | undefined;
|
|
151
151
|
}>>;
|
|
@@ -230,18 +230,18 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
230
230
|
maxValue: z.ZodNumber;
|
|
231
231
|
referenceVoltages: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
232
232
|
}, "strict", z.ZodTypeAny, {
|
|
233
|
+
maxValue: number;
|
|
233
234
|
instance: number;
|
|
234
235
|
channels: number;
|
|
235
236
|
resolution: number;
|
|
236
237
|
referenceVoltage: number;
|
|
237
|
-
maxValue: number;
|
|
238
238
|
referenceVoltages?: Record<string, number> | undefined;
|
|
239
239
|
}, {
|
|
240
|
+
maxValue: number;
|
|
240
241
|
instance: number;
|
|
241
242
|
channels: number;
|
|
242
243
|
resolution: number;
|
|
243
244
|
referenceVoltage: number;
|
|
244
|
-
maxValue: number;
|
|
245
245
|
referenceVoltages?: Record<string, number> | undefined;
|
|
246
246
|
}>, "many">;
|
|
247
247
|
pwm: z.ZodObject<{
|
|
@@ -273,14 +273,14 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
273
273
|
bits: z.ZodUnion<[z.ZodLiteral<8>, z.ZodLiteral<16>, z.ZodLiteral<32>, z.ZodLiteral<64>]>;
|
|
274
274
|
features: z.ZodOptional<z.ZodArray<z.ZodEnum<["pwm", "capture", "compare", "interrupt", "dma"]>, "many">>;
|
|
275
275
|
}, "strict", z.ZodTypeAny, {
|
|
276
|
+
bits: 8 | 16 | 32 | 64;
|
|
276
277
|
type: "general" | "high_speed" | "rtc" | "sys";
|
|
277
278
|
instance: number;
|
|
278
|
-
bits: 8 | 16 | 32 | 64;
|
|
279
279
|
features?: ("pwm" | "capture" | "compare" | "interrupt" | "dma")[] | undefined;
|
|
280
280
|
}, {
|
|
281
|
+
bits: 8 | 16 | 32 | 64;
|
|
281
282
|
type: "general" | "high_speed" | "rtc" | "sys";
|
|
282
283
|
instance: number;
|
|
283
|
-
bits: 8 | 16 | 32 | 64;
|
|
284
284
|
features?: ("pwm" | "capture" | "compare" | "interrupt" | "dma")[] | undefined;
|
|
285
285
|
}>, "many">;
|
|
286
286
|
wifi: z.ZodObject<{
|
|
@@ -365,68 +365,42 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
365
365
|
}>;
|
|
366
366
|
}, "strict", z.ZodTypeAny, {
|
|
367
367
|
architecture: string;
|
|
368
|
-
mcuId: string;
|
|
369
|
-
mcuName: string;
|
|
370
|
-
boardId: string;
|
|
371
|
-
boardName: string;
|
|
372
|
-
vendor: string;
|
|
373
|
-
clockSpeed: number;
|
|
374
|
-
fqbn: string;
|
|
375
|
-
arduinoDefine: string;
|
|
376
|
-
moduleFlash: number | null;
|
|
377
|
-
externalRam: number | null;
|
|
378
|
-
gpioRange: [number, number];
|
|
379
|
-
excludedGpio: number[];
|
|
380
|
-
pins: {
|
|
381
|
-
gpio: number;
|
|
382
|
-
capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
|
|
383
|
-
functions?: {
|
|
384
|
-
type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
|
|
385
|
-
instance: number;
|
|
386
|
-
role: string;
|
|
387
|
-
}[] | undefined;
|
|
388
|
-
alt?: string[] | undefined;
|
|
389
|
-
warnings?: string[] | undefined;
|
|
390
|
-
unsafe?: boolean | undefined;
|
|
391
|
-
notes?: string | undefined;
|
|
392
|
-
onboardLed?: boolean | undefined;
|
|
393
|
-
}[];
|
|
394
368
|
i2c: Record<string, {
|
|
395
|
-
|
|
396
|
-
scl?: string | undefined;
|
|
369
|
+
cs?: string | undefined;
|
|
397
370
|
mosi?: string | undefined;
|
|
398
|
-
miso?: string | undefined;
|
|
399
371
|
sck?: string | undefined;
|
|
400
|
-
|
|
372
|
+
miso?: string | undefined;
|
|
373
|
+
sda?: string | undefined;
|
|
374
|
+
scl?: string | undefined;
|
|
401
375
|
tx?: string | undefined;
|
|
402
376
|
rx?: string | undefined;
|
|
403
377
|
}>;
|
|
404
378
|
spi: Record<string, {
|
|
405
|
-
|
|
406
|
-
scl?: string | undefined;
|
|
379
|
+
cs?: string | undefined;
|
|
407
380
|
mosi?: string | undefined;
|
|
408
|
-
miso?: string | undefined;
|
|
409
381
|
sck?: string | undefined;
|
|
410
|
-
|
|
382
|
+
miso?: string | undefined;
|
|
383
|
+
sda?: string | undefined;
|
|
384
|
+
scl?: string | undefined;
|
|
411
385
|
tx?: string | undefined;
|
|
412
386
|
rx?: string | undefined;
|
|
413
387
|
}>;
|
|
414
388
|
uart: Record<string, {
|
|
415
|
-
|
|
416
|
-
scl?: string | undefined;
|
|
389
|
+
cs?: string | undefined;
|
|
417
390
|
mosi?: string | undefined;
|
|
418
|
-
miso?: string | undefined;
|
|
419
391
|
sck?: string | undefined;
|
|
420
|
-
|
|
392
|
+
miso?: string | undefined;
|
|
393
|
+
sda?: string | undefined;
|
|
394
|
+
scl?: string | undefined;
|
|
421
395
|
tx?: string | undefined;
|
|
422
396
|
rx?: string | undefined;
|
|
423
397
|
}>;
|
|
424
398
|
adc: {
|
|
399
|
+
maxValue: number;
|
|
425
400
|
instance: number;
|
|
426
401
|
channels: number;
|
|
427
402
|
resolution: number;
|
|
428
403
|
referenceVoltage: number;
|
|
429
|
-
maxValue: number;
|
|
430
404
|
referenceVoltages?: Record<string, number> | undefined;
|
|
431
405
|
}[];
|
|
432
406
|
pwm: {
|
|
@@ -439,6 +413,37 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
439
413
|
vid: string;
|
|
440
414
|
pid: string;
|
|
441
415
|
};
|
|
416
|
+
wifi: {
|
|
417
|
+
type: "wifi" | "wifi6";
|
|
418
|
+
supportsStation: boolean;
|
|
419
|
+
supportsAp: boolean;
|
|
420
|
+
};
|
|
421
|
+
mcuId: string;
|
|
422
|
+
mcuName: string;
|
|
423
|
+
boardId: string;
|
|
424
|
+
boardName: string;
|
|
425
|
+
vendor: string;
|
|
426
|
+
clockSpeed: number;
|
|
427
|
+
fqbn: string;
|
|
428
|
+
arduinoDefine: string;
|
|
429
|
+
moduleFlash: number | null;
|
|
430
|
+
externalRam: number | null;
|
|
431
|
+
gpioRange: [number, number];
|
|
432
|
+
excludedGpio: number[];
|
|
433
|
+
pins: {
|
|
434
|
+
gpio: number;
|
|
435
|
+
capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
|
|
436
|
+
functions?: {
|
|
437
|
+
type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
|
|
438
|
+
instance: number;
|
|
439
|
+
role: string;
|
|
440
|
+
}[] | undefined;
|
|
441
|
+
notes?: string | undefined;
|
|
442
|
+
alt?: string[] | undefined;
|
|
443
|
+
warnings?: string[] | undefined;
|
|
444
|
+
unsafe?: boolean | undefined;
|
|
445
|
+
onboardLed?: boolean | undefined;
|
|
446
|
+
}[];
|
|
442
447
|
unsafe: string[];
|
|
443
448
|
analog: string[];
|
|
444
449
|
peripheralInstances: {
|
|
@@ -459,9 +464,9 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
459
464
|
}[];
|
|
460
465
|
};
|
|
461
466
|
timers: {
|
|
467
|
+
bits: 8 | 16 | 32 | 64;
|
|
462
468
|
type: "general" | "high_speed" | "rtc" | "sys";
|
|
463
469
|
instance: number;
|
|
464
|
-
bits: 8 | 16 | 32 | 64;
|
|
465
470
|
features?: ("pwm" | "capture" | "compare" | "interrupt" | "dma")[] | undefined;
|
|
466
471
|
}[];
|
|
467
472
|
features: {
|
|
@@ -473,11 +478,6 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
473
478
|
hardwareRng: boolean;
|
|
474
479
|
fpu: boolean;
|
|
475
480
|
};
|
|
476
|
-
wifi: {
|
|
477
|
-
type: "wifi" | "wifi6";
|
|
478
|
-
supportsStation: boolean;
|
|
479
|
-
supportsAp: boolean;
|
|
480
|
-
};
|
|
481
481
|
bluetooth: {
|
|
482
482
|
type: "classic" | "ble" | "dual";
|
|
483
483
|
version: string;
|
|
@@ -489,75 +489,49 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
489
489
|
externalRam?: number | undefined;
|
|
490
490
|
rtcMemory?: number | undefined;
|
|
491
491
|
};
|
|
492
|
-
description?: string | undefined;
|
|
493
492
|
touch?: {
|
|
494
493
|
pins: string[];
|
|
495
494
|
channels: number;
|
|
496
495
|
} | null | undefined;
|
|
496
|
+
description?: string | undefined;
|
|
497
497
|
}, {
|
|
498
498
|
architecture: string;
|
|
499
|
-
mcuId: string;
|
|
500
|
-
mcuName: string;
|
|
501
|
-
boardId: string;
|
|
502
|
-
boardName: string;
|
|
503
|
-
vendor: string;
|
|
504
|
-
clockSpeed: number;
|
|
505
|
-
fqbn: string;
|
|
506
|
-
arduinoDefine: string;
|
|
507
|
-
moduleFlash: number | null;
|
|
508
|
-
externalRam: number | null;
|
|
509
|
-
gpioRange: [number, number];
|
|
510
|
-
excludedGpio: number[];
|
|
511
|
-
pins: {
|
|
512
|
-
gpio: number;
|
|
513
|
-
capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
|
|
514
|
-
functions?: {
|
|
515
|
-
type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
|
|
516
|
-
instance: number;
|
|
517
|
-
role: string;
|
|
518
|
-
}[] | undefined;
|
|
519
|
-
alt?: string[] | undefined;
|
|
520
|
-
warnings?: string[] | undefined;
|
|
521
|
-
unsafe?: boolean | undefined;
|
|
522
|
-
notes?: string | undefined;
|
|
523
|
-
onboardLed?: boolean | undefined;
|
|
524
|
-
}[];
|
|
525
499
|
i2c: Record<string, {
|
|
526
|
-
|
|
527
|
-
scl?: string | undefined;
|
|
500
|
+
cs?: string | undefined;
|
|
528
501
|
mosi?: string | undefined;
|
|
529
|
-
miso?: string | undefined;
|
|
530
502
|
sck?: string | undefined;
|
|
531
|
-
|
|
503
|
+
miso?: string | undefined;
|
|
504
|
+
sda?: string | undefined;
|
|
505
|
+
scl?: string | undefined;
|
|
532
506
|
tx?: string | undefined;
|
|
533
507
|
rx?: string | undefined;
|
|
534
508
|
}>;
|
|
535
509
|
spi: Record<string, {
|
|
536
|
-
|
|
537
|
-
scl?: string | undefined;
|
|
510
|
+
cs?: string | undefined;
|
|
538
511
|
mosi?: string | undefined;
|
|
539
|
-
miso?: string | undefined;
|
|
540
512
|
sck?: string | undefined;
|
|
541
|
-
|
|
513
|
+
miso?: string | undefined;
|
|
514
|
+
sda?: string | undefined;
|
|
515
|
+
scl?: string | undefined;
|
|
542
516
|
tx?: string | undefined;
|
|
543
517
|
rx?: string | undefined;
|
|
544
518
|
}>;
|
|
545
519
|
uart: Record<string, {
|
|
546
|
-
|
|
547
|
-
scl?: string | undefined;
|
|
520
|
+
cs?: string | undefined;
|
|
548
521
|
mosi?: string | undefined;
|
|
549
|
-
miso?: string | undefined;
|
|
550
522
|
sck?: string | undefined;
|
|
551
|
-
|
|
523
|
+
miso?: string | undefined;
|
|
524
|
+
sda?: string | undefined;
|
|
525
|
+
scl?: string | undefined;
|
|
552
526
|
tx?: string | undefined;
|
|
553
527
|
rx?: string | undefined;
|
|
554
528
|
}>;
|
|
555
529
|
adc: {
|
|
530
|
+
maxValue: number;
|
|
556
531
|
instance: number;
|
|
557
532
|
channels: number;
|
|
558
533
|
resolution: number;
|
|
559
534
|
referenceVoltage: number;
|
|
560
|
-
maxValue: number;
|
|
561
535
|
referenceVoltages?: Record<string, number> | undefined;
|
|
562
536
|
}[];
|
|
563
537
|
pwm: {
|
|
@@ -570,6 +544,37 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
570
544
|
vid: string;
|
|
571
545
|
pid: string;
|
|
572
546
|
};
|
|
547
|
+
wifi: {
|
|
548
|
+
type: "wifi" | "wifi6";
|
|
549
|
+
supportsStation: boolean;
|
|
550
|
+
supportsAp: boolean;
|
|
551
|
+
};
|
|
552
|
+
mcuId: string;
|
|
553
|
+
mcuName: string;
|
|
554
|
+
boardId: string;
|
|
555
|
+
boardName: string;
|
|
556
|
+
vendor: string;
|
|
557
|
+
clockSpeed: number;
|
|
558
|
+
fqbn: string;
|
|
559
|
+
arduinoDefine: string;
|
|
560
|
+
moduleFlash: number | null;
|
|
561
|
+
externalRam: number | null;
|
|
562
|
+
gpioRange: [number, number];
|
|
563
|
+
excludedGpio: number[];
|
|
564
|
+
pins: {
|
|
565
|
+
gpio: number;
|
|
566
|
+
capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
|
|
567
|
+
functions?: {
|
|
568
|
+
type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
|
|
569
|
+
instance: number;
|
|
570
|
+
role: string;
|
|
571
|
+
}[] | undefined;
|
|
572
|
+
notes?: string | undefined;
|
|
573
|
+
alt?: string[] | undefined;
|
|
574
|
+
warnings?: string[] | undefined;
|
|
575
|
+
unsafe?: boolean | undefined;
|
|
576
|
+
onboardLed?: boolean | undefined;
|
|
577
|
+
}[];
|
|
573
578
|
unsafe: string[];
|
|
574
579
|
analog: string[];
|
|
575
580
|
peripheralInstances: {
|
|
@@ -590,9 +595,9 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
590
595
|
}[];
|
|
591
596
|
};
|
|
592
597
|
timers: {
|
|
598
|
+
bits: 8 | 16 | 32 | 64;
|
|
593
599
|
type: "general" | "high_speed" | "rtc" | "sys";
|
|
594
600
|
instance: number;
|
|
595
|
-
bits: 8 | 16 | 32 | 64;
|
|
596
601
|
features?: ("pwm" | "capture" | "compare" | "interrupt" | "dma")[] | undefined;
|
|
597
602
|
}[];
|
|
598
603
|
features: {
|
|
@@ -604,11 +609,6 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
604
609
|
hardwareRng: boolean;
|
|
605
610
|
fpu: boolean;
|
|
606
611
|
};
|
|
607
|
-
wifi: {
|
|
608
|
-
type: "wifi" | "wifi6";
|
|
609
|
-
supportsStation: boolean;
|
|
610
|
-
supportsAp: boolean;
|
|
611
|
-
};
|
|
612
612
|
bluetooth: {
|
|
613
613
|
type: "classic" | "ble" | "dual";
|
|
614
614
|
version: string;
|
|
@@ -620,11 +620,11 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
620
620
|
externalRam?: number | undefined;
|
|
621
621
|
rtcMemory?: number | undefined;
|
|
622
622
|
};
|
|
623
|
-
description?: string | undefined;
|
|
624
623
|
touch?: {
|
|
625
624
|
pins: string[];
|
|
626
625
|
channels: number;
|
|
627
626
|
} | null | undefined;
|
|
627
|
+
description?: string | undefined;
|
|
628
628
|
}>;
|
|
629
629
|
export type BoardSpec = z.infer<typeof BoardSpecSchema>;
|
|
630
630
|
export declare function parseBoardSpec(jsoncText: string): BoardSpec;
|
|
@@ -300,9 +300,12 @@ export default {
|
|
|
300
300
|
return "";
|
|
301
301
|
}
|
|
302
302
|
function isContainerVar(node) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
303
|
+
// Only identifiers with a known container type count. A
|
|
304
|
+
// CallExpression receiver (e.g. arr.map(f).filter(g)) is the RESULT
|
|
305
|
+
// of a functional method — on arrays that's another array, which
|
|
306
|
+
// the transpiler lowers; treating it as a container flagged every
|
|
307
|
+
// supported method chain as an error.
|
|
308
|
+
return node.type === "Identifier" && containerVars.has(node.name);
|
|
306
309
|
}
|
|
307
310
|
return {
|
|
308
311
|
VariableDeclarator(node) {
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { LINT_RULES } from '../ir/feature-registry.js';
|
|
2
2
|
export function generateProjectPackageJson(options) {
|
|
3
3
|
const { projectName, frameworkPackage, boardPackage } = options;
|
|
4
|
+
// @typecad/hal is needed by every build, not just embedded ones: the
|
|
5
|
+
// transpiler unconditionally warms the HAL source modules (loadHALModules in
|
|
6
|
+
// transpile.ts), and resolveHALSourceDir() throws "Could not resolve
|
|
7
|
+
// @typecad/hal/src/" if the package is absent. Embedded targets pull it in
|
|
8
|
+
// transitively (@typecad/framework-arduino + board packages depend on it),
|
|
9
|
+
// but native targets have no board package and @typecad/framework-native does
|
|
10
|
+
// not declare it, so HAL must be an explicit direct dependency here.
|
|
4
11
|
const deps = {
|
|
5
12
|
"@typecad/cuttlefish": "^1.0.0-alpha.3",
|
|
13
|
+
"@typecad/hal": "^1.0.0-alpha.3",
|
|
6
14
|
[frameworkPackage]: "^1.0.0-alpha.3",
|
|
7
15
|
};
|
|
8
16
|
if (boardPackage) {
|
|
@@ -120,7 +128,7 @@ export function generateProjectTsconfig(options) {
|
|
|
120
128
|
"allowImportingTsExtensions": true,
|
|
121
129
|
"rootDirs": ["src", "types"]${paths}
|
|
122
130
|
},
|
|
123
|
-
"include": ["src/**/*.ts", "types/**/*.ts", "cuttlefish.config.ts"
|
|
131
|
+
"include": ["src/**/*.ts", "types/**/*.ts", "cuttlefish.config.ts", ".cuttlefish/cuttlefish-env.d.ts"${options.isNative ? '' : ', "sim/**/*.ts"'}]
|
|
124
132
|
}
|
|
125
133
|
`;
|
|
126
134
|
}
|
|
@@ -43,6 +43,40 @@ export const RULES = [
|
|
|
43
43
|
justification: "AVR freeHeap() measures the gap between the stack and heap via the avr-libc __heap_start/__brkval linker symbols; pointer-to-integer conversion is the only way to compute a byte distance between two addresses on a target with no numeric free-heap API.",
|
|
44
44
|
kind: "polyfill",
|
|
45
45
|
},
|
|
46
|
+
{
|
|
47
|
+
// framework-zephyr BLE lowering: characteristic read handlers are TS
|
|
48
|
+
// functions with heterogeneous inferred return types (const char*,
|
|
49
|
+
// double), but the GATT attribute table registers one C callback for
|
|
50
|
+
// every characteristic. Handlers are stored in a fixed-size void*
|
|
51
|
+
// table (__tc_ble.on_read[]) and the characteristic index rides in
|
|
52
|
+
// bt_gatt_attr::user_data; the dispatcher casts back to the concrete
|
|
53
|
+
// signature per the char's type field. C++14 has no type-safe way to
|
|
54
|
+
// store or invoke heterogeneous signatures through one type-erased
|
|
55
|
+
// slot. Marker-based: every site references the table or its index
|
|
56
|
+
// channel.
|
|
57
|
+
detect: /__tc_ble\.on_read|__tc_ble_attrs|attr->user_data/,
|
|
58
|
+
justification: "framework-zephyr BLE lowering stores heterogeneously-typed read handlers in a void* table (__tc_ble.on_read[]) keyed by bt_gatt_attr::user_data; C++14 offers no type-safe mechanism to store or invoke mixed signatures through one type-erased slot, so the store/dispatch sites must reinterpret_cast.",
|
|
59
|
+
kind: "polyfill",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
// Zephyr C APIs take byte buffers as uint8_t*/void* (bt_data.data,
|
|
63
|
+
// mqtt_utf8.utf8, MQTT payload.data, spi_buf.buf, i2c_read tx/rx)
|
|
64
|
+
// while cuttlefish lowers TS buffers and strings to char*/uint8_t
|
|
65
|
+
// arrays. The pointer reinterpretation happens exactly at the C API
|
|
66
|
+
// boundary in the framework shims (ble/mqtt/i2c/spi lowerings).
|
|
67
|
+
detect: /reinterpret_cast<(?:const )?uint8_t\*>|\.buf = reinterpret_cast<void\*>/,
|
|
68
|
+
justification: "Zephyr's C APIs (bt_data, mqtt_utf8, MQTT payload, spi_buf, i2c_read) accept byte buffers as uint8_t*/void* while the transpiler lowers TS buffers/strings to char*/uint8_t arrays; reinterpret_cast at the API boundary is the only way to pass the lowered buffer.",
|
|
69
|
+
kind: "polyfill",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
// Raw register declarations (framework-native and MCU register
|
|
73
|
+
// exports) map a literal address to a volatile uint32_t* MMIO
|
|
74
|
+
// pointer. C++14 has no standard integer→pointer conversion other
|
|
75
|
+
// than reinterpret_cast.
|
|
76
|
+
detect: /reinterpret_cast<volatile uint32_t\*>/,
|
|
77
|
+
justification: "MMIO register declarations convert a literal address to a volatile uint32_t* pointer; reinterpret_cast is the only standard C++14 integer-to-pointer conversion.",
|
|
78
|
+
kind: "other",
|
|
79
|
+
},
|
|
46
80
|
],
|
|
47
81
|
},
|
|
48
82
|
{ id: "M5-2-8", title: "No pointer arithmetic out of bounds", severity: "required", category: "C", enabled: true },
|
|
@@ -320,6 +320,15 @@ export function buildEmitterContext(program, options) {
|
|
|
320
320
|
if (!programAnalysis.usesNativeTiming && entryHasUI()) {
|
|
321
321
|
programAnalysis.usesNativeTiming = true;
|
|
322
322
|
}
|
|
323
|
+
// The UI runtime header calls constrain() in the progress/range node draw
|
|
324
|
+
// and touch-slider paths (injected by the emitter, not present in user
|
|
325
|
+
// source), so a mounted UI needs the constrain polyfill even when
|
|
326
|
+
// usesConstrain is false. OR entryHasUI() into the flag the native
|
|
327
|
+
// strategy reads when gating the constrain helper, mirroring the
|
|
328
|
+
// usesNativeTiming handling above.
|
|
329
|
+
if (!programAnalysis.usesConstrain && entryHasUI()) {
|
|
330
|
+
programAnalysis.usesConstrain = true;
|
|
331
|
+
}
|
|
323
332
|
options.platformContext.analysis = programAnalysis;
|
|
324
333
|
if (!options.platformContext.architecture && program.boardConstants) {
|
|
325
334
|
options.platformContext.architecture = program.boardConstants.get("architecture");
|
|
@@ -416,8 +425,12 @@ export function buildEmitterContext(program, options) {
|
|
|
416
425
|
}
|
|
417
426
|
// The UI runtime's per-frame tick uses millis() (injected by the emitter,
|
|
418
427
|
// not authored in user source), so keep the millis() shim when a UI is
|
|
419
|
-
// mounted even if the source-level analysis didn't flag usesMillis.
|
|
420
|
-
|
|
428
|
+
// mounted even if the source-level analysis didn't flag usesMillis. The
|
|
429
|
+
// async runtime and the setInterval/setTimeout scheduler also poll
|
|
430
|
+
// millis() without any user-source millis() call (Async.sleep lowers to a
|
|
431
|
+
// raw hal-op the timing scanners can't see) — mirror the usesNativeTiming
|
|
432
|
+
// derivation and keep the shim for those hidden consumers too.
|
|
433
|
+
if (!programAnalysis.usesMillis && !programAnalysis.hasAsync && programAnalysis.timerCallCount === 0 && !entryHasUI()) {
|
|
421
434
|
shimLines = shimLines.filter(l => !l.includes('millis()'));
|
|
422
435
|
}
|
|
423
436
|
// Strip the nullish helper FUNCTIONS (not the CUTTLEFISH_UNDEFINED macro)
|
|
@@ -112,7 +112,10 @@ add(ts.SyntaxKind.BigIntLiteral, {
|
|
|
112
112
|
hint: "Use a number literal with an explicit fixed-width type annotation.",
|
|
113
113
|
code: "TS2CPP_NO_EQUIVALENT",
|
|
114
114
|
eslint: {
|
|
115
|
-
|
|
115
|
+
// The parser emits the attribute as lowercase `bigint` (a string); the
|
|
116
|
+
// previous [bigInt=true] form matched nothing, so the editor never
|
|
117
|
+
// flagged what the build-time prescan did.
|
|
118
|
+
selector: "Literal[bigint]",
|
|
116
119
|
message: "[transpiler] BigInt literals are not supported (no C++ equivalent for embedded targets). Use a number literal with an explicit fixed-width type.",
|
|
117
120
|
},
|
|
118
121
|
});
|
|
@@ -222,7 +225,10 @@ const CONTEXT_LINT_RULES = [
|
|
|
222
225
|
source: "context",
|
|
223
226
|
},
|
|
224
227
|
{
|
|
225
|
-
|
|
228
|
+
// The parser names the attribute `operator`, not `type` — the previous
|
|
229
|
+
// [type='keyof'] form matched nothing, so the editor never flagged what
|
|
230
|
+
// the build-time prescan did.
|
|
231
|
+
selector: "TSTypeOperator[operator='keyof']",
|
|
226
232
|
message: "[transpiler] the keyof operator is not supported (no C++ equivalent). Use a string union or a switch over field names.",
|
|
227
233
|
source: "context",
|
|
228
234
|
},
|
|
@@ -317,12 +323,22 @@ const CONTEXT_LINT_RULES = [
|
|
|
317
323
|
source: "context",
|
|
318
324
|
},
|
|
319
325
|
{
|
|
320
|
-
|
|
326
|
+
// ui.bind is a recognized UI authoring call (intercepted by the
|
|
327
|
+
// transpiler's call-lowering), not Function.prototype.bind — the :not()
|
|
328
|
+
// guard exempts the `ui` receiver so the editor selector matches the
|
|
329
|
+
// build-time prescan (checkContextSensitive exempts exactly ui.bind).
|
|
330
|
+
// The exemption lives in the selector because generateEslintConfig()
|
|
331
|
+
// drops non-selector fields when rendering no-restricted-syntax. Only
|
|
332
|
+
// `bind` is exempted — ui.call/ui.apply are not UI APIs and the prescan
|
|
333
|
+
// flags them, so the editor does too.
|
|
334
|
+
selector: "CallExpression > MemberExpression.callee[property.name='bind']:not([object.name='ui'])",
|
|
335
|
+
message: "[transpiler] .bind/.call/.apply rebind `this` at call time, which has no C++ lowering (this is a fixed pointer). Call the function/method directly.",
|
|
336
|
+
source: "context",
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
selector: "CallExpression > MemberExpression.callee[property.name=/^(call|apply)$/]",
|
|
321
340
|
message: "[transpiler] .bind/.call/.apply rebind `this` at call time, which has no C++ lowering (this is a fixed pointer). Call the function/method directly.",
|
|
322
341
|
source: "context",
|
|
323
|
-
// ui.bind is a recognized UI authoring call (intercepted by the
|
|
324
|
-
// transpiler's call-lowering), not Function.prototype.bind.
|
|
325
|
-
filter: "(node) => { const o = node.callee.object; return !(o && o.type === 'Identifier' && o.name === 'ui'); }",
|
|
326
342
|
},
|
|
327
343
|
{
|
|
328
344
|
selector: "NewExpression[callee.name='Function']",
|
|
@@ -52,6 +52,10 @@ export interface ProgramAnalysisResult {
|
|
|
52
52
|
* __tc_TimerRuntime::MAX_TIMERS to the observed count (floor 1) rather than
|
|
53
53
|
* a blind constant, so a one-timer program links one slot, not eight. */
|
|
54
54
|
timerCallCount: number;
|
|
55
|
+
/** True when any function is declared `async` — the async runtime polls
|
|
56
|
+
* millis() every pump even when no timing call appears in user source
|
|
57
|
+
* (Async.sleep lowers to a raw hal-op the text scanners can't see). */
|
|
58
|
+
hasAsync: boolean;
|
|
55
59
|
/** ESP32 peripheral usage — framework-esp32 gates its IDF driver blocks and
|
|
56
60
|
* forced includes on these. Detected from HAL-op operation names, the same
|
|
57
61
|
* way usesUart/usesSPI/usesI2C are. Other frameworks have no CUTTLEFISH_*
|
|
@@ -103,8 +107,6 @@ export interface ProgramAnalysisResult {
|
|
|
103
107
|
/** Worker offload usage. Detected from worker.* ops. Frameworks gate the
|
|
104
108
|
* worker_runtime polyfill (and its per-framework backing) on this. */
|
|
105
109
|
usesWorker: boolean;
|
|
106
|
-
/** Native/desktop: std::chrono / steady_clock usage (gates <chrono>). */
|
|
107
|
-
usesChrono: boolean;
|
|
108
110
|
/** Native/desktop: std::set usage (gates <set>). */
|
|
109
111
|
usesSet: boolean;
|
|
110
112
|
/** Native/desktop: std::algorithm usage (std::sort/find/transform etc., gates <algorithm>). */
|
|
@@ -77,9 +77,6 @@ function analyzeExpression(expr, result, strategy) {
|
|
|
77
77
|
if (expr.value.includes('__tc_str_ptr')) {
|
|
78
78
|
result.usesStrPtr = true;
|
|
79
79
|
}
|
|
80
|
-
if (/std::chrono|steady_clock/.test(expr.value)) {
|
|
81
|
-
result.usesChrono = true;
|
|
82
|
-
}
|
|
83
80
|
if (/std::set\s*</.test(expr.value)) {
|
|
84
81
|
result.usesSet = true;
|
|
85
82
|
}
|
|
@@ -844,7 +841,7 @@ export function analyzeProgram(program, strategy) {
|
|
|
844
841
|
usesHwtimer: false,
|
|
845
842
|
usesCapacitive: false,
|
|
846
843
|
usesWorker: false,
|
|
847
|
-
|
|
844
|
+
hasAsync: false,
|
|
848
845
|
usesSet: false,
|
|
849
846
|
usesAlgorithm: false,
|
|
850
847
|
usesCstdio: false,
|
|
@@ -1010,6 +1007,7 @@ export function analyzeProgram(program, strategy) {
|
|
|
1010
1007
|
// consume site. Without this gate, every AVR program pulled in the Timer0
|
|
1011
1008
|
// ISR even when it never uses timing.
|
|
1012
1009
|
const hasAsync = program.functions.some(fn => fn.isAsync);
|
|
1010
|
+
result.hasAsync = hasAsync;
|
|
1013
1011
|
result.usesNativeTiming = result.usesMillis
|
|
1014
1012
|
|| result.usesTiming
|
|
1015
1013
|
|| result.timerCallCount > 0
|