@cplieger/deadset-ts 8.0.0-dev.17 → 8.0.0-dev.18
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/src/analysis.js +26 -71
- package/dist/src/augmentations.js +1 -1
- package/dist/src/calls.js +267 -48
- package/dist/src/conformance-record.js +1 -1
- package/dist/src/contract/contract.generated.js +2 -2
- package/dist/src/exempt.js +0 -26
- package/dist/src/exposure.js +400 -0
- package/dist/src/findings/completion.js +4 -17
- package/dist/src/findings/emitters.js +22 -33
- package/dist/src/findings/intra-function.js +3 -3
- package/dist/src/findings/reads-and-writes.js +71 -15
- package/dist/src/findings/unused-declarations.js +2 -22
- package/dist/src/findings/visibility-narrowing.js +14 -20
- package/dist/src/inventory.js +18 -0
- package/dist/src/{components.js → liveness/components.js} +1 -1
- package/dist/src/{graph.js → liveness/graph.js} +38 -21
- package/dist/src/liveness/matrix.js +99 -0
- package/dist/src/liveness/sweep.js +558 -0
- package/dist/src/query.js +46 -0
- package/dist/src/references/sink.js +87 -1
- package/dist/src/references.js +1 -1
- package/dist/src/roots/published-reach.js +4 -4
- package/dist/src/verbs/explain.js +73 -152
- package/dist/src/verbs/print-retained.js +1 -1
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/analysis.ts +41 -107
- package/src/augmentations.ts +1 -1
- package/src/calls.ts +326 -52
- package/src/conformance-record.ts +1 -1
- package/src/contract/contract.generated.ts +2 -2
- package/src/exempt.ts +31 -46
- package/src/exposure.ts +492 -0
- package/src/finding.ts +1 -1
- package/src/findings/boundary.ts +7 -0
- package/src/findings/completion.ts +5 -19
- package/src/findings/emitters.ts +23 -41
- package/src/findings/interfaces.ts +3 -3
- package/src/findings/intra-function.ts +3 -3
- package/src/findings/reads-and-writes.ts +99 -26
- package/src/findings/unused-declarations.ts +4 -28
- package/src/findings/visibility-narrowing.ts +25 -26
- package/src/interface-satisfaction.ts +1 -1
- package/src/inventory.ts +19 -0
- package/src/{components.ts → liveness/components.ts} +3 -3
- package/src/{graph.ts → liveness/graph.ts} +74 -26
- package/src/liveness/matrix.ts +162 -0
- package/src/liveness/sweep.ts +855 -0
- package/src/query.ts +81 -0
- package/src/references/sink.ts +101 -0
- package/src/references.ts +8 -1
- package/src/roots/published-reach.ts +9 -4
- package/src/stores.ts +2 -1
- package/src/tests/file-class.ts +19 -2
- package/src/verbs/explain.ts +81 -199
- package/src/verbs/print-retained.ts +1 -1
- package/dist/src/matrix.js +0 -275
- package/dist/src/sweep.js +0 -234
- package/src/matrix.ts +0 -466
- package/src/sweep.ts +0 -384
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One run's projects as one matrix: every declaration any project judges, keyed by its
|
|
3
|
+
* position and carrying the configurations that hold it, and one graph over every
|
|
4
|
+
* configuration's references and roots, which the sweep judges once (matrix.4, matrix.5).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { graphOf, swept, type Graph } from "./graph.ts";
|
|
8
|
+
import type { InventorySymbol } from "../inventory.ts";
|
|
9
|
+
import { byPosition } from "../position.ts";
|
|
10
|
+
import type { Reference } from "../references.ts";
|
|
11
|
+
import type { Root } from "../roots/root-set.ts";
|
|
12
|
+
|
|
13
|
+
/** What the passes answered for one configuration of the run. */
|
|
14
|
+
export interface Configured {
|
|
15
|
+
/** The name discovery gives the configuration's project. */
|
|
16
|
+
readonly configuration: string;
|
|
17
|
+
readonly symbols: readonly InventorySymbol[];
|
|
18
|
+
readonly references: readonly Reference[];
|
|
19
|
+
readonly roots: readonly Root[];
|
|
20
|
+
/** The paths the reference pass classified as test files. */
|
|
21
|
+
readonly testFiles: readonly string[];
|
|
22
|
+
/** The paths of the test-support files, which only test code imports. */
|
|
23
|
+
readonly supportFiles?: readonly string[] | undefined;
|
|
24
|
+
/** The paths of the files only tests reach that are no test-support file. */
|
|
25
|
+
readonly testUsedFiles?: readonly string[] | undefined;
|
|
26
|
+
/** The ids of the ambient declarations, which describe code the target does not implement. */
|
|
27
|
+
readonly ambient?: ReadonlySet<string> | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* The paths of the workspace-package files the configuration holds but does not
|
|
30
|
+
* compile itself. Their declarations count in its graph and its verdict on them is no
|
|
31
|
+
* finding.
|
|
32
|
+
*/
|
|
33
|
+
readonly referenceOnly?: readonly string[] | undefined;
|
|
34
|
+
/** Each declaration's dependents, by id, as the configuration's inventory states them. */
|
|
35
|
+
readonly dependents?: ReadonlyMap<string, readonly string[]> | undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** The run's configurations, indexed for the sweep. */
|
|
39
|
+
export interface Matrix {
|
|
40
|
+
/** The configurations, in the run's order. */
|
|
41
|
+
readonly configurations: readonly string[];
|
|
42
|
+
/**
|
|
43
|
+
* The graph over every configuration at once: every declaration a configuration
|
|
44
|
+
* holds in a file it does not hold only for its references, once per position and in
|
|
45
|
+
* site order, and every reference any configuration makes, a reference several
|
|
46
|
+
* configurations make at one position counted once and tagged with each of them.
|
|
47
|
+
*/
|
|
48
|
+
readonly union: Graph;
|
|
49
|
+
/**
|
|
50
|
+
* Per declaration of {@link Matrix.union}, at its position there, the configurations
|
|
51
|
+
* whose project holds it, in the run's order.
|
|
52
|
+
*/
|
|
53
|
+
readonly heldIn: readonly (readonly string[])[];
|
|
54
|
+
/**
|
|
55
|
+
* Per declaration of {@link Matrix.union}, whether a file only tests reach that is no
|
|
56
|
+
* test-support file holds it in some configuration: production code only tests use.
|
|
57
|
+
*/
|
|
58
|
+
readonly testUsed: readonly boolean[];
|
|
59
|
+
/** Each declaration's dependents, by id, as the first configuration holding it states them. */
|
|
60
|
+
readonly dependents: ReadonlyMap<string, readonly string[]>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* What makes one reference one reference, whichever configuration made it. A consumer's
|
|
65
|
+
* position is rendered against its own root, so the consumer is part of what it names.
|
|
66
|
+
*/
|
|
67
|
+
export function referenceKey(reference: Reference): string {
|
|
68
|
+
const { path, line, column } = reference.position;
|
|
69
|
+
return [
|
|
70
|
+
reference.consumer ?? "",
|
|
71
|
+
reference.from,
|
|
72
|
+
reference.to,
|
|
73
|
+
path,
|
|
74
|
+
String(line),
|
|
75
|
+
String(column),
|
|
76
|
+
reference.use,
|
|
77
|
+
].join("\u0000");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Indexes what the passes answered for each configuration of one run, in the run's order.
|
|
82
|
+
* A declaration is keyed by its rendered position, with the fields of the first
|
|
83
|
+
* configuration that judges it; one in a file every holder holds only for its references
|
|
84
|
+
* is judged by none and is not in the union, and a reference it makes enters the union as a
|
|
85
|
+
* consumer's does. One reference at one position of a file several configurations compile
|
|
86
|
+
* is one reference; two one configuration makes are two.
|
|
87
|
+
*/
|
|
88
|
+
export function matrixOf(per: readonly Configured[]): Matrix {
|
|
89
|
+
const symbols: InventorySymbol[] = [];
|
|
90
|
+
const holders = new Map<string, string[]>();
|
|
91
|
+
const references: Reference[] = [];
|
|
92
|
+
const makers: string[][] = [];
|
|
93
|
+
const firstSeen = new Map<string, { readonly index: number; readonly places: number[] }>();
|
|
94
|
+
const judged = new Set<string>();
|
|
95
|
+
const unjudged = new Set<string>();
|
|
96
|
+
const dependents = new Map<string, readonly string[]>();
|
|
97
|
+
per.forEach((one, index) => {
|
|
98
|
+
for (const [id, after] of one.dependents ?? []) {
|
|
99
|
+
if (!dependents.has(id)) {
|
|
100
|
+
dependents.set(id, after);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const referenceOnly = new Set(one.referenceOnly);
|
|
104
|
+
for (const symbol of one.symbols) {
|
|
105
|
+
const held = holders.get(symbol.id);
|
|
106
|
+
if (held === undefined) {
|
|
107
|
+
holders.set(symbol.id, [one.configuration]);
|
|
108
|
+
} else if (!held.includes(one.configuration)) {
|
|
109
|
+
held.push(one.configuration);
|
|
110
|
+
}
|
|
111
|
+
if (referenceOnly.has(symbol.position.path)) {
|
|
112
|
+
if (swept(symbol.kind)) {
|
|
113
|
+
unjudged.add(symbol.id);
|
|
114
|
+
}
|
|
115
|
+
} else if (!judged.has(symbol.id)) {
|
|
116
|
+
judged.add(symbol.id);
|
|
117
|
+
symbols.push(symbol);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (const reference of one.references) {
|
|
121
|
+
const key = referenceKey(reference);
|
|
122
|
+
const seen = firstSeen.get(key);
|
|
123
|
+
if (seen !== undefined && seen.index !== index) {
|
|
124
|
+
for (const place of seen.places) {
|
|
125
|
+
const making = makers[place];
|
|
126
|
+
if (making !== undefined && !making.includes(one.configuration)) {
|
|
127
|
+
making.push(one.configuration);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const places = seen?.places ?? [];
|
|
133
|
+
if (seen === undefined) {
|
|
134
|
+
firstSeen.set(key, { index, places });
|
|
135
|
+
}
|
|
136
|
+
places.push(references.length);
|
|
137
|
+
references.push(reference);
|
|
138
|
+
makers.push([one.configuration]);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
for (const id of judged) {
|
|
142
|
+
unjudged.delete(id);
|
|
143
|
+
}
|
|
144
|
+
symbols.sort((a, b) => byPosition(a.position, b.position));
|
|
145
|
+
const testUsed = new Set(per.flatMap((one) => one.testUsedFiles ?? []));
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
configurations: per.map((one) => one.configuration),
|
|
149
|
+
union: graphOf(
|
|
150
|
+
symbols,
|
|
151
|
+
references,
|
|
152
|
+
per.flatMap((one) => one.roots),
|
|
153
|
+
[...new Set(per.flatMap((one) => one.testFiles))],
|
|
154
|
+
[...new Set(per.flatMap((one) => one.supportFiles ?? []))],
|
|
155
|
+
new Set(per.flatMap((one) => [...(one.ambient ?? [])])),
|
|
156
|
+
{ unjudged, configurations: makers },
|
|
157
|
+
),
|
|
158
|
+
heldIn: symbols.map((symbol) => holders.get(symbol.id) ?? []),
|
|
159
|
+
testUsed: symbols.map((symbol) => testUsed.has(symbol.position.path)),
|
|
160
|
+
dependents,
|
|
161
|
+
};
|
|
162
|
+
}
|