@cplieger/deadset-ts 7.2.0-dev.4 → 8.0.0-dev.10
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 +1 -1
- package/dist/bin/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/analysis.js +245 -309
- package/dist/src/augmentations.js +124 -18
- package/dist/src/automatic-types.js +170 -0
- package/dist/src/build-scripts.js +425 -0
- package/dist/src/component-layer.js +4 -2
- package/dist/src/components.js +9 -9
- package/dist/src/config.js +6 -81
- package/dist/src/configuration-files.js +78 -188
- package/dist/src/configured-declarations.js +15 -20
- package/dist/src/conformance-record.js +2 -2
- package/dist/src/consumers.js +3 -30
- package/dist/src/contextual-uses.js +56 -9
- package/dist/src/contract/config.generated.js +558 -0
- package/dist/src/contract/contract.generated.js +1244 -0
- package/dist/src/contract/report.generated.js +862 -0
- package/dist/src/convention-rows.js +146 -1
- package/dist/src/conventions.js +136 -70
- package/dist/src/decorator.js +21 -18
- package/dist/src/dependencies.js +280 -62
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +4 -6
- package/dist/src/entry-point-gaps.js +9 -18
- package/dist/src/entry-points.js +106 -21
- package/dist/src/enum-group.js +3 -10
- package/dist/src/erased-stores.js +4 -6
- package/dist/src/exempt-classes.js +1 -63
- package/dist/src/exempt.js +21 -40
- package/dist/src/failure.js +36 -0
- package/dist/src/file-facts.js +2 -25
- package/dist/src/findings/completion.js +225 -63
- package/dist/src/findings/dependencies-and-module-machinery.js +72 -27
- package/dist/src/findings/emitters.js +6 -6
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +53 -19
- package/dist/src/findings/non-code-artifacts.js +71 -39
- package/dist/src/findings/reads-and-writes.js +16 -13
- package/dist/src/findings/self-check.js +10 -12
- package/dist/src/findings/unused-declarations.js +57 -28
- package/dist/src/findings/visibility-narrowing.js +40 -18
- package/dist/src/findings-pass.js +8 -15
- package/dist/src/framework-lifecycle.js +7 -7
- package/dist/src/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +72 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/generated-file.js +18 -4
- package/dist/src/git-ignore.js +99 -0
- package/dist/src/graph.js +9 -4
- package/dist/src/html-entries.js +6 -33
- package/dist/src/import-bindings.js +97 -0
- package/dist/src/in-operands.js +2 -1
- package/dist/src/index.js +1 -1
- package/dist/src/indexed-access.js +130 -28
- package/dist/src/injection-container.js +1 -1
- package/dist/src/interface-satisfaction.js +30 -12
- package/dist/src/intra-function-parts.js +341 -69
- package/dist/src/inventory.js +54 -29
- package/dist/src/javascript-file.js +33 -0
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +4 -6
- package/dist/src/kinds.js +3 -366
- package/dist/src/load/classify.js +270 -0
- package/dist/src/load/diagnostics.js +80 -0
- package/dist/src/load/discover.js +277 -0
- package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
- package/dist/src/load/expected-module.js +136 -0
- package/dist/src/load/load.js +27 -0
- package/dist/src/load/module-lookup.js +37 -0
- package/dist/src/load/plan.js +313 -0
- package/dist/src/load/specifiers.js +115 -0
- package/dist/src/load/synthesize.js +140 -0
- package/dist/src/load/test-globals.js +207 -0
- package/dist/src/load/test-joins.js +82 -0
- package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
- package/dist/src/{workspace-programs.js → load/workspace-programs.js} +88 -61
- package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +60 -59
- package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
- package/dist/src/{workspace.js → load/workspace.js} +62 -124
- package/dist/src/manifest.js +49 -54
- package/dist/src/matrix.js +94 -13
- package/dist/src/mdx-entries.js +174 -0
- package/dist/src/module-declarations.js +9 -13
- package/dist/src/outside-tests.js +1 -1
- package/dist/src/overrides.js +41 -10
- package/dist/src/partial.js +2 -1
- package/dist/src/paths.js +26 -15
- package/dist/src/position.js +2 -1
- package/dist/src/print.js +11 -78
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +1 -0
- package/dist/src/ref.js +11 -0
- package/dist/src/references.js +52 -31
- package/dist/src/report-schema.js +51 -0
- package/dist/src/report.js +59 -41
- package/dist/src/reporters/annotations.js +15 -8
- package/dist/src/reporters/sarif.js +16 -10
- package/dist/src/reporters/template.js +4 -19
- package/dist/src/resolve.js +245 -727
- package/dist/src/roots.js +374 -116
- package/dist/src/run.js +66 -77
- package/dist/src/schema.js +320 -342
- package/dist/src/scope.js +38 -115
- package/dist/src/serialization-contract.js +649 -29
- package/dist/src/session.js +41 -29
- package/dist/src/source-files.js +40 -15
- package/dist/src/suppress-file.js +34 -29
- package/dist/src/suppress-inline.js +21 -4
- package/dist/src/suppress.js +40 -56
- package/dist/src/sweep.js +32 -17
- package/dist/src/symbol-keys.js +105 -6
- package/dist/src/template-field.js +9 -19
- package/dist/src/test-support.js +119 -18
- package/dist/src/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/named-files.js +54 -0
- package/dist/src/text/shell.js +159 -0
- package/dist/src/text/yaml.js +393 -0
- package/dist/src/type-errors.js +27 -221
- package/dist/src/type-parameter-reads.js +172 -0
- package/dist/src/unseen-loads.js +100 -0
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/verbs/analyze.js +181 -125
- package/dist/src/verbs/describe.js +9 -16
- package/dist/src/verbs/explain.js +14 -9
- package/dist/src/verbs/print-config.js +2 -1
- package/dist/src/verbs/print-projects.js +6 -4
- package/dist/src/verbs/print-retained.js +4 -2
- package/dist/src/verbs/print-roots.js +4 -2
- package/dist/src/verbs/verb.js +1 -5
- package/dist/src/verbs/version.js +14 -3
- package/dist/src/workflow-steps.js +128 -33
- package/jsr.json +1 -1
- package/package.json +5 -4
- package/src/analysis.ts +333 -457
- package/src/augmentations.ts +152 -23
- package/src/automatic-types.ts +228 -0
- package/src/build-scripts.ts +543 -0
- package/src/component-layer.ts +4 -2
- package/src/components.ts +9 -10
- package/src/config.ts +31 -299
- package/src/configuration-files.ts +100 -191
- package/src/configured-declarations.ts +18 -23
- package/src/conformance-record.ts +2 -2
- package/src/consumers.ts +6 -57
- package/src/contextual-uses.ts +64 -12
- package/src/contract/config.generated.ts +818 -0
- package/src/contract/contract.generated.ts +1308 -0
- package/src/contract/report.generated.ts +1237 -0
- package/src/convention-rows.ts +186 -1
- package/src/conventions.ts +166 -90
- package/src/decorator.ts +28 -18
- package/src/dependencies.ts +356 -78
- package/src/edges.ts +41 -140
- package/src/element-access.ts +4 -7
- package/src/entry-point-gaps.ts +11 -20
- package/src/entry-points.ts +124 -28
- package/src/enum-group.ts +2 -11
- package/src/erased-stores.ts +3 -7
- package/src/exempt-classes.ts +1 -75
- package/src/exempt.ts +36 -50
- package/src/failure.ts +63 -0
- package/src/file-facts.ts +9 -24
- package/src/finding.ts +24 -9
- package/src/findings/boundary.ts +2 -0
- package/src/findings/completion.ts +297 -77
- package/src/findings/dependencies-and-module-machinery.ts +90 -31
- package/src/findings/emitter.ts +8 -9
- package/src/findings/emitters.ts +8 -8
- package/src/findings/interfaces.ts +4 -6
- package/src/findings/intra-function.ts +64 -20
- package/src/findings/non-code-artifacts.ts +88 -50
- package/src/findings/reads-and-writes.ts +20 -16
- package/src/findings/self-check.ts +11 -17
- package/src/findings/unused-declarations.ts +65 -28
- package/src/findings/visibility-narrowing.ts +51 -19
- package/src/findings-pass.ts +10 -19
- package/src/framework-lifecycle.ts +7 -7
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +92 -0
- package/src/fs/tree.ts +110 -0
- package/src/generated-file.ts +23 -4
- package/src/git-ignore.ts +122 -0
- package/src/graph.ts +11 -3
- package/src/host.ts +17 -14
- package/src/html-entries.ts +6 -33
- package/src/import-bindings.ts +128 -0
- package/src/in-operands.ts +2 -1
- package/src/index.ts +1 -1
- package/src/indexed-access.ts +152 -30
- package/src/injection-container.ts +1 -1
- package/src/interface-satisfaction.ts +33 -13
- package/src/intra-function-parts.ts +449 -85
- package/src/inventory.ts +73 -27
- package/src/javascript-file.ts +37 -0
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +3 -7
- package/src/kinds.ts +5 -413
- package/src/load/classify.ts +397 -0
- package/src/load/diagnostics.ts +144 -0
- package/src/load/discover.ts +455 -0
- package/src/{emit-map.ts → load/emit-map.ts} +1 -1
- package/src/load/expected-module.ts +188 -0
- package/src/load/load.ts +73 -0
- package/src/load/module-lookup.ts +50 -0
- package/src/load/plan.ts +504 -0
- package/src/load/specifiers.ts +168 -0
- package/src/load/synthesize.ts +211 -0
- package/src/load/test-globals.ts +251 -0
- package/src/load/test-joins.ts +98 -0
- package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
- package/src/{workspace-programs.ts → load/workspace-programs.ts} +127 -80
- package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +73 -64
- package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
- package/src/{workspace.ts → load/workspace.ts} +90 -134
- package/src/manifest.ts +81 -75
- package/src/matrix.ts +154 -18
- package/src/mdx-entries.ts +218 -0
- package/src/module-declarations.ts +11 -13
- package/src/outside-tests.ts +1 -1
- package/src/overrides.ts +51 -12
- package/src/partial.ts +3 -2
- package/src/paths.ts +27 -15
- package/src/position.ts +2 -1
- package/src/print.ts +12 -91
- package/src/product.ts +18 -0
- package/src/query.ts +11 -0
- package/src/ref.ts +13 -0
- package/src/references.ts +62 -32
- package/src/report-schema.ts +68 -0
- package/src/report.ts +105 -215
- package/src/reporters/annotations.ts +22 -11
- package/src/reporters/json.ts +1 -1
- package/src/reporters/reporter.ts +2 -4
- package/src/reporters/reporters.ts +1 -1
- package/src/reporters/sarif.ts +29 -16
- package/src/reporters/template.ts +4 -20
- package/src/reporters/text.ts +3 -3
- package/src/resolve.ts +283 -1111
- package/src/roots.ts +490 -137
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -387
- package/src/scope.ts +46 -138
- package/src/serialization-contract.ts +818 -26
- package/src/session.ts +77 -54
- package/src/source-files.ts +67 -17
- package/src/suppress-file.ts +36 -34
- package/src/suppress-inline.ts +20 -3
- package/src/suppress.ts +52 -63
- package/src/sweep.ts +53 -18
- package/src/symbol-keys.ts +131 -7
- package/src/template-field.ts +15 -25
- package/src/test-support.ts +155 -18
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/named-files.inputs.json +1522 -0
- package/src/text/named-files.ts +68 -0
- package/src/text/shell.ts +161 -0
- package/src/text/yaml.ts +423 -0
- package/src/type-errors.ts +35 -273
- package/src/type-parameter-reads.ts +227 -0
- package/src/unseen-loads.ts +134 -0
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/verbs/analyze.ts +245 -161
- package/src/verbs/describe.ts +14 -15
- package/src/verbs/explain.ts +15 -13
- package/src/verbs/print-config.ts +2 -1
- package/src/verbs/print-projects.ts +6 -4
- package/src/verbs/print-retained.ts +4 -2
- package/src/verbs/print-roots.ts +4 -2
- package/src/verbs/verb.ts +2 -8
- package/src/verbs/version.ts +15 -3
- package/src/workflow-steps.ts +149 -34
- package/dist/src/discover.js +0 -347
- package/dist/src/glob.js +0 -65
- package/dist/src/pnpm-workspace.js +0 -120
- package/dist/src/setup-failure.js +0 -23
- package/dist/src/test-joins.js +0 -101
- package/dist/src/version.js +0 -7
- package/src/discover.ts +0 -510
- package/src/glob.ts +0 -67
- package/src/pnpm-workspace.ts +0 -135
- package/src/setup-failure.ts +0 -39
- package/src/test-joins.ts +0 -120
- package/src/version.ts +0 -7
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The test files a derived matrix holds although no configuration's file list names them.
|
|
3
|
+
* The test runner compiles such a file with the options of the nearest compiler
|
|
4
|
+
* configuration at or above it, so the file joins that configuration's program as a file
|
|
5
|
+
* its list names, unless a `package.json` below that configuration's directory makes the
|
|
6
|
+
* file another package's, which its own test runner compiles.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { sourcePaths } from "../file-facts.ts";
|
|
10
|
+
import type { Host } from "../host.ts";
|
|
11
|
+
import { ancestors, dirnamePath, joinPath } from "../paths.ts";
|
|
12
|
+
import { bytewise } from "../text/compare.ts";
|
|
13
|
+
import { holdsManifest } from "../fs/manifest.ts";
|
|
14
|
+
import type { Configuration } from "./discover.ts";
|
|
15
|
+
import type { ProgramPlan } from "./plan.ts";
|
|
16
|
+
|
|
17
|
+
const PREFERRED = "/tsconfig.json";
|
|
18
|
+
|
|
19
|
+
/** The configurations of one directory in the order a file joins them: `tsconfig.json` first. */
|
|
20
|
+
function byPreference(a: string, b: string): number {
|
|
21
|
+
const first = a.endsWith(PREFERRED) ? 0 : 1;
|
|
22
|
+
const second = b.endsWith(PREFERRED) ? 0 : 1;
|
|
23
|
+
return first - second || bytewise(a, b);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Per configuration of `configurations`, the absolute paths of the test files that join it:
|
|
28
|
+
* each file below `root` a pattern of `patterns` names, that no configuration's file list
|
|
29
|
+
* holds, joins the configuration nearest at or above its directory when no `package.json`
|
|
30
|
+
* sits between them.
|
|
31
|
+
*/
|
|
32
|
+
export function joinedTestFiles(
|
|
33
|
+
host: Host,
|
|
34
|
+
root: string,
|
|
35
|
+
configurations: readonly Configuration[],
|
|
36
|
+
patterns: readonly RegExp[],
|
|
37
|
+
): ReadonlyMap<string, readonly string[]> {
|
|
38
|
+
const listed = new Set<string>();
|
|
39
|
+
const byDir = new Map<string, string[]>();
|
|
40
|
+
for (const { configFile, parsed } of configurations) {
|
|
41
|
+
parsed.fileNames.forEach((name) => listed.add(name));
|
|
42
|
+
const dir = dirnamePath(configFile);
|
|
43
|
+
byDir.set(dir, [...(byDir.get(dir) ?? []), configFile].sort(byPreference));
|
|
44
|
+
}
|
|
45
|
+
const joins = new Map<string, string[]>();
|
|
46
|
+
for (const path of sourcePaths(host, root)) {
|
|
47
|
+
const file = joinPath(root, path);
|
|
48
|
+
if (listed.has(file) || !patterns.some((pattern) => pattern.test(path))) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
for (const dir of ancestors(dirnamePath(file), root)) {
|
|
52
|
+
const [nearest] = byDir.get(dir) ?? [];
|
|
53
|
+
if (nearest !== undefined) {
|
|
54
|
+
joins.set(nearest, [...(joins.get(nearest) ?? []), file]);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
if (holdsManifest(host, dir)) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return joins;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The plans with each joined test file added to the configuration it joins: to a described
|
|
67
|
+
* program's root files, or to the file list of a configuration only the snapshot holds, which
|
|
68
|
+
* lists every file the configuration lists and the joined ones.
|
|
69
|
+
*/
|
|
70
|
+
export function joinedTests(
|
|
71
|
+
plans: readonly ProgramPlan[],
|
|
72
|
+
joins: ReadonlyMap<string, readonly string[]>,
|
|
73
|
+
): readonly ProgramPlan[] {
|
|
74
|
+
return plans.map((plan): ProgramPlan => {
|
|
75
|
+
const files = joins.get(plan.configFile);
|
|
76
|
+
const { build } = plan;
|
|
77
|
+
if (files === undefined) {
|
|
78
|
+
return plan;
|
|
79
|
+
}
|
|
80
|
+
if (build.kind === "program") {
|
|
81
|
+
return {
|
|
82
|
+
...plan,
|
|
83
|
+
build: {
|
|
84
|
+
kind: "program",
|
|
85
|
+
params: { ...build.params, rootFiles: [...(build.params.rootFiles ?? []), ...files] },
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const written = build.kind === "configuration" ? build.value : { extends: plan.configFile };
|
|
90
|
+
return {
|
|
91
|
+
...plan,
|
|
92
|
+
build: {
|
|
93
|
+
kind: "configuration",
|
|
94
|
+
value: { ...written, files: [...plan.parsed.fileNames, ...files], include: [] },
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { emittedFrom } from "./emit-map.ts";
|
|
10
|
-
import type { Host } from "
|
|
11
|
-
import { readManifest, type Manifest, type ManifestEntry } from "
|
|
12
|
-
import { joinPath, relativePath } from "
|
|
10
|
+
import type { Host } from "../host.ts";
|
|
11
|
+
import { readManifest, type Manifest, type ManifestEntry } from "../manifest.ts";
|
|
12
|
+
import { joinPath, relativePath } from "../paths.ts";
|
|
13
13
|
import type { WorkspaceMember } from "./workspace.ts";
|
|
14
14
|
import type { WorkspaceResolver } from "./workspace-resolution.ts";
|
|
15
|
+
import { MANIFEST } from "../fs/manifest.ts";
|
|
15
16
|
|
|
16
17
|
/** The one character a subpath pattern of a manifest's `exports` holds. */
|
|
17
18
|
const SUBPATH_WILDCARD = "*";
|
|
@@ -84,8 +85,7 @@ export function memberEntries(
|
|
|
84
85
|
}
|
|
85
86
|
const manifest = readManifest(host, member.dir);
|
|
86
87
|
const where =
|
|
87
|
-
relativePath(targetRoot, joinPath(member.dir,
|
|
88
|
-
joinPath(member.dir, "package.json");
|
|
88
|
+
relativePath(targetRoot, joinPath(member.dir, MANIFEST)) ?? joinPath(member.dir, MANIFEST);
|
|
89
89
|
const kept = manifest.entries.flatMap((entry): ManifestEntry[] => {
|
|
90
90
|
const exported = entry.member.startsWith("exports");
|
|
91
91
|
if (member.private && exported) {
|
|
@@ -16,10 +16,16 @@ import type {
|
|
|
16
16
|
} from "@typescript/native/sync";
|
|
17
17
|
import { isStringLiteralLikeNode } from "@typescript/native/ast";
|
|
18
18
|
import type { StringLiteralLikeNode } from "@typescript/native/ast";
|
|
19
|
-
import type { Host } from "
|
|
20
|
-
import {
|
|
21
|
-
import
|
|
19
|
+
import type { Host } from "../host.ts";
|
|
20
|
+
import { JAVASCRIPT_FILE } from "../javascript-file.ts";
|
|
21
|
+
import { isRecord } from "../json-document.ts";
|
|
22
|
+
import { dirnamePath, resolvePath } from "../paths.ts";
|
|
23
|
+
import { batched, type Engine, type ProgramBuild } from "../session.ts";
|
|
22
24
|
import type { WorkspaceResolver } from "./workspace-resolution.ts";
|
|
25
|
+
import { bytewise } from "../text/compare.ts";
|
|
26
|
+
import { PRODUCT } from "../product.ts";
|
|
27
|
+
import type { Parsed } from "./discover.ts";
|
|
28
|
+
import type { Build, CompilerOptions } from "./plan.ts";
|
|
23
29
|
|
|
24
30
|
/** One member import no member source answers for. */
|
|
25
31
|
interface UnresolvedImport {
|
|
@@ -42,31 +48,35 @@ export interface MemberReading {
|
|
|
42
48
|
readonly componentsUnread: string | undefined;
|
|
43
49
|
}
|
|
44
50
|
|
|
45
|
-
/**
|
|
46
|
-
|
|
47
|
-
| { readonly kind: "program"; readonly params: CreateSnapshotProgramParams }
|
|
48
|
-
/** A configuration only the snapshot holds, at a path no file has. */
|
|
49
|
-
| { readonly kind: "configuration"; readonly file: string; readonly text: string };
|
|
51
|
+
/** One configuration as a written configuration or a described program. */
|
|
52
|
+
type Written = Exclude<Build, { readonly kind: "project" }>;
|
|
50
53
|
|
|
51
54
|
/** The programs one run builds instead of opening projects, with what reading them did. */
|
|
52
55
|
interface WorkspacePrograms {
|
|
53
56
|
/** Per configuration that imports a member, how the snapshot reads it. */
|
|
54
|
-
readonly programs: ReadonlyMap<string,
|
|
57
|
+
readonly programs: ReadonlyMap<string, Written>;
|
|
55
58
|
readonly readings: readonly MemberReading[];
|
|
56
59
|
}
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
/** One configuration the rounds read: its parse and the options the plan builds it with. */
|
|
62
|
+
export interface PlannedConfiguration {
|
|
63
|
+
readonly configFile: string;
|
|
64
|
+
readonly parsed: Parsed;
|
|
65
|
+
readonly options: CompilerOptions;
|
|
66
|
+
/** The configuration of a program the run forms, which only the snapshot holds, at `configFile`. */
|
|
67
|
+
readonly written?: Readonly<Record<string, unknown>> | undefined;
|
|
68
|
+
}
|
|
62
69
|
|
|
63
70
|
/**
|
|
64
|
-
* The options a configuration's program is built with:
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
71
|
+
* The options a configuration's program is built with: the plan's, less the ones that lay
|
|
72
|
+
* out an emitted program's inputs and outputs. The analysis emits nothing, and a member's
|
|
73
|
+
* source is outside the importer's root directory by construction, which the compiler
|
|
74
|
+
* refuses under such a layout.
|
|
68
75
|
*/
|
|
69
|
-
function analysisOptions(
|
|
76
|
+
function analysisOptions(
|
|
77
|
+
options: CompilerOptions,
|
|
78
|
+
readsJavaScript: boolean,
|
|
79
|
+
): CreateSnapshotProgramParams["compilerOptions"] {
|
|
70
80
|
const {
|
|
71
81
|
composite,
|
|
72
82
|
rootDir: _rootDir,
|
|
@@ -74,8 +84,24 @@ function analysisOptions(parsed: Parsed): CreateSnapshotProgramParams["compilerO
|
|
|
74
84
|
declarationDir: _declarationDir,
|
|
75
85
|
tsBuildInfoFile: _tsBuildInfoFile,
|
|
76
86
|
...kept
|
|
77
|
-
} =
|
|
78
|
-
|
|
87
|
+
} = options;
|
|
88
|
+
const read = readsJavaScript ? { ...kept, allowJs: true } : kept;
|
|
89
|
+
return composite === true ? { ...read, declaration: true } : read;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Whether one reading answers a member import with a JavaScript file, which its program reads
|
|
94
|
+
* as source only where it allows JavaScript, a program formed for a JavaScript member being the
|
|
95
|
+
* member's source.
|
|
96
|
+
*/
|
|
97
|
+
function readsJavaScript(reading: Reading): boolean {
|
|
98
|
+
return (
|
|
99
|
+
reading.options.allowJs !== true &&
|
|
100
|
+
reading.entries.some((entry) => {
|
|
101
|
+
const file = entry.result.resolvedFileName;
|
|
102
|
+
return typeof file === "string" && JAVASCRIPT_FILE.test(file);
|
|
103
|
+
})
|
|
104
|
+
);
|
|
79
105
|
}
|
|
80
106
|
|
|
81
107
|
/** The conditions an `exports` lookup under one configuration and one resolution mode reads. */
|
|
@@ -97,9 +123,7 @@ function resolutionMode(kind: ModuleKind): ResolutionMode | undefined {
|
|
|
97
123
|
}
|
|
98
124
|
|
|
99
125
|
/** One configuration's state across the rounds. */
|
|
100
|
-
interface Reading {
|
|
101
|
-
readonly configFile: string;
|
|
102
|
-
readonly parsed: Parsed;
|
|
126
|
+
interface Reading extends PlannedConfiguration {
|
|
103
127
|
readonly entries: ModuleResolutionEntry[];
|
|
104
128
|
readonly seen: Set<string>;
|
|
105
129
|
/** Per member specifier, every file an import of it is read as. */
|
|
@@ -121,34 +145,56 @@ function unstatable(reading: Reading): string | undefined {
|
|
|
121
145
|
return undefined;
|
|
122
146
|
}
|
|
123
147
|
|
|
124
|
-
/** The path beside `configFile` its written configuration takes, which no file has. */
|
|
125
|
-
export function writtenPath(
|
|
148
|
+
/** The path beside `configFile` its written configuration takes, which no file and none of `taken` has. */
|
|
149
|
+
export function writtenPath(
|
|
150
|
+
host: Host,
|
|
151
|
+
configFile: string,
|
|
152
|
+
taken: ReadonlySet<string> = new Set(),
|
|
153
|
+
): string {
|
|
126
154
|
const stem = configFile.replace(/\.json$/u, "");
|
|
127
155
|
for (let counter = 0; ; counter += 1) {
|
|
128
|
-
const path = `${stem}
|
|
129
|
-
if (host.kindOf(path) === "absent") {
|
|
156
|
+
const path = `${stem}.${PRODUCT}${counter === 0 ? "" : `-${String(counter)}`}.json`;
|
|
157
|
+
if (host.kindOf(path) === "absent" && !taken.has(path)) {
|
|
130
158
|
return path;
|
|
131
159
|
}
|
|
132
160
|
}
|
|
133
161
|
}
|
|
134
162
|
|
|
135
163
|
/**
|
|
136
|
-
* The
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
|
|
140
|
-
|
|
164
|
+
* The path the snapshot holds one configuration's written form at: a formed configuration's
|
|
165
|
+
* own path, else a free one beside it that no configuration of `formed` holds, because a formed
|
|
166
|
+
* program in a directory with a `jsconfig.json` takes the name that file's written form would.
|
|
167
|
+
*/
|
|
168
|
+
export function writtenFileOf(
|
|
169
|
+
host: Host,
|
|
170
|
+
configuration: Pick<PlannedConfiguration, "configFile" | "written">,
|
|
171
|
+
formed: ReadonlySet<string>,
|
|
172
|
+
): string {
|
|
173
|
+
return configuration.written === undefined
|
|
174
|
+
? writtenPath(host, configuration.configFile, formed)
|
|
175
|
+
: configuration.configFile;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The configuration that reads as one configuration's program: it extends it, lays out no output
|
|
180
|
+
* ({@link analysisOptions}), maps each answered specifier to its file and keeps its references.
|
|
181
|
+
* Where the file list moves, the default `exclude` the dropped output directories are named in is
|
|
182
|
+
* restated, and one that {@link readsJavaScript} lists its files outright, as `allowJs` widens its
|
|
183
|
+
* `include` to JavaScript; a list that still differs, or answers `paths` cannot state, are a
|
|
184
|
+
* reason. A formed configuration, which no file holds to extend, is its own value with `paths`.
|
|
141
185
|
*/
|
|
142
186
|
function configurationOf(
|
|
143
187
|
engine: Engine,
|
|
144
188
|
host: Host,
|
|
145
189
|
reading: Reading,
|
|
146
|
-
|
|
190
|
+
formed: ReadonlySet<string>,
|
|
191
|
+
): Written | { readonly kind: "unread"; readonly reason: string } {
|
|
147
192
|
const reason = unstatable(reading);
|
|
148
193
|
if (reason !== undefined) {
|
|
149
194
|
return { kind: "unread", reason };
|
|
150
195
|
}
|
|
151
|
-
const { options
|
|
196
|
+
const { options } = reading;
|
|
197
|
+
const references = reading.parsed.projectReferences ?? [];
|
|
152
198
|
const raw: unknown = (options as Record<string, unknown>)["pathsBasePath"];
|
|
153
199
|
const base = typeof raw === "string" ? raw : dirnamePath(reading.configFile);
|
|
154
200
|
const paths: Record<string, string[]> = {};
|
|
@@ -161,6 +207,17 @@ function configurationOf(
|
|
|
161
207
|
paths[entry.moduleName] = [file];
|
|
162
208
|
}
|
|
163
209
|
}
|
|
210
|
+
if (reading.written !== undefined) {
|
|
211
|
+
const held = reading.written["compilerOptions"];
|
|
212
|
+
return {
|
|
213
|
+
kind: "configuration",
|
|
214
|
+
value: {
|
|
215
|
+
...reading.written,
|
|
216
|
+
compilerOptions: { ...(isRecord(held) ? held : {}), paths },
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
const javascript = readsJavaScript(reading);
|
|
164
221
|
const json = (exclude: readonly string[] | undefined): Record<string, unknown> => ({
|
|
165
222
|
extends: reading.configFile,
|
|
166
223
|
compilerOptions: {
|
|
@@ -169,18 +226,20 @@ function configurationOf(
|
|
|
169
226
|
declarationDir: null,
|
|
170
227
|
tsBuildInfoFile: null,
|
|
171
228
|
...(options.composite === true ? { composite: false, declaration: true } : {}),
|
|
229
|
+
...(javascript ? { allowJs: true } : {}),
|
|
172
230
|
paths,
|
|
173
231
|
},
|
|
174
232
|
...(references.length > 0
|
|
175
233
|
? { references: references.map((reference) => ({ path: reference.path })) }
|
|
176
234
|
: {}),
|
|
235
|
+
...(javascript ? { files: [...reading.parsed.fileNames], include: [] } : {}),
|
|
177
236
|
...(exclude === undefined ? {} : { exclude }),
|
|
178
237
|
});
|
|
179
|
-
const file =
|
|
180
|
-
const expected = [...reading.parsed.fileNames].sort().join("\u0000");
|
|
238
|
+
const file = writtenFileOf(host, reading, formed);
|
|
239
|
+
const expected = [...reading.parsed.fileNames].sort(bytewise).join("\u0000");
|
|
181
240
|
const listed = (value: Record<string, unknown>): string | undefined => {
|
|
182
241
|
try {
|
|
183
|
-
return [...engine.parseConfigJson(value, file).fileNames].sort().join("\u0000");
|
|
242
|
+
return [...engine.parseConfigJson(value, file).fileNames].sort(bytewise).join("\u0000");
|
|
184
243
|
} catch {
|
|
185
244
|
return undefined;
|
|
186
245
|
}
|
|
@@ -198,7 +257,7 @@ function configurationOf(
|
|
|
198
257
|
};
|
|
199
258
|
}
|
|
200
259
|
}
|
|
201
|
-
return { kind: "configuration",
|
|
260
|
+
return { kind: "configuration", value };
|
|
202
261
|
}
|
|
203
262
|
|
|
204
263
|
/** The program one configuration is built as, under the answers it holds so far. */
|
|
@@ -206,7 +265,7 @@ function programOf(
|
|
|
206
265
|
engine: Engine,
|
|
207
266
|
reading: Reading,
|
|
208
267
|
): { readonly params: CreateSnapshotProgramParams; readonly resolver: ModuleResolver } {
|
|
209
|
-
const compilerOptions = analysisOptions(reading.
|
|
268
|
+
const compilerOptions = analysisOptions(reading.options, readsJavaScript(reading));
|
|
210
269
|
const references = reading.parsed.projectReferences ?? [];
|
|
211
270
|
const resolver = engine.createModuleResolver(compilerOptions, reading.entries);
|
|
212
271
|
return {
|
|
@@ -223,23 +282,6 @@ function programOf(
|
|
|
223
282
|
};
|
|
224
283
|
}
|
|
225
284
|
|
|
226
|
-
function chunks<T>(items: readonly T[]): readonly (readonly T[])[] {
|
|
227
|
-
const found: T[][] = [];
|
|
228
|
-
for (let at = 0; at < items.length; at += BATCH) {
|
|
229
|
-
found.push(items.slice(at, at + BATCH));
|
|
230
|
-
}
|
|
231
|
-
return found;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/** Asks one question of every item, in round trips of at most {@link BATCH}. */
|
|
235
|
-
function batched<T, A>(
|
|
236
|
-
engine: Engine,
|
|
237
|
-
items: readonly T[],
|
|
238
|
-
question: (item: T) => Parameters<Engine["batch"]>[0][number],
|
|
239
|
-
): A[] {
|
|
240
|
-
return chunks(items).flatMap((run) => engine.batch(run.map(question)) as A[]);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
285
|
/** One round over one program: answers the member imports no earlier round asked about. */
|
|
244
286
|
function scan(
|
|
245
287
|
engine: Engine,
|
|
@@ -332,6 +374,18 @@ type Built =
|
|
|
332
374
|
}
|
|
333
375
|
| { readonly kind: "configuration"; readonly file: string; readonly text: string };
|
|
334
376
|
|
|
377
|
+
function configurationText(value: Readonly<Record<string, unknown>>): string {
|
|
378
|
+
return `${JSON.stringify(value, null, 2)}\n`;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/** One configuration value as the snapshot holds it, at `file`, which no file on disk holds. */
|
|
382
|
+
export function writtenConfiguration(
|
|
383
|
+
file: string,
|
|
384
|
+
value: Readonly<Record<string, unknown>>,
|
|
385
|
+
): Extract<ProgramBuild, { readonly kind: "configuration" }> {
|
|
386
|
+
return { kind: "configuration", file, text: configurationText(value) };
|
|
387
|
+
}
|
|
388
|
+
|
|
335
389
|
/**
|
|
336
390
|
* Answers the member imports of every reading `build` describes, round by round, all
|
|
337
391
|
* the readings still adding answers built in one snapshot per round. A reading `build`
|
|
@@ -387,45 +441,38 @@ function readRounds(
|
|
|
387
441
|
export function workspacePrograms(
|
|
388
442
|
engine: Engine,
|
|
389
443
|
host: Host,
|
|
390
|
-
|
|
444
|
+
configurations: readonly PlannedConfiguration[],
|
|
391
445
|
resolver: WorkspaceResolver,
|
|
392
446
|
): WorkspacePrograms {
|
|
393
|
-
const readings: Reading[] =
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
configFile,
|
|
404
|
-
parsed,
|
|
405
|
-
entries: [],
|
|
406
|
-
seen: new Set<string>(),
|
|
407
|
-
bound: new Map<string, Set<string>>(),
|
|
408
|
-
unresolved: [],
|
|
409
|
-
},
|
|
410
|
-
];
|
|
411
|
-
});
|
|
447
|
+
const readings: Reading[] = configurations.map((configuration) => ({
|
|
448
|
+
...configuration,
|
|
449
|
+
entries: [],
|
|
450
|
+
seen: new Set<string>(),
|
|
451
|
+
bound: new Map<string, Set<string>>(),
|
|
452
|
+
unresolved: [],
|
|
453
|
+
}));
|
|
454
|
+
const formed = new Set(
|
|
455
|
+
configurations.filter((one) => one.written !== undefined).map((one) => one.configFile),
|
|
456
|
+
);
|
|
412
457
|
readRounds(engine, readings, resolver, (reading) => ({
|
|
413
458
|
kind: "program",
|
|
414
459
|
...programOf(engine, reading),
|
|
415
460
|
}));
|
|
416
461
|
if (engine.readsComponents) {
|
|
417
462
|
readRounds(engine, readings, resolver, (reading) => {
|
|
418
|
-
const one = configurationOf(engine, host, reading);
|
|
419
|
-
return one.kind === "configuration"
|
|
463
|
+
const one = configurationOf(engine, host, reading, formed);
|
|
464
|
+
return one.kind === "configuration"
|
|
465
|
+
? writtenConfiguration(writtenFileOf(host, reading, formed), one.value)
|
|
466
|
+
: undefined;
|
|
420
467
|
});
|
|
421
468
|
}
|
|
422
|
-
const programs = new Map<string,
|
|
469
|
+
const programs = new Map<string, Written>();
|
|
423
470
|
const unread = new Map<string, string>();
|
|
424
471
|
for (const reading of readings) {
|
|
425
472
|
if (reading.entries.length === 0) {
|
|
426
473
|
continue;
|
|
427
474
|
}
|
|
428
|
-
const one = engine.readsComponents ? configurationOf(engine, host, reading) : undefined;
|
|
475
|
+
const one = engine.readsComponents ? configurationOf(engine, host, reading, formed) : undefined;
|
|
429
476
|
if (one !== undefined && one.kind !== "unread") {
|
|
430
477
|
programs.set(reading.configFile, one);
|
|
431
478
|
continue;
|