@cplieger/deadset-ts 8.0.0-dev.1 → 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 +181 -341
- package/dist/src/augmentations.js +106 -13
- package/dist/src/automatic-types.js +10 -29
- package/dist/src/build-scripts.js +425 -0
- package/dist/src/component-layer.js +4 -2
- package/dist/src/components.js +2 -3
- package/dist/src/config.js +6 -82
- package/dist/src/configuration-files.js +28 -176
- package/dist/src/configured-declarations.js +15 -20
- package/dist/src/conformance-record.js +1 -1
- 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 +73 -3
- package/dist/src/conventions.js +36 -66
- package/dist/src/dependencies.js +103 -40
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +4 -6
- package/dist/src/entry-point-gaps.js +2 -8
- package/dist/src/entry-points.js +11 -27
- 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 +139 -72
- package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
- package/dist/src/findings/emitters.js +5 -5
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +13 -10
- package/dist/src/findings/non-code-artifacts.js +7 -8
- 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 +41 -32
- package/dist/src/findings/visibility-narrowing.js +19 -16
- 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 +7 -4
- package/dist/src/git-ignore.js +39 -26
- package/dist/src/graph.js +5 -3
- package/dist/src/html-entries.js +6 -33
- package/dist/src/in-operands.js +2 -1
- package/dist/src/index.js +1 -1
- package/dist/src/injection-container.js +1 -1
- package/dist/src/intra-function-parts.js +63 -43
- package/dist/src/inventory.js +2 -21
- 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} +89 -66
- package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +23 -65
- 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 +76 -4
- package/dist/src/mdx-entries.js +3 -26
- package/dist/src/outside-tests.js +1 -1
- 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 -79
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +1 -0
- package/dist/src/ref.js +1 -0
- package/dist/src/references.js +48 -30
- package/dist/src/report-schema.js +51 -0
- package/dist/src/report.js +57 -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 -729
- package/dist/src/roots.js +273 -87
- package/dist/src/run.js +66 -77
- package/dist/src/schema.js +320 -343
- package/dist/src/scope.js +38 -115
- package/dist/src/serialization-contract.js +595 -21
- package/dist/src/session.js +34 -29
- package/dist/src/source-files.js +1 -1
- package/dist/src/suppress-file.js +25 -28
- package/dist/src/suppress-inline.js +3 -2
- package/dist/src/suppress.js +33 -51
- package/dist/src/sweep.js +7 -9
- package/dist/src/symbol-keys.js +3 -5
- package/dist/src/template-field.js +9 -19
- package/dist/src/test-support.js +8 -11
- 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 +11 -232
- 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 +166 -126
- package/dist/src/verbs/describe.js +9 -16
- package/dist/src/verbs/explain.js +10 -7
- 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 +62 -64
- package/jsr.json +1 -1
- package/package.json +4 -3
- package/src/analysis.ts +245 -502
- package/src/augmentations.ts +135 -17
- package/src/automatic-types.ts +11 -29
- package/src/build-scripts.ts +543 -0
- package/src/component-layer.ts +4 -2
- package/src/components.ts +2 -4
- package/src/config.ts +31 -302
- package/src/configuration-files.ts +34 -179
- package/src/configured-declarations.ts +18 -23
- package/src/conformance-record.ts +1 -1
- 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 +85 -3
- package/src/conventions.ts +46 -84
- package/src/dependencies.ts +118 -46
- package/src/edges.ts +41 -140
- package/src/element-access.ts +4 -7
- package/src/entry-point-gaps.ts +3 -9
- package/src/entry-points.ts +12 -38
- 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 +14 -9
- package/src/findings/boundary.ts +2 -0
- package/src/findings/completion.ts +181 -84
- package/src/findings/dependencies-and-module-machinery.ts +4 -7
- package/src/findings/emitter.ts +8 -9
- package/src/findings/emitters.ts +7 -7
- package/src/findings/interfaces.ts +4 -6
- package/src/findings/intra-function.ts +13 -11
- package/src/findings/non-code-artifacts.ts +9 -11
- package/src/findings/reads-and-writes.ts +20 -16
- package/src/findings/self-check.ts +11 -17
- package/src/findings/unused-declarations.ts +45 -32
- package/src/findings/visibility-narrowing.ts +20 -17
- 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 +7 -4
- package/src/git-ignore.ts +50 -26
- package/src/graph.ts +5 -3
- package/src/host.ts +12 -5
- package/src/html-entries.ts +6 -33
- package/src/in-operands.ts +2 -1
- package/src/index.ts +1 -1
- package/src/injection-container.ts +1 -1
- package/src/intra-function-parts.ts +73 -44
- package/src/inventory.ts +2 -20
- 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} +128 -85
- package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +33 -76
- 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 +122 -4
- package/src/mdx-entries.ts +3 -26
- package/src/outside-tests.ts +1 -1
- package/src/partial.ts +3 -2
- package/src/paths.ts +27 -15
- package/src/position.ts +2 -1
- package/src/print.ts +12 -92
- package/src/product.ts +18 -0
- package/src/query.ts +11 -0
- package/src/ref.ts +1 -0
- package/src/references.ts +52 -31
- package/src/report-schema.ts +68 -0
- package/src/report.ts +101 -224
- 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 -1114
- package/src/roots.ts +339 -104
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -388
- package/src/scope.ts +46 -138
- package/src/serialization-contract.ts +763 -22
- package/src/session.ts +70 -54
- package/src/source-files.ts +1 -1
- package/src/suppress-file.ts +24 -33
- package/src/suppress-inline.ts +2 -2
- package/src/suppress.ts +43 -58
- package/src/sweep.ts +23 -9
- package/src/symbol-keys.ts +2 -5
- package/src/template-field.ts +15 -25
- package/src/test-support.ts +17 -13
- 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 +18 -288
- package/src/unseen-loads.ts +134 -0
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/verbs/analyze.ts +224 -162
- package/src/verbs/describe.ts +14 -15
- package/src/verbs/explain.ts +10 -11
- 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 +74 -64
- package/dist/src/base-url.js +0 -18
- package/dist/src/discover.js +0 -468
- 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/base-url.ts +0 -24
- package/src/discover.ts +0 -653
- 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
package/dist/src/analysis.js
CHANGED
|
@@ -8,21 +8,21 @@
|
|
|
8
8
|
import { isStringLiteralLikeNode } from "@typescript/native/ast";
|
|
9
9
|
import { lineOf, readComponent } from "./component-files.js";
|
|
10
10
|
import { kindOf } from "./config.js";
|
|
11
|
-
import {
|
|
11
|
+
import { consumerReferences } from "./consumers.js";
|
|
12
12
|
import { configuredDeclarations, configuredRef, declarationsNamed, } from "./configured-declarations.js";
|
|
13
13
|
import { decorator } from "./decorator.js";
|
|
14
14
|
import { configurationNeeds, dependenciesOf, projectNeeds } from "./dependencies.js";
|
|
15
15
|
import { deprecatedDeclarations } from "./deprecation.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
16
|
+
import { moduleIdentity } from "./load/discover.js";
|
|
17
|
+
import { loadRun } from "./load/load.js";
|
|
18
|
+
import { generatedFiles } from "./conventions.js";
|
|
18
19
|
import { readEdgeSides } from "./edges.js";
|
|
19
20
|
import { enumGroup } from "./enum-group.js";
|
|
20
21
|
import { generatedFile, generatedFilesOf } from "./generated-file.js";
|
|
21
22
|
import { inOperandNames } from "./in-operands.js";
|
|
22
23
|
import { sourceFilesOf } from "./source-files.js";
|
|
23
|
-
import { evidenceRecords, heldRecords, disabledClasses, exemptionsOf, holdingWhile, isUnansweredRecord, retainedIn, } from "./exempt.js";
|
|
24
|
+
import { evidenceRecords, heldRecords, disabledClasses, exemptionsOf, holdingWhile, isUnansweredRecord, retainedIn, writtenRecords, } from "./exempt.js";
|
|
24
25
|
import { heldByInclusion, sourcePaths, sourceTree } from "./file-facts.js";
|
|
25
|
-
import { globExpression } from "./glob.js";
|
|
26
26
|
import { findingsPass, recordedFindings, rowKey } from "./findings-pass.js";
|
|
27
27
|
import { unmatchedRootFindings } from "./findings/self-check.js";
|
|
28
28
|
import { frameworkLifecycle } from "./framework-lifecycle.js";
|
|
@@ -31,27 +31,28 @@ import { injectionContainer } from "./injection-container.js";
|
|
|
31
31
|
import { interfaceSatisfaction, settledSatisfaction } from "./interface-satisfaction.js";
|
|
32
32
|
import { intraFunctionFacts, projectParts } from "./intra-function-parts.js";
|
|
33
33
|
import { inventory } from "./inventory.js";
|
|
34
|
-
import {
|
|
34
|
+
import { readManifest } from "./manifest.js";
|
|
35
35
|
import { liveFilesAt, matrixOf, referenceKey, sweepMatrix, } from "./matrix.js";
|
|
36
|
-
import { dirnamePath, extensionOf, joinPath,
|
|
36
|
+
import { ancestors, dirnamePath, extensionOf, joinPath, relativePath, resolvePath, } from "./paths.js";
|
|
37
37
|
import { byPosition, isComponentFile } from "./position.js";
|
|
38
|
-
import {
|
|
39
|
-
import { SetupError, setupLine } from "./setup-failure.js";
|
|
40
|
-
import { pathsOf, readErrors, skippedRoots, skippedUnits, } from "./type-errors.js";
|
|
38
|
+
import { skippedRoots, skippedUnits } from "./type-errors.js";
|
|
41
39
|
import { reflectiveLookup } from "./reflective-lookup.js";
|
|
42
40
|
import { references, testFileRulesOf } from "./references.js";
|
|
43
41
|
import { roots, unmatchedEverywhere, } from "./roots.js";
|
|
44
|
-
import { serializationContract } from "./serialization-contract.js";
|
|
42
|
+
import { decodedMembers, serializationContract } from "./serialization-contract.js";
|
|
45
43
|
import { outsideTestReferences, testFilesAt } from "./outside-tests.js";
|
|
46
|
-
import {
|
|
44
|
+
import { mergedGlobalInterfaces } from "./augmentations.js";
|
|
45
|
+
import { unseenLoadsOf } from "./unseen-loads.js";
|
|
46
|
+
import { GLOBALS_RUNNER, namesTestGlobals } from "./load/test-globals.js";
|
|
47
47
|
import { supportReferences, testSupportFiles } from "./test-support.js";
|
|
48
|
-
import { diagnosticsOf, ownedAs, runSession, } from "./session.js";
|
|
49
48
|
import { accessorsOf, storesOf } from "./stores.js";
|
|
50
49
|
import { isPartKind } from "./suppress.js";
|
|
51
50
|
import { bindRows, readBaseline, readIgnoreFile } from "./suppress-file.js";
|
|
52
51
|
import { inlineDirectives, inlineSuppressions } from "./suppress-inline.js";
|
|
53
52
|
import { readTemplates, templateField } from "./template-field.js";
|
|
54
|
-
import {
|
|
53
|
+
import { bytewise } from "./text/compare.js";
|
|
54
|
+
import { holdsManifest, manifestAt } from "./fs/manifest.js";
|
|
55
|
+
import { globExpression } from "./text/glob.js";
|
|
55
56
|
/** The setting whose source decides where a finding about a configured root sits. */
|
|
56
57
|
const ROOTS_SETTING = "roots.patterns";
|
|
57
58
|
/**
|
|
@@ -68,288 +69,77 @@ function documentOf(host, provenance, setting, targetRoot) {
|
|
|
68
69
|
const document = resolvePath(host.workingDirectory(), origin.label);
|
|
69
70
|
return relativePath(resolvePath(host.workingDirectory(), targetRoot), document) ?? "";
|
|
70
71
|
}
|
|
71
|
-
/** Two strings ordered bytewise. */
|
|
72
|
-
function compare(a, b) {
|
|
73
|
-
if (a === b) {
|
|
74
|
-
return 0;
|
|
75
|
-
}
|
|
76
|
-
return a < b ? -1 : 1;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* The manifests the analysis reads, each once: the target's own, then every workspace
|
|
80
|
-
* member's and every nested package's below the target root.
|
|
81
|
-
*/
|
|
82
|
-
function conventionManifests(host, targetRoot, memberDirs, nestedDirs) {
|
|
83
|
-
const found = new Map();
|
|
84
|
-
if (host.kindOf(joinPath(targetRoot, "package.json")) === "file") {
|
|
85
|
-
found.set(targetRoot, { dir: targetRoot, path: "package.json" });
|
|
86
|
-
}
|
|
87
|
-
for (const [dirs, nested] of [
|
|
88
|
-
[memberDirs, false],
|
|
89
|
-
[nestedDirs, true],
|
|
90
|
-
]) {
|
|
91
|
-
for (const dir of dirs) {
|
|
92
|
-
const below = relativePath(targetRoot, dir);
|
|
93
|
-
if (below !== undefined && !found.has(dir)) {
|
|
94
|
-
found.set(dir, { dir, path: `${below}/package.json`, nested });
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return [...found.values()];
|
|
99
|
-
}
|
|
100
72
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*/
|
|
105
|
-
function nestedPackageDirs(host, targetRoot, files, known) {
|
|
106
|
-
const seen = new Set();
|
|
107
|
-
const found = [];
|
|
108
|
-
for (const file of files) {
|
|
109
|
-
for (let dir = dirnamePath(file); dir !== targetRoot && !seen.has(dir) && relativePath(targetRoot, dir) !== undefined; dir = dirnamePath(dir)) {
|
|
110
|
-
seen.add(dir);
|
|
111
|
-
const below = relativePath(targetRoot, dir) ?? "";
|
|
112
|
-
if (!below.split("/").includes("node_modules") &&
|
|
113
|
-
!known.has(dir) &&
|
|
114
|
-
host.kindOf(joinPath(dir, "package.json")) === "file") {
|
|
115
|
-
found.push(dir);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return found.sort(compare);
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Reads every project the scope discovers, and each declared consumer's, in one snapshot,
|
|
123
|
-
* each checked for errors first. `stage` is handed a target project and enumerates and roots
|
|
124
|
-
* it if it reads it; a consumer project is read for its references to the target. A type error
|
|
125
|
-
* in an own file skips the unit holding it. A guess that does not load or meets a setup failure
|
|
126
|
-
* is dropped into `notBuilt` (see {@link isGuess}); any other such project fails the run, as
|
|
127
|
-
* does a run whose every guess was dropped.
|
|
73
|
+
* Reads every project the load phase analyzes through `stage`, which enumerates and roots one
|
|
74
|
+
* if it reads it, and each declared consumer's project for its references to the target,
|
|
75
|
+
* in the same snapshot. A type error in an own file skips the unit holding it.
|
|
128
76
|
*/
|
|
129
77
|
function readProjects(engine, host, scope, config, stage) {
|
|
130
78
|
const targetRoot = scope.target.path;
|
|
131
|
-
const discovered = discoverProjects(engine, host, scope, config.analysis.configurations);
|
|
132
|
-
if (discovered.configFiles.length === 0 && discovered.notBuilt.length === 0) {
|
|
133
|
-
throw new DiscoveryError(`${targetRoot} holds no compiler configuration, so the run holds no program`, []);
|
|
134
|
-
}
|
|
135
|
-
const ids = new Map(discovered.projects.map((project) => [project.configFile, project.id]));
|
|
136
|
-
const loads = consumerLoads(engine, host, scope, discovered.configFiles);
|
|
137
|
-
const consumerOf = new Map(loads.flatMap((load) => load.configFiles.map((configFile) => [configFile, load.consumer])));
|
|
138
79
|
const absoluteRoot = resolvePath(host.workingDirectory(), targetRoot);
|
|
139
|
-
const
|
|
80
|
+
const testPatterns = config.ts.test_files.map(globExpression);
|
|
140
81
|
const parse = (fileName, text) => engine.parseSourceFile(fileName, text);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
let nestedDirs = [];
|
|
145
|
-
let conventions = readConventions(host, parse, [], config.ts.disabledConventions);
|
|
146
|
-
let options;
|
|
147
|
-
const readManifests = (opened) => {
|
|
148
|
-
nestedDirs = nestedPackageDirs(host, normalizePath(absoluteRoot), opened
|
|
149
|
-
.filter((one) => !consumerOf.has(one.configFile))
|
|
150
|
-
.flatMap((one) => [one.configFile, ...one.fileNames()]), new Set(memberDirs));
|
|
151
|
-
conventions = readConventions(host, parse, conventionManifests(host, absoluteRoot, memberDirs, nestedDirs), config.ts.disabledConventions);
|
|
152
|
-
options = {
|
|
82
|
+
return loadRun(engine, host, scope, config, ({ plan, classified, runFiles }) => {
|
|
83
|
+
const { packages, conventions } = plan;
|
|
84
|
+
const options = {
|
|
153
85
|
host,
|
|
154
|
-
manifest:
|
|
155
|
-
otherPackages:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
],
|
|
159
|
-
patterns: config.rootPatterns,
|
|
160
|
-
entryFiles: config.ts.entryFiles,
|
|
86
|
+
manifest: packages.manifest,
|
|
87
|
+
otherPackages: packages.entries,
|
|
88
|
+
patterns: config.roots.patterns,
|
|
89
|
+
entryFiles: config.ts.entry_files,
|
|
161
90
|
conventions,
|
|
162
|
-
testFiles: config.ts.
|
|
91
|
+
testFiles: config.ts.test_files,
|
|
163
92
|
parse,
|
|
164
|
-
publishedAPI: config.
|
|
165
|
-
publishedMembers:
|
|
166
|
-
runFiles
|
|
93
|
+
publishedAPI: config.target.kind !== undefined && kindOf(config.target.kind) === "library",
|
|
94
|
+
publishedMembers: packages.published,
|
|
95
|
+
runFiles,
|
|
167
96
|
};
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
setupMet(opened.configFile, [
|
|
204
|
-
{ setupClass: "workspace-member-without-source", detail: setup },
|
|
205
|
-
]);
|
|
206
|
-
return undefined;
|
|
207
|
-
}
|
|
208
|
-
const referenceOnly = workspace === undefined || consumer !== undefined
|
|
209
|
-
? () => false
|
|
210
|
-
: workspace.referenceOnly(opened.configFile, opened.rootFiles);
|
|
211
|
-
const project = workspace === undefined || consumer !== undefined
|
|
212
|
-
? opened
|
|
213
|
-
: ownedAs(opened, (file, fromExternalLibrary) => workspace.ownFile(file, fromExternalLibrary));
|
|
214
|
-
const raw = projectErrors(diagnosticsOf(project));
|
|
215
|
-
const errors = { load: raw.load, check: ownErrors(raw.check, referenceOnly) };
|
|
216
|
-
const [unloaded] = errors.load;
|
|
217
|
-
if (unloaded !== undefined &&
|
|
218
|
-
consumer === undefined &&
|
|
219
|
-
isGuess(discovered, project.configFile)) {
|
|
220
|
-
dropped(project.configFile, renderDiagnostic(unloaded, (path) => relativePath(absoluteRoot, path) ?? path));
|
|
221
|
-
return undefined;
|
|
222
|
-
}
|
|
223
|
-
if (errors.load.length > 0) {
|
|
224
|
-
failures.push(...errors.load);
|
|
225
|
-
return undefined;
|
|
226
|
-
}
|
|
227
|
-
const reading = readErrors(project, errors.check, {
|
|
228
|
-
host,
|
|
229
|
-
targetRoot: consumer === undefined
|
|
230
|
-
? absoluteRoot
|
|
231
|
-
: resolvePath(host.workingDirectory(), consumer.path),
|
|
232
|
-
paths: pathsOf(engine, project.configFile),
|
|
97
|
+
const heldFiles = new Set();
|
|
98
|
+
const answers = classified.analyzed.map(({ plan: planned, project, skips, referenceOnly }) => {
|
|
99
|
+
const read = () => {
|
|
100
|
+
const held = inventory(project, host, targetRoot);
|
|
101
|
+
const found = roots(project, held, targetRoot, options);
|
|
102
|
+
const kept = skippedRoots(project, held, skips);
|
|
103
|
+
const rooted = kept.length === 0
|
|
104
|
+
? found
|
|
105
|
+
: {
|
|
106
|
+
...found,
|
|
107
|
+
liveUnderReachability: [
|
|
108
|
+
...found.liveUnderReachability,
|
|
109
|
+
...kept.map((id) => ({ id, kind: "type-error", source: "" })),
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
const own = sourceFilesOf(project, targetRoot);
|
|
113
|
+
return {
|
|
114
|
+
configuration: planned.id,
|
|
115
|
+
configFile: project.configFile,
|
|
116
|
+
held,
|
|
117
|
+
rooted,
|
|
118
|
+
typeErrorSkips: skips.map((one) => one.record),
|
|
119
|
+
skipped: skippedUnits(skips, absoluteRoot),
|
|
120
|
+
referenceOnly: project
|
|
121
|
+
.ownSourceFiles()
|
|
122
|
+
.filter((file) => referenceOnly(file.fileName))
|
|
123
|
+
.flatMap((file) => relativePath(absoluteRoot, file.fileName) ?? []),
|
|
124
|
+
generated: generatedFilesOf(own, generatedFiles(conventions, own)),
|
|
125
|
+
testFileNames: conventions.testFiles,
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
for (const file of project.ownSourceFiles()) {
|
|
129
|
+
heldFiles.add(relativePath(absoluteRoot, file.fileName) ?? file.fileName);
|
|
130
|
+
}
|
|
131
|
+
return stage(project, { configuration: planned.id, read });
|
|
233
132
|
});
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
})));
|
|
239
|
-
return undefined;
|
|
240
|
-
}
|
|
241
|
-
if (reading.missing.length > 0) {
|
|
242
|
-
setupMet(project.configFile, reading.missing);
|
|
243
|
-
return undefined;
|
|
244
|
-
}
|
|
245
|
-
const unconventional = consumer === undefined
|
|
246
|
-
? conventionFailuresFor(conventions, project.configFile, project.ownSourceFiles().map((file) => file.fileName))
|
|
247
|
-
: [];
|
|
248
|
-
if (unconventional.length > 0) {
|
|
249
|
-
setupMet(project.configFile, unconventional);
|
|
250
|
-
return undefined;
|
|
251
|
-
}
|
|
252
|
-
if (consumer !== undefined) {
|
|
253
|
-
for (const reference of consumerReferences(project, host, targetRoot, {
|
|
254
|
-
id: consumer.id,
|
|
255
|
-
root: consumer.path,
|
|
256
|
-
}, config)) {
|
|
133
|
+
const consumed = new Map();
|
|
134
|
+
for (const { project, consumer } of classified.consumed) {
|
|
135
|
+
const side = { id: consumer.id, root: consumer.path };
|
|
136
|
+
for (const reference of consumerReferences(project, host, targetRoot, side, config)) {
|
|
257
137
|
consumed.set(referenceKey(reference), reference);
|
|
258
138
|
}
|
|
259
|
-
return undefined;
|
|
260
139
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
})));
|
|
265
|
-
const missingGlobal = raw.unfound.find(({ diagnostic }) => diagnostic.code === MISSING_GLOBAL_TYPE);
|
|
266
|
-
const skips = missingGlobal === undefined
|
|
267
|
-
? reading.skips
|
|
268
|
-
: [
|
|
269
|
-
...reading.skips,
|
|
270
|
-
...project.ownSourceFiles().map((file) => ({
|
|
271
|
-
record: {
|
|
272
|
-
path: relativePath(absoluteRoot, file.fileName) ?? file.fileName,
|
|
273
|
-
line: 1,
|
|
274
|
-
message: missingGlobal.diagnostic.text,
|
|
275
|
-
},
|
|
276
|
-
file,
|
|
277
|
-
unit: file,
|
|
278
|
-
})),
|
|
279
|
-
];
|
|
280
|
-
const configuration = ids.get(project.configFile) ?? project.configFile;
|
|
281
|
-
const read = () => {
|
|
282
|
-
const held = inventory(project, host, targetRoot);
|
|
283
|
-
const found = roots(project, held, targetRoot, options);
|
|
284
|
-
const kept = skippedRoots(project, held, skips);
|
|
285
|
-
const rooted = kept.length === 0
|
|
286
|
-
? found
|
|
287
|
-
: {
|
|
288
|
-
...found,
|
|
289
|
-
liveUnderReachability: [
|
|
290
|
-
...found.liveUnderReachability,
|
|
291
|
-
...kept.map((id) => ({ id, kind: "type-error", source: "" })),
|
|
292
|
-
],
|
|
293
|
-
};
|
|
294
|
-
const own = sourceFilesOf(project, targetRoot);
|
|
295
|
-
return {
|
|
296
|
-
configuration,
|
|
297
|
-
configFile: project.configFile,
|
|
298
|
-
held,
|
|
299
|
-
rooted,
|
|
300
|
-
typeErrorSkips: skips.map((one) => one.record),
|
|
301
|
-
skipped: skippedUnits(skips, absoluteRoot),
|
|
302
|
-
referenceOnly: project
|
|
303
|
-
.ownSourceFiles()
|
|
304
|
-
.filter((file) => referenceOnly(file.fileName))
|
|
305
|
-
.flatMap((file) => relativePath(absoluteRoot, file.fileName) ?? []),
|
|
306
|
-
generated: generatedFilesOf(own, generatedFiles(conventions, own)),
|
|
307
|
-
testFileNames: conventions.testFiles,
|
|
308
|
-
};
|
|
309
|
-
};
|
|
310
|
-
for (const file of project.ownSourceFiles()) {
|
|
311
|
-
heldFiles.add(relativePath(absoluteRoot, file.fileName) ?? file.fileName);
|
|
312
|
-
}
|
|
313
|
-
return stage(project, { configuration, read });
|
|
314
|
-
}, discovered.derived ? "record" : "refuse", joins.size === 0 ? programs : withJoinedTests(engine, host, programs, joins), () => {
|
|
315
|
-
outsideTests = testFilesAt(host, targetRoot, sourcePaths(host, targetRoot).filter((path) => !heldFiles.has(path) && testPatterns.some((pattern) => pattern.test(path))), parse);
|
|
316
|
-
}, readManifests);
|
|
317
|
-
for (const configFile of session.unopened) {
|
|
318
|
-
if (consumerOf.has(configFile) || !isGuess(discovered, configFile)) {
|
|
319
|
-
throw new DiscoveryError(`${configFile} opened no project`, []);
|
|
320
|
-
}
|
|
321
|
-
dropped(configFile, "the compiler opened no project for the configuration");
|
|
322
|
-
}
|
|
323
|
-
if (unbuildable.length > 0) {
|
|
324
|
-
throw new SetupError(unbuildable);
|
|
325
|
-
}
|
|
326
|
-
if (failures.length > 0) {
|
|
327
|
-
throw new DiscoveryError(`${String(failures.length)} error(s), so no answer was produced`, failures);
|
|
328
|
-
}
|
|
329
|
-
const answers = session.projects.filter((answer) => answer !== undefined);
|
|
330
|
-
const [first] = notBuilt;
|
|
331
|
-
if (answers.length === 0 && setupDropped.length > 0) {
|
|
332
|
-
throw new SetupError(setupDropped);
|
|
333
|
-
}
|
|
334
|
-
if (answers.length === 0 && first !== undefined) {
|
|
335
|
-
throw new DiscoveryError(`no configuration discovery derived could be built; ${first.id}: ${first.error}`, []);
|
|
336
|
-
}
|
|
337
|
-
return {
|
|
338
|
-
answers,
|
|
339
|
-
consumers: {
|
|
340
|
-
loaded: loads.map((load) => load.consumer),
|
|
341
|
-
references: [...consumed.values()],
|
|
342
|
-
},
|
|
343
|
-
notBuilt,
|
|
344
|
-
unanswered: session.unanswered,
|
|
345
|
-
componentsUnread: workspace?.componentsUnread ?? [],
|
|
346
|
-
librariesUnfound,
|
|
347
|
-
conventionsApplied: conventions.applied,
|
|
348
|
-
conventionUses: conventions.uses,
|
|
349
|
-
memberDirs,
|
|
350
|
-
nestedDirs,
|
|
351
|
-
outsideTests,
|
|
352
|
-
};
|
|
140
|
+
const outsideTests = testFilesAt(host, targetRoot, sourcePaths(host, targetRoot).filter((path) => !heldFiles.has(path) && testPatterns.some((pattern) => pattern.test(path))), parse);
|
|
141
|
+
return { answers, references: [...consumed.values()], outsideTests };
|
|
142
|
+
});
|
|
353
143
|
}
|
|
354
144
|
/**
|
|
355
145
|
* The projects the run the scope and the configuration describe analyzes, each read
|
|
@@ -358,7 +148,11 @@ function readProjects(engine, host, scope, config, stage) {
|
|
|
358
148
|
*/
|
|
359
149
|
export function runProjects(engine, host, scope, config) {
|
|
360
150
|
const read = readProjects(engine, host, scope, config, (_project, opened) => opened.configuration);
|
|
361
|
-
return {
|
|
151
|
+
return {
|
|
152
|
+
configurations: read.result.answers,
|
|
153
|
+
notBuilt: read.classified.notBuilt,
|
|
154
|
+
unanswered: read.unanswered,
|
|
155
|
+
};
|
|
362
156
|
}
|
|
363
157
|
/**
|
|
364
158
|
* The root set of the run the scope and the configuration describe.
|
|
@@ -369,7 +163,7 @@ export function runProjects(engine, host, scope, config) {
|
|
|
369
163
|
export function runRoots(engine, host, scope, config, provenance) {
|
|
370
164
|
const targetRoot = scope.target.path;
|
|
371
165
|
const read = readProjects(engine, host, scope, config, (_project, opened) => opened.read());
|
|
372
|
-
const projects = read.answers;
|
|
166
|
+
const projects = read.result.answers;
|
|
373
167
|
const configurations = [];
|
|
374
168
|
const merged = new Map();
|
|
375
169
|
for (const answer of projects) {
|
|
@@ -397,13 +191,15 @@ export function runRoots(engine, host, scope, config, provenance) {
|
|
|
397
191
|
}
|
|
398
192
|
}
|
|
399
193
|
}
|
|
400
|
-
const ordered = [...merged.values()].sort((a, b) => byPosition(a.position, b.position) ||
|
|
401
|
-
|
|
194
|
+
const ordered = [...merged.values()].sort((a, b) => byPosition(a.position, b.position) ||
|
|
195
|
+
bytewise(a.kind, b.kind) ||
|
|
196
|
+
bytewise(a.source, b.source));
|
|
197
|
+
const unmatched = unmatchedEverywhere(config.roots.patterns, projects.map((answer) => answer.rooted));
|
|
402
198
|
return {
|
|
403
199
|
configurations,
|
|
404
200
|
roots: ordered,
|
|
405
201
|
findings: unmatchedRootFindings(unmatched, documentOf(host, provenance, ROOTS_SETTING, targetRoot)),
|
|
406
|
-
notBuilt: read.notBuilt,
|
|
202
|
+
notBuilt: read.classified.notBuilt,
|
|
407
203
|
unanswered: read.unanswered,
|
|
408
204
|
};
|
|
409
205
|
}
|
|
@@ -435,18 +231,9 @@ function testEvidence(host, targetRoot, projects) {
|
|
|
435
231
|
}
|
|
436
232
|
}
|
|
437
233
|
const manifests = new Map();
|
|
438
|
-
const
|
|
234
|
+
const manifestIn = (dir) => {
|
|
439
235
|
if (!manifests.has(dir)) {
|
|
440
|
-
|
|
441
|
-
try {
|
|
442
|
-
value = JSON.parse(host.readFile(joinPath(dir, "package.json")));
|
|
443
|
-
}
|
|
444
|
-
catch {
|
|
445
|
-
value = undefined;
|
|
446
|
-
}
|
|
447
|
-
manifests.set(dir, typeof value === "object" && value !== null && !Array.isArray(value)
|
|
448
|
-
? value
|
|
449
|
-
: undefined);
|
|
236
|
+
manifests.set(dir, manifestAt(host, dir));
|
|
450
237
|
}
|
|
451
238
|
return manifests.get(dir);
|
|
452
239
|
};
|
|
@@ -455,16 +242,14 @@ function testEvidence(host, targetRoot, projects) {
|
|
|
455
242
|
return {
|
|
456
243
|
imports,
|
|
457
244
|
devDependency: (path, name) => {
|
|
458
|
-
for (
|
|
459
|
-
const manifest =
|
|
245
|
+
for (const dir of ancestors(dirnamePath(joinPath(root, path)), root)) {
|
|
246
|
+
const manifest = manifestIn(dir);
|
|
460
247
|
const other = OTHER_SECTIONS.some((one) => declares(manifest?.[one], name));
|
|
461
248
|
if (declares(manifest?.[DEV_SECTION], name) || other) {
|
|
462
249
|
return !other;
|
|
463
250
|
}
|
|
464
|
-
if (normalizePath(dir) === normalizePath(root) || dirnamePath(dir) === dir) {
|
|
465
|
-
return false;
|
|
466
|
-
}
|
|
467
251
|
}
|
|
252
|
+
return false;
|
|
468
253
|
},
|
|
469
254
|
};
|
|
470
255
|
}
|
|
@@ -478,13 +263,13 @@ function readRun(engine, host, scope, config, mode, detectors, extra) {
|
|
|
478
263
|
const targetRoot = scope.target.path;
|
|
479
264
|
const disabled = disabledClasses(config);
|
|
480
265
|
const templates = disabled.has("template-field")
|
|
481
|
-
? { delimiters: config.analysis.
|
|
266
|
+
? { delimiters: config.analysis.template_delimiters, files: [] }
|
|
482
267
|
: readTemplates(host, targetRoot, config.analysis);
|
|
483
268
|
const consumers = scope.consumers.map((consumer) => consumer.path);
|
|
484
269
|
const read = readProjects(engine, host, scope, config, (project, opened) => {
|
|
485
270
|
const projectRead = opened.read();
|
|
486
271
|
const resolved = references(project, projectRead.held, targetRoot, {
|
|
487
|
-
testFiles: config.ts.
|
|
272
|
+
testFiles: config.ts.test_files,
|
|
488
273
|
testFileNames: projectRead.testFileNames,
|
|
489
274
|
});
|
|
490
275
|
const evidence = evidenceRecords({
|
|
@@ -494,11 +279,14 @@ function readRun(engine, host, scope, config, mode, detectors, extra) {
|
|
|
494
279
|
templates,
|
|
495
280
|
ts: config.ts,
|
|
496
281
|
consumers,
|
|
497
|
-
...(config.analysis.
|
|
282
|
+
...(config.analysis.generated_files === "include"
|
|
498
283
|
? {}
|
|
499
284
|
: { generated: projectRead.generated }),
|
|
500
285
|
}, detectors, disabled);
|
|
501
286
|
const components = project.ownSourceFiles().filter(isComponentFile);
|
|
287
|
+
const injected = project.program
|
|
288
|
+
.getSourceFileNames()
|
|
289
|
+
.some((name) => name.endsWith(`/node_modules/${GLOBALS_RUNNER}/globals.d.ts`));
|
|
502
290
|
const pathOf = (file) => relativePath(targetRoot, file.fileName) ?? file.fileName;
|
|
503
291
|
return {
|
|
504
292
|
projectRead,
|
|
@@ -506,51 +294,80 @@ function readRun(engine, host, scope, config, mode, detectors, extra) {
|
|
|
506
294
|
testFiles: resolved.testFilePaths,
|
|
507
295
|
evidence,
|
|
508
296
|
componentFiles: components.map(pathOf),
|
|
297
|
+
augmented: mergedGlobalInterfaces(project, projectRead.held, sourceFilesOf(project, targetRoot)).map((id) => ({ id, kind: "global-augmentation", source: "" })),
|
|
509
298
|
imports: new Map(project.ownSourceFiles().flatMap((file) => {
|
|
510
299
|
const path = relativePath(targetRoot, file.fileName);
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
300
|
+
if (path === undefined) {
|
|
301
|
+
return [];
|
|
302
|
+
}
|
|
303
|
+
const specifiers = file.imports.filter(isStringLiteralLikeNode).map((one) => one.text);
|
|
304
|
+
// A file calling the globals a program declares is written for their runner.
|
|
305
|
+
return [
|
|
306
|
+
[
|
|
307
|
+
path,
|
|
308
|
+
injected && namesTestGlobals(project, file)
|
|
309
|
+
? [...specifiers, GLOBALS_RUNNER]
|
|
310
|
+
: specifiers,
|
|
311
|
+
],
|
|
312
|
+
];
|
|
514
313
|
})),
|
|
515
314
|
componentWarnings: components.flatMap((file) => readComponent(file.originalText, extensionOf(file.fileName)).warnings.map((warning) => ({
|
|
516
315
|
path: pathOf(file),
|
|
517
316
|
line: lineOf(file.originalText, warning.offset),
|
|
518
317
|
reason: warning.reason,
|
|
519
318
|
}))),
|
|
319
|
+
decoded: decodedMembers(project, projectRead.held, productionFiles(project, targetRoot, resolved.testFilePaths), consumers),
|
|
520
320
|
extra: extra(project, projectRead, resolved.references, resolved.testFilePaths),
|
|
521
321
|
};
|
|
522
322
|
});
|
|
523
|
-
const outsidePaths = read.outsideTests.map((one) => one.path);
|
|
524
|
-
const withOutside = read.answers.map((one) => ({
|
|
323
|
+
const outsidePaths = read.result.outsideTests.map((one) => one.path);
|
|
324
|
+
const withOutside = read.result.answers.map((one) => ({
|
|
525
325
|
...one,
|
|
526
326
|
references: [
|
|
527
327
|
...one.references,
|
|
528
|
-
...outsideTestReferences(read.outsideTests, one.projectRead.held, targetRoot),
|
|
328
|
+
...outsideTestReferences(read.result.outsideTests, one.projectRead.held, targetRoot),
|
|
529
329
|
],
|
|
530
330
|
testFiles: [...one.testFiles, ...outsidePaths],
|
|
531
331
|
}));
|
|
532
332
|
// Test-support code is code only test code imports in any configuration of the run: a
|
|
533
333
|
// configuration that holds no test file says nothing about what the tests import.
|
|
534
|
-
const support = testSupportFiles(withOutside.flatMap((one) => one.projectRead.held.symbols), withOutside.flatMap((one) => one.references), withOutside.flatMap((one) => one.projectRead.rooted.liveUnderReachability), withOutside.flatMap((one) => one.testFiles), testEvidence(host, targetRoot, withOutside));
|
|
535
|
-
|
|
334
|
+
const { support, testUsed } = testSupportFiles(withOutside.flatMap((one) => one.projectRead.held.symbols), withOutside.flatMap((one) => one.references), withOutside.flatMap((one) => one.projectRead.rooted.liveUnderReachability), withOutside.flatMap((one) => one.testFiles), testEvidence(host, targetRoot, withOutside));
|
|
335
|
+
// A member a decode fills or a copy carries is written: a value decoded and sent again carries it on.
|
|
336
|
+
const written = new Set([
|
|
337
|
+
...countedWrites([...withOutside.flatMap((one) => one.references), ...read.result.references], support, mode),
|
|
338
|
+
...withOutside.flatMap((one) => [
|
|
339
|
+
...one.decoded.filled,
|
|
340
|
+
...one.decoded.parsed,
|
|
341
|
+
...one.decoded.copied,
|
|
342
|
+
]),
|
|
343
|
+
]);
|
|
344
|
+
const evidence = withOutside.map((one) => writtenRecords(one.evidence, written));
|
|
345
|
+
const settled = settledSatisfaction(withOutside.map((one, index) => ({
|
|
346
|
+
evidence: evidence[index] ?? [],
|
|
347
|
+
held: one.projectRead.held,
|
|
348
|
+
})), [...withOutside.flatMap((one) => one.references), ...read.result.references]);
|
|
536
349
|
const answers = withOutside.map((one, index) => {
|
|
537
350
|
const { projectRead } = one;
|
|
538
351
|
const satisfied = settled[index];
|
|
539
|
-
const detected = heldRecords(satisfied?.evidence ??
|
|
352
|
+
const detected = heldRecords(satisfied?.evidence ?? evidence[index] ?? [], {
|
|
540
353
|
mode,
|
|
541
354
|
testFiles: new Set([...one.testFiles, ...support]),
|
|
542
355
|
});
|
|
543
356
|
const exempt = detected.records;
|
|
544
357
|
const made = supportReferences([...one.references, ...(satisfied?.references ?? [])], support);
|
|
545
358
|
const held = new Set(projectRead.held.symbols.map((symbol) => symbol.position.path));
|
|
546
|
-
const supportFiles = [...support].filter((path) => held.has(path)).sort();
|
|
359
|
+
const supportFiles = [...support].filter((path) => held.has(path)).sort(bytewise);
|
|
360
|
+
const testUsedFiles = [...testUsed].filter((path) => held.has(path)).sort(bytewise);
|
|
547
361
|
const configured = {
|
|
548
362
|
configuration: projectRead.configuration,
|
|
549
363
|
symbols: projectRead.held.symbols,
|
|
550
364
|
references: [...made, ...evidenceReferences(projectRead.held.symbols, detected.inTestFiles)],
|
|
551
|
-
|
|
365
|
+
// The augmentations are rooted after test support is read: an outside declaration
|
|
366
|
+
// naming one calls nothing of its file.
|
|
367
|
+
roots: [...projectRead.rooted.liveUnderReachability, ...one.augmented],
|
|
552
368
|
testFiles: [...one.testFiles, ...supportFiles],
|
|
553
369
|
...(supportFiles.length === 0 ? {} : { supportFiles }),
|
|
370
|
+
...(testUsedFiles.length === 0 ? {} : { testUsedFiles }),
|
|
554
371
|
...(projectRead.held.ambient.size === 0 ? {} : { ambient: projectRead.held.ambient }),
|
|
555
372
|
...(projectRead.referenceOnly.length === 0
|
|
556
373
|
? {}
|
|
@@ -570,16 +387,19 @@ function readRun(engine, host, scope, config, mode, detectors, extra) {
|
|
|
570
387
|
.filter((reference) => reference.resolution === "by-name")
|
|
571
388
|
.map((reference) => reference.to),
|
|
572
389
|
...exempt.filter(isUnansweredRecord).map((record) => record.id),
|
|
390
|
+
...one.decoded.unanswered,
|
|
573
391
|
],
|
|
392
|
+
filledOutside: one.decoded.filled,
|
|
574
393
|
typeErrorSkips: projectRead.typeErrorSkips,
|
|
575
394
|
unmappedEntries: projectRead.rooted.unmappedEntries,
|
|
395
|
+
heldScripts: projectRead.rooted.heldScripts,
|
|
576
396
|
skipped: projectRead.skipped,
|
|
577
397
|
componentFiles: one.componentFiles,
|
|
578
398
|
componentWarnings: one.componentWarnings,
|
|
579
399
|
extra: one.extra,
|
|
580
400
|
};
|
|
581
401
|
});
|
|
582
|
-
const consumed = read.
|
|
402
|
+
const consumed = read.result.references;
|
|
583
403
|
const projects = answers.map((one) => consumed.length === 0
|
|
584
404
|
? one
|
|
585
405
|
: {
|
|
@@ -599,15 +419,17 @@ function readRun(engine, host, scope, config, mode, detectors, extra) {
|
|
|
599
419
|
]),
|
|
600
420
|
],
|
|
601
421
|
projects,
|
|
602
|
-
consumers: read.consumers
|
|
603
|
-
notBuilt: read.notBuilt,
|
|
422
|
+
consumers: read.plan.discovery.consumers,
|
|
423
|
+
notBuilt: read.classified.notBuilt,
|
|
604
424
|
unanswered: read.unanswered,
|
|
605
|
-
componentsUnread: read.componentsUnread,
|
|
606
|
-
librariesUnfound: read.librariesUnfound,
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
425
|
+
componentsUnread: read.plan.workspace?.componentsUnread ?? [],
|
|
426
|
+
librariesUnfound: read.classified.librariesUnfound,
|
|
427
|
+
unresolvedSpecifiers: read.classified.unresolvedSpecifiers,
|
|
428
|
+
unread: read.plan.unread,
|
|
429
|
+
conventionsApplied: read.plan.conventions.applied,
|
|
430
|
+
conventionUses: read.plan.conventions.uses,
|
|
431
|
+
memberDirs: read.plan.packages.members,
|
|
432
|
+
nestedDirs: read.plan.packages.nested,
|
|
611
433
|
};
|
|
612
434
|
}
|
|
613
435
|
/**
|
|
@@ -660,6 +482,13 @@ function evidenceReferences(symbols, inTestFiles) {
|
|
|
660
482
|
];
|
|
661
483
|
});
|
|
662
484
|
}
|
|
485
|
+
/**
|
|
486
|
+
* The declarations a write the mode counts stores into, a write a test-support file
|
|
487
|
+
* makes being a test's.
|
|
488
|
+
*/
|
|
489
|
+
function countedWrites(references, support, mode) {
|
|
490
|
+
return new Set(supportReferences(references, support).flatMap((reference) => reference.use === "write" && !(mode.production && reference.test) ? [reference.to] : []));
|
|
491
|
+
}
|
|
663
492
|
/**
|
|
664
493
|
* The declarations every reference the mode counts stores into, a loaded consumer's
|
|
665
494
|
* reference counting as a read: what the write-only kind would report but for a record.
|
|
@@ -730,7 +559,7 @@ function sweptOf(read, input) {
|
|
|
730
559
|
unanswered: read.unanswered,
|
|
731
560
|
heldByUnanswered: [...held],
|
|
732
561
|
skipped: read.projects.flatMap((one) => one.skipped),
|
|
733
|
-
componentFiles: [...new Set(read.projects.flatMap((one) => one.componentFiles))].sort(
|
|
562
|
+
componentFiles: [...new Set(read.projects.flatMap((one) => one.componentFiles))].sort(bytewise),
|
|
734
563
|
};
|
|
735
564
|
}
|
|
736
565
|
/**
|
|
@@ -744,6 +573,11 @@ function sweptOf(read, input) {
|
|
|
744
573
|
export function runSweep(engine, host, scope, config, input, detectors = DETECTORS) {
|
|
745
574
|
return sweptOf(readRun(engine, host, scope, config, input.mode, detectors, () => undefined), input);
|
|
746
575
|
}
|
|
576
|
+
/** The project's own files below the target root that are no test file. */
|
|
577
|
+
function productionFiles(project, targetRoot, testFiles) {
|
|
578
|
+
const tests = new Set(testFiles);
|
|
579
|
+
return [...sourceFilesOf(project, targetRoot).byPath].flatMap(([path, file]) => tests.has(path) ? [] : [file]);
|
|
580
|
+
}
|
|
747
581
|
/** Reads a run's projects with every per-project fact an emitter reads. */
|
|
748
582
|
export function readEmitterRun(engine, host, scope, config, mode, detectors) {
|
|
749
583
|
const targetRoot = scope.target.path;
|
|
@@ -759,8 +593,9 @@ export function readEmitterRun(engine, host, scope, config, mode, detectors) {
|
|
|
759
593
|
directives: inlineDirectives(project, read.held, targetRoot).filter((directive) => !read.referenceOnly.includes(directive.site.path)),
|
|
760
594
|
declarationsNamed: declarationsNamed(project, read.held, configuredDeclarations(config)),
|
|
761
595
|
parts: projectParts(project, read.held, references, targetRoot),
|
|
596
|
+
unseenLoads: unseenLoadsOf(project, read.configuration, targetRoot, testFiles),
|
|
762
597
|
}));
|
|
763
|
-
// Whether a declaration carries the marker decides its code, so one whose
|
|
598
|
+
// Whether a declaration carries the marker decides its code, so one whose answer went
|
|
764
599
|
// unread is reported by nothing.
|
|
765
600
|
const unread = run.projects.flatMap((one) => one.extra.deprecation.unanswered);
|
|
766
601
|
return unread.length === 0
|
|
@@ -803,16 +638,11 @@ function judgedMembers(host, targetRoot, read) {
|
|
|
803
638
|
}
|
|
804
639
|
/** The directory of the nearest `package.json` at or above a file, inside `root`, else `root`. */
|
|
805
640
|
function nearestManifestDir(host, root, file) {
|
|
806
|
-
|
|
807
|
-
if (host.kindOf(joinPath(dir, "package.json")) === "file") {
|
|
808
|
-
return dir;
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
return root;
|
|
641
|
+
return ancestors(dirnamePath(file), root).find((dir) => holdsManifest(host, dir)) ?? root;
|
|
812
642
|
}
|
|
813
643
|
/**
|
|
814
644
|
* The input every emitter reads over one sweep of a read run: the facts beside the sweep
|
|
815
|
-
* each
|
|
645
|
+
* each emitter reads, every per-project one read in the same session as the sweep.
|
|
816
646
|
*/
|
|
817
647
|
export function emitterInputOver(host, scope, config, read, input, selfCheck) {
|
|
818
648
|
const targetRoot = scope.target.path;
|
|
@@ -834,6 +664,7 @@ export function emitterInputOver(host, scope, config, read, input, selfCheck) {
|
|
|
834
664
|
heldByInclusion: new Set(projects.flatMap((one) => one.extra.heldByInclusion)),
|
|
835
665
|
generated: new Set(projects.flatMap((one) => one.extra.generated)),
|
|
836
666
|
inOperands: new Set(projects.flatMap((one) => one.extra.inOperands)),
|
|
667
|
+
unseenLoads: projects.flatMap((one) => one.extra.unseenLoads),
|
|
837
668
|
},
|
|
838
669
|
boundary: {
|
|
839
670
|
consumers: {
|
|
@@ -842,6 +673,7 @@ export function emitterInputOver(host, scope, config, read, input, selfCheck) {
|
|
|
842
673
|
},
|
|
843
674
|
encapsulated: readManifest(host, targetRoot).declaresExports,
|
|
844
675
|
edges: readEdgeSides(host, targetRoot),
|
|
676
|
+
filledOutside: new Set(projects.flatMap((one) => one.filledOutside)),
|
|
845
677
|
},
|
|
846
678
|
selfCheck,
|
|
847
679
|
intraFunction: intraFunctionFacts(projects.map((one) => one.extra.parts), projects.flatMap((one) => one.configured.references), new Set([...swept.exempt.map((one) => one.id), ...swept.heldByUnanswered])),
|
|
@@ -852,7 +684,7 @@ export function emitterInputOver(host, scope, config, read, input, selfCheck) {
|
|
|
852
684
|
* directives, the ignore file's entries and the baseline's rows are bound before any
|
|
853
685
|
* sweep, and the run is swept once under every bound record's mark and once under none,
|
|
854
686
|
* so a record is decided against the finding its code would have produced. The
|
|
855
|
-
*
|
|
687
|
+
* configuration family reports the refused suppressions and the roots that named nothing.
|
|
856
688
|
* Beside the inputs it answers the projects and test-file rules a report names.
|
|
857
689
|
*/
|
|
858
690
|
function readAnalysis(engine, host, scope, config, provenance, mode, detectors) {
|
|
@@ -870,7 +702,7 @@ function readAnalysis(engine, host, scope, config, provenance, mode, detectors)
|
|
|
870
702
|
id: one.configured.configuration,
|
|
871
703
|
configFile: one.configFile,
|
|
872
704
|
})),
|
|
873
|
-
testFileRules: testFileRulesOf(config.ts.
|
|
705
|
+
testFileRules: testFileRulesOf(config.ts.test_files, read.projects.flatMap((one) => one.configured.testFiles), read.projects.flatMap((one) => one.configured.supportFiles ?? [])),
|
|
874
706
|
typeErrorSkips: read.projects.flatMap((one) => one.typeErrorSkips),
|
|
875
707
|
componentWarnings: [
|
|
876
708
|
...new Map(read.projects
|
|
@@ -882,8 +714,12 @@ function readAnalysis(engine, host, scope, config, provenance, mode, detectors)
|
|
|
882
714
|
unanswered: read.unanswered,
|
|
883
715
|
componentsUnread: read.componentsUnread,
|
|
884
716
|
librariesUnfound: read.librariesUnfound,
|
|
717
|
+
unresolvedSpecifiers: read.unresolvedSpecifiers,
|
|
718
|
+
unread: read.unread,
|
|
885
719
|
conventionsApplied: read.conventionsApplied,
|
|
886
720
|
unmappedEntries: unmappedEverywhere(read.projects),
|
|
721
|
+
heldScripts: read.projects.flatMap((one) => one.heldScripts.map((held) => ({ ...held, configFile: one.configFile }))),
|
|
722
|
+
unseenLoads: read.projects.flatMap((one) => one.extra.unseenLoads),
|
|
887
723
|
},
|
|
888
724
|
configured: read.projects.map((one) => one.configured),
|
|
889
725
|
symbols,
|
|
@@ -899,7 +735,7 @@ function inputsOver(host, scope, config, provenance, mode, read, documents) {
|
|
|
899
735
|
};
|
|
900
736
|
const facts = {
|
|
901
737
|
refusals: suppressions.refusals,
|
|
902
|
-
unmatchedRoots: unmatchedEverywhere(config.
|
|
738
|
+
unmatchedRoots: unmatchedEverywhere(config.roots.patterns, read.projects.map((one) => one.extra.rooted)),
|
|
903
739
|
rootsDocument: documentOf(host, provenance, ROOTS_SETTING, targetRoot),
|
|
904
740
|
unmatchedDeclarations: configuredDeclarations(config)
|
|
905
741
|
.filter((_, at) => !read.projects.some((one) => one.extra.declarationsNamed[at] === true))
|
|
@@ -935,7 +771,7 @@ function unmappedEverywhere(projects) {
|
|
|
935
771
|
}
|
|
936
772
|
/**
|
|
937
773
|
* The analysis of the run the scope and the configuration describe: the run read with its
|
|
938
|
-
* suppressions bound, every
|
|
774
|
+
* suppressions bound, every emitter's findings with the suppressions applied and the
|
|
939
775
|
* declared edges evaluated, the projects and test-file rules the report names, and the sweep
|
|
940
776
|
* an explanation reads.
|
|
941
777
|
*/
|
|
@@ -946,12 +782,16 @@ export function runAnalysis(engine, host, scope, config, provenance, mode, detec
|
|
|
946
782
|
}
|
|
947
783
|
/**
|
|
948
784
|
* One count per configuration of the run in which the checker left a question unanswered:
|
|
949
|
-
* the questions asked in its project,
|
|
785
|
+
* the questions asked in its project, a formed program's manifest that does not parse or cannot
|
|
786
|
+
* be read and a package whose command strings name files the project holds each counted as one, and the
|
|
787
|
+
* declarations of its own the run holds for them.
|
|
950
788
|
*/
|
|
951
789
|
export function unansweredCounts(analysis) {
|
|
952
790
|
const held = new Set(analysis.swept.heldByUnanswered);
|
|
953
791
|
return analysis.run.projects.flatMap((project) => {
|
|
954
|
-
const questions = analysis.run.unanswered.filter((one) => one.configFile === project.configFile).length
|
|
792
|
+
const questions = analysis.run.unanswered.filter((one) => one.configFile === project.configFile).length +
|
|
793
|
+
analysis.run.unread.filter((one) => one.kind === "manifest" && one.configFile === project.configFile).length +
|
|
794
|
+
analysis.run.heldScripts.filter((one) => one.configFile === project.configFile).length;
|
|
955
795
|
if (questions === 0) {
|
|
956
796
|
return [];
|
|
957
797
|
}
|