@ucm-kit/adapter-typescript 0.1.30 → 0.1.31
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 +5 -1
- package/package.json +2 -2
- package/src/parite.mjs +28 -2
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ two capabilities without making
|
|
|
6
6
|
TypeScript compiler, a 23 MB dependency no other consumer should pay for.
|
|
7
7
|
|
|
8
8
|
```sh
|
|
9
|
-
npm install --save-dev @ucm-kit/adapter-typescript@0.1.
|
|
9
|
+
npm install --save-dev @ucm-kit/adapter-typescript@0.1.31 @ucm-kit/cli@0.1.38
|
|
10
10
|
npx ucm-typescript
|
|
11
11
|
npx --no-install ucm check
|
|
12
12
|
```
|
|
@@ -28,6 +28,10 @@ reported:
|
|
|
28
28
|
|
|
29
29
|
Parity requires a `tsconfig.json` at the root. Props are read with the
|
|
30
30
|
TypeScript type checker; compositions are counted by their occurrences in JSX.
|
|
31
|
+
The props of `Button.tsx` come from an interface or a type alias named
|
|
32
|
+
`ButtonProps`. The component is the function named `Button`, or the file's
|
|
33
|
+
default export. A prop counts as read whether it is destructured in the
|
|
34
|
+
signature or from `props` in the body.
|
|
31
35
|
|
|
32
36
|
Every one of these **warns without blocking**. The gap is in the code, so a
|
|
33
37
|
developer closes it. No re-export helps.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ucm-kit/adapter-typescript",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"description": "Adaptateur TypeScript UCM : parité statique des composants et génération des types dérivés des contrats.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"test": "node scripts/run-tests.cjs"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ucm-kit/core": "0.1.
|
|
38
|
+
"@ucm-kit/core": "0.1.34",
|
|
39
39
|
"typescript": ">=5.5.0 <6"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/src/parite.mjs
CHANGED
|
@@ -45,6 +45,15 @@ function trouverFonctionComposant(source, nomComposant) {
|
|
|
45
45
|
nommee = noeud;
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
|
+
// `export default function (…)` n'est pas une affectation d'export : c'est
|
|
49
|
+
// une déclaration, anonyme ou nommée autrement que le fichier.
|
|
50
|
+
if (
|
|
51
|
+
ts.isFunctionDeclaration(noeud)
|
|
52
|
+
&& noeud.modifiers?.some((modificateur) => modificateur.kind === ts.SyntaxKind.DefaultKeyword)
|
|
53
|
+
) {
|
|
54
|
+
parDefaut = noeud;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
48
57
|
if (ts.isExportAssignment(noeud) && !noeud.isExportEquals) {
|
|
49
58
|
parDefaut = fonctionEmballee(noeud.expression);
|
|
50
59
|
return;
|
|
@@ -65,7 +74,8 @@ function symboleLuDans(noeud, symbole, verificateur) {
|
|
|
65
74
|
let lu = false;
|
|
66
75
|
const visiter = (enfant) => {
|
|
67
76
|
if (lu) return;
|
|
68
|
-
|
|
77
|
+
// Le nom d'une décomposition déclare le symbole, il ne le lit pas.
|
|
78
|
+
if (ts.isIdentifier(enfant) && !(ts.isBindingElement(enfant.parent) && enfant.parent.name === enfant)) {
|
|
69
79
|
const symboleValeur = ts.isShorthandPropertyAssignment(enfant.parent)
|
|
70
80
|
? verificateur.getShorthandAssignmentValueSymbol(enfant.parent)
|
|
71
81
|
: verificateur.getSymbolAtLocation(enfant);
|
|
@@ -121,6 +131,21 @@ function propsConsommees(fonction, nomsProps, verificateur) {
|
|
|
121
131
|
&& estLeParametre(noeud.expression)
|
|
122
132
|
) {
|
|
123
133
|
for (const nom of nomsProps) consommees.add(nom);
|
|
134
|
+
} else if (
|
|
135
|
+
ts.isVariableDeclaration(noeud)
|
|
136
|
+
&& ts.isObjectBindingPattern(noeud.name)
|
|
137
|
+
&& noeud.initializer
|
|
138
|
+
&& estLeParametre(noeud.initializer)
|
|
139
|
+
) {
|
|
140
|
+
// `const { a } = props` : la prop compte si la variable locale est lue.
|
|
141
|
+
for (const element of noeud.name.elements) {
|
|
142
|
+
if (element.dotDotDotToken || !ts.isIdentifier(element.name)) continue;
|
|
143
|
+
const nom = nomDeBinding(element.propertyName ?? element.name);
|
|
144
|
+
const symbole = verificateur.getSymbolAtLocation(element.name);
|
|
145
|
+
if (nom && symbole && symboleLuDans(fonction.body, symbole, verificateur)) {
|
|
146
|
+
consommees.add(nom);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
124
149
|
}
|
|
125
150
|
ts.forEachChild(noeud, visiter);
|
|
126
151
|
};
|
|
@@ -267,7 +292,8 @@ export function lireApiPublique(fichiers, racine) {
|
|
|
267
292
|
let props = null;
|
|
268
293
|
|
|
269
294
|
ts.forEachChild(source, (noeud) => {
|
|
270
|
-
if (!ts.isInterfaceDeclaration(noeud) || noeud
|
|
295
|
+
if (!(ts.isInterfaceDeclaration(noeud) || ts.isTypeAliasDeclaration(noeud))) return;
|
|
296
|
+
if (noeud.name.text !== attendue) return;
|
|
271
297
|
const type = verificateur.getTypeAtLocation(noeud.name);
|
|
272
298
|
const membres = verificateur.getPropertiesOfType(type);
|
|
273
299
|
const consommees = propsConsommees(
|