@kernlang/review 3.2.3 → 3.3.4
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 +140 -3
- package/dist/cache.js.map +1 -1
- package/dist/call-graph.d.ts +4 -1
- package/dist/call-graph.js +290 -25
- package/dist/call-graph.js.map +1 -1
- package/dist/external-tools.d.ts +23 -4
- package/dist/external-tools.js +68 -12
- package/dist/external-tools.js.map +1 -1
- package/dist/graph.js +149 -39
- package/dist/graph.js.map +1 -1
- package/dist/index.d.ts +27 -3
- package/dist/index.js +254 -41
- package/dist/index.js.map +1 -1
- package/dist/inferrer.d.ts +5 -0
- package/dist/inferrer.js +1 -1
- package/dist/inferrer.js.map +1 -1
- package/dist/mappers/ts-concepts.js +31 -6
- package/dist/mappers/ts-concepts.js.map +1 -1
- package/dist/public-api.d.ts +73 -0
- package/dist/public-api.js +351 -0
- package/dist/public-api.js.map +1 -0
- package/dist/reporter.d.ts +5 -0
- package/dist/reporter.js +119 -84
- package/dist/reporter.js.map +1 -1
- package/dist/review-health.d.ts +38 -0
- package/dist/review-health.js +60 -0
- package/dist/review-health.js.map +1 -0
- package/dist/rules/async.js +4 -16
- package/dist/rules/async.js.map +1 -1
- package/dist/rules/base.js +112 -87
- package/dist/rules/base.js.map +1 -1
- package/dist/rules/confidence.d.ts +2 -2
- package/dist/rules/confidence.js +32 -15
- package/dist/rules/confidence.js.map +1 -1
- package/dist/rules/dead-code.d.ts +2 -1
- package/dist/rules/dead-code.js +49 -3
- package/dist/rules/dead-code.js.map +1 -1
- package/dist/rules/index.js +131 -0
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/kern-source-cross-file.d.ts +2 -0
- package/dist/rules/kern-source-cross-file.js +102 -0
- package/dist/rules/kern-source-cross-file.js.map +1 -0
- package/dist/rules/kern-source.js +51 -4
- package/dist/rules/kern-source.js.map +1 -1
- package/dist/rules/nextjs-app-router.js +936 -31
- package/dist/rules/nextjs-app-router.js.map +1 -1
- package/dist/rules/nextjs.js +193 -10
- package/dist/rules/nextjs.js.map +1 -1
- package/dist/rules/react-composition.js +442 -61
- package/dist/rules/react-composition.js.map +1 -1
- package/dist/rules/react-hooks.js +51 -2
- package/dist/rules/react-hooks.js.map +1 -1
- package/dist/rules/react.js +265 -49
- package/dist/rules/react.js.map +1 -1
- package/dist/rules/utils.d.ts +37 -2
- package/dist/rules/utils.js +113 -0
- package/dist/rules/utils.js.map +1 -1
- package/dist/semantic-diff.js +1 -1
- package/dist/semantic-diff.js.map +1 -1
- package/dist/taint-ast.js +228 -4
- package/dist/taint-ast.js.map +1 -1
- package/dist/taint-crossfile.d.ts +30 -2
- package/dist/taint-crossfile.js +280 -59
- package/dist/taint-crossfile.js.map +1 -1
- package/dist/taint-types.d.ts +2 -1
- package/dist/taint-types.js +32 -2
- package/dist/taint-types.js.map +1 -1
- package/dist/taint.d.ts +1 -1
- package/dist/taint.js +1 -1
- package/dist/taint.js.map +1 -1
- package/dist/types.d.ts +78 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* correctness; this layer catches the common footguns with high precision.
|
|
7
7
|
*/
|
|
8
8
|
import { Node, SyntaxKind } from 'ts-morph';
|
|
9
|
-
import { finding, nodeSpan } from './utils.js';
|
|
9
|
+
import { finding, nodeSpan, shouldSkipHookRules } from './utils.js';
|
|
10
10
|
const EFFECT_HOOKS = new Set(['useEffect', 'useLayoutEffect']);
|
|
11
11
|
const MEMO_HOOKS = new Set(['useMemo', 'useCallback']);
|
|
12
12
|
const REACT_HOOK_NAMES = new Set([
|
|
@@ -375,6 +375,55 @@ function stateDerivedFromProps(ctx) {
|
|
|
375
375
|
}
|
|
376
376
|
return findings;
|
|
377
377
|
}
|
|
378
|
+
// ── Rule: usecallback-no-benefit ─────────────────────────────────────────
|
|
379
|
+
// useCallback used only as a host-element event handler provides no memoized
|
|
380
|
+
// consumer and usually just adds indirection.
|
|
381
|
+
function useCallbackNoBenefit(ctx) {
|
|
382
|
+
const findings = [];
|
|
383
|
+
for (const decl of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration)) {
|
|
384
|
+
const init = decl.getInitializer();
|
|
385
|
+
if (!init || !Node.isCallExpression(init))
|
|
386
|
+
continue;
|
|
387
|
+
const calleeText = init.getExpression().getText();
|
|
388
|
+
const calleeName = calleeText.includes('.') ? calleeText.split('.').pop() : calleeText;
|
|
389
|
+
if (calleeName !== 'useCallback')
|
|
390
|
+
continue;
|
|
391
|
+
const nameNode = decl.getNameNode();
|
|
392
|
+
if (!Node.isIdentifier(nameNode))
|
|
393
|
+
continue;
|
|
394
|
+
const callbackName = nameNode.getText();
|
|
395
|
+
const refs = ctx.sourceFile
|
|
396
|
+
.getDescendantsOfKind(SyntaxKind.Identifier)
|
|
397
|
+
.filter((id) => id.getText() === callbackName && id !== nameNode);
|
|
398
|
+
if (refs.length !== 1)
|
|
399
|
+
continue;
|
|
400
|
+
const onlyRef = refs[0];
|
|
401
|
+
const jsxAttr = onlyRef.getFirstAncestorByKind(SyntaxKind.JsxAttribute);
|
|
402
|
+
if (!jsxAttr)
|
|
403
|
+
continue;
|
|
404
|
+
const jsxTag = jsxAttr.getFirstAncestorByKind(SyntaxKind.JsxSelfClosingElement) ||
|
|
405
|
+
jsxAttr.getFirstAncestorByKind(SyntaxKind.JsxOpeningElement);
|
|
406
|
+
if (!jsxTag)
|
|
407
|
+
continue;
|
|
408
|
+
const tagName = jsxTag.getTagNameNode().getText();
|
|
409
|
+
if (!/^[a-z]/.test(tagName))
|
|
410
|
+
continue; // only intrinsic DOM tags
|
|
411
|
+
findings.push(finding('usecallback-no-benefit', 'info', 'pattern', `'${callbackName}' is wrapped in useCallback but is only used as a '${jsxAttr.getNameNode().getText()}' handler on <${tagName}> — this adds memoization overhead without a memoized consumer`, ctx.filePath, decl.getStartLineNumber(), 1, {
|
|
412
|
+
suggestion: 'Inline the handler in JSX or use a normal local function. Keep useCallback for memoized children, hook dependency stability, or imperative subscription APIs that need stable identity',
|
|
413
|
+
}));
|
|
414
|
+
}
|
|
415
|
+
return findings;
|
|
416
|
+
}
|
|
378
417
|
// ── Exported React Hooks Rules ───────────────────────────────────────────
|
|
379
|
-
|
|
418
|
+
/** All rules in this file assume a client runtime — skip on server/api/middleware
|
|
419
|
+
* unless the file still has React content (JSX / react import / hook call). */
|
|
420
|
+
function clientOnly(fn) {
|
|
421
|
+
return ((ctx) => (shouldSkipHookRules(ctx) ? [] : fn(ctx)));
|
|
422
|
+
}
|
|
423
|
+
export const reactHooksRules = [
|
|
424
|
+
clientOnly(exhaustiveDeps),
|
|
425
|
+
clientOnly(refInDeps),
|
|
426
|
+
clientOnly(stateDerivedFromProps),
|
|
427
|
+
clientOnly(useCallbackNoBenefit),
|
|
428
|
+
];
|
|
380
429
|
//# sourceMappingURL=react-hooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-hooks.js","sourceRoot":"","sources":["../../src/rules/react-hooks.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react-hooks.js","sourceRoot":"","sources":["../../src/rules/react-hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/rules/react.js
CHANGED
|
@@ -4,7 +4,16 @@
|
|
|
4
4
|
* Catches React-specific bugs that KERN IR + AST can detect mechanically.
|
|
5
5
|
*/
|
|
6
6
|
import { Node, SyntaxKind } from 'ts-morph';
|
|
7
|
-
import { finding } from './utils.js';
|
|
7
|
+
import { cleanupExpressionMatches, escapeRegex, findAssignedIdentifier, finding, getTopLevelCleanupExpressions, shouldSkipHookRules, } from './utils.js';
|
|
8
|
+
/**
|
|
9
|
+
* Wrap a hook-specific rule so it short-circuits on server/api/middleware
|
|
10
|
+
* files — unless the file still has React content (JSX / react import /
|
|
11
|
+
* hook call), which means the boundary classifier is wrong for this file
|
|
12
|
+
* (common on `/routes/` and `/controllers/` React components).
|
|
13
|
+
*/
|
|
14
|
+
function clientOnly(fn) {
|
|
15
|
+
return ((ctx) => (shouldSkipHookRules(ctx) ? [] : fn(ctx)));
|
|
16
|
+
}
|
|
8
17
|
/**
|
|
9
18
|
* Check if a file is actually a React file — has JSX syntax or React imports.
|
|
10
19
|
* Backend/utility files in a React-targeted project should not trigger React rules.
|
|
@@ -21,6 +30,36 @@ function isReactFile(ctx) {
|
|
|
21
30
|
return true;
|
|
22
31
|
return false;
|
|
23
32
|
}
|
|
33
|
+
function unwrapJsxExpression(node) {
|
|
34
|
+
let current = node;
|
|
35
|
+
while (Node.isParenthesizedExpression(current) ||
|
|
36
|
+
Node.isAsExpression(current) ||
|
|
37
|
+
Node.isTypeAssertion(current) ||
|
|
38
|
+
Node.isNonNullExpression(current) ||
|
|
39
|
+
Node.isSatisfiesExpression(current)) {
|
|
40
|
+
current = current.getExpression();
|
|
41
|
+
}
|
|
42
|
+
return current;
|
|
43
|
+
}
|
|
44
|
+
function getMapCallbackRootJsx(callback) {
|
|
45
|
+
const body = callback.getBody();
|
|
46
|
+
if (Node.isBlock(body)) {
|
|
47
|
+
const returnStmt = body.getStatements().find((stmt) => Node.isReturnStatement(stmt));
|
|
48
|
+
const expr = returnStmt?.getExpression();
|
|
49
|
+
if (!expr)
|
|
50
|
+
return undefined;
|
|
51
|
+
const unwrapped = unwrapJsxExpression(expr);
|
|
52
|
+
if (Node.isJsxElement(unwrapped) || Node.isJsxSelfClosingElement(unwrapped) || Node.isJsxFragment(unwrapped)) {
|
|
53
|
+
return unwrapped;
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const unwrapped = unwrapJsxExpression(body);
|
|
58
|
+
if (Node.isJsxElement(unwrapped) || Node.isJsxSelfClosingElement(unwrapped) || Node.isJsxFragment(unwrapped)) {
|
|
59
|
+
return unwrapped;
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
24
63
|
// ── Rule 11: async-effect ────────────────────────────────────────────────
|
|
25
64
|
// useEffect(async () => ...) — React doesn't support async effect callbacks
|
|
26
65
|
function asyncEffect(ctx) {
|
|
@@ -106,6 +145,25 @@ function renderSideEffect(ctx) {
|
|
|
106
145
|
}
|
|
107
146
|
// ── Rule 13: unstable-key ────────────────────────────────────────────────
|
|
108
147
|
// Missing key or key={index} in .map() JSX expressions
|
|
148
|
+
function mappedFragmentKey(ctx) {
|
|
149
|
+
const findings = [];
|
|
150
|
+
for (const call of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
151
|
+
const callee = call.getExpression();
|
|
152
|
+
if (!Node.isPropertyAccessExpression(callee) || callee.getName() !== 'map')
|
|
153
|
+
continue;
|
|
154
|
+
const args = call.getArguments();
|
|
155
|
+
if (args.length === 0)
|
|
156
|
+
continue;
|
|
157
|
+
const callback = args[0];
|
|
158
|
+
if (!Node.isArrowFunction(callback) && !Node.isFunctionExpression(callback))
|
|
159
|
+
continue;
|
|
160
|
+
const rootJsx = getMapCallbackRootJsx(callback);
|
|
161
|
+
if (!rootJsx || !Node.isJsxFragment(rootJsx))
|
|
162
|
+
continue;
|
|
163
|
+
findings.push(finding('mapped-fragment-key', 'warning', 'bug', 'JSX fragment returned from .map() cannot carry a key — use <Fragment key={...}> or a keyed element', ctx.filePath, rootJsx.getStartLineNumber(), 1, { suggestion: 'Replace <>...</> with <Fragment key={item.id}>...</Fragment> or wrap in a keyed element' }));
|
|
164
|
+
}
|
|
165
|
+
return findings;
|
|
166
|
+
}
|
|
109
167
|
function unstableKey(ctx) {
|
|
110
168
|
const findings = [];
|
|
111
169
|
// AST-based: walk CallExpressions where callee is .map()
|
|
@@ -121,27 +179,23 @@ function unstableKey(ctx) {
|
|
|
121
179
|
if (args.length === 0)
|
|
122
180
|
continue;
|
|
123
181
|
const callback = args[0];
|
|
124
|
-
if (
|
|
182
|
+
if (!Node.isArrowFunction(callback) && !Node.isFunctionExpression(callback))
|
|
125
183
|
continue;
|
|
126
184
|
// Get the index parameter (second param of the callback)
|
|
127
185
|
const params = callback.getKind() === SyntaxKind.ArrowFunction
|
|
128
186
|
? callback.getParameters()
|
|
129
187
|
: callback.getParameters();
|
|
130
188
|
const indexParam = params.length >= 2 ? params[1].getName() : null;
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
...callback.getDescendantsOfKind(SyntaxKind.JsxOpeningElement),
|
|
134
|
-
...callback.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement),
|
|
135
|
-
];
|
|
136
|
-
if (jsxElements.length === 0)
|
|
189
|
+
const rootJsx = getMapCallbackRootJsx(callback);
|
|
190
|
+
if (!rootJsx)
|
|
137
191
|
continue; // No JSX → skip (fixes non-JSX .map() FP)
|
|
138
|
-
|
|
139
|
-
|
|
192
|
+
if (Node.isJsxFragment(rootJsx))
|
|
193
|
+
continue; // handled by mapped-fragment-key
|
|
140
194
|
const line = call.getStartLineNumber();
|
|
141
195
|
// Get attributes from the first JSX element
|
|
142
|
-
const attributes =
|
|
143
|
-
?
|
|
144
|
-
:
|
|
196
|
+
const attributes = rootJsx.getKind() === SyntaxKind.JsxSelfClosingElement
|
|
197
|
+
? rootJsx.getAttributes()
|
|
198
|
+
: rootJsx.getOpeningElement().getAttributes();
|
|
145
199
|
let hasKey = false;
|
|
146
200
|
let usesIndexKey = false;
|
|
147
201
|
for (const attr of attributes) {
|
|
@@ -358,6 +412,71 @@ function effectSelfUpdateLoop(ctx) {
|
|
|
358
412
|
// ── Rule: missing-effect-cleanup ─────────────────────────────────────────
|
|
359
413
|
// useEffect with setInterval/addEventListener but no cleanup return function
|
|
360
414
|
function missingEffectCleanup(ctx) {
|
|
415
|
+
const buildEffectLeakSpecs = (callback) => {
|
|
416
|
+
const specs = [];
|
|
417
|
+
for (const desc of callback.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
418
|
+
const callee = desc.getExpression();
|
|
419
|
+
if (Node.isIdentifier(callee)) {
|
|
420
|
+
const name = callee.getText();
|
|
421
|
+
const assignedName = findAssignedIdentifier(desc);
|
|
422
|
+
if (name === 'setInterval' || name === 'setTimeout') {
|
|
423
|
+
const clearName = name === 'setInterval' ? 'clearInterval' : 'clearTimeout';
|
|
424
|
+
specs.push({
|
|
425
|
+
label: name,
|
|
426
|
+
line: desc.getStartLineNumber(),
|
|
427
|
+
cleanupPatterns: assignedName
|
|
428
|
+
? [new RegExp(`\\b${clearName}\\s*\\(\\s*${escapeRegex(assignedName)}\\s*\\)`)]
|
|
429
|
+
: [new RegExp(`\\b${clearName}\\s*\\(`)],
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (!Node.isPropertyAccessExpression(callee))
|
|
435
|
+
continue;
|
|
436
|
+
const method = callee.getName();
|
|
437
|
+
const targetText = callee.getExpression().getText();
|
|
438
|
+
const assignedName = findAssignedIdentifier(desc);
|
|
439
|
+
if (method === 'addEventListener') {
|
|
440
|
+
specs.push({
|
|
441
|
+
label: 'addEventListener',
|
|
442
|
+
line: desc.getStartLineNumber(),
|
|
443
|
+
cleanupPatterns: [new RegExp(`${escapeRegex(targetText)}\\s*\\.\\s*removeEventListener\\s*\\(`)],
|
|
444
|
+
});
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
if (method === 'on') {
|
|
448
|
+
specs.push({
|
|
449
|
+
label: 'on',
|
|
450
|
+
line: desc.getStartLineNumber(),
|
|
451
|
+
cleanupPatterns: assignedName
|
|
452
|
+
? [
|
|
453
|
+
new RegExp(`\\b${escapeRegex(assignedName)}\\s*\\(`),
|
|
454
|
+
new RegExp(`\\b${escapeRegex(assignedName)}\\s*\\.\\s*(?:unsubscribe|dispose|destroy|off|removeListener)\\s*\\(`),
|
|
455
|
+
new RegExp(`${escapeRegex(targetText)}\\s*\\.\\s*(?:off|removeListener|unsubscribe)\\s*\\(`),
|
|
456
|
+
]
|
|
457
|
+
: [/\.\s*(?:off|removeListener|unsubscribe|dispose|destroy)\s*\(/],
|
|
458
|
+
cleanupReturnIdentifiers: assignedName ? [assignedName] : [],
|
|
459
|
+
cleanupReturnCallPattern: /\.\s*on\s*\(/,
|
|
460
|
+
});
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
if (method === 'subscribe') {
|
|
464
|
+
specs.push({
|
|
465
|
+
label: 'subscribe',
|
|
466
|
+
line: desc.getStartLineNumber(),
|
|
467
|
+
cleanupPatterns: assignedName
|
|
468
|
+
? [
|
|
469
|
+
new RegExp(`\\b${escapeRegex(assignedName)}\\s*\\(`),
|
|
470
|
+
new RegExp(`\\b${escapeRegex(assignedName)}\\s*\\.\\s*(?:unsubscribe|dispose|destroy|off)\\s*\\(`),
|
|
471
|
+
]
|
|
472
|
+
: [/\.\s*(?:unsubscribe|dispose|destroy|off)\s*\(/],
|
|
473
|
+
cleanupReturnIdentifiers: assignedName ? [assignedName] : [],
|
|
474
|
+
cleanupReturnCallPattern: /\.\s*subscribe\s*\(/,
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return specs;
|
|
479
|
+
};
|
|
361
480
|
const findings = [];
|
|
362
481
|
for (const call of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
363
482
|
const callee = call.getExpression().getText();
|
|
@@ -369,24 +488,13 @@ function missingEffectCleanup(ctx) {
|
|
|
369
488
|
const callback = args[0];
|
|
370
489
|
if (!Node.isArrowFunction(callback) && !Node.isFunctionExpression(callback))
|
|
371
490
|
continue;
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
if (Node.isBlock(body)) {
|
|
375
|
-
hasCleanup = body.getStatements().some((s) => {
|
|
376
|
-
if (!Node.isReturnStatement(s))
|
|
377
|
-
return false;
|
|
378
|
-
const expr = s.getExpression();
|
|
379
|
-
return (expr != null && (Node.isArrowFunction(expr) || Node.isFunctionExpression(expr) || Node.isIdentifier(expr)));
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
if (hasCleanup)
|
|
491
|
+
const leakSpecs = buildEffectLeakSpecs(callback).filter((spec, index, specs) => specs.findIndex((candidate) => candidate.label === spec.label && candidate.line === spec.line) === index);
|
|
492
|
+
if (leakSpecs.length === 0)
|
|
383
493
|
continue;
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (leakyCalls.length > 0) {
|
|
389
|
-
findings.push(finding('missing-effect-cleanup', 'warning', 'bug', `useEffect uses '${leakyCalls[0].getExpression().getText()}' but is missing a cleanup return function`, ctx.filePath, call.getStartLineNumber(), 1, { suggestion: 'Return a cleanup function: return () => clearInterval(id);' }));
|
|
494
|
+
const cleanupExprs = getTopLevelCleanupExpressions(callback.getBody());
|
|
495
|
+
const leakedSpec = leakSpecs.find((spec) => !cleanupExprs.some((expr) => cleanupExpressionMatches(expr, spec)));
|
|
496
|
+
if (leakedSpec) {
|
|
497
|
+
findings.push(finding('missing-effect-cleanup', 'warning', 'bug', `useEffect uses '${leakedSpec.label}' but is missing matching cleanup`, ctx.filePath, call.getStartLineNumber(), 1, { suggestion: 'Return a cleanup function: return () => clearInterval(id);' }));
|
|
390
498
|
}
|
|
391
499
|
}
|
|
392
500
|
return findings;
|
|
@@ -465,6 +573,110 @@ function refInRender(ctx) {
|
|
|
465
573
|
}
|
|
466
574
|
return false;
|
|
467
575
|
}
|
|
576
|
+
function getNearestNestedFunctionScope(node) {
|
|
577
|
+
let cur = node.getParent();
|
|
578
|
+
while (cur) {
|
|
579
|
+
if (Node.isArrowFunction(cur) || Node.isFunctionExpression(cur) || Node.isFunctionDeclaration(cur)) {
|
|
580
|
+
const outer = cur.getFirstAncestor((ancestor) => Node.isArrowFunction(ancestor) ||
|
|
581
|
+
Node.isFunctionExpression(ancestor) ||
|
|
582
|
+
Node.isFunctionDeclaration(ancestor));
|
|
583
|
+
return outer ? cur : undefined;
|
|
584
|
+
}
|
|
585
|
+
cur = cur.getParent();
|
|
586
|
+
}
|
|
587
|
+
return undefined;
|
|
588
|
+
}
|
|
589
|
+
function getEnclosingFunctionScope(node) {
|
|
590
|
+
let cur = node.getParent();
|
|
591
|
+
while (cur) {
|
|
592
|
+
if (Node.isArrowFunction(cur) || Node.isFunctionExpression(cur) || Node.isFunctionDeclaration(cur)) {
|
|
593
|
+
return cur;
|
|
594
|
+
}
|
|
595
|
+
cur = cur.getParent();
|
|
596
|
+
}
|
|
597
|
+
return undefined;
|
|
598
|
+
}
|
|
599
|
+
function getFunctionBindingName(fn) {
|
|
600
|
+
if (Node.isFunctionDeclaration(fn)) {
|
|
601
|
+
const nameNode = fn.getNameNode();
|
|
602
|
+
return nameNode && Node.isIdentifier(nameNode) ? nameNode : undefined;
|
|
603
|
+
}
|
|
604
|
+
const parent = fn.getParent();
|
|
605
|
+
if (Node.isVariableDeclaration(parent)) {
|
|
606
|
+
const nameNode = parent.getNameNode();
|
|
607
|
+
return Node.isIdentifier(nameNode) ? nameNode : undefined;
|
|
608
|
+
}
|
|
609
|
+
return undefined;
|
|
610
|
+
}
|
|
611
|
+
function hasRenderTimeInvocation(fn) {
|
|
612
|
+
const binding = getFunctionBindingName(fn);
|
|
613
|
+
if (!binding)
|
|
614
|
+
return true;
|
|
615
|
+
const declarations = binding.getSymbol()?.getDeclarations() ?? [];
|
|
616
|
+
if (declarations.length === 0)
|
|
617
|
+
return true;
|
|
618
|
+
for (const candidate of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.Identifier)) {
|
|
619
|
+
if (candidate === binding)
|
|
620
|
+
continue;
|
|
621
|
+
if (candidate.getText() !== binding.getText())
|
|
622
|
+
continue;
|
|
623
|
+
if (candidate.getStart() >= fn.getStart() && candidate.getEnd() <= fn.getEnd())
|
|
624
|
+
continue;
|
|
625
|
+
const candidateDeclarations = candidate.getSymbol()?.getDeclarations() ?? [];
|
|
626
|
+
if (!candidateDeclarations.some((decl) => declarations.includes(decl)))
|
|
627
|
+
continue;
|
|
628
|
+
const parent = candidate.getParent();
|
|
629
|
+
const isDirectInvocation = (Node.isCallExpression(parent) && parent.getExpression() === candidate) ||
|
|
630
|
+
(Node.isNewExpression(parent) && parent.getExpression() === candidate) ||
|
|
631
|
+
(Node.isTaggedTemplateExpression(parent) && parent.getTag() === candidate);
|
|
632
|
+
if (!isDirectInvocation)
|
|
633
|
+
continue;
|
|
634
|
+
if (isInSafeScope(candidate))
|
|
635
|
+
continue;
|
|
636
|
+
return true;
|
|
637
|
+
}
|
|
638
|
+
return false;
|
|
639
|
+
}
|
|
640
|
+
function isGuardedLazyRefInitialization(prop, refName) {
|
|
641
|
+
const ifAncestor = prop.getFirstAncestorByKind(SyntaxKind.IfStatement);
|
|
642
|
+
if (!ifAncestor)
|
|
643
|
+
return false;
|
|
644
|
+
const condText = ifAncestor.getExpression().getText().replace(/\s+/g, '');
|
|
645
|
+
const escapedRef = refName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
646
|
+
const patterns = [
|
|
647
|
+
new RegExp(`\\b${escapedRef}\\.current\\b.*(?:===|==|!==|!=).*(?:null|undefined)`),
|
|
648
|
+
new RegExp(`(?:null|undefined).*(?:===|==|!==|!=).*\\b${escapedRef}\\.current\\b`),
|
|
649
|
+
new RegExp(`!${escapedRef}\\.current\\b`),
|
|
650
|
+
new RegExp(`\\b${escapedRef}\\.current\\.length===0\\b`),
|
|
651
|
+
new RegExp(`\\b${escapedRef}\\.current\\.length==0\\b`),
|
|
652
|
+
new RegExp(`!${escapedRef}\\.current\\.length\\b`),
|
|
653
|
+
];
|
|
654
|
+
return patterns.some((pattern) => pattern.test(condText));
|
|
655
|
+
}
|
|
656
|
+
function scopeHasGuardedLazyInitializationReadAllowance(scope, refName) {
|
|
657
|
+
const escapedRef = refName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
658
|
+
for (const ifStmt of scope.getDescendantsOfKind(SyntaxKind.IfStatement)) {
|
|
659
|
+
const condText = ifStmt.getExpression().getText().replace(/\s+/g, '');
|
|
660
|
+
const guardPatterns = [
|
|
661
|
+
new RegExp(`\\b${escapedRef}\\.current\\b.*(?:===|==|!==|!=).*(?:null|undefined)`),
|
|
662
|
+
new RegExp(`(?:null|undefined).*(?:===|==|!==|!=).*\\b${escapedRef}\\.current\\b`),
|
|
663
|
+
new RegExp(`!${escapedRef}\\.current\\b`),
|
|
664
|
+
new RegExp(`\\b${escapedRef}\\.current\\.length===0\\b`),
|
|
665
|
+
new RegExp(`\\b${escapedRef}\\.current\\.length==0\\b`),
|
|
666
|
+
new RegExp(`!${escapedRef}\\.current\\.length\\b`),
|
|
667
|
+
];
|
|
668
|
+
if (!guardPatterns.some((pattern) => pattern.test(condText)))
|
|
669
|
+
continue;
|
|
670
|
+
const writesInThen = ifStmt
|
|
671
|
+
.getThenStatement()
|
|
672
|
+
.getDescendantsOfKind(SyntaxKind.BinaryExpression)
|
|
673
|
+
.some((expr) => expr.getLeft().getText() === `${refName}.current` &&
|
|
674
|
+
expr.getOperatorToken().getKind() === SyntaxKind.EqualsToken);
|
|
675
|
+
if (writesInThen)
|
|
676
|
+
return true;
|
|
677
|
+
}
|
|
678
|
+
return false;
|
|
679
|
+
}
|
|
468
680
|
// Find .current access on ref variables
|
|
469
681
|
for (const prop of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression)) {
|
|
470
682
|
if (prop.getName() !== 'current')
|
|
@@ -479,21 +691,24 @@ function refInRender(ctx) {
|
|
|
479
691
|
continue;
|
|
480
692
|
// Skip lazy initialization pattern: if (ref.current === null) ref.current = x
|
|
481
693
|
// React explicitly allows this during render (react.dev/reference/react/useRef)
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
}
|
|
694
|
+
if (isGuardedLazyRefInitialization(prop, obj.getText()))
|
|
695
|
+
continue;
|
|
696
|
+
// Writes inside nested local callbacks are not render-time unless the
|
|
697
|
+
// callback is actually invoked during render.
|
|
698
|
+
const nestedFunctionScope = getNearestNestedFunctionScope(prop);
|
|
699
|
+
if (nestedFunctionScope && !hasRenderTimeInvocation(nestedFunctionScope))
|
|
700
|
+
continue;
|
|
491
701
|
// Check if this is a read or write
|
|
492
702
|
const parent = prop.getParent();
|
|
493
703
|
const isWrite = parent &&
|
|
494
704
|
Node.isBinaryExpression(parent) &&
|
|
495
705
|
parent.getLeft() === prop &&
|
|
496
706
|
parent.getOperatorToken().getKind() === SyntaxKind.EqualsToken;
|
|
707
|
+
if (!isWrite) {
|
|
708
|
+
const enclosingScope = getEnclosingFunctionScope(prop);
|
|
709
|
+
if (enclosingScope && scopeHasGuardedLazyInitializationReadAllowance(enclosingScope, obj.getText()))
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
497
712
|
const action = isWrite ? 'written to' : 'read';
|
|
498
713
|
findings.push(finding('ref-in-render', 'error', 'bug', `ref.current ${action} during render — refs are not tracked by React and may be stale`, ctx.filePath, prop.getStartLineNumber(), 1, {
|
|
499
714
|
suggestion: isWrite
|
|
@@ -613,17 +828,18 @@ function reducerMutation(ctx) {
|
|
|
613
828
|
}
|
|
614
829
|
// ── Exported React Rules ─────────────────────────────────────────────────
|
|
615
830
|
export const reactRules = [
|
|
616
|
-
asyncEffect,
|
|
617
|
-
renderSideEffect,
|
|
831
|
+
clientOnly(asyncEffect),
|
|
832
|
+
clientOnly(renderSideEffect),
|
|
833
|
+
mappedFragmentKey,
|
|
618
834
|
unstableKey,
|
|
619
|
-
staleClosure,
|
|
620
|
-
stateExplosion,
|
|
621
|
-
hookOrder,
|
|
622
|
-
effectSelfUpdateLoop,
|
|
623
|
-
missingEffectCleanup,
|
|
835
|
+
clientOnly(staleClosure),
|
|
836
|
+
clientOnly(stateExplosion),
|
|
837
|
+
clientOnly(hookOrder),
|
|
838
|
+
clientOnly(effectSelfUpdateLoop),
|
|
839
|
+
clientOnly(missingEffectCleanup),
|
|
624
840
|
inlineContextValue,
|
|
625
|
-
refInRender,
|
|
626
|
-
missingMemoDeps,
|
|
627
|
-
reducerMutation,
|
|
841
|
+
clientOnly(refInRender),
|
|
842
|
+
clientOnly(missingMemoDeps),
|
|
843
|
+
clientOnly(reducerMutation),
|
|
628
844
|
];
|
|
629
845
|
//# sourceMappingURL=react.js.map
|