@opensip-cli/graph 0.1.1 → 0.1.3
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 +2 -2
- package/dist/__tests__/rules/always-throws-branch.test.js +94 -0
- package/dist/__tests__/rules/always-throws-branch.test.js.map +1 -1
- package/dist/__tests__/rules/duplicated-function-body-self-match.test.d.ts +18 -0
- package/dist/__tests__/rules/duplicated-function-body-self-match.test.d.ts.map +1 -0
- package/dist/__tests__/rules/duplicated-function-body-self-match.test.js +167 -0
- package/dist/__tests__/rules/duplicated-function-body-self-match.test.js.map +1 -0
- package/dist/__tests__/rules/no-side-effect-path.test.js +115 -0
- package/dist/__tests__/rules/no-side-effect-path.test.js.map +1 -1
- package/dist/__tests__/rules/orphan-subtree-dynamic-import.test.d.ts +27 -0
- package/dist/__tests__/rules/orphan-subtree-dynamic-import.test.d.ts.map +1 -0
- package/dist/__tests__/rules/orphan-subtree-dynamic-import.test.js +189 -0
- package/dist/__tests__/rules/orphan-subtree-dynamic-import.test.js.map +1 -0
- package/dist/cli/__tests__/graph-worker-sharded.integration.test.d.ts +8 -0
- package/dist/cli/__tests__/graph-worker-sharded.integration.test.d.ts.map +1 -0
- package/dist/cli/__tests__/graph-worker-sharded.integration.test.js +138 -0
- package/dist/cli/__tests__/graph-worker-sharded.integration.test.js.map +1 -0
- package/dist/cli/__tests__/graph-worker.test.js +67 -1
- package/dist/cli/__tests__/graph-worker.test.js.map +1 -1
- package/dist/cli/graph/graph-command-spec.d.ts.map +1 -1
- package/dist/cli/graph/graph-command-spec.js +30 -14
- package/dist/cli/graph/graph-command-spec.js.map +1 -1
- package/dist/cli/graph-runner.d.ts +10 -11
- package/dist/cli/graph-runner.d.ts.map +1 -1
- package/dist/cli/graph-runner.js +29 -25
- package/dist/cli/graph-runner.js.map +1 -1
- package/dist/cli/graph-worker.d.ts +9 -8
- package/dist/cli/graph-worker.d.ts.map +1 -1
- package/dist/cli/graph-worker.js +32 -11
- package/dist/cli/graph-worker.js.map +1 -1
- package/dist/cli/graph.d.ts +14 -13
- package/dist/cli/graph.d.ts.map +1 -1
- package/dist/cli/graph.js +39 -18
- package/dist/cli/graph.js.map +1 -1
- package/dist/cli/orchestrate/__tests__/operational-smoke.test.d.ts +6 -0
- package/dist/cli/orchestrate/__tests__/operational-smoke.test.d.ts.map +1 -0
- package/dist/cli/orchestrate/__tests__/operational-smoke.test.js +73 -0
- package/dist/cli/orchestrate/__tests__/operational-smoke.test.js.map +1 -0
- package/dist/cli/orchestrate/__tests__/shard-model.test.js +20 -0
- package/dist/cli/orchestrate/__tests__/shard-model.test.js.map +1 -1
- package/dist/rules/_entry-points.d.ts +16 -2
- package/dist/rules/_entry-points.d.ts.map +1 -1
- package/dist/rules/_entry-points.js +147 -2
- package/dist/rules/_entry-points.js.map +1 -1
- package/dist/rules/always-throws-branch.d.ts.map +1 -1
- package/dist/rules/always-throws-branch.js +99 -5
- package/dist/rules/always-throws-branch.js.map +1 -1
- package/dist/rules/duplicated-function-body.js +42 -12
- package/dist/rules/duplicated-function-body.js.map +1 -1
- package/dist/rules/no-side-effect-path.d.ts.map +1 -1
- package/dist/rules/no-side-effect-path.js +73 -9
- package/dist/rules/no-side-effect-path.js.map +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operational-smoke.test.d.ts","sourceRoot":"","sources":["../../../../src/cli/orchestrate/__tests__/operational-smoke.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operational smoke — bounded runtime for the sharded graph pipeline on a
|
|
3
|
+
* minimal two-shard fixture (architecture review: orchestrate blast radius).
|
|
4
|
+
*/
|
|
5
|
+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
6
|
+
import { tmpdir } from 'node:os';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
9
|
+
import { runShardedGraph } from '../sharded-graph.js';
|
|
10
|
+
const STAMPED_KEY = 'smoke-key';
|
|
11
|
+
const WORKER_SCRIPT = String.raw `
|
|
12
|
+
const { readFileSync } = require('node:fs');
|
|
13
|
+
const spec = JSON.parse(readFileSync(process.argv[3], 'utf8'));
|
|
14
|
+
const id = spec.shard.id;
|
|
15
|
+
const name = id.replace(/[^a-zA-Z0-9]/g, '_');
|
|
16
|
+
const occ = {
|
|
17
|
+
bodyHash: 'h-' + id, simpleName: name, qualifiedName: id + '.' + name,
|
|
18
|
+
filePath: id + '/index.ts', line: 1, column: 0, endLine: 1,
|
|
19
|
+
kind: 'function-declaration', params: [], returnType: null,
|
|
20
|
+
enclosingClass: null, decorators: [], visibility: 'exported',
|
|
21
|
+
inTestFile: false, definedInGenerated: false, calls: [],
|
|
22
|
+
};
|
|
23
|
+
const result = {
|
|
24
|
+
shardId: id,
|
|
25
|
+
fragment: {
|
|
26
|
+
version: '3.0', tool: 'graph', language: 'typescript', builtAt: 'x',
|
|
27
|
+
cacheKey: ${JSON.stringify(STAMPED_KEY)}, resolutionMode: 'exact', functions: { [name]: [occ] },
|
|
28
|
+
},
|
|
29
|
+
fingerprint: 'smoke', boundaryCalls: [], parseErrors: [],
|
|
30
|
+
};
|
|
31
|
+
process.stdout.write(JSON.stringify(result));
|
|
32
|
+
process.exit(0);
|
|
33
|
+
`;
|
|
34
|
+
const adapter = {
|
|
35
|
+
id: 'typescript',
|
|
36
|
+
cacheKey: () => STAMPED_KEY,
|
|
37
|
+
ruleHints: undefined,
|
|
38
|
+
};
|
|
39
|
+
const SMOKE_BUDGET_MS = 30_000;
|
|
40
|
+
describe('graph orchestrate operational smoke', () => {
|
|
41
|
+
let dir;
|
|
42
|
+
let cliScript;
|
|
43
|
+
beforeEach(() => {
|
|
44
|
+
dir = mkdtempSync(join(tmpdir(), 'graph-smoke-'));
|
|
45
|
+
cliScript = join(dir, 'fake-cli.cjs');
|
|
46
|
+
writeFileSync(cliScript, WORKER_SCRIPT, 'utf8');
|
|
47
|
+
});
|
|
48
|
+
afterEach(() => {
|
|
49
|
+
rmSync(dir, { recursive: true, force: true });
|
|
50
|
+
});
|
|
51
|
+
it('completes two-shard run within budget', async () => {
|
|
52
|
+
const shards = [
|
|
53
|
+
{ id: 'pkg:a', rootDir: dir, files: [join(dir, 'a.ts')] },
|
|
54
|
+
{ id: 'pkg:b', rootDir: dir, files: [join(dir, 'b.ts')] },
|
|
55
|
+
];
|
|
56
|
+
const started = Date.now();
|
|
57
|
+
const out = await runShardedGraph({
|
|
58
|
+
shards,
|
|
59
|
+
projectRoot: dir,
|
|
60
|
+
cliScript,
|
|
61
|
+
adapter,
|
|
62
|
+
resolutionMode: 'exact',
|
|
63
|
+
useCache: false,
|
|
64
|
+
catalogRepo: null,
|
|
65
|
+
rules: [],
|
|
66
|
+
});
|
|
67
|
+
const elapsed = Date.now() - started;
|
|
68
|
+
expect(elapsed).toBeLessThan(SMOKE_BUDGET_MS);
|
|
69
|
+
expect(Object.keys(out.catalog.functions)).toHaveLength(2);
|
|
70
|
+
expect(out.failedShardIds).toEqual([]);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=operational-smoke.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operational-smoke.test.js","sourceRoot":"","sources":["../../../../src/cli/orchestrate/__tests__/operational-smoke.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAErE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAKtD,MAAM,WAAW,GAAG,WAAW,CAAC;AAChC,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;gBAgBhB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;;;;;;CAM1C,CAAC;AAEF,MAAM,OAAO,GAAG;IACd,EAAE,EAAE,YAAY;IAChB,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW;IAC3B,SAAS,EAAE,SAAS;CACc,CAAC;AAErC,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,IAAI,GAAW,CAAC;IAChB,IAAI,SAAiB,CAAC;IAEtB,UAAU,CAAC,GAAG,EAAE;QACd,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;QAClD,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QACtC,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,MAAM,GAAY;YACtB,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE;YACzD,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE;SAC1D,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC;YAChC,MAAM;YACN,WAAW,EAAE,GAAG;YAChB,SAAS;YACT,OAAO;YACP,cAAc,EAAE,OAAO;YACvB,QAAQ,EAAE,KAAK;YACf,WAAW,EAAE,IAAI;YACjB,KAAK,EAAE,EAAE;SACV,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QAErC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -5,6 +5,19 @@
|
|
|
5
5
|
* ts.Node / ts.Program may ever appear in it).
|
|
6
6
|
*/
|
|
7
7
|
import { describe, expect, it } from 'vitest';
|
|
8
|
+
const SHARDS = [
|
|
9
|
+
{
|
|
10
|
+
id: 'pkg:core',
|
|
11
|
+
rootDir: '/repo/packages/core',
|
|
12
|
+
files: ['/repo/packages/core/src/index.ts', '/repo/packages/core/src/util.ts'],
|
|
13
|
+
configPathAbs: '/repo/packages/core/tsconfig.json',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: ':root',
|
|
17
|
+
rootDir: '/repo',
|
|
18
|
+
files: ['/repo/scripts/release.ts'],
|
|
19
|
+
},
|
|
20
|
+
];
|
|
8
21
|
const RESULT = {
|
|
9
22
|
shardId: 'pkg:core',
|
|
10
23
|
fragment: {
|
|
@@ -61,6 +74,13 @@ const RESULT = {
|
|
|
61
74
|
parseErrors: [],
|
|
62
75
|
};
|
|
63
76
|
describe('ShardBuildResult serialization', () => {
|
|
77
|
+
it('round-trips the planned Shard[] through JSON for graph-run-worker specs', () => {
|
|
78
|
+
// The live parent pre-plans shards to choose engine labels, then writes the
|
|
79
|
+
// plan into the graph-run-worker spec. Keep Shard plain-data only.
|
|
80
|
+
// eslint-disable-next-line unicorn/prefer-structured-clone -- testing JSON serialization specifically
|
|
81
|
+
const roundTripped = JSON.parse(JSON.stringify(SHARDS));
|
|
82
|
+
expect(roundTripped).toEqual(SHARDS);
|
|
83
|
+
});
|
|
64
84
|
it('round-trips losslessly through JSON (the worker-boundary contract)', () => {
|
|
65
85
|
// Intentionally JSON, not structuredClone: the real worker boundary
|
|
66
86
|
// serializes to JSON over stdout, so this is the exact contract.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shard-model.test.js","sourceRoot":"","sources":["../../../../src/cli/orchestrate/__tests__/shard-model.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAI9C,MAAM,MAAM,GAAqB;IAC/B,OAAO,EAAE,UAAU;IACnB,QAAQ,EAAE;QACR,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE,0BAA0B;QACnC,QAAQ,EAAE,gBAAgB;QAC1B,cAAc,EAAE,OAAO;QACvB,SAAS,EAAE;YACT,IAAI,EAAE;gBACJ;oBACE,QAAQ,EAAE,IAAI;oBACd,UAAU,EAAE,MAAM;oBAClB,aAAa,EAAE,WAAW;oBAC1B,QAAQ,EAAE,eAAe;oBACzB,IAAI,EAAE,CAAC;oBACP,MAAM,EAAE,CAAC;oBACT,OAAO,EAAE,CAAC;oBACV,IAAI,EAAE,sBAAsB;oBAC5B,MAAM,EAAE,EAAE;oBACV,UAAU,EAAE,IAAI;oBAChB,cAAc,EAAE,IAAI;oBACpB,UAAU,EAAE,EAAE;oBACd,UAAU,EAAE,UAAU;oBACtB,UAAU,EAAE,KAAK;oBACjB,kBAAkB,EAAE,KAAK;oBACzB,KAAK,EAAE;wBACL;4BACE,EAAE,EAAE,CAAC,IAAI,CAAC;4BACV,IAAI,EAAE,CAAC;4BACP,MAAM,EAAE,CAAC;4BACT,UAAU,EAAE,QAAQ;4BACpB,UAAU,EAAE,MAAM;4BAClB,IAAI,EAAE,OAAO;yBACd;qBACF;iBACF;aACF;SACF;KACF;IACD,WAAW,EAAE,QAAQ;IACrB,aAAa,EAAE;QACb;YACE,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,eAAe;YAC1B,UAAU,EAAE,KAAK;YACjB,eAAe,EAAE,YAAY;YAC7B,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,CAAC;YACT,IAAI,EAAE,OAAO;SACd;KACF;IACD,WAAW,EAAE,EAAE;CAChB,CAAC;AAEF,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,oEAAoE;QACpE,iEAAiE;QACjE,sGAAsG;QACtG,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAqB,CAAC;QAC5E,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACnE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"shard-model.test.js","sourceRoot":"","sources":["../../../../src/cli/orchestrate/__tests__/shard-model.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,14 +14,28 @@
|
|
|
14
14
|
* does not resolve) is still an external entry point — counting its
|
|
15
15
|
* own recursion as a "caller" would wrongly hide it (and its whole
|
|
16
16
|
* file-local helper subtree) as an orphan.
|
|
17
|
+
* 6. It's an EXPORTED symbol of a module reached via a dynamic
|
|
18
|
+
* `import('<spec>')` / `await import('<spec>')` expression (including
|
|
19
|
+
* the `const { x } = await import(...)` destructure form). The call
|
|
20
|
+
* graph's static resolver cannot trace a binding through a dynamic
|
|
21
|
+
* import, so a function reached only that way would otherwise look
|
|
22
|
+
* orphaned. We treat the dynamic-import target the same way a static
|
|
23
|
+
* import edge makes the imported module's exported surface reachable:
|
|
24
|
+
* resolve the relative specifier to the target file and seed its
|
|
25
|
+
* exported occurrences as entry points. This is conservative — it
|
|
26
|
+
* only adds reachability (never suppresses a genuine orphan), and it
|
|
27
|
+
* fires solely on exported symbols of an actually-imported file.
|
|
17
28
|
*
|
|
18
29
|
* v0.2 ships heuristics 3, 4, 5; 1 and 2 are project-specific and
|
|
19
|
-
* deferred until cross-package call resolution is reliable.
|
|
30
|
+
* deferred until cross-package call resolution is reliable. Heuristic 6
|
|
31
|
+
* (dynamic-import reachability) was added to fix a verified false
|
|
32
|
+
* positive: a CLI command reached only via
|
|
33
|
+
* `const { runReplay } = await import('../commands/.../replay.js')`.
|
|
20
34
|
*/
|
|
21
35
|
import type { Catalog, Indexes } from '../types.js';
|
|
22
36
|
export interface EntryPoint {
|
|
23
37
|
readonly bodyHash: string;
|
|
24
|
-
readonly reason: 'module-init' | 'name-match' | 'no-callers-exported';
|
|
38
|
+
readonly reason: 'module-init' | 'name-match' | 'no-callers-exported' | 'dynamic-import';
|
|
25
39
|
}
|
|
26
40
|
export declare function inferEntryPoints(catalog: Catalog, indexes: Indexes): readonly EntryPoint[];
|
|
27
41
|
//# sourceMappingURL=_entry-points.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_entry-points.d.ts","sourceRoot":"","sources":["../../src/rules/_entry-points.ts"],"names":[],"mappings":"AACA
|
|
1
|
+
{"version":3,"file":"_entry-points.d.ts","sourceRoot":"","sources":["../../src/rules/_entry-points.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAsB,OAAO,EAAE,MAAM,aAAa,CAAC;AAYxE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,YAAY,GAAG,qBAAqB,GAAG,gBAAgB,CAAC;CAC1F;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,UAAU,EAAE,CAyB1F"}
|
|
@@ -15,9 +15,23 @@
|
|
|
15
15
|
* does not resolve) is still an external entry point — counting its
|
|
16
16
|
* own recursion as a "caller" would wrongly hide it (and its whole
|
|
17
17
|
* file-local helper subtree) as an orphan.
|
|
18
|
+
* 6. It's an EXPORTED symbol of a module reached via a dynamic
|
|
19
|
+
* `import('<spec>')` / `await import('<spec>')` expression (including
|
|
20
|
+
* the `const { x } = await import(...)` destructure form). The call
|
|
21
|
+
* graph's static resolver cannot trace a binding through a dynamic
|
|
22
|
+
* import, so a function reached only that way would otherwise look
|
|
23
|
+
* orphaned. We treat the dynamic-import target the same way a static
|
|
24
|
+
* import edge makes the imported module's exported surface reachable:
|
|
25
|
+
* resolve the relative specifier to the target file and seed its
|
|
26
|
+
* exported occurrences as entry points. This is conservative — it
|
|
27
|
+
* only adds reachability (never suppresses a genuine orphan), and it
|
|
28
|
+
* fires solely on exported symbols of an actually-imported file.
|
|
18
29
|
*
|
|
19
30
|
* v0.2 ships heuristics 3, 4, 5; 1 and 2 are project-specific and
|
|
20
|
-
* deferred until cross-package call resolution is reliable.
|
|
31
|
+
* deferred until cross-package call resolution is reliable. Heuristic 6
|
|
32
|
+
* (dynamic-import reachability) was added to fix a verified false
|
|
33
|
+
* positive: a CLI command reached only via
|
|
34
|
+
* `const { runReplay } = await import('../commands/.../replay.js')`.
|
|
21
35
|
*/
|
|
22
36
|
const NAME_HEURISTICS = new Set([
|
|
23
37
|
'main',
|
|
@@ -30,10 +44,23 @@ const NAME_HEURISTICS = new Set([
|
|
|
30
44
|
]);
|
|
31
45
|
export function inferEntryPoints(catalog, indexes) {
|
|
32
46
|
const out = [];
|
|
47
|
+
const seen = new Set();
|
|
33
48
|
for (const occ of indexes.byBodyHash.values()) {
|
|
34
49
|
const reason = classify(occ, indexes);
|
|
35
|
-
if (reason !== null)
|
|
50
|
+
if (reason !== null) {
|
|
36
51
|
out.push({ bodyHash: occ.bodyHash, reason });
|
|
52
|
+
seen.add(occ.bodyHash);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Heuristic 6: exported symbols of any dynamically-imported module are
|
|
56
|
+
// entry points (the static call resolver cannot trace a binding through
|
|
57
|
+
// `import(...)`). Deduped against the heuristics above so a function is
|
|
58
|
+
// never emitted twice.
|
|
59
|
+
for (const hash of dynamicImportEntryHashes(indexes)) {
|
|
60
|
+
if (!seen.has(hash)) {
|
|
61
|
+
out.push({ bodyHash: hash, reason: 'dynamic-import' });
|
|
62
|
+
seen.add(hash);
|
|
63
|
+
}
|
|
37
64
|
}
|
|
38
65
|
// Honor caller-supplied override at the rule level via GraphConfig
|
|
39
66
|
// (handled by the consuming rule). This module returns the inferred
|
|
@@ -78,4 +105,122 @@ function hasExternalCaller(occ, indexes) {
|
|
|
78
105
|
}
|
|
79
106
|
return false;
|
|
80
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Matches a dynamic-import call expression and captures its specifier:
|
|
110
|
+
* `import('./x.js')`, `await import("./x")`, and the
|
|
111
|
+
* `const { y } = await import('./x.js')` destructure form all surface in
|
|
112
|
+
* the catalog as a call edge whose `text` begins with `import(` followed
|
|
113
|
+
* by the string-literal specifier. We capture the specifier verbatim.
|
|
114
|
+
*/
|
|
115
|
+
const DYNAMIC_IMPORT_RE = /\bimport\(\s*['"]([^'"]+)['"]\s*\)/;
|
|
116
|
+
/**
|
|
117
|
+
* Body hashes of every EXPORTED occurrence that lives in a file targeted
|
|
118
|
+
* by a dynamic `import('<spec>')` anywhere in the project. Built by:
|
|
119
|
+
* 1. collecting every relative dynamic-import specifier (from call-edge
|
|
120
|
+
* text), resolved to a project-relative target path against the
|
|
121
|
+
* importing occurrence's directory;
|
|
122
|
+
* 2. mapping those target paths to the catalog's actual file paths
|
|
123
|
+
* (tolerating the `.js → .ts/.tsx` ESM extension rewrite and
|
|
124
|
+
* `index` directory imports);
|
|
125
|
+
* 3. emitting the exported occurrences declared in each matched file.
|
|
126
|
+
*
|
|
127
|
+
* Bare/workspace specifiers (`@scope/pkg`, `node:fs`) are ignored — they
|
|
128
|
+
* resolve outside the catalog and the exported-no-caller heuristic
|
|
129
|
+
* already covers cross-package surface.
|
|
130
|
+
*/
|
|
131
|
+
function dynamicImportEntryHashes(indexes) {
|
|
132
|
+
const targetFiles = collectDynamicImportTargetFiles(indexes);
|
|
133
|
+
if (targetFiles.size === 0)
|
|
134
|
+
return [];
|
|
135
|
+
const exportedByFile = buildExportedByFile(indexes);
|
|
136
|
+
const out = [];
|
|
137
|
+
for (const target of targetFiles) {
|
|
138
|
+
for (const candidate of candidateFilePaths(target)) {
|
|
139
|
+
const occs = exportedByFile.get(candidate);
|
|
140
|
+
if (occs) {
|
|
141
|
+
for (const o of occs)
|
|
142
|
+
out.push(o.bodyHash);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return out;
|
|
147
|
+
}
|
|
148
|
+
/** Resolve every relative dynamic-import specifier to a project-relative
|
|
149
|
+
* (extension-bearing) target path, keyed off the importing occurrence's
|
|
150
|
+
* directory. */
|
|
151
|
+
function collectDynamicImportTargetFiles(indexes) {
|
|
152
|
+
const targets = new Set();
|
|
153
|
+
for (const occ of indexes.byBodyHash.values()) {
|
|
154
|
+
for (const call of occ.calls) {
|
|
155
|
+
const match = DYNAMIC_IMPORT_RE.exec(call.text);
|
|
156
|
+
if (!match)
|
|
157
|
+
continue;
|
|
158
|
+
const specifier = match[1];
|
|
159
|
+
// Only relative specifiers resolve into the catalog.
|
|
160
|
+
if (!specifier.startsWith('.'))
|
|
161
|
+
continue;
|
|
162
|
+
targets.add(resolveRelative(dirOf(occ.filePath), specifier));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return targets;
|
|
166
|
+
}
|
|
167
|
+
/** filePath → exported function occurrences declared in that file. */
|
|
168
|
+
function buildExportedByFile(indexes) {
|
|
169
|
+
const byFile = new Map();
|
|
170
|
+
for (const occ of indexes.byBodyHash.values()) {
|
|
171
|
+
if (occ.visibility !== 'exported')
|
|
172
|
+
continue;
|
|
173
|
+
if (!occ.filePath)
|
|
174
|
+
continue;
|
|
175
|
+
const bucket = byFile.get(occ.filePath);
|
|
176
|
+
if (bucket)
|
|
177
|
+
bucket.push(occ);
|
|
178
|
+
else
|
|
179
|
+
byFile.set(occ.filePath, [occ]);
|
|
180
|
+
}
|
|
181
|
+
return byFile;
|
|
182
|
+
}
|
|
183
|
+
/** Project-relative posix directory of a file ('' for a root-level file). */
|
|
184
|
+
function dirOf(filePath) {
|
|
185
|
+
const slash = filePath.lastIndexOf('/');
|
|
186
|
+
return slash === -1 ? '' : filePath.slice(0, slash);
|
|
187
|
+
}
|
|
188
|
+
/** Resolve a relative specifier against a posix directory, collapsing
|
|
189
|
+
* `.` / `..` segments. Returns a project-relative posix path. */
|
|
190
|
+
function resolveRelative(dir, specifier) {
|
|
191
|
+
const segments = dir.length > 0 ? dir.split('/') : [];
|
|
192
|
+
for (const part of specifier.split('/')) {
|
|
193
|
+
if (part === '' || part === '.')
|
|
194
|
+
continue;
|
|
195
|
+
if (part === '..')
|
|
196
|
+
segments.pop();
|
|
197
|
+
else
|
|
198
|
+
segments.push(part);
|
|
199
|
+
}
|
|
200
|
+
return segments.join('/');
|
|
201
|
+
}
|
|
202
|
+
/** Candidate catalog file paths a resolved specifier may map to —
|
|
203
|
+
* tolerating the ESM `.js → .ts/.tsx` rewrite and `index` imports.
|
|
204
|
+
* Order is irrelevant; lookups are exact-match against real files. */
|
|
205
|
+
function candidateFilePaths(target) {
|
|
206
|
+
const base = stripKnownExtension(target);
|
|
207
|
+
return [
|
|
208
|
+
target,
|
|
209
|
+
`${base}.ts`,
|
|
210
|
+
`${base}.tsx`,
|
|
211
|
+
`${base}.js`,
|
|
212
|
+
`${base}.jsx`,
|
|
213
|
+
`${base}.mts`,
|
|
214
|
+
`${base}.cts`,
|
|
215
|
+
`${base}/index.ts`,
|
|
216
|
+
`${base}/index.tsx`,
|
|
217
|
+
`${base}/index.js`,
|
|
218
|
+
];
|
|
219
|
+
}
|
|
220
|
+
/** Drop a trailing JS/TS module extension so the `.js → .ts` ESM rewrite
|
|
221
|
+
* can be re-applied as candidates. Leaves an extensionless path intact. */
|
|
222
|
+
function stripKnownExtension(path) {
|
|
223
|
+
const match = /\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/.exec(path);
|
|
224
|
+
return match ? path.slice(0, path.length - match[0].length) : path;
|
|
225
|
+
}
|
|
81
226
|
//# sourceMappingURL=_entry-points.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_entry-points.js","sourceRoot":"","sources":["../../src/rules/_entry-points.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAC3H
|
|
1
|
+
{"version":3,"file":"_entry-points.js","sourceRoot":"","sources":["../../src/rules/_entry-points.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"always-throws-branch.d.ts","sourceRoot":"","sources":["../../src/rules/always-throws-branch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"always-throws-branch.d.ts","sourceRoot":"","sources":["../../src/rules/always-throws-branch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA6FH,eAAO,MAAM,sBAAsB,4BAqDjC,CAAC"}
|
|
@@ -25,11 +25,88 @@
|
|
|
25
25
|
import { createGraphSignal } from './create-graph-signal.js';
|
|
26
26
|
import { defineRule } from './define-rule.js';
|
|
27
27
|
const TYPESCRIPT_FALLBACK_THROW_REGEX = /^\s*throw\s+(?:new\s+)?[A-Z]\w*/;
|
|
28
|
+
/**
|
|
29
|
+
* Prefix the adapters stamp onto a *creation* edge (`[creates] () => …`),
|
|
30
|
+
* mirroring `CREATION_EDGE_PREFIX` in `lang-adapter/edge-helpers.ts`. An
|
|
31
|
+
* occurrence that is the TARGET of such an edge is an inline callable
|
|
32
|
+
* (arrow / function-expression) that some enclosing scope merely *creates*
|
|
33
|
+
* and returns/passes — not a standalone helper the program calls for its
|
|
34
|
+
* always-throwing effect. Inlined here (rather than imported) to keep this
|
|
35
|
+
* rule module dependency-free of the edge-helper surface; the literal is the
|
|
36
|
+
* documented producer-side contract.
|
|
37
|
+
*/
|
|
38
|
+
const CREATION_EDGE_PREFIX = '[creates] ';
|
|
39
|
+
/**
|
|
40
|
+
* A function "appears to always throw" only when a throw is reachable in its
|
|
41
|
+
* OWN control flow. A `throw` that lives inside a NESTED function expression /
|
|
42
|
+
* arrow / returned closure is NOT the outer function's control flow — the outer
|
|
43
|
+
* function merely RETURNS or PASSES the closure; the throw fires only when the
|
|
44
|
+
* inner callable is later invoked.
|
|
45
|
+
*
|
|
46
|
+
* Two boundaries enforce that, both conservative (genuine always-throw helpers
|
|
47
|
+
* keep firing):
|
|
48
|
+
*
|
|
49
|
+
* 1. **Nested-body boundary.** When an adapter attributes a throw-shaped edge
|
|
50
|
+
* to an enclosing occurrence even though the throw textually lives inside a
|
|
51
|
+
* nested function declared within that occurrence's source span, the edge is
|
|
52
|
+
* not part of the enclosing function's own control flow. We drop any edge
|
|
53
|
+
* whose source line falls inside a nested occurrence's `[line, endLine]`
|
|
54
|
+
* span before testing "every remaining edge is a throw."
|
|
55
|
+
*
|
|
56
|
+
* 2. **Returned-closure boundary.** The flagged occurrence is itself an inline
|
|
57
|
+
* callable that an enclosing scope created (the target of a `[creates] …`
|
|
58
|
+
* edge). A Proxy `get` trap of the form `get() { return () => { throw … } }`
|
|
59
|
+
* produces exactly this: the inner arrow's only edge is the throw, but the
|
|
60
|
+
* arrow is a lazily-throwing closure the trap returns — invoking the trap
|
|
61
|
+
* does NOT throw. We never flag an occurrence that is a created inline
|
|
62
|
+
* callable.
|
|
63
|
+
*/
|
|
64
|
+
function collectCreatedInlineCallableHashes(catalog) {
|
|
65
|
+
const created = new Set();
|
|
66
|
+
for (const occurrences of Object.values(catalog.functions)) {
|
|
67
|
+
for (const occ of occurrences) {
|
|
68
|
+
for (const e of occ.calls) {
|
|
69
|
+
if (!e.text.startsWith(CREATION_EDGE_PREFIX))
|
|
70
|
+
continue;
|
|
71
|
+
for (const targetHash of e.to)
|
|
72
|
+
created.add(targetHash);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return created;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Nested occurrences declared *inside* `outer`'s source span (same file,
|
|
80
|
+
* strictly contained `[line, endLine]`, not `outer` itself). A throw edge whose
|
|
81
|
+
* source line falls within one of these spans belongs to the nested function's
|
|
82
|
+
* control flow, not `outer`'s.
|
|
83
|
+
*/
|
|
84
|
+
function nestedSpansWithin(outer, catalog) {
|
|
85
|
+
const spans = [];
|
|
86
|
+
for (const occurrences of Object.values(catalog.functions)) {
|
|
87
|
+
for (const occ of occurrences) {
|
|
88
|
+
if (occ.filePath !== outer.filePath)
|
|
89
|
+
continue;
|
|
90
|
+
if (occ.bodyHash === outer.bodyHash && occ.line === outer.line && occ.column === outer.column)
|
|
91
|
+
continue;
|
|
92
|
+
// Strictly contained within the outer's declaration span.
|
|
93
|
+
if (occ.line >= outer.line && occ.endLine <= outer.endLine && occ.line > outer.line) {
|
|
94
|
+
spans.push({ line: occ.line, endLine: occ.endLine });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return spans;
|
|
99
|
+
}
|
|
100
|
+
/** True when `edge`'s source line falls inside any nested-function span. */
|
|
101
|
+
function edgeIsInsideNestedFunction(edge, nestedSpans) {
|
|
102
|
+
return nestedSpans.some((s) => edge.line >= s.line && edge.line <= s.endLine);
|
|
103
|
+
}
|
|
28
104
|
export const alwaysThrowsBranchRule = defineRule({
|
|
29
105
|
slug: 'graph:always-throws-branch',
|
|
30
106
|
defaultSeverity: 'warning',
|
|
31
|
-
evaluate({ indexes, hints, config }) {
|
|
107
|
+
evaluate({ catalog, indexes, hints, config }) {
|
|
32
108
|
const throwRegex = hints?.throwSyntaxRegex ?? TYPESCRIPT_FALLBACK_THROW_REGEX;
|
|
109
|
+
const createdInlineCallables = collectCreatedInlineCallableHashes(catalog);
|
|
33
110
|
const signals = [];
|
|
34
111
|
for (const occ of indexes.byBodyHash.values()) {
|
|
35
112
|
if (occ.kind === 'module-init')
|
|
@@ -41,11 +118,28 @@ export const alwaysThrowsBranchRule = defineRule({
|
|
|
41
118
|
// rule applies.
|
|
42
119
|
if (occ.inTestFile)
|
|
43
120
|
continue;
|
|
121
|
+
// Returned-closure boundary: this occurrence is an inline callable that
|
|
122
|
+
// an enclosing scope created and returns/passes. A throw in its body
|
|
123
|
+
// fires only when the closure is later invoked — it is NOT the creating
|
|
124
|
+
// function's control flow (the Proxy-`get`-trap false positive).
|
|
125
|
+
if (createdInlineCallables.has(occ.bodyHash))
|
|
126
|
+
continue;
|
|
44
127
|
if (occ.calls.length === 0)
|
|
45
128
|
continue;
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
129
|
+
// Nested-body boundary: drop edges that textually live inside a nested
|
|
130
|
+
// function declared within this occurrence's span — they are the nested
|
|
131
|
+
// function's control flow, not this one's.
|
|
132
|
+
const nestedSpans = nestedSpansWithin(occ, catalog);
|
|
133
|
+
const ownControlFlowEdges = nestedSpans.length === 0
|
|
134
|
+
? occ.calls
|
|
135
|
+
: occ.calls.filter((e) => !edgeIsInsideNestedFunction(e, nestedSpans));
|
|
136
|
+
// If every throw-shaped edge was inside a nested function, this
|
|
137
|
+
// function has no own-control-flow throw — do not flag.
|
|
138
|
+
if (ownControlFlowEdges.length === 0)
|
|
139
|
+
continue;
|
|
140
|
+
// All remaining (own-control-flow) edges look like throw shapes — every
|
|
141
|
+
// documented call site is a throw / raise / panic per the adapter's regex.
|
|
142
|
+
const everyCallIsThrow = ownControlFlowEdges.every((e) => throwRegex.test(e.text));
|
|
49
143
|
if (!everyCallIsThrow)
|
|
50
144
|
continue;
|
|
51
145
|
signals.push(createGraphSignal('graph:always-throws-branch', config, {
|
|
@@ -56,7 +150,7 @@ export const alwaysThrowsBranchRule = defineRule({
|
|
|
56
150
|
suggestion: 'Inline the throw at every caller, or document the precondition this function enforces.',
|
|
57
151
|
metadata: {
|
|
58
152
|
qualifiedName: occ.qualifiedName,
|
|
59
|
-
edgeCount:
|
|
153
|
+
edgeCount: ownControlFlowEdges.length,
|
|
60
154
|
},
|
|
61
155
|
}));
|
|
62
156
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"always-throws-branch.js","sourceRoot":"","sources":["../../src/rules/always-throws-branch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"always-throws-branch.js","sourceRoot":"","sources":["../../src/rules/always-throws-branch.ts"],"names":[],"mappings":"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"}
|
|
@@ -137,10 +137,49 @@ function emitPerInstanceSignals(groups, suppressedHashes, config) {
|
|
|
137
137
|
}
|
|
138
138
|
return signals;
|
|
139
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* A function's stable physical identity: where it is declared. The catalog's
|
|
142
|
+
* `functions` record is keyed by simple name, and the same physical function
|
|
143
|
+
* can surface more than once across that index (e.g. indexed under both its
|
|
144
|
+
* simple and qualified name, or a recursive function whose self-reference is
|
|
145
|
+
* walked as an extra occurrence). Two entries that share this identity are the
|
|
146
|
+
* SAME function — they must never count as a duplicate of each other. Keying on
|
|
147
|
+
* file + declaration position + simple name keeps genuinely-distinct functions
|
|
148
|
+
* (same body, different file/line) in separate identities while collapsing
|
|
149
|
+
* self-matches.
|
|
150
|
+
*/
|
|
151
|
+
function identityOf(occ) {
|
|
152
|
+
return `${occ.filePath}:${String(occ.line)}:${String(occ.column)}:${occ.simpleName}`;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Add an occurrence to its body-hash bucket, deduping by physical identity so a
|
|
156
|
+
* function never appears twice in its own bucket. Without this, a function that
|
|
157
|
+
* surfaces more than once in the catalog index (self-reference, dual name
|
|
158
|
+
* indexing) would form a phantom 2-member group and self-report as a duplicate.
|
|
159
|
+
*/
|
|
160
|
+
function pushDeduped(buckets, seenByHash, occ) {
|
|
161
|
+
let bucket = buckets.get(occ.bodyHash);
|
|
162
|
+
let seen = seenByHash.get(occ.bodyHash);
|
|
163
|
+
if (!bucket) {
|
|
164
|
+
bucket = [];
|
|
165
|
+
buckets.set(occ.bodyHash, bucket);
|
|
166
|
+
seen = new Set();
|
|
167
|
+
seenByHash.set(occ.bodyHash, seen);
|
|
168
|
+
}
|
|
169
|
+
/* v8 ignore next */
|
|
170
|
+
if (!seen)
|
|
171
|
+
return;
|
|
172
|
+
const id = identityOf(occ);
|
|
173
|
+
if (seen.has(id))
|
|
174
|
+
return;
|
|
175
|
+
seen.add(id);
|
|
176
|
+
bucket.push(occ);
|
|
177
|
+
}
|
|
140
178
|
function groupByHash(catalog, minLines, minBodySize, features) {
|
|
141
179
|
// Walk the catalog directly; the byBodyHash index dedupes by hash,
|
|
142
180
|
// which is exactly what we need to NOT do here.
|
|
143
181
|
const buckets = new Map();
|
|
182
|
+
const seenByHash = new Map();
|
|
144
183
|
for (const name of Object.keys(catalog.functions)) {
|
|
145
184
|
const occs = catalog.functions[name];
|
|
146
185
|
/* v8 ignore next */
|
|
@@ -149,12 +188,7 @@ function groupByHash(catalog, minLines, minBodySize, features) {
|
|
|
149
188
|
for (const occ of occs) {
|
|
150
189
|
if (!isInterestingForDup(occ, minLines, minBodySize, features))
|
|
151
190
|
continue;
|
|
152
|
-
|
|
153
|
-
if (!bucket) {
|
|
154
|
-
bucket = [];
|
|
155
|
-
buckets.set(occ.bodyHash, bucket);
|
|
156
|
-
}
|
|
157
|
-
bucket.push(occ);
|
|
191
|
+
pushDeduped(buckets, seenByHash, occ);
|
|
158
192
|
}
|
|
159
193
|
}
|
|
160
194
|
return [...buckets.values()];
|
|
@@ -167,6 +201,7 @@ function groupByHash(catalog, minLines, minBodySize, features) {
|
|
|
167
201
|
*/
|
|
168
202
|
function groupByHashUnfloored(catalog) {
|
|
169
203
|
const buckets = new Map();
|
|
204
|
+
const seenByHash = new Map();
|
|
170
205
|
for (const name of Object.keys(catalog.functions)) {
|
|
171
206
|
const occs = catalog.functions[name];
|
|
172
207
|
/* v8 ignore next */
|
|
@@ -175,12 +210,7 @@ function groupByHashUnfloored(catalog) {
|
|
|
175
210
|
for (const occ of occs) {
|
|
176
211
|
if (!isEligibleKind(occ))
|
|
177
212
|
continue;
|
|
178
|
-
|
|
179
|
-
if (!bucket) {
|
|
180
|
-
bucket = [];
|
|
181
|
-
buckets.set(occ.bodyHash, bucket);
|
|
182
|
-
}
|
|
183
|
-
bucket.push(occ);
|
|
213
|
+
pushDeduped(buckets, seenByHash, occ);
|
|
184
214
|
}
|
|
185
215
|
}
|
|
186
216
|
return buckets;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duplicated-function-body.js","sourceRoot":"","sources":["../../src/rules/duplicated-function-body.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"duplicated-function-body.js","sourceRoot":"","sources":["../../src/rules/duplicated-function-body.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-side-effect-path.d.ts","sourceRoot":"","sources":["../../src/rules/no-side-effect-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;
|
|
1
|
+
{"version":3,"file":"no-side-effect-path.d.ts","sourceRoot":"","sources":["../../src/rules/no-side-effect-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAkGH,eAAO,MAAM,oBAAoB,4BA8B/B,CAAC"}
|