@kernlang/review 3.3.4 → 3.3.6
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/cache.js +1 -1
- package/dist/concept-rules/auth-drift.d.ts +29 -0
- package/dist/concept-rules/auth-drift.js +127 -0
- package/dist/concept-rules/auth-drift.js.map +1 -0
- package/dist/concept-rules/contract-drift.d.ts +21 -0
- package/dist/concept-rules/contract-drift.js +65 -0
- package/dist/concept-rules/contract-drift.js.map +1 -0
- package/dist/concept-rules/contract-method-drift.d.ts +22 -0
- package/dist/concept-rules/contract-method-drift.js +105 -0
- package/dist/concept-rules/contract-method-drift.js.map +1 -0
- package/dist/concept-rules/cross-stack-utils.d.ts +96 -0
- package/dist/concept-rules/cross-stack-utils.js +259 -0
- package/dist/concept-rules/cross-stack-utils.js.map +1 -0
- package/dist/concept-rules/duplicate-route.d.ts +20 -0
- package/dist/concept-rules/duplicate-route.js +112 -0
- package/dist/concept-rules/duplicate-route.js.map +1 -0
- package/dist/concept-rules/index.js +26 -1
- package/dist/concept-rules/index.js.map +1 -1
- package/dist/concept-rules/missing-response-model.d.ts +10 -0
- package/dist/concept-rules/missing-response-model.js +38 -0
- package/dist/concept-rules/missing-response-model.js.map +1 -0
- package/dist/concept-rules/orphan-route.d.ts +20 -0
- package/dist/concept-rules/orphan-route.js +96 -0
- package/dist/concept-rules/orphan-route.js.map +1 -0
- package/dist/concept-rules/sync-handler-does-io.d.ts +9 -0
- package/dist/concept-rules/sync-handler-does-io.js +56 -0
- package/dist/concept-rules/sync-handler-does-io.js.map +1 -0
- package/dist/concept-rules/tainted-across-wire.d.ts +33 -0
- package/dist/concept-rules/tainted-across-wire.js +95 -0
- package/dist/concept-rules/tainted-across-wire.js.map +1 -0
- package/dist/concept-rules/untyped-api-response.d.ts +30 -0
- package/dist/concept-rules/untyped-api-response.js +73 -0
- package/dist/concept-rules/untyped-api-response.js.map +1 -0
- package/dist/concept-rules/untyped-both-ends-response.d.ts +10 -0
- package/dist/concept-rules/untyped-both-ends-response.js +55 -0
- package/dist/concept-rules/untyped-both-ends-response.js.map +1 -0
- package/dist/external-tools.d.ts +17 -4
- package/dist/external-tools.js +12 -1
- package/dist/external-tools.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +115 -9
- package/dist/index.js.map +1 -1
- package/dist/llm-bridge.d.ts +38 -1
- package/dist/llm-bridge.js +172 -12
- package/dist/llm-bridge.js.map +1 -1
- package/dist/llm-review.js +29 -11
- package/dist/llm-review.js.map +1 -1
- package/dist/mappers/ts-concepts.js +650 -11
- package/dist/mappers/ts-concepts.js.map +1 -1
- package/dist/rules/index.js +17 -1
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/kern-source.js +37 -5
- package/dist/rules/kern-source.js.map +1 -1
- package/dist/rules/set-setter-collision.d.ts +21 -0
- package/dist/rules/set-setter-collision.js +74 -0
- package/dist/rules/set-setter-collision.js.map +1 -0
- package/dist/rules/suggest-kern-primitive.d.ts +30 -0
- package/dist/rules/suggest-kern-primitive.js +543 -0
- package/dist/rules/suggest-kern-primitive.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* suggest-kern-primitive — migration rule that flags JS patterns where an
|
|
3
|
+
* equivalent KERN primitive exists (array methods + fmt + conditional + async).
|
|
4
|
+
*
|
|
5
|
+
* Fires as `info` / precision=`experimental` so kern-sight hides it by default.
|
|
6
|
+
* Opt in with `--rule suggest-kern-primitive` for a one-shot migration scan.
|
|
7
|
+
*
|
|
8
|
+
* Covers the 22 shipped array primitives (post PR #93 + #103 + PR C):
|
|
9
|
+
* filter, find, some, every, findIndex, reduce, map, flatMap, flat, slice,
|
|
10
|
+
* at, sort, reverse, join, includes, indexOf, lastIndexOf, concat, forEach,
|
|
11
|
+
* compact, pluck, unique.
|
|
12
|
+
*
|
|
13
|
+
* Plus three structural primitives:
|
|
14
|
+
* - Template literal in `const` → `fmt name=x template="…"`
|
|
15
|
+
* - JSX ternary in `{…}` → `conditional if="…"` + handler/else
|
|
16
|
+
* - async fn with try/catch → `async name=X` + `recover`/`strategy`
|
|
17
|
+
*
|
|
18
|
+
* Special-cased shapes (route to the narrower primitive rather than the generic one):
|
|
19
|
+
* - `.filter(Boolean)` → `compact`
|
|
20
|
+
* - `.map(x => x.prop[.chain])` → `pluck`
|
|
21
|
+
* - `[...new Set(coll)]` → `unique`
|
|
22
|
+
*
|
|
23
|
+
* Immutability note: TS `.sort()` and `.reverse()` mutate; KERN emits the
|
|
24
|
+
* immutable `[...coll].sort(...)` / `[...coll].reverse()` shape. Suggestions
|
|
25
|
+
* for those two methods include a callout so authors can audit callers before
|
|
26
|
+
* migrating.
|
|
27
|
+
*/
|
|
28
|
+
import { Node, SyntaxKind } from 'ts-morph';
|
|
29
|
+
import { finding } from './utils.js';
|
|
30
|
+
const ARRAY_METHODS = {
|
|
31
|
+
filter: { kernNode: 'filter', shape: 'predicate' },
|
|
32
|
+
find: { kernNode: 'find', shape: 'predicate' },
|
|
33
|
+
some: { kernNode: 'some', shape: 'predicate' },
|
|
34
|
+
every: { kernNode: 'every', shape: 'predicate' },
|
|
35
|
+
findIndex: { kernNode: 'findIndex', shape: 'predicate' },
|
|
36
|
+
map: { kernNode: 'map', shape: 'expr' },
|
|
37
|
+
flatMap: { kernNode: 'flatMap', shape: 'expr' },
|
|
38
|
+
reduce: { kernNode: 'reduce', shape: 'reduce' },
|
|
39
|
+
slice: { kernNode: 'slice', shape: 'slice' },
|
|
40
|
+
at: { kernNode: 'at', shape: 'at' },
|
|
41
|
+
flat: { kernNode: 'flat', shape: 'flat' },
|
|
42
|
+
join: { kernNode: 'join', shape: 'join' },
|
|
43
|
+
includes: { kernNode: 'includes', shape: 'value' },
|
|
44
|
+
indexOf: { kernNode: 'indexOf', shape: 'value' },
|
|
45
|
+
lastIndexOf: { kernNode: 'lastIndexOf', shape: 'value' },
|
|
46
|
+
concat: { kernNode: 'concat', shape: 'concat' },
|
|
47
|
+
forEach: { kernNode: 'forEach', shape: 'forEach' },
|
|
48
|
+
sort: { kernNode: 'sort', shape: 'sort' },
|
|
49
|
+
reverse: { kernNode: 'reverse', shape: 'reverse' },
|
|
50
|
+
};
|
|
51
|
+
// Node kinds whose descendants should be skipped — don't flag opportunities
|
|
52
|
+
// inside test files, type-only files, or generated code paths by path hint.
|
|
53
|
+
function shouldSkipFile(ctx) {
|
|
54
|
+
const p = ctx.filePath.toLowerCase();
|
|
55
|
+
if (p.endsWith('.d.ts'))
|
|
56
|
+
return true;
|
|
57
|
+
if (p.includes('/node_modules/'))
|
|
58
|
+
return true;
|
|
59
|
+
if (p.includes('/dist/') || p.includes('/build/'))
|
|
60
|
+
return true;
|
|
61
|
+
if (p.includes('/generated/'))
|
|
62
|
+
return true;
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
function isArrowLike(n) {
|
|
66
|
+
return !!n && (Node.isArrowFunction(n) || Node.isFunctionExpression(n));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Extract an arrow/function body as a single expression string.
|
|
70
|
+
* Returns null for block bodies (multi-statement), which aren't a clean fit
|
|
71
|
+
* for an inline `where=` / `expr=` suggestion — those need a handler block.
|
|
72
|
+
*/
|
|
73
|
+
function extractSingleExprBody(arrow) {
|
|
74
|
+
const body = arrow.getBody();
|
|
75
|
+
if (Node.isBlock(body))
|
|
76
|
+
return null;
|
|
77
|
+
return body.getText();
|
|
78
|
+
}
|
|
79
|
+
function escapeKernString(s) {
|
|
80
|
+
return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\r?\n/g, ' ').replace(/\s+/g, ' ').trim();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Template-content escape: preserve whitespace (template body is significant)
|
|
84
|
+
* but neutralise characters that would break out of a double-quoted `template=`
|
|
85
|
+
* prop. `${…}` placeholders pass through untouched — that's the whole reason
|
|
86
|
+
* `fmt` exists.
|
|
87
|
+
*/
|
|
88
|
+
function escapeKernTemplate(s) {
|
|
89
|
+
return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
90
|
+
}
|
|
91
|
+
function isJsxLike(n) {
|
|
92
|
+
return Node.isJsxElement(n) || Node.isJsxFragment(n) || Node.isJsxSelfClosingElement(n);
|
|
93
|
+
}
|
|
94
|
+
function paramName(arrow, idx) {
|
|
95
|
+
const params = arrow.getParameters();
|
|
96
|
+
if (params.length <= idx)
|
|
97
|
+
return null;
|
|
98
|
+
const name = params[idx].getName();
|
|
99
|
+
// Destructured or rest parameters — skip, they don't round-trip into a bare identifier binding.
|
|
100
|
+
if (name.startsWith('{') || name.startsWith('[') || name.startsWith('...'))
|
|
101
|
+
return null;
|
|
102
|
+
return name;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Is the arrow a Boolean-coercion shape `x => !!x` or `x => Boolean(x)` where
|
|
106
|
+
* the coerced expression is just the first parameter? These are the two
|
|
107
|
+
* common handwritten equivalents of `.filter(Boolean)` and route to `compact`.
|
|
108
|
+
*
|
|
109
|
+
* Only matches when the arrow's body references the parameter directly — not
|
|
110
|
+
* a property access or a computed expression — so we don't silently rewrite
|
|
111
|
+
* `x => !!x.active` (which is `filter where="x.active"`, not `compact`).
|
|
112
|
+
*/
|
|
113
|
+
function isBooleanCoercionOfFirstParam(arrow) {
|
|
114
|
+
if (arrow.getParameters().length !== 1)
|
|
115
|
+
return false;
|
|
116
|
+
const param = paramName(arrow, 0);
|
|
117
|
+
if (!param)
|
|
118
|
+
return false;
|
|
119
|
+
const body = arrow.getBody();
|
|
120
|
+
if (Node.isBlock(body))
|
|
121
|
+
return false;
|
|
122
|
+
// `!!x` — PrefixUnaryExpression(!, PrefixUnaryExpression(!, <Identifier param>))
|
|
123
|
+
if (Node.isPrefixUnaryExpression(body) && body.getOperatorToken() === SyntaxKind.ExclamationToken) {
|
|
124
|
+
const inner = body.getOperand();
|
|
125
|
+
if (Node.isPrefixUnaryExpression(inner) && inner.getOperatorToken() === SyntaxKind.ExclamationToken) {
|
|
126
|
+
const innermost = inner.getOperand();
|
|
127
|
+
if (Node.isIdentifier(innermost) && innermost.getText() === param)
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// `Boolean(x)` — CallExpression where callee is Identifier "Boolean" and sole arg is the param.
|
|
132
|
+
if (Node.isCallExpression(body)) {
|
|
133
|
+
const callee = body.getExpression();
|
|
134
|
+
if (Node.isIdentifier(callee) && callee.getText() === 'Boolean') {
|
|
135
|
+
const args = body.getArguments();
|
|
136
|
+
if (args.length === 1 && Node.isIdentifier(args[0]) && args[0].getText() === param)
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* If the arrow body is a property-access chain rooted at `item` (the first
|
|
144
|
+
* parameter), return the dot-path without the item prefix. Returns null for
|
|
145
|
+
* anything else — computed access, method calls, nested expressions, or
|
|
146
|
+
* optional-chain segments (since `pluck` emits plain dot-access that would
|
|
147
|
+
* throw if an intermediate is nullish).
|
|
148
|
+
*
|
|
149
|
+
* item => item.name → "name"
|
|
150
|
+
* u => u.profile.address.city → "profile.address.city"
|
|
151
|
+
* u => u.profile?.name → null (optional chain; kern `pluck` emits plain `.`)
|
|
152
|
+
* x => x.toUpperCase() → null (method call, not property chain)
|
|
153
|
+
* x => x[0] → null (computed, index access)
|
|
154
|
+
* x => x → null (just the parameter, no projection)
|
|
155
|
+
*/
|
|
156
|
+
function propertyAccessChainFromItem(arrow, itemName) {
|
|
157
|
+
const body = arrow.getBody();
|
|
158
|
+
if (Node.isBlock(body))
|
|
159
|
+
return null;
|
|
160
|
+
if (!Node.isPropertyAccessExpression(body))
|
|
161
|
+
return null;
|
|
162
|
+
const segments = [];
|
|
163
|
+
let cur = body;
|
|
164
|
+
while (Node.isPropertyAccessExpression(cur)) {
|
|
165
|
+
// Optional-chain segments would require KERN to emit `item.a?.b`, which
|
|
166
|
+
// the current `pluck` lowering does not support. Fall back to `map`.
|
|
167
|
+
if (cur.hasQuestionDotToken())
|
|
168
|
+
return null;
|
|
169
|
+
segments.unshift(cur.getName());
|
|
170
|
+
cur = cur.getExpression();
|
|
171
|
+
}
|
|
172
|
+
if (!Node.isIdentifier(cur) || cur.getText() !== itemName)
|
|
173
|
+
return null;
|
|
174
|
+
return segments.join('.');
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Is the TS text safe to inject into a KERN bare prop value (after `prop=`)?
|
|
178
|
+
* KERN's bare-prop parser stops at whitespace, `{`, and `$`. Anything else
|
|
179
|
+
* must be wrapped in a raw-expression form `{{ … }}` so the receiver survives
|
|
180
|
+
* parsing intact.
|
|
181
|
+
*/
|
|
182
|
+
function isBareKernValue(s) {
|
|
183
|
+
return /^[A-Za-z_$][\w.$[\]]*$/.test(s);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Wrap a TS expression text for use as a KERN bare prop value. Identifiers
|
|
187
|
+
* and simple property paths pass through; anything else becomes a raw-
|
|
188
|
+
* expression block so whitespace/operators/calls don't break parsing.
|
|
189
|
+
*/
|
|
190
|
+
function toKernInValue(s) {
|
|
191
|
+
return isBareKernValue(s) ? s : `{{ ${s} }}`;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Build the KERN primitive suggestion string for a single JS call site.
|
|
195
|
+
* Returns null when the call shape can't be cleanly migrated (e.g. block body,
|
|
196
|
+
* missing required args) — caller should skip silently in those cases.
|
|
197
|
+
*/
|
|
198
|
+
function buildSuggestion(spec, collection, call) {
|
|
199
|
+
const args = call.getArguments();
|
|
200
|
+
const name = '<name>';
|
|
201
|
+
// Wrap non-bare receivers (chained calls, parenthesized, whitespace) so
|
|
202
|
+
// KERN bare-prop parsing doesn't truncate at the first space.
|
|
203
|
+
const inVal = toKernInValue(collection);
|
|
204
|
+
switch (spec.shape) {
|
|
205
|
+
case 'predicate': {
|
|
206
|
+
// Skip arrows whose body references the second (index) parameter —
|
|
207
|
+
// KERN's predicate-form primitives don't bind an index, so migrating
|
|
208
|
+
// `(x, i) => i === 0` would silently drop `i`.
|
|
209
|
+
if (args.length !== 1 || !isArrowLike(args[0]))
|
|
210
|
+
return null;
|
|
211
|
+
const arrow = args[0];
|
|
212
|
+
if (arrow.getParameters().length > 1)
|
|
213
|
+
return null;
|
|
214
|
+
const item = paramName(arrow, 0);
|
|
215
|
+
if (!item)
|
|
216
|
+
return null;
|
|
217
|
+
const body = extractSingleExprBody(arrow);
|
|
218
|
+
if (body === null)
|
|
219
|
+
return null;
|
|
220
|
+
const itemProp = item === 'item' ? '' : ` item=${item}`;
|
|
221
|
+
return `${spec.kernNode} name=${name} in=${inVal}${itemProp} where="${escapeKernString(body)}"`;
|
|
222
|
+
}
|
|
223
|
+
case 'expr': {
|
|
224
|
+
if (args.length !== 1 || !isArrowLike(args[0]))
|
|
225
|
+
return null;
|
|
226
|
+
const arrow = args[0];
|
|
227
|
+
if (arrow.getParameters().length > 1)
|
|
228
|
+
return null;
|
|
229
|
+
const item = paramName(arrow, 0);
|
|
230
|
+
if (!item)
|
|
231
|
+
return null;
|
|
232
|
+
const body = extractSingleExprBody(arrow);
|
|
233
|
+
if (body === null)
|
|
234
|
+
return null;
|
|
235
|
+
const itemProp = item === 'item' ? '' : ` item=${item}`;
|
|
236
|
+
return `${spec.kernNode} name=${name} in=${inVal}${itemProp} expr="${escapeKernString(body)}"`;
|
|
237
|
+
}
|
|
238
|
+
case 'reduce': {
|
|
239
|
+
if (args.length < 1 || !isArrowLike(args[0]))
|
|
240
|
+
return null;
|
|
241
|
+
const arrow = args[0];
|
|
242
|
+
if (arrow.getParameters().length > 2)
|
|
243
|
+
return null;
|
|
244
|
+
const acc = paramName(arrow, 0);
|
|
245
|
+
const item = paramName(arrow, 1);
|
|
246
|
+
if (!acc || !item)
|
|
247
|
+
return null;
|
|
248
|
+
const body = extractSingleExprBody(arrow);
|
|
249
|
+
if (body === null)
|
|
250
|
+
return null;
|
|
251
|
+
const initial = args[1]?.getText();
|
|
252
|
+
if (!initial)
|
|
253
|
+
return null;
|
|
254
|
+
const accProp = acc === 'acc' ? '' : ` acc=${acc}`;
|
|
255
|
+
const itemProp = item === 'item' ? '' : ` item=${item}`;
|
|
256
|
+
return `reduce name=${name} in=${inVal}${accProp}${itemProp} initial="${escapeKernString(initial)}" expr="${escapeKernString(body)}"`;
|
|
257
|
+
}
|
|
258
|
+
case 'slice': {
|
|
259
|
+
const parts = [`slice name=${name} in=${inVal}`];
|
|
260
|
+
const start = args[0]?.getText();
|
|
261
|
+
const end = args[1]?.getText();
|
|
262
|
+
if (start)
|
|
263
|
+
parts.push(`start=${start}`);
|
|
264
|
+
if (end)
|
|
265
|
+
parts.push(`end=${end}`);
|
|
266
|
+
return parts.join(' ');
|
|
267
|
+
}
|
|
268
|
+
case 'at': {
|
|
269
|
+
const index = args[0]?.getText();
|
|
270
|
+
if (!index)
|
|
271
|
+
return null;
|
|
272
|
+
return `at name=${name} in=${inVal} index=${index}`;
|
|
273
|
+
}
|
|
274
|
+
case 'flat': {
|
|
275
|
+
const depth = args[0]?.getText();
|
|
276
|
+
return depth ? `flat name=${name} in=${inVal} depth=${depth}` : `flat name=${name} in=${inVal}`;
|
|
277
|
+
}
|
|
278
|
+
case 'join': {
|
|
279
|
+
const arg = args[0];
|
|
280
|
+
if (!arg)
|
|
281
|
+
return `join name=${name} in=${inVal}`;
|
|
282
|
+
// Only string literals are safe as bare `separator=` props. Non-
|
|
283
|
+
// literal separators need the raw-expression form; skip everything
|
|
284
|
+
// else so the suggestion never changes runtime behavior.
|
|
285
|
+
if (Node.isStringLiteral(arg) || Node.isNoSubstitutionTemplateLiteral(arg)) {
|
|
286
|
+
return `join name=${name} in=${inVal} separator=${arg.getText()}`;
|
|
287
|
+
}
|
|
288
|
+
return `join name=${name} in=${inVal} separator={{ ${arg.getText()} }}`;
|
|
289
|
+
}
|
|
290
|
+
case 'value': {
|
|
291
|
+
const arg = args[0];
|
|
292
|
+
if (!arg)
|
|
293
|
+
return null;
|
|
294
|
+
const value = arg.getText();
|
|
295
|
+
// String literals can safely ride inside the double-quoted `value=`
|
|
296
|
+
// prop (with escaping). Non-literal values need the raw-expression
|
|
297
|
+
// form so the parser doesn't treat an identifier as a literal string.
|
|
298
|
+
const valueProp = Node.isStringLiteral(arg) || Node.isNoSubstitutionTemplateLiteral(arg)
|
|
299
|
+
? `value="${escapeKernString(value)}"`
|
|
300
|
+
: `value={{ ${value} }}`;
|
|
301
|
+
const from = args[1]?.getText();
|
|
302
|
+
const fromProp = from ? ` from=${from}` : '';
|
|
303
|
+
return `${spec.kernNode} name=${name} in=${inVal} ${valueProp}${fromProp}`;
|
|
304
|
+
}
|
|
305
|
+
case 'concat': {
|
|
306
|
+
if (args.length < 1)
|
|
307
|
+
return null;
|
|
308
|
+
const withArg = args.map((a) => a.getText()).join(', ');
|
|
309
|
+
return `concat name=${name} in=${inVal} with={{ ${withArg} }}`;
|
|
310
|
+
}
|
|
311
|
+
case 'forEach': {
|
|
312
|
+
if (args.length !== 1 || !isArrowLike(args[0]))
|
|
313
|
+
return null;
|
|
314
|
+
const arrow = args[0];
|
|
315
|
+
const item = paramName(arrow, 0);
|
|
316
|
+
if (!item)
|
|
317
|
+
return null;
|
|
318
|
+
const idx = paramName(arrow, 1);
|
|
319
|
+
const idxProp = idx ? ` index=${idx}` : '';
|
|
320
|
+
const itemProp = item === 'item' ? '' : ` item=${item}`;
|
|
321
|
+
return `forEach in=${inVal}${itemProp}${idxProp}\n handler <<<\n ...\n >>>`;
|
|
322
|
+
}
|
|
323
|
+
case 'sort': {
|
|
324
|
+
if (args.length === 0) {
|
|
325
|
+
return `sort name=${name} in=${inVal} # NOTE: kern sort is immutable (spread source); TS .sort() mutates in place`;
|
|
326
|
+
}
|
|
327
|
+
if (!isArrowLike(args[0]))
|
|
328
|
+
return null;
|
|
329
|
+
const arrow = args[0];
|
|
330
|
+
const a = paramName(arrow, 0);
|
|
331
|
+
const b = paramName(arrow, 1);
|
|
332
|
+
if (!a || !b)
|
|
333
|
+
return null;
|
|
334
|
+
const body = extractSingleExprBody(arrow);
|
|
335
|
+
if (body === null)
|
|
336
|
+
return null;
|
|
337
|
+
const aProp = a === 'a' ? '' : ` a=${a}`;
|
|
338
|
+
const bProp = b === 'b' ? '' : ` b=${b}`;
|
|
339
|
+
return `sort name=${name} in=${inVal}${aProp}${bProp} compare="${escapeKernString(body)}" # NOTE: kern sort is immutable`;
|
|
340
|
+
}
|
|
341
|
+
case 'reverse': {
|
|
342
|
+
if (args.length !== 0)
|
|
343
|
+
return null;
|
|
344
|
+
return `reverse name=${name} in=${inVal} # NOTE: kern reverse is immutable`;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
export function suggestKernPrimitive(ctx) {
|
|
349
|
+
if (shouldSkipFile(ctx))
|
|
350
|
+
return [];
|
|
351
|
+
const findings = [];
|
|
352
|
+
// `[...new Set(coll)]` → route to the dedicated `unique` primitive.
|
|
353
|
+
for (const arr of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ArrayLiteralExpression)) {
|
|
354
|
+
const elements = arr.getElements();
|
|
355
|
+
if (elements.length !== 1)
|
|
356
|
+
continue;
|
|
357
|
+
const first = elements[0];
|
|
358
|
+
if (!Node.isSpreadElement(first))
|
|
359
|
+
continue;
|
|
360
|
+
const spread = first.getExpression();
|
|
361
|
+
if (!Node.isNewExpression(spread))
|
|
362
|
+
continue;
|
|
363
|
+
if (spread.getExpression().getText() !== 'Set')
|
|
364
|
+
continue;
|
|
365
|
+
const args = spread.getArguments();
|
|
366
|
+
if (args.length !== 1)
|
|
367
|
+
continue;
|
|
368
|
+
const source = args[0].getText();
|
|
369
|
+
findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS [...new Set(...)] could migrate to KERN `unique` — named primitive for dedup', ctx.filePath, arr.getStartLineNumber(), 1, { suggestion: `unique name=<name> in=${toKernInValue(source)}` }));
|
|
370
|
+
}
|
|
371
|
+
for (const call of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
372
|
+
const callee = call.getExpression();
|
|
373
|
+
if (!Node.isPropertyAccessExpression(callee))
|
|
374
|
+
continue;
|
|
375
|
+
const methodName = callee.getName();
|
|
376
|
+
const spec = ARRAY_METHODS[methodName];
|
|
377
|
+
if (!spec)
|
|
378
|
+
continue;
|
|
379
|
+
const collection = callee.getExpression().getText();
|
|
380
|
+
const collectionIn = toKernInValue(collection);
|
|
381
|
+
// `.filter(Boolean)`, `.filter(x => !!x)`, `.filter(x => Boolean(x))` →
|
|
382
|
+
// route to the dedicated `compact` primitive. The three shapes are all
|
|
383
|
+
// equivalent drop-falsy idioms; KERN prefers the named primitive.
|
|
384
|
+
if (methodName === 'filter' && call.getArguments().length === 1) {
|
|
385
|
+
const arg = call.getArguments()[0];
|
|
386
|
+
const isBooleanRef = Node.isIdentifier(arg) && arg.getText() === 'Boolean';
|
|
387
|
+
const isCoercionArrow = isArrowLike(arg) && isBooleanCoercionOfFirstParam(arg);
|
|
388
|
+
if (isBooleanRef || isCoercionArrow) {
|
|
389
|
+
findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS drop-falsy filter could migrate to KERN `compact` — named primitive for drop-falsy', ctx.filePath, call.getStartLineNumber(), 1, { suggestion: `compact name=<name> in=${collectionIn}` }));
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
// `.map(x => x.prop[.chain])` → route to the dedicated `pluck` primitive.
|
|
394
|
+
// Only fires on single-param arrows (to skip `(x, i) => ...` which KERN
|
|
395
|
+
// can't represent) and non-optional property chains.
|
|
396
|
+
if (methodName === 'map' && call.getArguments().length === 1) {
|
|
397
|
+
const arg = call.getArguments()[0];
|
|
398
|
+
if (isArrowLike(arg) && arg.getParameters().length === 1) {
|
|
399
|
+
const item = paramName(arg, 0);
|
|
400
|
+
if (item) {
|
|
401
|
+
const path = propertyAccessChainFromItem(arg, item);
|
|
402
|
+
if (path) {
|
|
403
|
+
findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS .map(x => x.<prop>) could migrate to KERN `pluck` — named primitive for property extraction', ctx.filePath, call.getStartLineNumber(), 1, {
|
|
404
|
+
suggestion: item === 'item'
|
|
405
|
+
? `pluck name=<name> in=${collectionIn} prop=${path}`
|
|
406
|
+
: `pluck name=<name> in=${collectionIn} item=${item} prop=${path}`,
|
|
407
|
+
}));
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
const suggestion = buildSuggestion(spec, collection, call);
|
|
414
|
+
if (!suggestion)
|
|
415
|
+
continue;
|
|
416
|
+
findings.push(finding('suggest-kern-primitive', 'info', 'pattern', `JS .${methodName}(…) could migrate to KERN \`${spec.kernNode}\` — one declarative binding instead of a handler-embedded call`, ctx.filePath, call.getStartLineNumber(), call.getStart() - call.getSourceFile().getFullText().lastIndexOf('\n', call.getStart()), { suggestion }));
|
|
417
|
+
}
|
|
418
|
+
// ── fmt detector ───────────────────────────────────────────────────────
|
|
419
|
+
// Two call sites map cleanly to KERN's `fmt` primitive:
|
|
420
|
+
//
|
|
421
|
+
// const label = `${count} files`; → fmt name=label template="…"
|
|
422
|
+
// return `${msg} (${code})`; → fmt name=<result> template="…"; return <result>
|
|
423
|
+
//
|
|
424
|
+
// Only fires on TemplateExpression (has substitutions); plain backtick
|
|
425
|
+
// strings are NoSubstitutionTemplateLiteral and don't need fmt.
|
|
426
|
+
// Single-line only — multiline templates have meaningful whitespace that's
|
|
427
|
+
// awkward to round-trip through a one-line suggestion.
|
|
428
|
+
for (const tpl of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.TemplateExpression)) {
|
|
429
|
+
const parent = tpl.getParent();
|
|
430
|
+
if (!parent)
|
|
431
|
+
continue;
|
|
432
|
+
const fullText = tpl.getText();
|
|
433
|
+
if (!fullText.startsWith('`') || !fullText.endsWith('`') || fullText.length < 2)
|
|
434
|
+
continue;
|
|
435
|
+
const body = fullText.slice(1, -1);
|
|
436
|
+
if (body.includes('\n'))
|
|
437
|
+
continue;
|
|
438
|
+
// Shape A — const initializer: `const x = \`…\`;`
|
|
439
|
+
if (Node.isVariableDeclaration(parent) && parent.getInitializer() === tpl) {
|
|
440
|
+
const nameNode = parent.getNameNode();
|
|
441
|
+
if (!Node.isIdentifier(nameNode))
|
|
442
|
+
continue; // skip destructured bindings
|
|
443
|
+
const name = nameNode.getText();
|
|
444
|
+
findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS template literal could migrate to KERN `fmt` — named primitive for string interpolation', ctx.filePath, tpl.getStartLineNumber(), 1, { suggestion: `fmt name=${name} template="${escapeKernTemplate(body)}"` }));
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
// Shape B — return value: `return \`…\`;`
|
|
448
|
+
// Migration is a two-step: bind the formatted string to a named `fmt`
|
|
449
|
+
// node first, then `return` that name. The suggestion shows both lines
|
|
450
|
+
// so authors can paste directly.
|
|
451
|
+
if (Node.isReturnStatement(parent) && parent.getExpression() === tpl) {
|
|
452
|
+
findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS template literal in return position could migrate to KERN `fmt` — bind to a name, then return it', ctx.filePath, tpl.getStartLineNumber(), 1, { suggestion: `fmt name=<result> template="${escapeKernTemplate(body)}"\nreturn <result>` }));
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
// ── conditional JSX detector ───────────────────────────────────────────
|
|
457
|
+
// `{cond ? <A /> : <B />}` inside JSX → `conditional if="cond"` + two
|
|
458
|
+
// handler children. Only fires when BOTH branches are JSX (skips the
|
|
459
|
+
// `cond ? <A /> : null` case — that's a then-only `{cond && <A />}` shape).
|
|
460
|
+
// Only fires when the ternary sits inside a JsxExpression container — a
|
|
461
|
+
// top-level `return cond ? <A /> : <B />` doesn't cleanly map to a
|
|
462
|
+
// conditional node (the whole return would need rewrapping).
|
|
463
|
+
for (const cond of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ConditionalExpression)) {
|
|
464
|
+
const whenTrue = cond.getWhenTrue();
|
|
465
|
+
const whenFalse = cond.getWhenFalse();
|
|
466
|
+
if (!isJsxLike(whenTrue) || !isJsxLike(whenFalse))
|
|
467
|
+
continue;
|
|
468
|
+
const parent = cond.getParent();
|
|
469
|
+
if (!parent || !Node.isJsxExpression(parent))
|
|
470
|
+
continue;
|
|
471
|
+
const condText = cond.getCondition().getText();
|
|
472
|
+
const suggestion = `conditional if="${escapeKernString(condText)}"\n` +
|
|
473
|
+
` handler <<<\n ${whenTrue.getText()}\n >>>\n` +
|
|
474
|
+
` else\n handler <<<\n ${whenFalse.getText()}\n >>>`;
|
|
475
|
+
findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JSX ternary could migrate to KERN `conditional` — declarative if/else render branch', ctx.filePath, cond.getStartLineNumber(), 1, { suggestion }));
|
|
476
|
+
}
|
|
477
|
+
// ── async try/catch detector ───────────────────────────────────────────
|
|
478
|
+
// `async function f() { try { await … } catch (e) { … } }` → `async name=f`
|
|
479
|
+
// with a handler child for the try body and a `recover`/`strategy` pair for
|
|
480
|
+
// the catch body.
|
|
481
|
+
//
|
|
482
|
+
// Only fires when:
|
|
483
|
+
// - the function is `async`
|
|
484
|
+
// - its body is a single TryStatement (so the full body maps to the async node)
|
|
485
|
+
// - the try block contains at least one `await` (else there's no async shape)
|
|
486
|
+
// - a catch clause is present (else there's no recovery to migrate)
|
|
487
|
+
const asyncFns = [
|
|
488
|
+
...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration),
|
|
489
|
+
...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression),
|
|
490
|
+
...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction),
|
|
491
|
+
];
|
|
492
|
+
for (const fn of asyncFns) {
|
|
493
|
+
if (!fn.isAsync())
|
|
494
|
+
continue;
|
|
495
|
+
const body = fn.getBody();
|
|
496
|
+
if (!body || !Node.isBlock(body))
|
|
497
|
+
continue;
|
|
498
|
+
const stmts = body.getStatements();
|
|
499
|
+
if (stmts.length !== 1)
|
|
500
|
+
continue;
|
|
501
|
+
const tryStmt = stmts[0];
|
|
502
|
+
if (!Node.isTryStatement(tryStmt))
|
|
503
|
+
continue;
|
|
504
|
+
const tryBlock = tryStmt.getTryBlock();
|
|
505
|
+
const catchClause = tryStmt.getCatchClause();
|
|
506
|
+
if (!catchClause)
|
|
507
|
+
continue;
|
|
508
|
+
if (tryBlock.getDescendantsOfKind(SyntaxKind.AwaitExpression).length === 0)
|
|
509
|
+
continue;
|
|
510
|
+
let name = '<name>';
|
|
511
|
+
if (Node.isFunctionDeclaration(fn)) {
|
|
512
|
+
name = fn.getName() ?? '<name>';
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
const p = fn.getParent();
|
|
516
|
+
if (p && Node.isVariableDeclaration(p)) {
|
|
517
|
+
const n = p.getNameNode();
|
|
518
|
+
if (Node.isIdentifier(n))
|
|
519
|
+
name = n.getText();
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
const indent = (text, spaces) => text
|
|
523
|
+
.split('\n')
|
|
524
|
+
.map((line) => ' '.repeat(spaces) + line)
|
|
525
|
+
.join('\n');
|
|
526
|
+
const tryText = tryBlock
|
|
527
|
+
.getStatements()
|
|
528
|
+
.map((s) => s.getText())
|
|
529
|
+
.join('\n');
|
|
530
|
+
const catchText = catchClause
|
|
531
|
+
.getBlock()
|
|
532
|
+
.getStatements()
|
|
533
|
+
.map((s) => s.getText())
|
|
534
|
+
.join('\n');
|
|
535
|
+
const suggestion = `async name=${name}\n` +
|
|
536
|
+
` handler <<<\n${indent(tryText, 4)}\n >>>\n` +
|
|
537
|
+
` recover\n strategy <<<\n${indent(catchText, 6)}\n >>>`;
|
|
538
|
+
findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'async try/catch could migrate to KERN `async` — named primitive with `recover`/`strategy` child', ctx.filePath, fn.getStartLineNumber(), 1, { suggestion }));
|
|
539
|
+
}
|
|
540
|
+
return findings;
|
|
541
|
+
}
|
|
542
|
+
export const suggestKernPrimitiveRules = [suggestKernPrimitive];
|
|
543
|
+
//# sourceMappingURL=suggest-kern-primitive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-kern-primitive.js","sourceRoot":"","sources":["../../src/rules/suggest-kern-primitive.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -282,6 +282,8 @@ export interface ReviewConfig {
|
|
|
282
282
|
graphFileMap?: Map<string, GraphFile>;
|
|
283
283
|
/** Path to host project's tsconfig.json — loaded into the ts-morph Project so jsx/paths/lib/allowJs match the real build. */
|
|
284
284
|
tsConfigFilePath?: string;
|
|
285
|
+
/** When true, emit the `missing-confidence` finding for .kern files without confidence annotations. Default: false (opt-in) — teams that don't use confidence annotations see no noise. */
|
|
286
|
+
requireConfidenceAnnotations?: boolean;
|
|
285
287
|
/** Override what dead-export treats as intentional public API. */
|
|
286
288
|
publicApi?: {
|
|
287
289
|
/** Absolute or projectRoot-relative paths whose exports are all public. */
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwaH,4EAA4E;AAE5E;sEACsE;AACtE,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,SAAiB,EAAE,QAAgB;IACnF,OAAO,GAAG,MAAM,IAAI,SAAS,IAAI,QAAQ,EAAE,CAAC;AAC9C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kernlang/review",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.6",
|
|
4
4
|
"description": "Kern Review — scan TS, infer .kern IR, roundtrip diff, report",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"license": "AGPL-3.0",
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"ts-morph": "^28.0.0",
|
|
29
|
-
"@kernlang/core": "3.3.
|
|
29
|
+
"@kernlang/core": "3.3.6"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "tsc -b",
|