@rigour-labs/core 6.12.2-rc.3 → 6.12.2-rc.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.
|
@@ -284,24 +284,51 @@ function redundancyFailures(typed, changedLines, config) {
|
|
|
284
284
|
}
|
|
285
285
|
return [];
|
|
286
286
|
};
|
|
287
|
+
// The parts of `target` that receive T's values inside `value`, found by walking both the same way: arrays, union
|
|
288
|
+
// members of the value, and same-named properties (`R[]` receiving `{ …, p: T }[]` gives the type of `R.p`).
|
|
289
|
+
const receiving = (t, value, target, depth = 0) => {
|
|
290
|
+
const to = checker.getNonNullableType(target);
|
|
291
|
+
if (value.symbol === t.sym || value.aliasSymbol === t.sym)
|
|
292
|
+
return mentionsType(t, to) ? [] : [to];
|
|
293
|
+
if (depth > MENTION_DEPTH)
|
|
294
|
+
return [];
|
|
295
|
+
if (value.isUnion())
|
|
296
|
+
return value.types.flatMap(v => receiving(t, v, target, depth + 1));
|
|
297
|
+
if (checker.isArrayType(value))
|
|
298
|
+
return checker.isArrayType(to) ? receiving(t, checker.getTypeArguments(value)[0], checker.getTypeArguments(to)[0], depth + 1) : [];
|
|
299
|
+
if (!(value.flags & ts.TypeFlags.Object))
|
|
300
|
+
return [];
|
|
301
|
+
return checker.getPropertiesOfType(value).flatMap(p => {
|
|
302
|
+
const into = checker.getPropertyOfType(to, p.name);
|
|
303
|
+
return into ? receiving(t, checker.getTypeOfSymbol(p), checker.getTypeOfSymbol(into), depth + 1) : [];
|
|
304
|
+
});
|
|
305
|
+
};
|
|
306
|
+
// Where T's values go: the declared types they travel as (`into`), and the types of the places that receive them
|
|
307
|
+
// (`receivers`: a same-shape inline type, a parameter's type), whose members are T's members under another type.
|
|
287
308
|
const flowMemo = new Map();
|
|
288
|
-
const
|
|
309
|
+
const flowsOf = (t) => {
|
|
289
310
|
const cached = flowMemo.get(t.sym);
|
|
290
311
|
if (cached)
|
|
291
312
|
return cached;
|
|
292
313
|
const into = new Set();
|
|
314
|
+
const receivers = new Set();
|
|
293
315
|
for (const sf of typed.appSources) {
|
|
294
316
|
walk(sf, node => {
|
|
295
317
|
if (!ts.isExpression(node) || !isFlowSite(node) || !mentionsType(t, checker.getTypeAtLocation(node)))
|
|
296
318
|
return;
|
|
319
|
+
const target = checker.getContextualType(node);
|
|
320
|
+
if (target && !(target.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) && !mentionsType(t, target))
|
|
321
|
+
for (const r of receiving(t, checker.getTypeAtLocation(node), target))
|
|
322
|
+
receivers.add(r);
|
|
297
323
|
for (const d of namedAt(node, t))
|
|
298
324
|
into.add(d);
|
|
299
325
|
});
|
|
300
326
|
}
|
|
301
|
-
const found = [...into];
|
|
327
|
+
const found = { into: [...into], receivers: [...receivers] };
|
|
302
328
|
flowMemo.set(t.sym, found);
|
|
303
329
|
return found;
|
|
304
330
|
};
|
|
331
|
+
const flowsInto = (t) => flowsOf(t).into;
|
|
305
332
|
// T leaves the program where its own values do, or where a type it travels as does.
|
|
306
333
|
const leaves = (t, seen = new Set([t.sym])) => {
|
|
307
334
|
const direct = escapes(t);
|
|
@@ -371,8 +398,27 @@ function redundancyFailures(typed, changedLines, config) {
|
|
|
371
398
|
if (!sym)
|
|
372
399
|
return 'no such property';
|
|
373
400
|
const declaration = sym.declarations?.[0];
|
|
374
|
-
const
|
|
375
|
-
const
|
|
401
|
+
const ownRead = (s) => !!s && (s === sym || !!s.declarations?.some(d => d === declaration));
|
|
402
|
+
const ownType = (expr) => mentionsType(t, checker.getTypeAtLocation(expr));
|
|
403
|
+
let found = scanReads(name, ownRead, ownType);
|
|
404
|
+
if (found)
|
|
405
|
+
return found;
|
|
406
|
+
// A value of T received as another type (`p?: { x: string }` holding a T) is read through that type's member of the same name.
|
|
407
|
+
const { receivers } = flowsOf(t);
|
|
408
|
+
const members = new Set(receivers.map(r => checker.getPropertyOfType(r, name)).filter((m) => !!m));
|
|
409
|
+
if (members.size) {
|
|
410
|
+
const memberDecls = new Set([...members].flatMap(m => m.declarations ?? []));
|
|
411
|
+
const viaRead = (s) => !!s && (members.has(s) || !!s.declarations?.some(d => memberDecls.has(d)));
|
|
412
|
+
const viaType = (expr) => receivers.includes(checker.getNonNullableType(checker.getTypeAtLocation(expr)));
|
|
413
|
+
found = scanReads(name, viaRead, viaType);
|
|
414
|
+
if (found)
|
|
415
|
+
return found;
|
|
416
|
+
}
|
|
417
|
+
const text = textReads(t, name);
|
|
418
|
+
return text ? `${text.file} (by name)` : undefined;
|
|
419
|
+
};
|
|
420
|
+
// A read of `name` in a non-test file: an access whose symbol `isOurs` accepts, or a destructuring or `['name']` of a value `ofType` accepts.
|
|
421
|
+
const scanReads = (name, isOurs, ofType) => {
|
|
376
422
|
for (const sf of typed.appSources) {
|
|
377
423
|
if (!sf.text.includes(name) && !sf.text.includes('...'))
|
|
378
424
|
continue;
|
|
@@ -390,8 +436,7 @@ function redundancyFailures(typed, changedLines, config) {
|
|
|
390
436
|
if (read)
|
|
391
437
|
return at(read);
|
|
392
438
|
}
|
|
393
|
-
|
|
394
|
-
return text ? `${text.file} (by name)` : undefined;
|
|
439
|
+
return undefined;
|
|
395
440
|
};
|
|
396
441
|
for (const t of declaredTypes) {
|
|
397
442
|
const hosts = hostsOf(t);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/core",
|
|
3
|
-
"version": "6.12.2-rc.
|
|
3
|
+
"version": "6.12.2-rc.4",
|
|
4
4
|
"description": "Rigour's review engine: deterministic gates on changed lines, rules and lessons learned from your team's fixes, and per-check precision from what you fix versus dismiss, across TypeScript, JavaScript, Python, Go, Ruby and C#.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.13"
|
|
@@ -75,11 +75,11 @@
|
|
|
75
75
|
"@anthropic-ai/sdk": "^0.132.1",
|
|
76
76
|
"pg": "^8.16.3",
|
|
77
77
|
"openai": "^5.23.2",
|
|
78
|
-
"@rigour-labs/brain-darwin-arm64": "6.12.2-rc.
|
|
79
|
-
"@rigour-labs/brain-linux-
|
|
80
|
-
"@rigour-labs/brain-
|
|
81
|
-
"@rigour-labs/brain-win-x64": "6.12.2-rc.
|
|
82
|
-
"@rigour-labs/brain-
|
|
78
|
+
"@rigour-labs/brain-darwin-arm64": "6.12.2-rc.4",
|
|
79
|
+
"@rigour-labs/brain-linux-x64": "6.12.2-rc.4",
|
|
80
|
+
"@rigour-labs/brain-linux-arm64": "6.12.2-rc.4",
|
|
81
|
+
"@rigour-labs/brain-win-x64": "6.12.2-rc.4",
|
|
82
|
+
"@rigour-labs/brain-darwin-x64": "6.12.2-rc.4"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@types/fs-extra": "^11.0.4",
|