@cplieger/deadset-ts 8.0.0-dev.15 → 8.0.0-dev.17
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/alias-chain.js +0 -5
- package/dist/src/amd.js +81 -0
- package/dist/src/analysis.js +94 -54
- package/dist/src/augmentations.js +23 -24
- package/dist/src/bindings.js +382 -0
- package/dist/src/calls.js +25 -8
- package/dist/src/commands/read.js +6 -7
- package/dist/src/commands/tools.js +5 -9
- package/dist/src/component-files.js +3 -2
- package/dist/src/conformance-record.js +1 -1
- package/dist/src/consumers.js +9 -10
- package/dist/src/contextual-uses.js +1 -17
- package/dist/src/contract/config.generated.js +5 -2
- package/dist/src/contract/contract.generated.js +119 -2
- package/dist/src/contract/report.generated.js +6 -2
- package/dist/src/dependencies.js +98 -71
- package/dist/src/destructuring.js +1 -19
- package/dist/src/element-access.js +179 -164
- package/dist/src/entries/build-scripts.js +222 -0
- package/dist/src/{configuration-files.js → entries/configuration-files.js} +22 -64
- package/dist/src/{convention-rows.js → entries/convention-rows.js} +120 -27
- package/dist/src/entries/conventions.js +739 -0
- package/dist/src/{html-entries.js → entries/html-entries.js} +9 -12
- package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +3 -3
- package/dist/src/entries/run-directories.js +77 -0
- package/dist/src/entries/sources.js +144 -0
- package/dist/src/entries/static-module.js +670 -0
- package/dist/src/entries/test-runners.js +684 -0
- package/dist/src/{workflow-steps.js → entries/workflow-steps.js} +18 -8
- package/dist/src/extensions.js +37 -0
- package/dist/src/facts.js +38 -0
- package/dist/src/findings/completion.js +40 -4
- package/dist/src/findings/emitters.js +5 -8
- package/dist/src/{implementations.js → findings/implementations.js} +3 -3
- package/dist/src/{in-operands.js → findings/in-operands.js} +2 -2
- package/dist/src/findings/self-check.js +36 -20
- package/dist/src/findings-pass.js +5 -6
- package/dist/src/framework-lifecycle.js +42 -15
- package/dist/src/fs/manifest.js +15 -20
- package/dist/src/generated-file.js +172 -29
- package/dist/src/graph.js +14 -8
- package/dist/src/import-bindings.js +73 -28
- package/dist/src/index/sites.js +557 -0
- package/dist/src/index.js +1 -1
- package/dist/src/indexed-access.js +523 -478
- package/dist/src/injection-container.js +1 -1
- package/dist/src/interface-satisfaction.js +1 -1
- package/dist/src/inventory/commonjs.js +62 -17
- package/dist/src/inventory/enumerate.js +2 -1
- package/dist/src/javascript-file.js +26 -11
- package/dist/src/keyof-comparisons.js +124 -103
- package/dist/src/load/classify.js +28 -9
- package/dist/src/load/diagnostics.js +8 -1
- package/dist/src/load/discover.js +15 -7
- package/dist/src/load/expected-module.js +2 -2
- package/dist/src/load/plan.js +2 -2
- package/dist/src/load/specifiers.js +2 -4
- package/dist/src/load/synthesize.js +10 -5
- package/dist/src/load/workspace-manifests.js +1 -1
- package/dist/src/load/workspace-resolution.js +2 -2
- package/dist/src/matrix.js +12 -17
- package/dist/src/module-declarations.js +70 -85
- package/dist/src/overrides.js +134 -112
- package/dist/src/paths.js +56 -1
- package/dist/src/platform-calls.js +78 -0
- package/dist/src/platform-symbols.js +134 -0
- package/dist/src/references/read-rule.js +1 -0
- package/dist/src/references/read-rules.js +48 -0
- package/dist/src/references/sink.js +151 -0
- package/dist/src/references/sources.js +450 -0
- package/dist/src/references.js +111 -1116
- package/dist/src/resolve.js +1 -1
- package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +7 -4
- package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +5 -8
- package/dist/src/{manifest.js → roots/manifest.js} +4 -4
- package/dist/src/roots/published-reach.js +412 -0
- package/dist/src/roots/root-set.js +489 -0
- package/dist/src/roots/unseen-loads.js +236 -0
- package/dist/src/serialization-contract.js +9 -4
- package/dist/src/source-files.js +5 -9
- package/dist/src/stores.js +4 -2
- package/dist/src/suppress.js +30 -32
- package/dist/src/sweep.js +25 -13
- package/dist/src/symbol-keys.js +89 -83
- package/dist/src/tests/file-class.js +76 -0
- package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
- package/dist/src/{test-support.js → tests/support.js} +5 -12
- package/dist/src/type-parameter-reads.js +178 -139
- package/dist/src/unimplemented-callees.js +262 -242
- package/dist/src/verbs/analyze.js +15 -3
- package/dist/src/verbs/describe.js +5 -3
- package/dist/src/verbs/explain.js +50 -28
- package/dist/src/verbs/print-retained.js +2 -2
- package/jsr.json +1 -1
- package/package.json +3 -3
- package/src/alias-chain.ts +0 -7
- package/src/amd.ts +130 -0
- package/src/analysis.ts +156 -70
- package/src/augmentations.ts +41 -27
- package/src/automatic-types.ts +1 -1
- package/src/bindings.ts +460 -0
- package/src/calls.ts +25 -7
- package/src/commands/read.ts +6 -8
- package/src/commands/tools.ts +5 -11
- package/src/component-files.ts +4 -2
- package/src/conformance-record.ts +1 -1
- package/src/consumers.ts +12 -11
- package/src/contextual-uses.ts +2 -22
- package/src/contract/config.generated.ts +5 -2
- package/src/contract/contract.generated.ts +138 -2
- package/src/contract/report.generated.ts +6 -2
- package/src/dependencies.ts +117 -71
- package/src/destructuring.ts +1 -31
- package/src/element-access.ts +188 -182
- package/src/entries/build-scripts.ts +292 -0
- package/src/{configuration-files.ts → entries/configuration-files.ts} +33 -82
- package/src/{convention-rows.ts → entries/convention-rows.ts} +167 -28
- package/src/{conventions.ts → entries/conventions.ts} +349 -523
- package/src/{html-entries.ts → entries/html-entries.ts} +19 -18
- package/src/{mdx-entries.ts → entries/mdx-entries.ts} +5 -5
- package/src/entries/run-directories.ts +108 -0
- package/src/entries/sources.ts +266 -0
- package/src/entries/static-module.ts +858 -0
- package/src/entries/test-runners.ts +868 -0
- package/src/{workflow-steps.ts → entries/workflow-steps.ts} +29 -11
- package/src/exempt.ts +3 -2
- package/src/extensions.ts +45 -0
- package/src/facts.ts +46 -0
- package/src/file-facts.ts +1 -1
- package/src/findings/boundary.ts +2 -0
- package/src/findings/completion.ts +43 -4
- package/src/findings/emitter.ts +1 -1
- package/src/findings/emitters.ts +14 -10
- package/src/{implementations.ts → findings/implementations.ts} +4 -4
- package/src/{in-operands.ts → findings/in-operands.ts} +3 -3
- package/src/findings/self-check.ts +41 -22
- package/src/findings/visibility-narrowing.ts +1 -1
- package/src/findings-pass.ts +5 -12
- package/src/framework-lifecycle.ts +43 -15
- package/src/fs/manifest.ts +25 -21
- package/src/generated-file.ts +240 -36
- package/src/graph.ts +27 -11
- package/src/import-bindings.ts +98 -29
- package/src/index/sites.ts +781 -0
- package/src/index.ts +1 -1
- package/src/indexed-access.ts +570 -527
- package/src/injection-container.ts +1 -1
- package/src/interface-satisfaction.ts +1 -1
- package/src/inventory/commonjs.ts +102 -17
- package/src/inventory/enumerate.ts +2 -1
- package/src/javascript-file.ts +29 -12
- package/src/keyof-comparisons.ts +131 -116
- package/src/load/classify.ts +49 -13
- package/src/load/diagnostics.ts +11 -1
- package/src/load/discover.ts +27 -11
- package/src/load/expected-module.ts +8 -2
- package/src/load/plan.ts +11 -2
- package/src/load/specifiers.ts +8 -5
- package/src/load/synthesize.ts +12 -6
- package/src/load/test-globals.ts +1 -1
- package/src/load/workspace-manifests.ts +1 -1
- package/src/load/workspace-resolution.ts +9 -2
- package/src/load/workspace-run.ts +1 -1
- package/src/matrix.ts +13 -17
- package/src/module-declarations.ts +74 -98
- package/src/overrides.ts +162 -134
- package/src/paths.ts +65 -1
- package/src/platform-calls.ts +119 -0
- package/src/platform-symbols.ts +189 -0
- package/src/references/read-rule.ts +60 -0
- package/src/references/read-rules.ts +55 -0
- package/src/references/sink.ts +213 -0
- package/src/references/sources.ts +632 -0
- package/src/references.ts +174 -1492
- package/src/report.ts +2 -2
- package/src/resolve.ts +1 -1
- package/src/{configured-declarations.ts → roots/configured-declarations.ts} +10 -7
- package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +5 -8
- package/src/{manifest.ts → roots/manifest.ts} +5 -5
- package/src/roots/published-reach.ts +481 -0
- package/src/{roots.ts → roots/root-set.ts} +203 -630
- package/src/roots/unseen-loads.ts +345 -0
- package/src/serialization-contract.ts +9 -4
- package/src/source-files.ts +5 -10
- package/src/stores.ts +13 -2
- package/src/suppress.ts +48 -33
- package/src/sweep.ts +37 -14
- package/src/symbol-keys.ts +102 -102
- package/src/tests/file-class.ts +118 -0
- package/src/{outside-tests.ts → tests/outside.ts} +16 -10
- package/src/{test-support.ts → tests/support.ts} +15 -21
- package/src/type-parameter-reads.ts +187 -158
- package/src/unimplemented-callees.ts +297 -280
- package/src/verbs/analyze.ts +19 -5
- package/src/verbs/describe.ts +5 -2
- package/src/verbs/explain.ts +75 -32
- package/src/verbs/print-retained.ts +2 -2
- package/dist/src/build-scripts.js +0 -418
- package/dist/src/conventions.js +0 -907
- package/dist/src/entry-points.js +0 -444
- package/dist/src/own-body.js +0 -28
- package/dist/src/roots.js +0 -865
- package/dist/src/unseen-loads.js +0 -189
- package/src/build-scripts.ts +0 -536
- package/src/entry-points.ts +0 -584
- package/src/own-body.ts +0 -42
- package/src/unseen-loads.ts +0 -282
|
@@ -66,11 +66,9 @@ function readConfiguration(engine, configFile) {
|
|
|
66
66
|
try {
|
|
67
67
|
const parsed = engine.parseConfigFile(configFile);
|
|
68
68
|
const circular = parsed.errors.find(({ code }) => code === CIRCULAR_EXTENDS);
|
|
69
|
-
// The compiler leaves the message's `{0}` unfilled:
|
|
70
|
-
// https://github.com/microsoft/TypeScript/pull/64755
|
|
71
69
|
return circular === undefined
|
|
72
70
|
? { parsed }
|
|
73
|
-
: { reason: `TS${String(circular.code)}: ${circular.text
|
|
71
|
+
: { reason: `TS${String(circular.code)}: ${circular.text}` };
|
|
74
72
|
}
|
|
75
73
|
catch (error) {
|
|
76
74
|
return { reason: message(error) };
|
|
@@ -137,8 +135,12 @@ export function targetWithoutSources(target) {
|
|
|
137
135
|
return failureExit("no-program", `${target} holds no compiler configuration, no file named ${MARKERS.join(", ")}, and no JavaScript file: run from the directory that holds one, or name the languages to analyze`);
|
|
138
136
|
}
|
|
139
137
|
/** A target configuration a matrix or the invocation names that cannot be built, ending the run. */
|
|
140
|
-
function unbuilt(named, reason) {
|
|
141
|
-
throw failureExit(
|
|
138
|
+
function unbuilt(named, reason, failureClass = "no-program") {
|
|
139
|
+
throw failureExit(failureClass, unreadableDetail(named, reason));
|
|
140
|
+
}
|
|
141
|
+
/** What fails and the fix, for a configuration `named` that `reason` keeps from being built. */
|
|
142
|
+
export function unreadableDetail(named, reason) {
|
|
143
|
+
return `${named} ${reason}: correct the configuration, or name the configurations to analyze`;
|
|
142
144
|
}
|
|
143
145
|
/**
|
|
144
146
|
* The projects a build matrix declares, in its order, each a file below the target root, a
|
|
@@ -172,7 +174,7 @@ function declaredProjects(engine, host, targetRoot, entries) {
|
|
|
172
174
|
}
|
|
173
175
|
const read = readConfiguration(engine, configFile);
|
|
174
176
|
if ("reason" in read) {
|
|
175
|
-
unbuilt(named, `cannot be read as a compiler configuration: ${read.reason}
|
|
177
|
+
unbuilt(named, `cannot be read as a compiler configuration: ${read.reason}`, "unreadable-configuration");
|
|
176
178
|
}
|
|
177
179
|
references.set(configFile, referencesOf(read.parsed));
|
|
178
180
|
const configuration = {
|
|
@@ -212,13 +214,19 @@ function derivedProjects(engine, host, scope) {
|
|
|
212
214
|
const idOf = (configFile) => relativePath(targetRoot, configFile) ?? configFile;
|
|
213
215
|
const notBuilt = [];
|
|
214
216
|
const found = derivedFrom(engine, host, [...fromScope, ...configFilesUnder(host, targetRoot)], (reference) => relativePath(rootDir, reference) !== undefined, (configFile, reason) => {
|
|
217
|
+
const why = `cannot be read as a compiler configuration: ${reason}`;
|
|
215
218
|
if (fromScope.includes(configFile)) {
|
|
216
|
-
unbuilt(configFile,
|
|
219
|
+
unbuilt(configFile, why, "unreadable-configuration");
|
|
217
220
|
}
|
|
221
|
+
const failure = {
|
|
222
|
+
failureClass: "unreadable-configuration",
|
|
223
|
+
detail: targetRelative(unreadableDetail(idOf(configFile), why), absoluteRoot),
|
|
224
|
+
};
|
|
218
225
|
notBuilt.push({
|
|
219
226
|
id: idOf(configFile),
|
|
220
227
|
configFile,
|
|
221
228
|
error: targetRelative(reason, absoluteRoot),
|
|
229
|
+
failures: [failure],
|
|
222
230
|
});
|
|
223
231
|
});
|
|
224
232
|
const configurations = found.map(({ configFile, parsed }) => ({
|
|
@@ -2,7 +2,7 @@ import { isNoSubstitutionTemplateLiteral, isStringLiteral, } from "@typescript/n
|
|
|
2
2
|
import { packageOfSpecifier } from "../dependencies.js";
|
|
3
3
|
import { MANIFEST } from "../fs/manifest.js";
|
|
4
4
|
import { entriesOf } from "../fs/tree.js";
|
|
5
|
-
import {
|
|
5
|
+
import { cannotStartPackageName, dirnamePath, joinPath, relativePath, resolvePath, } from "../paths.js";
|
|
6
6
|
import { dependencySpecifiers, installedPackage, manifestsAbove } from "./module-lookup.js";
|
|
7
7
|
/** The string literal holding one offset, innermost first, a doc comment's included. */
|
|
8
8
|
function literalAt(file, offset) {
|
|
@@ -77,7 +77,7 @@ function declaringManifest(host, dir, targetRoot, name) {
|
|
|
77
77
|
function expectedModule(context, importer, specifier) {
|
|
78
78
|
const { host, targetRoot } = context;
|
|
79
79
|
const fix = "run the generator or the build that writes it";
|
|
80
|
-
if (
|
|
80
|
+
if (cannotStartPackageName(specifier)) {
|
|
81
81
|
return provided(host, resolvePath(dirnamePath(importer), specifier), false)
|
|
82
82
|
? undefined
|
|
83
83
|
: `which names no file of the target: ${fix}`;
|
package/dist/src/load/plan.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { readConventions } from "../conventions.js";
|
|
1
|
+
import { readConventions, } from "../entries/conventions.js";
|
|
2
2
|
import { holdsManifest, inInstalledPackages, MANIFEST, readManifestAt } from "../fs/manifest.js";
|
|
3
3
|
import { gitIgnored } from "../git-ignore.js";
|
|
4
|
-
import { packageEntries, readManifest } from "../manifest.js";
|
|
4
|
+
import { packageEntries, readManifest, } from "../roots/manifest.js";
|
|
5
5
|
import { ancestors, dirnamePath, joinPath, normalizePath, relativePath, resolvePath, } from "../paths.js";
|
|
6
6
|
import { bytewise } from "../text/compare.js";
|
|
7
7
|
import { globExpression } from "../text/glob.js";
|
|
@@ -9,12 +9,10 @@ import { isBinaryExpression, isCallExpression, isParenthesizedExpression, isStri
|
|
|
9
9
|
import { packageOfSpecifier } from "../dependencies.js";
|
|
10
10
|
import { readManifestAt } from "../fs/manifest.js";
|
|
11
11
|
import { JAVASCRIPT_FILE } from "../javascript-file.js";
|
|
12
|
-
import { ancestors, dirnamePath, relativePath, resolvePath } from "../paths.js";
|
|
12
|
+
import { ancestors, dirnamePath, isRelativeSpecifier, relativePath, resolvePath, } from "../paths.js";
|
|
13
13
|
import { renderPosition } from "../position.js";
|
|
14
14
|
import { batched } from "../session.js";
|
|
15
15
|
import { dependencySpecifiers } from "./module-lookup.js";
|
|
16
|
-
/** A relative specifier: `.`, `..`, or one starting `./` or `../`. */
|
|
17
|
-
const RELATIVE = /^\.\.?(?:\/|$)/u;
|
|
18
16
|
/**
|
|
19
17
|
* Whether one specifier is loaded optionally: written inside a `try` block, or as a call whose
|
|
20
18
|
* result an `||` or a `??` falls back from, so the program is written for its absence.
|
|
@@ -87,7 +85,7 @@ export function readSpecifiers(engine, host, project, { checked, root, outputs }
|
|
|
87
85
|
const resolved = (answers[at]?.resolvedFileName ?? "") !== "";
|
|
88
86
|
const specifier = usage.node.text;
|
|
89
87
|
const name = packageOfSpecifier(specifier);
|
|
90
|
-
if (
|
|
88
|
+
if (isRelativeSpecifier(specifier)) {
|
|
91
89
|
const named = resolvePath(dirnamePath(usage.file.fileName), specifier);
|
|
92
90
|
if (!resolved && !outputs.some((dir) => relativePath(dir, named) !== undefined)) {
|
|
93
91
|
unresolved.push({
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* is written for.
|
|
6
6
|
*/
|
|
7
7
|
import { readCommands } from "../commands/read.js";
|
|
8
|
-
import { CONVENTION_ROWS } from "../convention-rows.js";
|
|
8
|
+
import { CONVENTION_ROWS } from "../entries/convention-rows.js";
|
|
9
9
|
import { holdsManifest, MANIFEST, readManifestAt } from "../fs/manifest.js";
|
|
10
10
|
import { filesBelow } from "../fs/tree.js";
|
|
11
|
-
import { JAVASCRIPT_FILE,
|
|
11
|
+
import { JAVASCRIPT_FILE, minifiedBy, minifiedByName } from "../javascript-file.js";
|
|
12
12
|
import { isRecord } from "../json-document.js";
|
|
13
|
-
import { manifestCommands } from "../manifest.js";
|
|
13
|
+
import { manifestCommands } from "../roots/manifest.js";
|
|
14
14
|
import { ancestors, dirnamePath, joinPath, relativePath } from "../paths.js";
|
|
15
15
|
import { bytewise } from "../text/compare.js";
|
|
16
16
|
import { writtenPath } from "./workspace-programs.js";
|
|
@@ -33,11 +33,11 @@ const FORMED_OPTIONS = {
|
|
|
33
33
|
};
|
|
34
34
|
/** Whether one file is minified build output; one that cannot be read is left to the compiler. */
|
|
35
35
|
function minifiedFile(host, file) {
|
|
36
|
-
if (minifiedByName(file)) {
|
|
36
|
+
if (minifiedByName(file) !== undefined) {
|
|
37
37
|
return true;
|
|
38
38
|
}
|
|
39
39
|
try {
|
|
40
|
-
return
|
|
40
|
+
return minifiedBy(file, host.readFile(file)) !== undefined;
|
|
41
41
|
}
|
|
42
42
|
catch {
|
|
43
43
|
return false;
|
|
@@ -89,6 +89,11 @@ const RUNTIME_OPTIONS = {
|
|
|
89
89
|
bundler: { module: "preserve", moduleResolution: "bundler" },
|
|
90
90
|
node: { module: "nodenext", moduleResolution: "nodenext" },
|
|
91
91
|
};
|
|
92
|
+
/** Whether one configuration is a program the run formed to resolve its modules as Node does. */
|
|
93
|
+
export function formedForNode(configuration) {
|
|
94
|
+
const options = configuration.written?.["compilerOptions"];
|
|
95
|
+
return isRecord(options) && options["moduleResolution"] === RUNTIME_OPTIONS.node.moduleResolution;
|
|
96
|
+
}
|
|
92
97
|
/** The manifest members that say a package is written for Node. */
|
|
93
98
|
const NODE_MEMBERS = ["main", "exports", "bin", "type"];
|
|
94
99
|
/**
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* workspace imports, so only its commands are entry points.
|
|
7
7
|
*/
|
|
8
8
|
import { emittedFrom } from "./emit-map.js";
|
|
9
|
-
import { readManifest } from "../manifest.js";
|
|
9
|
+
import { readManifest } from "../roots/manifest.js";
|
|
10
10
|
import { joinPath, relativePath } from "../paths.js";
|
|
11
11
|
import { MANIFEST } from "../fs/manifest.js";
|
|
12
12
|
/** The one character a subpath pattern of a manifest's `exports` holds. */
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { emittedFrom } from "./emit-map.js";
|
|
9
9
|
import { packageOfSpecifier } from "../dependencies.js";
|
|
10
10
|
import { gitIgnored } from "../git-ignore.js";
|
|
11
|
-
import { ancestors, dirnamePath, joinPath, relativePath, resolvePath } from "../paths.js";
|
|
11
|
+
import { ancestors, cannotStartPackageName, dirnamePath, joinPath, relativePath, resolvePath, } from "../paths.js";
|
|
12
12
|
import { satisfies } from "../version-range.js";
|
|
13
13
|
import { isRecord } from "../json-document.js";
|
|
14
14
|
import { MANIFEST } from "../fs/manifest.js";
|
|
@@ -99,7 +99,7 @@ function dependsOn(specifier, member, fromDir) {
|
|
|
99
99
|
const inRange = (range) => member.version !== undefined && satisfies(member.version, range);
|
|
100
100
|
if (specifier.startsWith("workspace:")) {
|
|
101
101
|
const rest = specifier.slice("workspace:".length);
|
|
102
|
-
if (
|
|
102
|
+
if (cannotStartPackageName(rest)) {
|
|
103
103
|
return atPath(rest);
|
|
104
104
|
}
|
|
105
105
|
const alias = /^((?:@[^/@]+\/)?[^/@]+)@(.*)$/u.exec(rest);
|
package/dist/src/matrix.js
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
import { componentsOf } from "./components.js";
|
|
7
7
|
import { graphOf, OUTSIDE } from "./graph.js";
|
|
8
8
|
import { byPosition } from "./position.js";
|
|
9
|
-
import {
|
|
9
|
+
import { edgeWithheldBy } from "./tests/file-class.js";
|
|
10
|
+
import { reachedWithTheTests, splitRefs, sweep, } from "./sweep.js";
|
|
10
11
|
/**
|
|
11
12
|
* What makes one reference one reference, whichever configuration made it. A consumer's
|
|
12
13
|
* position is rendered against its own root, so the consumer is part of what it names.
|
|
@@ -81,19 +82,12 @@ export function matrixOf(per) {
|
|
|
81
82
|
};
|
|
82
83
|
}
|
|
83
84
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* reference under one configuration is a reference, so what one project uses is never
|
|
91
|
-
* reported, and a configuration that does not hold a declaration says nothing about it.
|
|
92
|
-
* The candidate's relation is reference counting where every configuration found it so,
|
|
93
|
-
* and reachability otherwise; its counts are the union's, one per reference.
|
|
94
|
-
*
|
|
95
|
-
* The components are computed once, over the union and the intersected dead set, so one
|
|
96
|
-
* dead component is one entry of the run with one identifier.
|
|
85
|
+
* Which declarations of the run are dead in every configuration that holds them. Each
|
|
86
|
+
* configuration is swept on its own graph, since a file it does not compile references nothing
|
|
87
|
+
* there and a root it does not hold seeds nothing. A declaration is a candidate when every
|
|
88
|
+
* configuration holding it judged it one; its relation is reference counting where every one
|
|
89
|
+
* found it so, else reachability, and its counts are the union's. Components are computed once,
|
|
90
|
+
* over the union and the intersected dead set, so one dead component has one identifier.
|
|
97
91
|
*/
|
|
98
92
|
export function sweepMatrix(matrix, input) {
|
|
99
93
|
const per = matrix.graphs.map((graph) => sweep(graph, input));
|
|
@@ -140,12 +134,13 @@ export function sweepMatrix(matrix, input) {
|
|
|
140
134
|
}
|
|
141
135
|
const held = matrix.heldIn[at] ?? [];
|
|
142
136
|
const admitted = admittedAt(at);
|
|
143
|
-
const
|
|
137
|
+
const split = splitRefs(union.made[at], input.mode);
|
|
138
|
+
const testRefs = split.test;
|
|
144
139
|
const heldByTests = heldBy[union.parent[at] ?? OUTSIDE] ??
|
|
145
140
|
(union.support[at] === true && testRefs > 0 && !admitted ? symbol.id : undefined);
|
|
146
141
|
const unreferenced = union.test[at] === true && !admitted && testReached[at] !== true;
|
|
147
142
|
heldBy[at] = heldByTests;
|
|
148
|
-
const productionRefs =
|
|
143
|
+
const productionRefs = split.production;
|
|
149
144
|
const counted = all.every((candidate) => candidate.relation === "reference-counting");
|
|
150
145
|
candidates.push({
|
|
151
146
|
id: symbol.id,
|
|
@@ -188,7 +183,7 @@ function compiledReferences(matrix, dead, mode) {
|
|
|
188
183
|
}
|
|
189
184
|
for (const edge of edges) {
|
|
190
185
|
const to = graph.symbols[edge.to]?.id ?? "";
|
|
191
|
-
if ((
|
|
186
|
+
if (!edgeWithheldBy(mode, edge) && dead.has(to) && !kept.has(to)) {
|
|
192
187
|
kept.add(to);
|
|
193
188
|
changed = true;
|
|
194
189
|
}
|
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
* to the same module. One that names it by name or pattern also reads the members it
|
|
6
6
|
* imports, whatever file the specifier resolves to, as a compiler reading no such file does.
|
|
7
7
|
*/
|
|
8
|
-
import { isCallExpression, isExportDeclaration, isExternalModuleReference, isImportDeclaration, isImportEqualsDeclaration, isImportTypeNode, isLiteralTypeNode, isModuleDeclaration,
|
|
8
|
+
import { isCallExpression, isExportDeclaration, isExternalModuleReference, isImportDeclaration, isImportEqualsDeclaration, isImportTypeNode, isLiteralTypeNode, isModuleDeclaration, isNoSubstitutionTemplateLiteral, isStringLiteral, SyntaxKind, } from "@typescript/native/ast";
|
|
9
|
+
import { namesImported } from "./import-bindings.js";
|
|
9
10
|
import { nodeKey } from "./inventory.js";
|
|
10
|
-
import { renderPosition } from "./position.js";
|
|
11
11
|
import { UNANSWERED } from "./query.js";
|
|
12
12
|
import { aliasFragment, nameComponent } from "./ref.js";
|
|
13
|
+
import { isPathSpecifier } from "./paths.js";
|
|
13
14
|
/** Whether a node is a specifier's text: a string literal or a template with no substitution. */
|
|
14
15
|
function literalText(node) {
|
|
15
16
|
return node !== undefined && (isStringLiteral(node) || isNoSubstitutionTemplateLiteral(node));
|
|
@@ -36,32 +37,12 @@ function specifierOf(node) {
|
|
|
36
37
|
}
|
|
37
38
|
return undefined;
|
|
38
39
|
}
|
|
39
|
-
/**
|
|
40
|
-
* The export names an import or a re-export reads from the module it names: none for a
|
|
41
|
-
* namespace, a star or a bare form.
|
|
42
|
-
*/
|
|
43
|
-
export function namesImported(node) {
|
|
44
|
-
if (isImportDeclaration(node)) {
|
|
45
|
-
const clause = node.importClause;
|
|
46
|
-
const bindings = clause?.namedBindings;
|
|
47
|
-
return [
|
|
48
|
-
...(clause?.name === undefined ? [] : ["default"]),
|
|
49
|
-
...(bindings === undefined || isNamespaceImport(bindings)
|
|
50
|
-
? []
|
|
51
|
-
: bindings.elements.map((one) => (one.propertyName ?? one.name).text)),
|
|
52
|
-
];
|
|
53
|
-
}
|
|
54
|
-
const clause = isExportDeclaration(node) ? node.exportClause : undefined;
|
|
55
|
-
return clause === undefined || isNamespaceExport(clause)
|
|
56
|
-
? []
|
|
57
|
-
: clause.elements.map((one) => (one.propertyName ?? one.name).text);
|
|
58
|
-
}
|
|
59
40
|
/**
|
|
60
41
|
* Whether a specifier matches a declaration's name, the name's one `*` standing for any run.
|
|
61
42
|
* A relative name is resolved against its own file, so no specifier names it by its text.
|
|
62
43
|
*/
|
|
63
44
|
function namesModule(specifier, name) {
|
|
64
|
-
if (
|
|
45
|
+
if (isPathSpecifier(name)) {
|
|
65
46
|
return false;
|
|
66
47
|
}
|
|
67
48
|
const star = name.indexOf("*");
|
|
@@ -107,67 +88,71 @@ function namedBy(held) {
|
|
|
107
88
|
});
|
|
108
89
|
}
|
|
109
90
|
/**
|
|
110
|
-
* The
|
|
111
|
-
*
|
|
91
|
+
* The reads the imports of a side's files make of the module declarations of the target they
|
|
92
|
+
* name, each at the import's specifier. A specifier the checker leaves unanswered still names
|
|
93
|
+
* a declaration by its name or pattern.
|
|
112
94
|
*/
|
|
113
|
-
export
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const visit = (node, from) => {
|
|
122
|
-
const own = held.declarations.get(nodeKey(file, node));
|
|
123
|
-
if (isModuleDeclaration(node) && literalText(node.name) && own !== undefined) {
|
|
124
|
-
declared.push({ id: own, name: node.name });
|
|
125
|
-
}
|
|
126
|
-
const specifier = specifierOf(node);
|
|
127
|
-
if (specifier !== undefined) {
|
|
128
|
-
imports.push({ file, from, specifier, names: namesImported(node) });
|
|
129
|
-
}
|
|
130
|
-
node.forEachChild((child) => {
|
|
131
|
-
visit(child, own ?? from);
|
|
132
|
-
});
|
|
133
|
-
};
|
|
134
|
-
file.forEachChild((child) => {
|
|
135
|
-
visit(child, fileId);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
if (declared.length === 0 || imports.length === 0) {
|
|
139
|
-
return [];
|
|
140
|
-
}
|
|
141
|
-
const asked = [...declared.map((one) => one.name), ...imports.map((one) => one.specifier)];
|
|
142
|
-
const answers = project.symbolsAt(asked.map((node) => project.handle(node)));
|
|
143
|
-
const moduleOf = (at) => {
|
|
144
|
-
const symbol = answers[at];
|
|
145
|
-
return symbol === undefined || symbol === UNANSWERED ? undefined : symbol.id;
|
|
146
|
-
};
|
|
147
|
-
const named = namedBy(held);
|
|
148
|
-
const found = [];
|
|
149
|
-
imports.forEach((one, index) => {
|
|
150
|
-
const resolved = moduleOf(declared.length + index);
|
|
151
|
-
const position = renderPosition(one.file, root, one.specifier.getStart());
|
|
152
|
-
const read = (to, resolution, test) => {
|
|
153
|
-
found.push({ from: one.from, to, position, use: "read", resolution, test });
|
|
154
|
-
};
|
|
155
|
-
const test = testFiles.has(position.path);
|
|
156
|
-
const same = new Set(declared
|
|
157
|
-
.filter((_, at) => resolved !== undefined && resolved === moduleOf(at))
|
|
158
|
-
.map((declaration) => declaration.id));
|
|
159
|
-
for (const id of same) {
|
|
160
|
-
read(id, "batch", test);
|
|
161
|
-
}
|
|
162
|
-
for (const declaration of named(one.specifier.text, one.names)) {
|
|
163
|
-
// A wildcard declaration is how the compiler types the file a matching specifier
|
|
164
|
-
// names, so the import uses it whoever writes it, a test included.
|
|
165
|
-
if (declaration.wildcard || !same.has(declaration.id)) {
|
|
166
|
-
for (const to of [declaration.id, ...declaration.members]) {
|
|
167
|
-
read(to, "syntax", test && !declaration.wildcard);
|
|
95
|
+
export const moduleDeclarations = {
|
|
96
|
+
start() {
|
|
97
|
+
const imports = [];
|
|
98
|
+
return {
|
|
99
|
+
visit(node, { file, from }) {
|
|
100
|
+
const specifier = specifierOf(node);
|
|
101
|
+
if (specifier !== undefined) {
|
|
102
|
+
imports.push({ file, from, specifier, names: namesImported(node) });
|
|
168
103
|
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
104
|
+
},
|
|
105
|
+
reads({ project, held }) {
|
|
106
|
+
const found = [];
|
|
107
|
+
// A module declaration whose name is a string is written at a file's top level.
|
|
108
|
+
const declared = project.ownSourceFiles().flatMap((file) => file.statements.flatMap((statement) => {
|
|
109
|
+
const id = held.declarations.get(nodeKey(file, statement));
|
|
110
|
+
return isModuleDeclaration(statement) && literalText(statement.name) && id !== undefined
|
|
111
|
+
? [{ id, name: statement.name }]
|
|
112
|
+
: [];
|
|
113
|
+
}));
|
|
114
|
+
if (declared.length === 0 || imports.length === 0) {
|
|
115
|
+
return found;
|
|
116
|
+
}
|
|
117
|
+
const asked = [...declared.map((one) => one.name), ...imports.map((one) => one.specifier)];
|
|
118
|
+
const answers = project.symbolsAt(asked.map((node) => project.handle(node)));
|
|
119
|
+
const moduleOf = (at) => {
|
|
120
|
+
const symbol = answers[at];
|
|
121
|
+
return symbol === undefined || symbol === UNANSWERED ? undefined : symbol.id;
|
|
122
|
+
};
|
|
123
|
+
const named = namedBy(held);
|
|
124
|
+
imports.forEach((one, index) => {
|
|
125
|
+
const resolved = moduleOf(declared.length + index);
|
|
126
|
+
const read = (to, via, production) => {
|
|
127
|
+
found.push({
|
|
128
|
+
kind: "named",
|
|
129
|
+
from: one.from,
|
|
130
|
+
to,
|
|
131
|
+
file: one.file,
|
|
132
|
+
at: one.specifier,
|
|
133
|
+
use: "read",
|
|
134
|
+
via,
|
|
135
|
+
...(production ? { production: true } : {}),
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
const same = new Set(declared
|
|
139
|
+
.filter((_, at) => resolved !== undefined && resolved === moduleOf(at))
|
|
140
|
+
.map((declaration) => declaration.id));
|
|
141
|
+
for (const id of same) {
|
|
142
|
+
read(id, "batch", false);
|
|
143
|
+
}
|
|
144
|
+
for (const declaration of named(one.specifier.text, one.names)) {
|
|
145
|
+
// A wildcard declaration is how the compiler types the file a matching specifier
|
|
146
|
+
// names, so the import uses it whoever writes it, a test included.
|
|
147
|
+
if (declaration.wildcard || !same.has(declaration.id)) {
|
|
148
|
+
for (const to of [declaration.id, ...declaration.members]) {
|
|
149
|
+
read(to, "syntax", declaration.wildcard);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return found;
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
};
|