@cplieger/deadset-ts 8.0.0-dev.1 → 8.0.0-dev.2
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 +3 -1
- package/dist/src/augmentations.js +44 -13
- package/dist/src/conformance-record.js +1 -1
- package/dist/src/convention-rows.js +23 -0
- package/dist/src/findings/completion.js +61 -24
- package/dist/src/findings/unused-declarations.js +9 -4
- package/dist/src/findings/visibility-narrowing.js +8 -3
- package/dist/src/kinds.js +2 -2
- package/dist/src/matrix.js +39 -1
- package/dist/src/references.js +34 -3
- package/dist/src/suppress.js +1 -0
- package/dist/src/test-support.js +8 -11
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/analysis.ts +3 -1
- package/src/augmentations.ts +59 -16
- package/src/conformance-record.ts +1 -1
- package/src/convention-rows.ts +25 -0
- package/src/finding.ts +5 -0
- package/src/findings/completion.ts +82 -29
- package/src/findings/unused-declarations.ts +11 -4
- package/src/findings/visibility-narrowing.ts +9 -3
- package/src/kinds.ts +2 -2
- package/src/matrix.ts +72 -1
- package/src/references.ts +38 -2
- package/src/suppress.ts +1 -0
- package/src/test-support.ts +17 -13
package/src/references.ts
CHANGED
|
@@ -15,7 +15,10 @@ import {
|
|
|
15
15
|
isIdentifier,
|
|
16
16
|
isImportDeclaration,
|
|
17
17
|
isImportEqualsDeclaration,
|
|
18
|
+
isInterfaceDeclaration,
|
|
18
19
|
isMetaProperty,
|
|
20
|
+
isModuleBlock,
|
|
21
|
+
isModuleDeclaration,
|
|
19
22
|
isNewExpression,
|
|
20
23
|
isNamespaceExport,
|
|
21
24
|
isNoSubstitutionTemplateLiteral,
|
|
@@ -49,7 +52,7 @@ import {
|
|
|
49
52
|
type Inventory,
|
|
50
53
|
type InventorySymbol,
|
|
51
54
|
} from "./inventory.ts";
|
|
52
|
-
import { augmentationReferences } from "./augmentations.ts";
|
|
55
|
+
import { ambientGlobalInterfaces, augmentationReferences } from "./augmentations.ts";
|
|
53
56
|
import { elementAccessReferences } from "./element-access.ts";
|
|
54
57
|
import { indexedAccessReferences } from "./indexed-access.ts";
|
|
55
58
|
import { keyofComparisonReferences } from "./keyof-comparisons.ts";
|
|
@@ -1610,6 +1613,39 @@ export function references<Brand>(
|
|
|
1610
1613
|
}
|
|
1611
1614
|
}
|
|
1612
1615
|
|
|
1616
|
+
/** The ambient global interfaces of the walked files that merge into a declaration outside the project's own files. */
|
|
1617
|
+
const libraryMerged = (scripts: ReadonlySet<string>): ReadonlySet<string> => {
|
|
1618
|
+
const names = new Map<string, Node>();
|
|
1619
|
+
const visit = (node: Node): void => {
|
|
1620
|
+
if (isInterfaceDeclaration(node)) {
|
|
1621
|
+
const id = declaredAt(node);
|
|
1622
|
+
if (id !== undefined) {
|
|
1623
|
+
names.set(id, node.name);
|
|
1624
|
+
}
|
|
1625
|
+
} else if (isModuleDeclaration(node) || isModuleBlock(node)) {
|
|
1626
|
+
node.forEachChild(visit);
|
|
1627
|
+
}
|
|
1628
|
+
};
|
|
1629
|
+
for (const { file } of walked) {
|
|
1630
|
+
file.forEachChild(visit);
|
|
1631
|
+
}
|
|
1632
|
+
const global = new Set(ambientGlobalInterfaces(held, [...names.keys()], scripts));
|
|
1633
|
+
const asked = [...names].filter(([id]) => global.has(id));
|
|
1634
|
+
if (asked.length === 0) {
|
|
1635
|
+
return new Set();
|
|
1636
|
+
}
|
|
1637
|
+
const answers = project.symbolsAt(asked.map(([, name]) => project.handle(name)));
|
|
1638
|
+
return new Set(
|
|
1639
|
+
asked.flatMap(([id], at) => {
|
|
1640
|
+
const symbol = answers[at];
|
|
1641
|
+
return typeof symbol === "object" &&
|
|
1642
|
+
symbol.declarations.some((handle) => !ownPaths.has(handle.path))
|
|
1643
|
+
? [id]
|
|
1644
|
+
: [];
|
|
1645
|
+
}),
|
|
1646
|
+
);
|
|
1647
|
+
};
|
|
1648
|
+
|
|
1613
1649
|
const usesOf = new Map(walked.map((one) => [one.file, one.uses]));
|
|
1614
1650
|
for (const [file, writes] of valued) {
|
|
1615
1651
|
const uses = usesOf.get(file) ?? [];
|
|
@@ -1637,7 +1673,7 @@ export function references<Brand>(
|
|
|
1637
1673
|
const scripts = new Set(
|
|
1638
1674
|
walked.filter((one) => one.file.externalModuleIndicator === undefined).map((one) => one.fileId),
|
|
1639
1675
|
);
|
|
1640
|
-
found.push(...augmentationReferences(held, found, scripts));
|
|
1676
|
+
found.push(...augmentationReferences(held, found, scripts, libraryMerged(scripts)));
|
|
1641
1677
|
found.sort(
|
|
1642
1678
|
(a, b) =>
|
|
1643
1679
|
byPosition(a.position, b.position) ||
|
package/src/suppress.ts
CHANGED
|
@@ -115,6 +115,7 @@ export const GO_REF_EXPRESSIONS: readonly string[] = [
|
|
|
115
115
|
`^go://${GO_PATH}#${GO_IDENT}$`,
|
|
116
116
|
`^go://${GO_PATH}#${GO_IDENT}(?:\\.${GO_IDENT})+$`,
|
|
117
117
|
`^go://${GO_PATH}#${GO_IDENT}(?:\\.${GO_IDENT})?\\[${GO_IDENT}\\]$`,
|
|
118
|
+
`^go://${GO_PATH}#(?:${GO_IDENT}(?:\\.${GO_IDENT})?)?\\(${GO_IDENT}\\)$`,
|
|
118
119
|
`^go://${GO_PATH}#${GO_FILE}:file$`,
|
|
119
120
|
`^go://${GO_PATH}#${GO_PATH}(?:@${GO_VERSION})?:require$`,
|
|
120
121
|
`^go://${GO_PATH}#${GO_PATH}(?:@${GO_VERSION})?:replace$`,
|
package/src/test-support.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* test code.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { CONVENTION_ROWS } from "./convention-rows.ts";
|
|
9
|
+
import { CONVENTION_ROWS, TEST_LIBRARIES, TEST_LIBRARY_SCOPES } from "./convention-rows.ts";
|
|
10
10
|
import { packageOfSpecifier } from "./dependencies.ts";
|
|
11
11
|
import type { InventorySymbol } from "./inventory.ts";
|
|
12
12
|
import type { Reference } from "./references.ts";
|
|
@@ -17,17 +17,13 @@ const SKIP_ROOT = "type-error";
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* The test runners and test libraries an import of which is test evidence: each runner a
|
|
20
|
-
* convention row reads test files for, the
|
|
20
|
+
* convention row reads test files for, and the convention table's test libraries.
|
|
21
21
|
*/
|
|
22
22
|
const TEST_PACKAGES: ReadonlySet<string> = new Set([
|
|
23
23
|
...CONVENTION_ROWS.filter((row) => row.testFiles !== undefined).map((row) => row.package),
|
|
24
|
-
|
|
25
|
-
"@playwright/test",
|
|
24
|
+
...TEST_LIBRARIES,
|
|
26
25
|
]);
|
|
27
26
|
|
|
28
|
-
/** The scopes every package of which is a test library. */
|
|
29
|
-
const TEST_SCOPES = ["@testing-library/"] as const;
|
|
30
|
-
|
|
31
27
|
/**
|
|
32
28
|
* The Node.js built-in modules a bare specifier names, which are no package. The set is
|
|
33
29
|
* closed: Node.js adds a new built-in under the `node:` scheme alone
|
|
@@ -94,7 +90,7 @@ function namesTestPackage(specifier: string): boolean {
|
|
|
94
90
|
const name = specifier.startsWith("node:") ? specifier : packageOfSpecifier(specifier);
|
|
95
91
|
return (
|
|
96
92
|
name !== undefined &&
|
|
97
|
-
(TEST_PACKAGES.has(name) ||
|
|
93
|
+
(TEST_PACKAGES.has(name) || TEST_LIBRARY_SCOPES.some((scope) => name.startsWith(scope)))
|
|
98
94
|
);
|
|
99
95
|
}
|
|
100
96
|
|
|
@@ -134,13 +130,21 @@ function evidenceReader(
|
|
|
134
130
|
};
|
|
135
131
|
}
|
|
136
132
|
|
|
133
|
+
/** The files only tests reach, split by whether each carries test evidence of its own. */
|
|
134
|
+
interface TestReached {
|
|
135
|
+
/** The test-support files: test code. */
|
|
136
|
+
readonly support: ReadonlySet<string>;
|
|
137
|
+
/** The files only tests reach that are no test-support file: production code only tests use. */
|
|
138
|
+
readonly testUsed: ReadonlySet<string>;
|
|
139
|
+
}
|
|
140
|
+
|
|
137
141
|
/**
|
|
138
142
|
* The files of one project that are test-support code, below the target root: the
|
|
139
143
|
* largest set of files a test file reaches, none of them a test file or holding a root,
|
|
140
144
|
* each carrying test evidence of its own, whose every user outside the set is a test
|
|
141
|
-
* file
|
|
142
|
-
*
|
|
143
|
-
* the test-file rules classified.
|
|
145
|
+
* file; and the files only tests reach that are not among them. A root has a caller
|
|
146
|
+
* outside the reference graph: a runtime, a tool, a configuration, or a consumer of a
|
|
147
|
+
* library's published API. `testFiles` are the files the test-file rules classified.
|
|
144
148
|
*/
|
|
145
149
|
export function testSupportFiles(
|
|
146
150
|
symbols: readonly InventorySymbol[],
|
|
@@ -148,7 +152,7 @@ export function testSupportFiles(
|
|
|
148
152
|
roots: readonly Root[],
|
|
149
153
|
testFiles: readonly string[],
|
|
150
154
|
evidence: TestEvidence,
|
|
151
|
-
):
|
|
155
|
+
): TestReached {
|
|
152
156
|
const fileOf = new Map(symbols.map((symbol) => [symbol.id, symbol.position.path]));
|
|
153
157
|
const users = new Map<string, Set<string>>();
|
|
154
158
|
const uses = new Map<string, Set<string>>();
|
|
@@ -203,7 +207,7 @@ export function testSupportFiles(
|
|
|
203
207
|
const support = withoutOutsideUsers(
|
|
204
208
|
new Set([...onlyTests].filter((path) => carries(onlyTests, path))),
|
|
205
209
|
);
|
|
206
|
-
return support;
|
|
210
|
+
return { support, testUsed: new Set([...onlyTests].filter((path) => !support.has(path))) };
|
|
207
211
|
}
|
|
208
212
|
|
|
209
213
|
/** The references with every one a test-support file makes counted as a test reference. */
|