@cplieger/deadset-ts 8.0.0-dev.2 → 8.0.0-dev.20
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 +3 -1
- package/THIRD_PARTY_NOTICES.md +27 -0
- package/dist/bin/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/alias-chain.js +2 -7
- package/dist/src/amd.js +81 -0
- package/dist/src/analysis.js +269 -432
- package/dist/src/augmentations.js +64 -3
- package/dist/src/automatic-types.js +10 -29
- package/dist/src/bindings.js +382 -0
- package/dist/src/calls.js +279 -43
- package/dist/src/commands/held.js +499 -0
- package/dist/src/commands/read.js +161 -0
- package/dist/src/commands/shell.js +169 -0
- package/dist/src/commands/tools.js +1847 -0
- package/dist/src/component-files.js +3 -2
- package/dist/src/component-layer.js +4 -2
- package/dist/src/config.js +6 -82
- package/dist/src/conformance-record.js +1 -1
- package/dist/src/consumers.js +10 -38
- package/dist/src/contextual-uses.js +57 -26
- package/dist/src/contract/config.generated.js +561 -0
- package/dist/src/contract/contract.generated.js +1369 -0
- package/dist/src/contract/report.generated.js +866 -0
- package/dist/src/dependencies.js +164 -121
- package/dist/src/destructuring.js +1 -19
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +181 -168
- package/dist/src/entries/build-scripts.js +222 -0
- package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
- package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
- package/dist/src/entries/conventions.js +740 -0
- package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
- package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
- 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 +650 -0
- package/dist/src/entries/workflow-steps.js +345 -0
- 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 -66
- package/dist/src/exposure.js +400 -0
- package/dist/src/extensions.js +37 -0
- package/dist/src/facts.js +38 -0
- package/dist/src/failure.js +36 -0
- package/dist/src/file-facts.js +3 -26
- package/dist/src/findings/completion.js +109 -56
- package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
- package/dist/src/findings/emitters.js +27 -41
- package/dist/src/{implementations.js → findings/implementations.js} +3 -3
- package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +16 -13
- package/dist/src/findings/non-code-artifacts.js +17 -12
- package/dist/src/findings/reads-and-writes.js +86 -27
- package/dist/src/findings/self-check.js +44 -30
- package/dist/src/findings/unused-declarations.js +29 -45
- package/dist/src/findings/visibility-narrowing.js +23 -31
- package/dist/src/findings-pass.js +13 -21
- package/dist/src/framework-lifecycle.js +46 -19
- package/dist/src/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +67 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/generated-file.js +174 -28
- package/dist/src/git-ignore.js +39 -26
- package/dist/src/import-bindings.js +73 -28
- package/dist/src/index/sites.js +557 -0
- package/dist/src/index.js +2 -2
- package/dist/src/indexed-access.js +523 -478
- package/dist/src/injection-container.js +2 -2
- package/dist/src/interface-satisfaction.js +1 -1
- package/dist/src/intra-function-parts.js +63 -43
- package/dist/src/inventory/commonjs.js +507 -0
- package/dist/src/inventory/enumerate.js +167 -0
- package/dist/src/inventory/syntax.js +236 -0
- package/dist/src/inventory.js +323 -724
- package/dist/src/javascript-file.js +48 -0
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +126 -107
- package/dist/src/kinds.js +3 -366
- package/dist/src/{components.js → liveness/components.js} +2 -3
- package/dist/src/{graph.js → liveness/graph.js} +52 -28
- package/dist/src/liveness/matrix.js +99 -0
- package/dist/src/liveness/sweep.js +558 -0
- package/dist/src/load/classify.js +289 -0
- package/dist/src/load/diagnostics.js +87 -0
- package/dist/src/load/discover.js +285 -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/package-scope.js +56 -0
- package/dist/src/load/plan.js +313 -0
- package/dist/src/load/specifiers.js +113 -0
- package/dist/src/load/synthesize.js +152 -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} +24 -66
- 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/module-declarations.js +70 -85
- package/dist/src/overrides.js +134 -112
- package/dist/src/partial.js +2 -1
- package/dist/src/paths.js +82 -16
- package/dist/src/platform-calls.js +78 -0
- package/dist/src/platform-symbols.js +134 -0
- package/dist/src/position.js +43 -1
- package/dist/src/print.js +11 -79
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +47 -0
- package/dist/src/ref.js +12 -20
- package/dist/src/references/read-rule.js +1 -0
- package/dist/src/references/read-rules.js +48 -0
- package/dist/src/references/sink.js +237 -0
- package/dist/src/references/sources.js +450 -0
- package/dist/src/references.js +117 -1074
- 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 +246 -730
- package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
- package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
- package/dist/src/roots/manifest.js +216 -0
- package/dist/src/roots/published-reach.js +412 -0
- package/dist/src/roots/root-set.js +487 -0
- package/dist/src/roots/unseen-loads.js +236 -0
- 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 +601 -22
- package/dist/src/session.js +37 -29
- package/dist/src/source-files.js +6 -10
- package/dist/src/stores.js +4 -2
- package/dist/src/suppress-file.js +25 -28
- package/dist/src/suppress-inline.js +36 -83
- package/dist/src/suppress.js +50 -71
- package/dist/src/symbol-keys.js +92 -88
- package/dist/src/template-field.js +9 -19
- 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/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/named-files.js +298 -0
- package/dist/src/text/yaml.js +684 -0
- package/dist/src/type-errors.js +11 -232
- package/dist/src/type-parameter-reads.js +178 -139
- package/dist/src/unimplemented-callees.js +262 -242
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/vendor/unbash/ansi-c.js +132 -0
- package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
- package/dist/src/vendor/unbash/arithmetic.js +591 -0
- package/dist/src/vendor/unbash/assignment.js +131 -0
- package/dist/src/vendor/unbash/chars.js +48 -0
- package/dist/src/vendor/unbash/command.js +41 -0
- package/dist/src/vendor/unbash/expansion.js +80 -0
- package/dist/src/vendor/unbash/glob.js +268 -0
- package/dist/src/vendor/unbash/heredoc.js +27 -0
- package/dist/src/vendor/unbash/internal-types.js +1 -0
- package/dist/src/vendor/unbash/lexer.js +4274 -0
- package/dist/src/vendor/unbash/limits.js +3 -0
- package/dist/src/vendor/unbash/parser.js +1366 -0
- package/dist/src/vendor/unbash/parts.js +57 -0
- package/dist/src/vendor/unbash/substitution-context.js +8 -0
- package/dist/src/vendor/unbash/traversal.js +212 -0
- package/dist/src/vendor/unbash/types.js +1 -0
- package/dist/src/vendor/unbash/word-value.js +61 -0
- package/dist/src/vendor/unbash/word.js +40 -0
- package/dist/src/verbs/analyze.js +194 -127
- package/dist/src/verbs/describe.js +13 -18
- package/dist/src/verbs/explain.js +85 -139
- 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 +7 -5
- 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/jsr.json +2 -1
- package/package.json +14 -8
- package/src/alias-chain.ts +2 -9
- package/src/amd.ts +130 -0
- package/src/analysis.ts +424 -650
- package/src/augmentations.ts +93 -4
- package/src/automatic-types.ts +12 -30
- package/src/bindings.ts +460 -0
- package/src/calls.ts +338 -46
- package/src/commands/held.ts +632 -0
- package/src/commands/read.ts +242 -0
- package/src/commands/shell.ts +228 -0
- package/src/commands/tools.ts +2382 -0
- package/src/component-files.ts +4 -2
- package/src/component-layer.ts +4 -2
- package/src/config.ts +31 -302
- package/src/conformance-record.ts +1 -1
- package/src/consumers.ts +16 -66
- package/src/contextual-uses.ts +66 -34
- package/src/contract/config.generated.ts +821 -0
- package/src/contract/contract.generated.ts +1452 -0
- package/src/contract/report.generated.ts +1241 -0
- package/src/dependencies.ts +222 -127
- package/src/destructuring.ts +1 -31
- package/src/edges.ts +41 -140
- package/src/element-access.ts +190 -187
- package/src/entries/build-scripts.ts +292 -0
- package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
- package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
- package/src/{conventions.ts → entries/conventions.ts} +367 -583
- package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
- package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
- 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 +835 -0
- package/src/entries/workflow-steps.ts +432 -0
- 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 +70 -98
- package/src/exposure.ts +492 -0
- package/src/extensions.ts +45 -0
- package/src/facts.ts +46 -0
- package/src/failure.ts +63 -0
- package/src/file-facts.ts +15 -25
- package/src/finding.ts +10 -10
- package/src/findings/boundary.ts +11 -0
- package/src/findings/completion.ts +133 -64
- package/src/findings/dependencies-and-module-machinery.ts +4 -7
- package/src/findings/emitter.ts +9 -10
- package/src/findings/emitters.ts +38 -52
- package/src/{implementations.ts → findings/implementations.ts} +4 -4
- package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
- package/src/findings/interfaces.ts +7 -9
- package/src/findings/intra-function.ts +16 -14
- package/src/findings/non-code-artifacts.ts +24 -15
- package/src/findings/reads-and-writes.ts +118 -41
- package/src/findings/self-check.ts +51 -38
- package/src/findings/unused-declarations.ts +31 -49
- package/src/findings/visibility-narrowing.ts +36 -40
- package/src/findings-pass.ts +15 -31
- package/src/framework-lifecycle.ts +47 -19
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +96 -0
- package/src/fs/tree.ts +110 -0
- package/src/generated-file.ts +242 -35
- package/src/git-ignore.ts +50 -26
- package/src/host.ts +12 -5
- package/src/import-bindings.ts +98 -29
- package/src/index/sites.ts +781 -0
- package/src/index.ts +2 -2
- package/src/indexed-access.ts +570 -527
- package/src/injection-container.ts +2 -2
- package/src/interface-satisfaction.ts +2 -2
- package/src/intra-function-parts.ts +73 -44
- package/src/inventory/commonjs.ts +696 -0
- package/src/inventory/enumerate.ts +203 -0
- package/src/inventory/syntax.ts +311 -0
- package/src/inventory.ts +442 -895
- package/src/javascript-file.ts +54 -0
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +133 -122
- package/src/kinds.ts +5 -413
- package/src/{components.ts → liveness/components.ts} +4 -6
- package/src/{graph.ts → liveness/graph.ts} +100 -35
- package/src/liveness/matrix.ts +162 -0
- package/src/liveness/sweep.ts +855 -0
- package/src/load/classify.ts +433 -0
- package/src/load/diagnostics.ts +154 -0
- package/src/load/discover.ts +471 -0
- package/src/{emit-map.ts → load/emit-map.ts} +1 -1
- package/src/load/expected-module.ts +194 -0
- package/src/load/load.ts +73 -0
- package/src/load/module-lookup.ts +50 -0
- package/src/load/package-scope.ts +74 -0
- package/src/load/plan.ts +513 -0
- package/src/load/specifiers.ts +171 -0
- package/src/load/synthesize.ts +230 -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} +41 -77
- package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
- package/src/{workspace.ts → load/workspace.ts} +90 -134
- package/src/module-declarations.ts +74 -98
- package/src/overrides.ts +162 -134
- package/src/partial.ts +3 -2
- package/src/paths.ts +92 -16
- package/src/platform-calls.ts +119 -0
- package/src/platform-symbols.ts +189 -0
- package/src/position.ts +44 -1
- package/src/print.ts +12 -92
- package/src/product.ts +18 -0
- package/src/query.ts +92 -0
- package/src/ref.ts +12 -20
- package/src/references/read-rule.ts +60 -0
- package/src/references/read-rules.ts +55 -0
- package/src/references/sink.ts +314 -0
- package/src/references/sources.ts +632 -0
- package/src/references.ts +187 -1450
- package/src/report-schema.ts +68 -0
- package/src/report.ts +103 -226
- 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 +284 -1115
- package/src/{configured-declarations.ts → roots/configured-declarations.ts} +27 -29
- package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
- package/src/roots/manifest.ts +303 -0
- package/src/roots/published-reach.ts +486 -0
- package/src/{roots.ts → roots/root-set.ts} +286 -469
- package/src/roots/unseen-loads.ts +345 -0
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -388
- package/src/scope.ts +46 -138
- package/src/serialization-contract.ts +769 -23
- package/src/session.ts +87 -55
- package/src/source-files.ts +6 -11
- package/src/stores.ts +15 -3
- package/src/suppress-file.ts +24 -33
- package/src/suppress-inline.ts +55 -91
- package/src/suppress.ts +78 -79
- package/src/symbol-keys.ts +104 -107
- package/src/template-field.ts +15 -25
- package/src/tests/file-class.ts +135 -0
- package/src/{outside-tests.ts → tests/outside.ts} +16 -10
- package/src/{test-support.ts → tests/support.ts} +15 -21
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/named-files.ts +388 -0
- package/src/text/yaml.ts +747 -0
- package/src/type-errors.ts +18 -288
- package/src/type-parameter-reads.ts +187 -158
- package/src/unimplemented-callees.ts +297 -280
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/vendor/unbash/LICENSE +15 -0
- package/src/vendor/unbash/VENDORED.md +16 -0
- package/src/vendor/unbash/ansi-c.ts +132 -0
- package/src/vendor/unbash/arithmetic-parts.ts +53 -0
- package/src/vendor/unbash/arithmetic.ts +641 -0
- package/src/vendor/unbash/assignment.ts +163 -0
- package/src/vendor/unbash/chars.ts +48 -0
- package/src/vendor/unbash/command.ts +47 -0
- package/src/vendor/unbash/expansion.ts +144 -0
- package/src/vendor/unbash/glob.ts +284 -0
- package/src/vendor/unbash/heredoc.ts +34 -0
- package/src/vendor/unbash/internal-types.ts +94 -0
- package/src/vendor/unbash/lexer.ts +4352 -0
- package/src/vendor/unbash/limits.ts +3 -0
- package/src/vendor/unbash/parser.ts +1612 -0
- package/src/vendor/unbash/parts.ts +96 -0
- package/src/vendor/unbash/substitution-context.ts +20 -0
- package/src/vendor/unbash/traversal.ts +182 -0
- package/src/vendor/unbash/types.ts +660 -0
- package/src/vendor/unbash/word-value.ts +64 -0
- package/src/vendor/unbash/word.ts +50 -0
- package/src/verbs/analyze.ts +255 -164
- package/src/verbs/describe.ts +19 -17
- package/src/verbs/explain.ts +93 -169
- package/src/verbs/print-config.ts +2 -1
- package/src/verbs/print-projects.ts +6 -4
- package/src/verbs/print-retained.ts +7 -5
- package/src/verbs/print-roots.ts +4 -2
- package/src/verbs/verb.ts +2 -8
- package/src/verbs/version.ts +15 -3
- package/dist/src/base-url.js +0 -18
- package/dist/src/conventions.js +0 -937
- package/dist/src/discover.js +0 -468
- package/dist/src/entry-points.js +0 -529
- package/dist/src/glob.js +0 -65
- package/dist/src/manifest.js +0 -165
- package/dist/src/matrix.js +0 -246
- package/dist/src/pnpm-workspace.js +0 -120
- package/dist/src/roots.js +0 -672
- package/dist/src/setup-failure.js +0 -23
- package/dist/src/sweep.js +0 -224
- package/dist/src/test-joins.js +0 -101
- package/dist/src/version.js +0 -7
- package/dist/src/workflow-steps.js +0 -185
- package/src/base-url.ts +0 -24
- package/src/discover.ts +0 -653
- package/src/entry-points.ts +0 -687
- package/src/glob.ts +0 -67
- package/src/manifest.ts +0 -234
- package/src/matrix.ts +0 -423
- package/src/pnpm-workspace.ts +0 -135
- package/src/setup-failure.ts +0 -39
- package/src/sweep.ts +0 -347
- package/src/test-joins.ts +0 -120
- package/src/version.ts +0 -7
- package/src/workflow-steps.ts +0 -216
package/src/analysis.ts
CHANGED
|
@@ -6,131 +6,107 @@
|
|
|
6
6
|
* another project's checker, which holds only for views the session hands out.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { isStringLiteralLikeNode } from "@typescript/native/ast";
|
|
9
|
+
import { isStringLiteralLikeNode, type SourceFile } from "@typescript/native/ast";
|
|
10
10
|
import { lineOf, readComponent } from "./component-files.ts";
|
|
11
|
-
import { kindOf, type
|
|
12
|
-
import {
|
|
13
|
-
consumerLoads,
|
|
14
|
-
consumerReferences,
|
|
15
|
-
moduleIdentity,
|
|
16
|
-
type LoadedConsumer,
|
|
17
|
-
} from "./consumers.ts";
|
|
11
|
+
import { kindOf, type PartialConfig, type Provenance, type ResolvedConfig } from "./config.ts";
|
|
12
|
+
import { consumerReferences } from "./consumers.ts";
|
|
18
13
|
import {
|
|
19
14
|
configuredDeclarations,
|
|
20
15
|
configuredRef,
|
|
21
16
|
declarationsNamed,
|
|
22
|
-
} from "./configured-declarations.ts";
|
|
17
|
+
} from "./roots/configured-declarations.ts";
|
|
23
18
|
import { decorator } from "./decorator.ts";
|
|
24
19
|
import { configurationNeeds, dependenciesOf, projectNeeds } from "./dependencies.ts";
|
|
20
|
+
import { carriersOf, NO_CARRIERS, type Carriers } from "./exposure.ts";
|
|
25
21
|
import { deprecatedDeclarations, type Deprecation } from "./deprecation.ts";
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
renderDiagnostic,
|
|
33
|
-
targetRelative,
|
|
34
|
-
withBaseUrlPaths,
|
|
35
|
-
type LocatedDiagnostic,
|
|
36
|
-
type NotBuilt,
|
|
37
|
-
} from "./discover.ts";
|
|
38
|
-
import {
|
|
39
|
-
conventionFailuresFor,
|
|
40
|
-
generatedFiles,
|
|
41
|
-
readConventions,
|
|
42
|
-
type AppliedConvention,
|
|
43
|
-
type ConventionManifest,
|
|
44
|
-
type Conventions,
|
|
45
|
-
} from "./conventions.ts";
|
|
22
|
+
import { moduleIdentity, type LoadedConsumer, type NotBuilt } from "./load/discover.ts";
|
|
23
|
+
import type { LibraryUnfound } from "./load/classify.ts";
|
|
24
|
+
import { loadRun, type LoadedRun } from "./load/load.ts";
|
|
25
|
+
import type { AppliedConvention } from "./entries/conventions.ts";
|
|
26
|
+
import { readSources, type SourceFacts } from "./entries/sources.ts";
|
|
27
|
+
import { readWorkflows, type Workflows } from "./entries/workflow-steps.ts";
|
|
46
28
|
import { readEdgeSides } from "./edges.ts";
|
|
47
29
|
import { enumGroup } from "./enum-group.ts";
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
30
|
+
import { bindingsOf, distinctBindings, type BindingRecord } from "./bindings.ts";
|
|
31
|
+
import { generatedFile, generatedFilesOf, type GeneratedFact } from "./generated-file.ts";
|
|
32
|
+
import { inOperandNames } from "./findings/in-operands.ts";
|
|
50
33
|
import { sourceFilesOf } from "./source-files.ts";
|
|
51
34
|
import {
|
|
52
35
|
evidenceRecords,
|
|
53
36
|
heldRecords,
|
|
54
37
|
disabledClasses,
|
|
55
38
|
exemptionsOf,
|
|
56
|
-
holdingWhile,
|
|
57
39
|
isUnansweredRecord,
|
|
58
|
-
|
|
40
|
+
writtenRecords,
|
|
59
41
|
type Detector,
|
|
60
42
|
type Detectors,
|
|
61
43
|
} from "./exempt.ts";
|
|
62
44
|
import type { TSExemptionClass } from "./exempt-classes.ts";
|
|
63
45
|
import { heldByInclusion, sourcePaths, sourceTree } from "./file-facts.ts";
|
|
64
|
-
import { globExpression } from "./glob.ts";
|
|
65
46
|
import type { Finding } from "./finding.ts";
|
|
66
47
|
import { findingsPass, recordedFindings, rowKey, type PassResult } from "./findings-pass.ts";
|
|
67
48
|
import type { EmitterInput } from "./findings/emitter.ts";
|
|
68
49
|
import { unmatchedRootFindings, type SelfCheckFacts } from "./findings/self-check.ts";
|
|
69
50
|
import { frameworkLifecycle } from "./framework-lifecycle.ts";
|
|
70
51
|
import type { Host } from "./host.ts";
|
|
71
|
-
import { implementations, mergeImplementations } from "./implementations.ts";
|
|
52
|
+
import { implementations, mergeImplementations } from "./findings/implementations.ts";
|
|
72
53
|
import { injectionContainer } from "./injection-container.ts";
|
|
73
54
|
import { interfaceSatisfaction, settledSatisfaction } from "./interface-satisfaction.ts";
|
|
74
55
|
import { intraFunctionFacts, projectParts, type ProjectParts } from "./intra-function-parts.ts";
|
|
75
|
-
import {
|
|
76
|
-
import {
|
|
77
|
-
import {
|
|
78
|
-
|
|
79
|
-
matrixOf,
|
|
80
|
-
referenceKey,
|
|
81
|
-
sweepMatrix,
|
|
82
|
-
type Configured,
|
|
83
|
-
type Matrix,
|
|
84
|
-
type SweepResult,
|
|
85
|
-
} from "./matrix.ts";
|
|
56
|
+
import { type Inventory, type InventorySymbol } from "./inventory.ts";
|
|
57
|
+
import { inventory } from "./inventory/enumerate.ts";
|
|
58
|
+
import { readManifest, type ManifestEntry } from "./roots/manifest.ts";
|
|
59
|
+
import { matrixOf, referenceKey, type Configured, type Matrix } from "./liveness/matrix.ts";
|
|
86
60
|
import {
|
|
61
|
+
ancestors,
|
|
87
62
|
dirnamePath,
|
|
88
63
|
extensionOf,
|
|
89
64
|
joinPath,
|
|
90
|
-
normalizePath,
|
|
91
65
|
relativePath,
|
|
92
66
|
resolvePath,
|
|
93
67
|
} from "./paths.ts";
|
|
94
68
|
import type { UnansweredQuestion } from "./query.ts";
|
|
95
69
|
import { byPosition, isComponentFile, type Position } from "./position.ts";
|
|
96
|
-
import {
|
|
97
|
-
import {
|
|
98
|
-
import {
|
|
99
|
-
pathsOf,
|
|
100
|
-
readErrors,
|
|
101
|
-
skippedRoots,
|
|
102
|
-
skippedUnits,
|
|
103
|
-
type SkippedUnit,
|
|
104
|
-
} from "./type-errors.ts";
|
|
70
|
+
import type { TypeErrorSkip, UnansweredCount } from "./report.ts";
|
|
71
|
+
import { skippedUnits, type SkippedUnit } from "./type-errors.ts";
|
|
105
72
|
import { reflectiveLookup } from "./reflective-lookup.ts";
|
|
106
|
-
import { references,
|
|
73
|
+
import { references, type Reference } from "./references.ts";
|
|
107
74
|
import {
|
|
108
|
-
|
|
75
|
+
rootSet,
|
|
109
76
|
unmatchedEverywhere,
|
|
110
77
|
type RootKind,
|
|
111
|
-
type RootOptions,
|
|
112
78
|
type Roots,
|
|
113
|
-
|
|
79
|
+
type HeldScripts,
|
|
80
|
+
} from "./roots/root-set.ts";
|
|
114
81
|
import type { Scope } from "./scope.ts";
|
|
115
|
-
import { serializationContract } from "./serialization-contract.ts";
|
|
116
|
-
import { outsideTestReferences, testFilesAt, type OutsideTest } from "./outside
|
|
117
|
-
import {
|
|
118
|
-
import {
|
|
82
|
+
import { decodedMembers, serializationContract, type Decoded } from "./serialization-contract.ts";
|
|
83
|
+
import { outsideTestReferences, testFilesAt, type OutsideTest } from "./tests/outside.ts";
|
|
84
|
+
import type { UnseenLoad } from "./roots/unseen-loads.ts";
|
|
85
|
+
import type { UnresolvedSpecifier } from "./load/specifiers.ts";
|
|
86
|
+
import { formedForNode } from "./load/synthesize.ts";
|
|
87
|
+
import type { UnreadInput } from "./load/plan.ts";
|
|
88
|
+
import { GLOBALS_RUNNER, namesTestGlobals } from "./load/test-globals.ts";
|
|
119
89
|
import {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
type
|
|
125
|
-
|
|
126
|
-
} from "./
|
|
90
|
+
targetTestFile,
|
|
91
|
+
testFilePaths,
|
|
92
|
+
testFileRulesOf,
|
|
93
|
+
withheldBy,
|
|
94
|
+
type TestFileRule,
|
|
95
|
+
} from "./tests/file-class.ts";
|
|
96
|
+
import { testSupportFiles, type TestEvidence } from "./tests/support.ts";
|
|
97
|
+
import type { Engine, ProjectView } from "./session.ts";
|
|
127
98
|
import { accessorsOf, storesOf } from "./stores.ts";
|
|
128
99
|
import { isPartKind, type SuppressionRecord, type Suppressions, type Verdict } from "./suppress.ts";
|
|
129
100
|
import { bindRows, readBaseline, readIgnoreFile, type Recorded } from "./suppress-file.ts";
|
|
130
101
|
import { inlineDirectives, inlineSuppressions, type InlineDirective } from "./suppress-inline.ts";
|
|
131
|
-
import
|
|
102
|
+
import { sweep, type Sweep, type SweepPolicy } from "./liveness/sweep.ts";
|
|
103
|
+
import type { Exemption } from "./exempt.ts";
|
|
104
|
+
import type { Mode } from "./tests/file-class.ts";
|
|
132
105
|
import { readTemplates, templateField } from "./template-field.ts";
|
|
133
|
-
import {
|
|
106
|
+
import { bytewise } from "./text/compare.ts";
|
|
107
|
+
import { holdsManifest, manifestAt } from "./fs/manifest.ts";
|
|
108
|
+
import { runDirectories } from "./entries/run-directories.ts";
|
|
109
|
+
import { globExpression } from "./text/glob.ts";
|
|
134
110
|
|
|
135
111
|
/** The setting whose source decides where a finding about a configured root sits. */
|
|
136
112
|
const ROOTS_SETTING = "roots.patterns";
|
|
@@ -187,14 +163,6 @@ function documentOf(
|
|
|
187
163
|
return relativePath(resolvePath(host.workingDirectory(), targetRoot), document) ?? "";
|
|
188
164
|
}
|
|
189
165
|
|
|
190
|
-
/** Two strings ordered bytewise. */
|
|
191
|
-
function compare(a: string, b: string): number {
|
|
192
|
-
if (a === b) {
|
|
193
|
-
return 0;
|
|
194
|
-
}
|
|
195
|
-
return a < b ? -1 : 1;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
166
|
/** What every stage after the root set reads of one project. */
|
|
199
167
|
interface ProjectRead {
|
|
200
168
|
readonly configuration: string;
|
|
@@ -211,10 +179,14 @@ interface ProjectRead {
|
|
|
211
179
|
readonly typeErrorSkips: readonly TypeErrorSkip[];
|
|
212
180
|
/** The lines each of those skips withholds every finding on. */
|
|
213
181
|
readonly skipped: readonly SkippedUnit[];
|
|
214
|
-
/** The project's generated files, by path below the target root, each with
|
|
215
|
-
readonly generated: ReadonlyMap<string,
|
|
216
|
-
/** The
|
|
217
|
-
readonly
|
|
182
|
+
/** The project's generated files, by path below the target root, each with what decided it. */
|
|
183
|
+
readonly generated: ReadonlyMap<string, GeneratedFact>;
|
|
184
|
+
/** The binding identities its generated files publish (`bindings.6`, `bindings.7`). */
|
|
185
|
+
readonly bindings: readonly BindingRecord[];
|
|
186
|
+
/** What the project's entry sources enter and name, read once. */
|
|
187
|
+
readonly sources: SourceFacts;
|
|
188
|
+
/** Whether the run formed the program to resolve its modules as Node does (program.36). */
|
|
189
|
+
readonly formedForNode: boolean;
|
|
218
190
|
}
|
|
219
191
|
|
|
220
192
|
/** One target project the run analyzes, as its stage is handed it. */
|
|
@@ -224,346 +196,67 @@ interface OpenedProject {
|
|
|
224
196
|
readonly read: () => ProjectRead;
|
|
225
197
|
}
|
|
226
198
|
|
|
227
|
-
/** What a run
|
|
228
|
-
interface
|
|
229
|
-
|
|
230
|
-
readonly loaded: readonly LoadedConsumer[];
|
|
199
|
+
/** What reading a loaded run's projects answered. */
|
|
200
|
+
interface ProjectsRead<Answer> {
|
|
201
|
+
readonly answers: readonly Answer[];
|
|
231
202
|
/** Every reference a consumer makes to a declaration of the target, each once. */
|
|
232
203
|
readonly references: readonly Reference[];
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
/** What a run read of its projects: each target project's answer, and its consumers. */
|
|
236
|
-
interface ReadProjects<Answer> {
|
|
237
|
-
readonly answers: readonly Answer[];
|
|
238
|
-
readonly consumers: ConsumerReads;
|
|
239
|
-
/** The derived configurations the run dropped, in the order it met them. */
|
|
240
|
-
readonly notBuilt: readonly NotBuilt[];
|
|
241
|
-
/** Every question the checker could not answer, each once. */
|
|
242
|
-
readonly unanswered: readonly UnansweredQuestion[];
|
|
243
|
-
/** Per configuration whose component files the run cannot read, the reason. */
|
|
244
|
-
readonly componentsUnread: readonly ComponentsUnread[];
|
|
245
|
-
/** Per analyzed configuration, each library it names that the compiler cannot find. */
|
|
246
|
-
readonly librariesUnfound: readonly LibraryUnfound[];
|
|
247
|
-
/** The convention rows the run applied. */
|
|
248
|
-
readonly conventionsApplied: readonly AppliedConvention[];
|
|
249
|
-
/** The dependencies the applied rows' short names use. */
|
|
250
|
-
readonly conventionUses: readonly string[];
|
|
251
|
-
/** The directory of every workspace member, absolute. */
|
|
252
|
-
readonly memberDirs: readonly string[];
|
|
253
|
-
/** The directory of every nested package, absolute. */
|
|
254
|
-
readonly nestedDirs: readonly string[];
|
|
204
|
+
/** The declarations a consumer's read rules held, each once. */
|
|
205
|
+
readonly consumerHeld: readonly string[];
|
|
255
206
|
/** The test files below the target root no project the run reads holds, parsed. */
|
|
256
207
|
readonly outsideTests: readonly OutsideTest[];
|
|
208
|
+
/** The target root's workflow steps, git hooks and makefile, read once for every project. */
|
|
209
|
+
readonly workflows: Workflows;
|
|
257
210
|
}
|
|
258
211
|
|
|
259
212
|
/**
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
|
|
263
|
-
function conventionManifests(
|
|
264
|
-
host: Host,
|
|
265
|
-
targetRoot: string,
|
|
266
|
-
memberDirs: readonly string[],
|
|
267
|
-
nestedDirs: readonly string[],
|
|
268
|
-
): readonly ConventionManifest[] {
|
|
269
|
-
const found = new Map<string, ConventionManifest>();
|
|
270
|
-
if (host.kindOf(joinPath(targetRoot, "package.json")) === "file") {
|
|
271
|
-
found.set(targetRoot, { dir: targetRoot, path: "package.json" });
|
|
272
|
-
}
|
|
273
|
-
for (const [dirs, nested] of [
|
|
274
|
-
[memberDirs, false],
|
|
275
|
-
[nestedDirs, true],
|
|
276
|
-
] as const) {
|
|
277
|
-
for (const dir of dirs) {
|
|
278
|
-
const below = relativePath(targetRoot, dir);
|
|
279
|
-
if (below !== undefined && !found.has(dir)) {
|
|
280
|
-
found.set(dir, { dir, path: `${below}/package.json`, nested });
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
return [...found.values()];
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* The nested packages of a run: each directory below the target root, in no `node_modules`
|
|
289
|
-
* directory and none of `known`, that holds a `package.json` and lies at or above one of
|
|
290
|
-
* `files`, the program's source files and the compiler configuration files, in path order.
|
|
291
|
-
*/
|
|
292
|
-
function nestedPackageDirs(
|
|
293
|
-
host: Host,
|
|
294
|
-
targetRoot: string,
|
|
295
|
-
files: Iterable<string>,
|
|
296
|
-
known: ReadonlySet<string>,
|
|
297
|
-
): readonly string[] {
|
|
298
|
-
const seen = new Set<string>();
|
|
299
|
-
const found: string[] = [];
|
|
300
|
-
for (const file of files) {
|
|
301
|
-
for (
|
|
302
|
-
let dir = dirnamePath(file);
|
|
303
|
-
dir !== targetRoot && !seen.has(dir) && relativePath(targetRoot, dir) !== undefined;
|
|
304
|
-
dir = dirnamePath(dir)
|
|
305
|
-
) {
|
|
306
|
-
seen.add(dir);
|
|
307
|
-
const below = relativePath(targetRoot, dir) ?? "";
|
|
308
|
-
if (
|
|
309
|
-
!below.split("/").includes("node_modules") &&
|
|
310
|
-
!known.has(dir) &&
|
|
311
|
-
host.kindOf(joinPath(dir, "package.json")) === "file"
|
|
312
|
-
) {
|
|
313
|
-
found.push(dir);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
return found.sort(compare);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Reads every project the scope discovers, and each declared consumer's, in one snapshot,
|
|
322
|
-
* each checked for errors first. `stage` is handed a target project and enumerates and roots
|
|
323
|
-
* it if it reads it; a consumer project is read for its references to the target. A type error
|
|
324
|
-
* in an own file skips the unit holding it. A guess that does not load or meets a setup failure
|
|
325
|
-
* is dropped into `notBuilt` (see {@link isGuess}); any other such project fails the run, as
|
|
326
|
-
* does a run whose every guess was dropped.
|
|
213
|
+
* Reads every project the load phase analyzes through `stage`, which enumerates and roots one
|
|
214
|
+
* if it reads it, and each declared consumer's project for its references to the target,
|
|
215
|
+
* in the same snapshot. A type error in an own file skips the unit holding it.
|
|
327
216
|
*/
|
|
328
217
|
function readProjects<Answer>(
|
|
329
218
|
engine: Engine,
|
|
330
219
|
host: Host,
|
|
331
220
|
scope: Scope,
|
|
332
|
-
config:
|
|
221
|
+
config: PartialConfig,
|
|
333
222
|
stage: <Brand>(project: ProjectView<Brand>, opened: OpenedProject) => Answer,
|
|
334
|
-
):
|
|
223
|
+
): LoadedRun<ProjectsRead<Answer>> {
|
|
335
224
|
const targetRoot = scope.target.path;
|
|
336
|
-
const discovered = discoverProjects(engine, host, scope, config.analysis.configurations);
|
|
337
|
-
if (discovered.configFiles.length === 0 && discovered.notBuilt.length === 0) {
|
|
338
|
-
throw new DiscoveryError(
|
|
339
|
-
`${targetRoot} holds no compiler configuration, so the run holds no program`,
|
|
340
|
-
[],
|
|
341
|
-
);
|
|
342
|
-
}
|
|
343
|
-
const ids = new Map(discovered.projects.map((project) => [project.configFile, project.id]));
|
|
344
|
-
const loads = consumerLoads(engine, host, scope, discovered.configFiles);
|
|
345
|
-
const consumerOf = new Map(
|
|
346
|
-
loads.flatMap((load) =>
|
|
347
|
-
load.configFiles.map((configFile) => [configFile, load.consumer] as const),
|
|
348
|
-
),
|
|
349
|
-
);
|
|
350
225
|
const absoluteRoot = resolvePath(host.workingDirectory(), targetRoot);
|
|
351
|
-
const
|
|
352
|
-
engine,
|
|
353
|
-
host,
|
|
354
|
-
absoluteRoot,
|
|
355
|
-
discovered.configFiles,
|
|
356
|
-
readManifest(host, targetRoot),
|
|
357
|
-
);
|
|
226
|
+
const testPatterns = config.ts.test_files.map(globExpression);
|
|
358
227
|
const parse = (fileName: string, text: string) => engine.parseSourceFile(fileName, text);
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
let conventions = readConventions(host, parse, [], config.ts.disabledConventions);
|
|
364
|
-
let options: RootOptions & { readonly parse: typeof parse; readonly conventions: Conventions };
|
|
365
|
-
const readManifests = (opened: readonly OpenedFiles[]): void => {
|
|
366
|
-
nestedDirs = nestedPackageDirs(
|
|
228
|
+
return loadRun(engine, host, scope, config, ({ plan, classified, runFiles }) => {
|
|
229
|
+
const { packages, conventions } = plan;
|
|
230
|
+
const workflows = readWorkflows(host, targetRoot);
|
|
231
|
+
const options = {
|
|
367
232
|
host,
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
new Set(memberDirs),
|
|
373
|
-
);
|
|
374
|
-
conventions = readConventions(
|
|
375
|
-
host,
|
|
376
|
-
parse,
|
|
377
|
-
conventionManifests(host, absoluteRoot, memberDirs, nestedDirs),
|
|
378
|
-
config.ts.disabledConventions,
|
|
379
|
-
);
|
|
380
|
-
options = {
|
|
381
|
-
host,
|
|
382
|
-
manifest: workspace?.manifest ?? readManifest(host, targetRoot),
|
|
383
|
-
otherPackages: [
|
|
384
|
-
...(workspace?.entries ?? []),
|
|
385
|
-
...packageEntries(host, normalizePath(absoluteRoot), nestedDirs),
|
|
386
|
-
],
|
|
387
|
-
patterns: config.rootPatterns,
|
|
388
|
-
entryFiles: config.ts.entryFiles,
|
|
389
|
-
conventions,
|
|
390
|
-
testFiles: config.ts.testFiles,
|
|
233
|
+
manifest: packages.manifest,
|
|
234
|
+
otherPackages: packages.entries,
|
|
235
|
+
patterns: config.roots.patterns,
|
|
236
|
+
entryFiles: config.ts.entry_files,
|
|
391
237
|
parse,
|
|
392
|
-
publishedAPI: config.
|
|
393
|
-
publishedMembers:
|
|
394
|
-
|
|
395
|
-
),
|
|
396
|
-
runFiles: new Set(
|
|
397
|
-
opened.flatMap((one) =>
|
|
398
|
-
one.fileNames().map((name) => resolvePath(host.workingDirectory(), name)),
|
|
399
|
-
),
|
|
400
|
-
),
|
|
238
|
+
publishedAPI: config.target.kind !== undefined && kindOf(config.target.kind) === "library",
|
|
239
|
+
publishedMembers: packages.published,
|
|
240
|
+
runFiles,
|
|
401
241
|
};
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const dropped = (configFile: string, error: string): void => {
|
|
405
|
-
notBuilt.push({
|
|
406
|
-
id: ids.get(configFile) ?? configFile,
|
|
407
|
-
configFile,
|
|
408
|
-
error: targetRelative(error, absoluteRoot),
|
|
409
|
-
});
|
|
410
|
-
};
|
|
411
|
-
const failures: LocatedDiagnostic[] = [];
|
|
412
|
-
const unbuildable: SetupFailure[] = [];
|
|
413
|
-
const setupDropped: SetupFailure[] = [];
|
|
414
|
-
const librariesUnfound: LibraryUnfound[] = [];
|
|
415
|
-
const consumed = new Map<string, Reference>();
|
|
416
|
-
const heldFiles = new Set<string>();
|
|
417
|
-
let outsideTests: readonly OutsideTest[] = [];
|
|
418
|
-
const setupMet = (configFile: string, met: readonly SetupFailure[]): void => {
|
|
419
|
-
const [first] = met;
|
|
420
|
-
if (first !== undefined && isGuess(discovered, configFile)) {
|
|
421
|
-
dropped(configFile, setupLine(first));
|
|
422
|
-
setupDropped.push(...met);
|
|
423
|
-
} else {
|
|
424
|
-
unbuildable.push(...met);
|
|
425
|
-
}
|
|
426
|
-
};
|
|
427
|
-
const testPatterns = config.ts.testFiles.map(globExpression);
|
|
428
|
-
const joins = discovered.derived
|
|
429
|
-
? joinedTestFiles(engine, host, absoluteRoot, discovered.configFiles, testPatterns)
|
|
430
|
-
: new Map<string, readonly string[]>();
|
|
431
|
-
const programs = withBaseUrlPaths(
|
|
432
|
-
engine,
|
|
433
|
-
host,
|
|
434
|
-
[...discovered.configFiles, ...consumerOf.keys()],
|
|
435
|
-
workspace?.programs ?? new Map(),
|
|
436
|
-
);
|
|
437
|
-
const session = runSession(
|
|
438
|
-
engine,
|
|
439
|
-
[...discovered.configFiles, ...consumerOf.keys()],
|
|
440
|
-
(opened) => {
|
|
441
|
-
const consumer = consumerOf.get(opened.configFile);
|
|
442
|
-
const setup = consumer === undefined ? workspace?.unbuildable(opened.configFile) : undefined;
|
|
443
|
-
if (setup !== undefined) {
|
|
444
|
-
setupMet(opened.configFile, [
|
|
445
|
-
{ setupClass: "workspace-member-without-source", detail: setup },
|
|
446
|
-
]);
|
|
447
|
-
return undefined;
|
|
448
|
-
}
|
|
449
|
-
const referenceOnly =
|
|
450
|
-
workspace === undefined || consumer !== undefined
|
|
451
|
-
? () => false
|
|
452
|
-
: workspace.referenceOnly(opened.configFile, opened.rootFiles);
|
|
453
|
-
const project =
|
|
454
|
-
workspace === undefined || consumer !== undefined
|
|
455
|
-
? opened
|
|
456
|
-
: ownedAs(opened, (file, fromExternalLibrary) =>
|
|
457
|
-
workspace.ownFile(file, fromExternalLibrary),
|
|
458
|
-
);
|
|
459
|
-
const raw = projectErrors(diagnosticsOf(project));
|
|
460
|
-
const errors = { load: raw.load, check: ownErrors(raw.check, referenceOnly) };
|
|
461
|
-
const [unloaded] = errors.load;
|
|
462
|
-
if (
|
|
463
|
-
unloaded !== undefined &&
|
|
464
|
-
consumer === undefined &&
|
|
465
|
-
isGuess(discovered, project.configFile)
|
|
466
|
-
) {
|
|
467
|
-
dropped(
|
|
468
|
-
project.configFile,
|
|
469
|
-
renderDiagnostic(unloaded, (path) => relativePath(absoluteRoot, path) ?? path),
|
|
470
|
-
);
|
|
471
|
-
return undefined;
|
|
472
|
-
}
|
|
473
|
-
if (errors.load.length > 0) {
|
|
474
|
-
failures.push(...errors.load);
|
|
475
|
-
return undefined;
|
|
476
|
-
}
|
|
477
|
-
const reading = readErrors(project, errors.check, {
|
|
478
|
-
host,
|
|
479
|
-
targetRoot:
|
|
480
|
-
consumer === undefined
|
|
481
|
-
? absoluteRoot
|
|
482
|
-
: resolvePath(host.workingDirectory(), consumer.path),
|
|
483
|
-
paths: pathsOf(engine, project.configFile),
|
|
484
|
-
});
|
|
485
|
-
if (consumer !== undefined && reading.missing.length > 0) {
|
|
486
|
-
unbuildable.push(
|
|
487
|
-
...reading.missing.map((one) => ({
|
|
488
|
-
setupClass: "missing-consumer" as const,
|
|
489
|
-
detail: `the consumer ${consumer.path} does not build, its dependencies not installed: ${one.detail}`,
|
|
490
|
-
})),
|
|
491
|
-
);
|
|
492
|
-
return undefined;
|
|
493
|
-
}
|
|
494
|
-
if (reading.missing.length > 0) {
|
|
495
|
-
setupMet(project.configFile, reading.missing);
|
|
496
|
-
return undefined;
|
|
497
|
-
}
|
|
498
|
-
const unconventional =
|
|
499
|
-
consumer === undefined
|
|
500
|
-
? conventionFailuresFor(
|
|
501
|
-
conventions,
|
|
502
|
-
project.configFile,
|
|
503
|
-
project.ownSourceFiles().map((file) => file.fileName),
|
|
504
|
-
)
|
|
505
|
-
: [];
|
|
506
|
-
if (unconventional.length > 0) {
|
|
507
|
-
setupMet(project.configFile, unconventional);
|
|
508
|
-
return undefined;
|
|
509
|
-
}
|
|
510
|
-
if (consumer !== undefined) {
|
|
511
|
-
for (const reference of consumerReferences(
|
|
512
|
-
project,
|
|
513
|
-
host,
|
|
514
|
-
targetRoot,
|
|
515
|
-
{
|
|
516
|
-
id: consumer.id,
|
|
517
|
-
root: consumer.path,
|
|
518
|
-
},
|
|
519
|
-
config,
|
|
520
|
-
)) {
|
|
521
|
-
consumed.set(referenceKey(reference), reference);
|
|
522
|
-
}
|
|
523
|
-
return undefined;
|
|
524
|
-
}
|
|
525
|
-
librariesUnfound.push(
|
|
526
|
-
...raw.unfound.map((one) => ({
|
|
527
|
-
configFile: project.configFile,
|
|
528
|
-
error: renderDiagnostic(one, (path) => relativePath(absoluteRoot, path) ?? path),
|
|
529
|
-
})),
|
|
530
|
-
);
|
|
531
|
-
const missingGlobal = raw.unfound.find(
|
|
532
|
-
({ diagnostic }) => diagnostic.code === MISSING_GLOBAL_TYPE,
|
|
533
|
-
);
|
|
534
|
-
const skips =
|
|
535
|
-
missingGlobal === undefined
|
|
536
|
-
? reading.skips
|
|
537
|
-
: [
|
|
538
|
-
...reading.skips,
|
|
539
|
-
...project.ownSourceFiles().map((file) => ({
|
|
540
|
-
record: {
|
|
541
|
-
path: relativePath(absoluteRoot, file.fileName) ?? file.fileName,
|
|
542
|
-
line: 1,
|
|
543
|
-
message: missingGlobal.diagnostic.text,
|
|
544
|
-
},
|
|
545
|
-
file,
|
|
546
|
-
unit: file,
|
|
547
|
-
})),
|
|
548
|
-
];
|
|
549
|
-
const configuration = ids.get(project.configFile) ?? project.configFile;
|
|
242
|
+
const heldFiles = new Set<string>();
|
|
243
|
+
const answers = classified.analyzed.map(({ plan: planned, project, skips, referenceOnly }) => {
|
|
550
244
|
const read = (): ProjectRead => {
|
|
551
245
|
const held = inventory(project, host, targetRoot);
|
|
552
|
-
const found = roots(project, held, targetRoot, options);
|
|
553
|
-
const kept = skippedRoots(project, held, skips);
|
|
554
|
-
const rooted =
|
|
555
|
-
kept.length === 0
|
|
556
|
-
? found
|
|
557
|
-
: {
|
|
558
|
-
...found,
|
|
559
|
-
liveUnderReachability: [
|
|
560
|
-
...found.liveUnderReachability,
|
|
561
|
-
...kept.map((id) => ({ id, kind: "type-error" as const, source: "" })),
|
|
562
|
-
],
|
|
563
|
-
};
|
|
564
246
|
const own = sourceFilesOf(project, targetRoot);
|
|
247
|
+
const sources = readSources({
|
|
248
|
+
host,
|
|
249
|
+
targetRoot,
|
|
250
|
+
files: own,
|
|
251
|
+
parse,
|
|
252
|
+
testFiles: config.ts.test_files,
|
|
253
|
+
conventions,
|
|
254
|
+
workflows,
|
|
255
|
+
});
|
|
256
|
+
const rooted = rootSet(project, held, targetRoot, { ...options, sources, skips });
|
|
257
|
+
const generated = generatedFilesOf(own, sources.generated);
|
|
565
258
|
return {
|
|
566
|
-
configuration,
|
|
259
|
+
configuration: planned.id,
|
|
567
260
|
configFile: project.configFile,
|
|
568
261
|
held,
|
|
569
262
|
rooted,
|
|
@@ -573,71 +266,53 @@ function readProjects<Answer>(
|
|
|
573
266
|
.ownSourceFiles()
|
|
574
267
|
.filter((file) => referenceOnly(file.fileName))
|
|
575
268
|
.flatMap((file) => relativePath(absoluteRoot, file.fileName) ?? []),
|
|
576
|
-
generated
|
|
577
|
-
|
|
269
|
+
generated,
|
|
270
|
+
bindings: bindingsOf(
|
|
271
|
+
own.byPath,
|
|
272
|
+
generated,
|
|
273
|
+
new Map(
|
|
274
|
+
held.symbols
|
|
275
|
+
.filter((one) => one.kind === "file")
|
|
276
|
+
.map((one) => [one.position.path, one.ref]),
|
|
277
|
+
),
|
|
278
|
+
),
|
|
279
|
+
sources,
|
|
280
|
+
formedForNode: formedForNode(planned),
|
|
578
281
|
};
|
|
579
282
|
};
|
|
580
283
|
for (const file of project.ownSourceFiles()) {
|
|
581
284
|
heldFiles.add(relativePath(absoluteRoot, file.fileName) ?? file.fileName);
|
|
582
285
|
}
|
|
583
|
-
return stage(project, { configuration, read });
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
()
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
},
|
|
597
|
-
readManifests,
|
|
598
|
-
);
|
|
599
|
-
for (const configFile of session.unopened) {
|
|
600
|
-
if (consumerOf.has(configFile) || !isGuess(discovered, configFile)) {
|
|
601
|
-
throw new DiscoveryError(`${configFile} opened no project`, []);
|
|
286
|
+
return stage(project, { configuration: planned.id, read });
|
|
287
|
+
});
|
|
288
|
+
const consumed = new Map<string, Reference>();
|
|
289
|
+
const consumerHeld = new Set<string>();
|
|
290
|
+
for (const { project, consumer } of classified.consumed) {
|
|
291
|
+
const side = { id: consumer.id, root: consumer.path };
|
|
292
|
+
const read = consumerReferences(project, host, targetRoot, side, config, parse);
|
|
293
|
+
for (const reference of read.references) {
|
|
294
|
+
consumed.set(referenceKey(reference), reference);
|
|
295
|
+
}
|
|
296
|
+
for (const id of read.held) {
|
|
297
|
+
consumerHeld.add(id);
|
|
298
|
+
}
|
|
602
299
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
`${String(failures.length)} error(s), so no answer was produced`,
|
|
611
|
-
failures,
|
|
612
|
-
);
|
|
613
|
-
}
|
|
614
|
-
const answers = session.projects.filter((answer): answer is Answer => answer !== undefined);
|
|
615
|
-
const [first] = notBuilt;
|
|
616
|
-
if (answers.length === 0 && setupDropped.length > 0) {
|
|
617
|
-
throw new SetupError(setupDropped);
|
|
618
|
-
}
|
|
619
|
-
if (answers.length === 0 && first !== undefined) {
|
|
620
|
-
throw new DiscoveryError(
|
|
621
|
-
`no configuration discovery derived could be built; ${first.id}: ${first.error}`,
|
|
622
|
-
[],
|
|
300
|
+
const outsideTests = testFilesAt(
|
|
301
|
+
host,
|
|
302
|
+
targetRoot,
|
|
303
|
+
sourcePaths(host, targetRoot).filter(
|
|
304
|
+
(path) => !heldFiles.has(path) && testPatterns.some((pattern) => pattern.test(path)),
|
|
305
|
+
),
|
|
306
|
+
parse,
|
|
623
307
|
);
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
answers,
|
|
627
|
-
consumers: {
|
|
628
|
-
loaded: loads.map((load) => load.consumer),
|
|
308
|
+
return {
|
|
309
|
+
answers,
|
|
629
310
|
references: [...consumed.values()],
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
conventionsApplied: conventions.applied,
|
|
636
|
-
conventionUses: conventions.uses,
|
|
637
|
-
memberDirs,
|
|
638
|
-
nestedDirs,
|
|
639
|
-
outsideTests,
|
|
640
|
-
};
|
|
311
|
+
consumerHeld: [...consumerHeld],
|
|
312
|
+
outsideTests,
|
|
313
|
+
workflows,
|
|
314
|
+
};
|
|
315
|
+
});
|
|
641
316
|
}
|
|
642
317
|
|
|
643
318
|
/** The projects one run analyzes, and what reading them left out. */
|
|
@@ -655,7 +330,12 @@ interface RunProjects {
|
|
|
655
330
|
* for the errors and setup failures that decide whether it is analyzed, dropped or
|
|
656
331
|
* fails the run, exactly as the analysis reads them.
|
|
657
332
|
*/
|
|
658
|
-
export function runProjects(
|
|
333
|
+
export function runProjects(
|
|
334
|
+
engine: Engine,
|
|
335
|
+
host: Host,
|
|
336
|
+
scope: Scope,
|
|
337
|
+
config: PartialConfig,
|
|
338
|
+
): RunProjects {
|
|
659
339
|
const read = readProjects(
|
|
660
340
|
engine,
|
|
661
341
|
host,
|
|
@@ -663,7 +343,11 @@ export function runProjects(engine: Engine, host: Host, scope: Scope, config: Co
|
|
|
663
343
|
config,
|
|
664
344
|
(_project, opened) => opened.configuration,
|
|
665
345
|
);
|
|
666
|
-
return {
|
|
346
|
+
return {
|
|
347
|
+
configurations: read.result.answers,
|
|
348
|
+
notBuilt: read.classified.notBuilt,
|
|
349
|
+
unanswered: read.unanswered,
|
|
350
|
+
};
|
|
667
351
|
}
|
|
668
352
|
|
|
669
353
|
/**
|
|
@@ -676,12 +360,12 @@ export function runRoots(
|
|
|
676
360
|
engine: Engine,
|
|
677
361
|
host: Host,
|
|
678
362
|
scope: Scope,
|
|
679
|
-
config:
|
|
363
|
+
config: ResolvedConfig,
|
|
680
364
|
provenance: Provenance,
|
|
681
365
|
): RunRoots {
|
|
682
366
|
const targetRoot = scope.target.path;
|
|
683
367
|
const read = readProjects(engine, host, scope, config, (_project, opened) => opened.read());
|
|
684
|
-
const projects = read.answers;
|
|
368
|
+
const projects = read.result.answers;
|
|
685
369
|
|
|
686
370
|
const configurations: string[] = [];
|
|
687
371
|
const merged = new Map<string, Omit<RunRoot, "configurations"> & { configurations: string[] }>();
|
|
@@ -712,10 +396,12 @@ export function runRoots(
|
|
|
712
396
|
|
|
713
397
|
const ordered = [...merged.values()].sort(
|
|
714
398
|
(a, b) =>
|
|
715
|
-
byPosition(a.position, b.position) ||
|
|
399
|
+
byPosition(a.position, b.position) ||
|
|
400
|
+
bytewise(a.kind, b.kind) ||
|
|
401
|
+
bytewise(a.source, b.source),
|
|
716
402
|
);
|
|
717
403
|
const unmatched = unmatchedEverywhere(
|
|
718
|
-
config.
|
|
404
|
+
config.roots.patterns,
|
|
719
405
|
projects.map((answer) => answer.rooted),
|
|
720
406
|
);
|
|
721
407
|
return {
|
|
@@ -725,39 +411,33 @@ export function runRoots(
|
|
|
725
411
|
unmatched,
|
|
726
412
|
documentOf(host, provenance, ROOTS_SETTING, targetRoot),
|
|
727
413
|
),
|
|
728
|
-
notBuilt: read.notBuilt,
|
|
414
|
+
notBuilt: read.classified.notBuilt,
|
|
729
415
|
unanswered: read.unanswered,
|
|
730
416
|
};
|
|
731
417
|
}
|
|
732
418
|
|
|
419
|
+
/** The production mode a configuration sets: a consumer's test reference is classed as `analysis.consumer_tests` says. */
|
|
420
|
+
export function productionMode(config: PartialConfig): Mode {
|
|
421
|
+
return {
|
|
422
|
+
production: true,
|
|
423
|
+
consumerTestsProduction: config.analysis.consumer_tests === "production",
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
|
|
733
427
|
/** The run's sweep, beside the matrix it judged. */
|
|
734
428
|
export interface RunSweep {
|
|
735
429
|
readonly matrix: Matrix;
|
|
736
|
-
readonly sweep:
|
|
737
|
-
/** The exemption records that hold under the sweep. */
|
|
738
|
-
readonly exempt: readonly Exemption[];
|
|
739
|
-
/**
|
|
740
|
-
* The exemption records that held back a declaration some configuration of the run
|
|
741
|
-
* would otherwise judge dead, in the declarations' site order.
|
|
742
|
-
*/
|
|
743
|
-
readonly retained: readonly Exemption[];
|
|
430
|
+
readonly sweep: Sweep;
|
|
744
431
|
/** The derived configurations the run dropped. */
|
|
745
432
|
readonly notBuilt: readonly NotBuilt[];
|
|
746
433
|
/** Every question the checker could not answer, each once. */
|
|
747
434
|
readonly unanswered: readonly UnansweredQuestion[];
|
|
748
|
-
/**
|
|
749
|
-
* Every declaration an unanswered question could have kept live, and every one only
|
|
750
|
-
* such a declaration keeps live. The run reports none of them.
|
|
751
|
-
*/
|
|
752
|
-
readonly heldByUnanswered: readonly string[];
|
|
753
435
|
/** The lines of the units type errors skipped, on which the run reports nothing. */
|
|
754
436
|
readonly skipped: readonly SkippedUnit[];
|
|
755
|
-
/** The component files the run read, by path below the target root, each once. */
|
|
756
|
-
readonly componentFiles: readonly string[];
|
|
757
437
|
}
|
|
758
438
|
|
|
759
439
|
/** One `<script` start tag of a component file the run read no block for. */
|
|
760
|
-
|
|
440
|
+
interface ComponentWarning {
|
|
761
441
|
/** The file, below the target root. */
|
|
762
442
|
readonly path: string;
|
|
763
443
|
readonly line: number;
|
|
@@ -784,6 +464,10 @@ interface SweptProject<Extra> {
|
|
|
784
464
|
readonly exempt: readonly Exemption[];
|
|
785
465
|
/** The declarations of the project an unanswered question could have kept live. */
|
|
786
466
|
readonly unanswered: readonly string[];
|
|
467
|
+
/** The data members a generic declared outside the analysis fills, which it may read. */
|
|
468
|
+
readonly filledOutside: readonly string[];
|
|
469
|
+
/** What only a bundler's retry of an import Node leaves unresolved names (program.38). */
|
|
470
|
+
readonly possiblyLoaded: readonly string[];
|
|
787
471
|
readonly typeErrorSkips: readonly TypeErrorSkip[];
|
|
788
472
|
readonly skipped: readonly SkippedUnit[];
|
|
789
473
|
/** The component files the project holds of its own, by path below the target root. */
|
|
@@ -791,6 +475,7 @@ interface SweptProject<Extra> {
|
|
|
791
475
|
readonly componentWarnings: readonly ComponentWarning[];
|
|
792
476
|
/** The manifest entries the project reads back to no file of its own. */
|
|
793
477
|
readonly unmappedEntries: readonly ManifestEntry[];
|
|
478
|
+
readonly heldScripts: readonly HeldScripts[];
|
|
794
479
|
readonly extra: Extra;
|
|
795
480
|
}
|
|
796
481
|
|
|
@@ -798,12 +483,17 @@ interface SweptProject<Extra> {
|
|
|
798
483
|
interface ReadProject<Extra> {
|
|
799
484
|
readonly projectRead: ProjectRead;
|
|
800
485
|
readonly references: readonly Reference[];
|
|
486
|
+
/** The declarations its read rules held where the checker did not answer. */
|
|
487
|
+
readonly held: readonly string[];
|
|
488
|
+
readonly possiblyLoaded: readonly string[];
|
|
801
489
|
readonly testFiles: readonly string[];
|
|
802
490
|
readonly evidence: readonly Exemption[];
|
|
803
491
|
readonly componentFiles: readonly string[];
|
|
804
492
|
readonly componentWarnings: readonly ComponentWarning[];
|
|
805
493
|
/** Per own file below the target root, the module specifiers its imports write. */
|
|
806
494
|
readonly imports: ReadonlyMap<string, readonly string[]>;
|
|
495
|
+
/** The data members its production code decodes into. */
|
|
496
|
+
readonly decoded: Decoded;
|
|
807
497
|
readonly extra: Extra;
|
|
808
498
|
}
|
|
809
499
|
|
|
@@ -816,6 +506,8 @@ interface ReadRun<Extra> {
|
|
|
816
506
|
readonly projects: readonly SweptProject<Extra>[];
|
|
817
507
|
/** Every declared consumer, each loaded, in the scope's order. */
|
|
818
508
|
readonly consumers: readonly LoadedConsumer[];
|
|
509
|
+
/** Whether the scope declares a consumer, loaded or not. */
|
|
510
|
+
readonly declaresConsumers: boolean;
|
|
819
511
|
/** The derived configurations the run dropped. */
|
|
820
512
|
readonly notBuilt: readonly NotBuilt[];
|
|
821
513
|
/** Every question the checker could not answer, each once. */
|
|
@@ -824,6 +516,10 @@ interface ReadRun<Extra> {
|
|
|
824
516
|
readonly componentsUnread: readonly ComponentsUnread[];
|
|
825
517
|
/** Per analyzed configuration, each library it names that the compiler cannot find. */
|
|
826
518
|
readonly librariesUnfound: readonly LibraryUnfound[];
|
|
519
|
+
/** The relative specifiers of the run's unchecked JavaScript files that resolve to no file. */
|
|
520
|
+
readonly unresolvedSpecifiers: readonly UnresolvedSpecifier[];
|
|
521
|
+
/** The inputs the run could not read. */
|
|
522
|
+
readonly unread: readonly UnreadInput[];
|
|
827
523
|
/** The convention rows the run applied. */
|
|
828
524
|
readonly conventionsApplied: readonly AppliedConvention[];
|
|
829
525
|
/** The dependencies the applied rows' short names use. */
|
|
@@ -832,6 +528,8 @@ interface ReadRun<Extra> {
|
|
|
832
528
|
readonly memberDirs: readonly string[];
|
|
833
529
|
/** The directory of every nested package, absolute. */
|
|
834
530
|
readonly nestedDirs: readonly string[];
|
|
531
|
+
/** The target root's workflow steps, git hooks and makefile, read once. */
|
|
532
|
+
readonly workflows: Workflows;
|
|
835
533
|
}
|
|
836
534
|
|
|
837
535
|
/** The manifest section of a package test evidence counts, and the sections that keep one out of it. */
|
|
@@ -855,20 +553,9 @@ function testEvidence(
|
|
|
855
553
|
}
|
|
856
554
|
}
|
|
857
555
|
const manifests = new Map<string, Readonly<Record<string, unknown>> | undefined>();
|
|
858
|
-
const
|
|
556
|
+
const manifestIn = (dir: string): Readonly<Record<string, unknown>> | undefined => {
|
|
859
557
|
if (!manifests.has(dir)) {
|
|
860
|
-
|
|
861
|
-
try {
|
|
862
|
-
value = JSON.parse(host.readFile(joinPath(dir, "package.json")));
|
|
863
|
-
} catch {
|
|
864
|
-
value = undefined;
|
|
865
|
-
}
|
|
866
|
-
manifests.set(
|
|
867
|
-
dir,
|
|
868
|
-
typeof value === "object" && value !== null && !Array.isArray(value)
|
|
869
|
-
? (value as Record<string, unknown>)
|
|
870
|
-
: undefined,
|
|
871
|
-
);
|
|
558
|
+
manifests.set(dir, manifestAt(host, dir));
|
|
872
559
|
}
|
|
873
560
|
return manifests.get(dir);
|
|
874
561
|
};
|
|
@@ -878,16 +565,14 @@ function testEvidence(
|
|
|
878
565
|
return {
|
|
879
566
|
imports,
|
|
880
567
|
devDependency: (path, name) => {
|
|
881
|
-
for (
|
|
882
|
-
const manifest =
|
|
568
|
+
for (const dir of ancestors(dirnamePath(joinPath(root, path)), root)) {
|
|
569
|
+
const manifest = manifestIn(dir);
|
|
883
570
|
const other = OTHER_SECTIONS.some((one) => declares(manifest?.[one], name));
|
|
884
571
|
if (declares(manifest?.[DEV_SECTION], name) || other) {
|
|
885
572
|
return !other;
|
|
886
573
|
}
|
|
887
|
-
if (normalizePath(dir) === normalizePath(root) || dirnamePath(dir) === dir) {
|
|
888
|
-
return false;
|
|
889
|
-
}
|
|
890
574
|
}
|
|
575
|
+
return false;
|
|
891
576
|
},
|
|
892
577
|
};
|
|
893
578
|
}
|
|
@@ -902,7 +587,7 @@ function readRun<Extra>(
|
|
|
902
587
|
engine: Engine,
|
|
903
588
|
host: Host,
|
|
904
589
|
scope: Scope,
|
|
905
|
-
config:
|
|
590
|
+
config: ResolvedConfig,
|
|
906
591
|
mode: Mode,
|
|
907
592
|
detectors: Detectors,
|
|
908
593
|
extra: <Brand>(
|
|
@@ -910,20 +595,27 @@ function readRun<Extra>(
|
|
|
910
595
|
read: ProjectRead,
|
|
911
596
|
references: readonly Reference[],
|
|
912
597
|
testFiles: readonly string[],
|
|
598
|
+
unseenLoads: readonly UnseenLoad[],
|
|
913
599
|
) => Extra,
|
|
914
600
|
): ReadRun<Extra> {
|
|
915
601
|
const targetRoot = scope.target.path;
|
|
916
602
|
const disabled = disabledClasses(config);
|
|
917
603
|
const templates = disabled.has("template-field")
|
|
918
|
-
? { delimiters: config.analysis.
|
|
604
|
+
? { delimiters: config.analysis.template_delimiters, files: [] }
|
|
919
605
|
: readTemplates(host, targetRoot, config.analysis);
|
|
920
606
|
const consumers = scope.consumers.map((consumer) => consumer.path);
|
|
607
|
+
const directories = runDirectories(host, targetRoot, (fileName, text) =>
|
|
608
|
+
engine.parseSourceFile(fileName, text),
|
|
609
|
+
);
|
|
921
610
|
const read = readProjects<ReadProject<Extra>>(engine, host, scope, config, (project, opened) => {
|
|
922
611
|
const projectRead = opened.read();
|
|
612
|
+
const testFile = targetTestFile(projectRead.sources.testFiles);
|
|
923
613
|
const resolved = references(project, projectRead.held, targetRoot, {
|
|
924
|
-
|
|
925
|
-
|
|
614
|
+
testFile,
|
|
615
|
+
directories,
|
|
616
|
+
formedForNode: projectRead.formedForNode,
|
|
926
617
|
});
|
|
618
|
+
const testFiles = testFilePaths(project, targetRoot, testFile);
|
|
927
619
|
const evidence = evidenceRecords(
|
|
928
620
|
{
|
|
929
621
|
project,
|
|
@@ -932,7 +624,7 @@ function readRun<Extra>(
|
|
|
932
624
|
templates,
|
|
933
625
|
ts: config.ts,
|
|
934
626
|
consumers,
|
|
935
|
-
...(config.analysis.
|
|
627
|
+
...(config.analysis.generated_files === "include"
|
|
936
628
|
? {}
|
|
937
629
|
: { generated: projectRead.generated }),
|
|
938
630
|
},
|
|
@@ -940,20 +632,35 @@ function readRun<Extra>(
|
|
|
940
632
|
disabled,
|
|
941
633
|
);
|
|
942
634
|
const components = project.ownSourceFiles().filter(isComponentFile);
|
|
635
|
+
const injected = project.program
|
|
636
|
+
.getSourceFileNames()
|
|
637
|
+
.some((name) => name.endsWith(`/node_modules/${GLOBALS_RUNNER}/globals.d.ts`));
|
|
943
638
|
const pathOf = (file: (typeof components)[number]): string =>
|
|
944
639
|
relativePath(targetRoot, file.fileName) ?? file.fileName;
|
|
945
640
|
return {
|
|
946
641
|
projectRead,
|
|
947
642
|
references: resolved.references,
|
|
948
|
-
|
|
643
|
+
held: resolved.held,
|
|
644
|
+
possiblyLoaded: resolved.possiblyLoaded,
|
|
645
|
+
testFiles,
|
|
949
646
|
evidence,
|
|
950
647
|
componentFiles: components.map(pathOf),
|
|
951
648
|
imports: new Map(
|
|
952
649
|
project.ownSourceFiles().flatMap((file) => {
|
|
953
650
|
const path = relativePath(targetRoot, file.fileName);
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
651
|
+
if (path === undefined) {
|
|
652
|
+
return [];
|
|
653
|
+
}
|
|
654
|
+
const specifiers = file.imports.filter(isStringLiteralLikeNode).map((one) => one.text);
|
|
655
|
+
// A file calling the globals a program declares is written for their runner.
|
|
656
|
+
return [
|
|
657
|
+
[
|
|
658
|
+
path,
|
|
659
|
+
injected && namesTestGlobals(project, file)
|
|
660
|
+
? [...specifiers, GLOBALS_RUNNER]
|
|
661
|
+
: specifiers,
|
|
662
|
+
],
|
|
663
|
+
];
|
|
957
664
|
}),
|
|
958
665
|
),
|
|
959
666
|
componentWarnings: components.flatMap((file) =>
|
|
@@ -963,15 +670,30 @@ function readRun<Extra>(
|
|
|
963
670
|
reason: warning.reason,
|
|
964
671
|
})),
|
|
965
672
|
),
|
|
966
|
-
|
|
673
|
+
decoded: decodedMembers(
|
|
674
|
+
project,
|
|
675
|
+
projectRead.held,
|
|
676
|
+
productionFiles(project, targetRoot, testFiles),
|
|
677
|
+
consumers,
|
|
678
|
+
),
|
|
679
|
+
extra: extra(
|
|
680
|
+
project,
|
|
681
|
+
projectRead,
|
|
682
|
+
resolved.references,
|
|
683
|
+
testFiles,
|
|
684
|
+
resolved.unseenLoads.map((position) => ({
|
|
685
|
+
configuration: projectRead.configuration,
|
|
686
|
+
position,
|
|
687
|
+
})),
|
|
688
|
+
),
|
|
967
689
|
};
|
|
968
690
|
});
|
|
969
|
-
const outsidePaths = read.outsideTests.map((one) => one.path);
|
|
970
|
-
const withOutside = read.answers.map((one) => ({
|
|
691
|
+
const outsidePaths = read.result.outsideTests.map((one) => one.path);
|
|
692
|
+
const withOutside = read.result.answers.map((one) => ({
|
|
971
693
|
...one,
|
|
972
694
|
references: [
|
|
973
695
|
...one.references,
|
|
974
|
-
...outsideTestReferences(read.outsideTests, one.projectRead.held, targetRoot),
|
|
696
|
+
...outsideTestReferences(read.result.outsideTests, one.projectRead.held, targetRoot),
|
|
975
697
|
],
|
|
976
698
|
testFiles: [...one.testFiles, ...outsidePaths],
|
|
977
699
|
}));
|
|
@@ -980,26 +702,48 @@ function readRun<Extra>(
|
|
|
980
702
|
const { support, testUsed } = testSupportFiles(
|
|
981
703
|
withOutside.flatMap((one) => one.projectRead.held.symbols),
|
|
982
704
|
withOutside.flatMap((one) => one.references),
|
|
983
|
-
|
|
705
|
+
// An outside declaration naming a global augmentation calls nothing of its file.
|
|
706
|
+
withOutside.flatMap((one) =>
|
|
707
|
+
one.projectRead.rooted.liveUnderReachability.filter(
|
|
708
|
+
(root) => root.kind !== "global-augmentation",
|
|
709
|
+
),
|
|
710
|
+
),
|
|
984
711
|
withOutside.flatMap((one) => one.testFiles),
|
|
985
712
|
testEvidence(host, targetRoot, withOutside),
|
|
986
713
|
);
|
|
714
|
+
// A member a decode fills or a copy carries is written: a value decoded and sent again carries it on.
|
|
715
|
+
const written = new Set([
|
|
716
|
+
...countedWrites(
|
|
717
|
+
[...withOutside.flatMap((one) => one.references), ...read.result.references],
|
|
718
|
+
support,
|
|
719
|
+
mode,
|
|
720
|
+
),
|
|
721
|
+
...withOutside.flatMap((one) => [
|
|
722
|
+
...one.decoded.filled,
|
|
723
|
+
...one.decoded.parsed,
|
|
724
|
+
...one.decoded.copied,
|
|
725
|
+
]),
|
|
726
|
+
]);
|
|
727
|
+
const evidence = withOutside.map((one) => writtenRecords(one.evidence, written));
|
|
987
728
|
const settled = settledSatisfaction(
|
|
988
|
-
withOutside.map((one) => ({
|
|
989
|
-
|
|
729
|
+
withOutside.map((one, index) => ({
|
|
730
|
+
evidence: evidence[index] ?? [],
|
|
731
|
+
held: one.projectRead.held,
|
|
732
|
+
})),
|
|
733
|
+
[...withOutside.flatMap((one) => one.references), ...read.result.references],
|
|
990
734
|
);
|
|
991
735
|
const answers = withOutside.map((one, index): SweptProject<Extra> => {
|
|
992
736
|
const { projectRead } = one;
|
|
993
737
|
const satisfied = settled[index];
|
|
994
|
-
const detected = heldRecords(satisfied?.evidence ??
|
|
738
|
+
const detected = heldRecords(satisfied?.evidence ?? evidence[index] ?? [], {
|
|
995
739
|
mode,
|
|
996
740
|
testFiles: new Set([...one.testFiles, ...support]),
|
|
997
741
|
});
|
|
998
742
|
const exempt = detected.records;
|
|
999
|
-
const made =
|
|
743
|
+
const made = [...one.references, ...(satisfied?.references ?? [])];
|
|
1000
744
|
const held = new Set(projectRead.held.symbols.map((symbol) => symbol.position.path));
|
|
1001
|
-
const supportFiles = [...support].filter((path) => held.has(path)).sort();
|
|
1002
|
-
const testUsedFiles = [...testUsed].filter((path) => held.has(path)).sort();
|
|
745
|
+
const supportFiles = [...support].filter((path) => held.has(path)).sort(bytewise);
|
|
746
|
+
const testUsedFiles = [...testUsed].filter((path) => held.has(path)).sort(bytewise);
|
|
1003
747
|
const configured: Configured = {
|
|
1004
748
|
configuration: projectRead.configuration,
|
|
1005
749
|
symbols: projectRead.held.symbols,
|
|
@@ -1023,20 +767,23 @@ function readRun<Extra>(
|
|
|
1023
767
|
unanswered: [
|
|
1024
768
|
...projectRead.held.unanswered,
|
|
1025
769
|
...projectRead.rooted.unanswered,
|
|
1026
|
-
...made
|
|
1027
|
-
|
|
1028
|
-
.map((reference) => reference.to),
|
|
770
|
+
...made.filter((reference) => reference.guessed === true).map((reference) => reference.to),
|
|
771
|
+
...one.held,
|
|
1029
772
|
...exempt.filter(isUnansweredRecord).map((record) => record.id),
|
|
773
|
+
...one.decoded.unanswered,
|
|
1030
774
|
],
|
|
775
|
+
filledOutside: one.decoded.filled,
|
|
776
|
+
possiblyLoaded: one.possiblyLoaded,
|
|
1031
777
|
typeErrorSkips: projectRead.typeErrorSkips,
|
|
1032
778
|
unmappedEntries: projectRead.rooted.unmappedEntries,
|
|
779
|
+
heldScripts: projectRead.rooted.heldScripts,
|
|
1033
780
|
skipped: projectRead.skipped,
|
|
1034
781
|
componentFiles: one.componentFiles,
|
|
1035
782
|
componentWarnings: one.componentWarnings,
|
|
1036
783
|
extra: one.extra,
|
|
1037
784
|
};
|
|
1038
785
|
});
|
|
1039
|
-
const consumed = read.
|
|
786
|
+
const consumed = read.result.references;
|
|
1040
787
|
const projects = answers.map((one) =>
|
|
1041
788
|
consumed.length === 0
|
|
1042
789
|
? one
|
|
@@ -1054,49 +801,27 @@ function readRun<Extra>(
|
|
|
1054
801
|
unansweredHeld: [
|
|
1055
802
|
...new Set([
|
|
1056
803
|
...answers.flatMap((one) => one.unanswered),
|
|
1057
|
-
...consumed.filter((one) => one.
|
|
804
|
+
...consumed.filter((one) => one.guessed === true).map((one) => one.to),
|
|
805
|
+
...read.result.consumerHeld,
|
|
1058
806
|
]),
|
|
1059
807
|
],
|
|
1060
808
|
projects,
|
|
1061
|
-
consumers: read.consumers
|
|
1062
|
-
|
|
809
|
+
consumers: read.plan.discovery.consumers,
|
|
810
|
+
declaresConsumers: scope.consumers.length > 0,
|
|
811
|
+
notBuilt: read.classified.notBuilt,
|
|
1063
812
|
unanswered: read.unanswered,
|
|
1064
|
-
componentsUnread: read.componentsUnread,
|
|
1065
|
-
librariesUnfound: read.librariesUnfound,
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
813
|
+
componentsUnread: read.plan.workspace?.componentsUnread ?? [],
|
|
814
|
+
librariesUnfound: read.classified.librariesUnfound,
|
|
815
|
+
unresolvedSpecifiers: read.classified.unresolvedSpecifiers,
|
|
816
|
+
unread: read.plan.unread,
|
|
817
|
+
conventionsApplied: read.plan.conventions.applied,
|
|
818
|
+
conventionUses: read.plan.conventions.uses,
|
|
819
|
+
memberDirs: read.plan.packages.members,
|
|
820
|
+
nestedDirs: read.plan.packages.nested,
|
|
821
|
+
workflows: read.result.workflows,
|
|
1070
822
|
};
|
|
1071
823
|
}
|
|
1072
824
|
|
|
1073
|
-
/**
|
|
1074
|
-
* The run swept under one set of marks with the records that hold. A record a component
|
|
1075
|
-
* file's markup holds counts only while the file is live, and what it holds may be what
|
|
1076
|
-
* keeps the file live, so each file's markup joins only once a sweep without it finds the
|
|
1077
|
-
* file live, until a sweep finds no further file live.
|
|
1078
|
-
*/
|
|
1079
|
-
function holdingSweep<Extra>(
|
|
1080
|
-
read: ReadRun<Extra>,
|
|
1081
|
-
input: Pick<SweepInput, "marked" | "mode">,
|
|
1082
|
-
): { readonly swept: SweepInput; readonly result: SweepResult } {
|
|
1083
|
-
const paths = new Set(read.exempt.flatMap((record) => record.whileLive ?? []));
|
|
1084
|
-
let live = new Set<string>();
|
|
1085
|
-
for (;;) {
|
|
1086
|
-
const swept: SweepInput = {
|
|
1087
|
-
...input,
|
|
1088
|
-
exempt: holdingWhile(read.exempt, live),
|
|
1089
|
-
unanswered: read.unansweredHeld,
|
|
1090
|
-
};
|
|
1091
|
-
const result = sweepMatrix(read.matrix, swept);
|
|
1092
|
-
const next = new Set(liveFilesAt(read.matrix, result, paths).map((one) => one.position.path));
|
|
1093
|
-
if (next.size === live.size) {
|
|
1094
|
-
return { swept, result };
|
|
1095
|
-
}
|
|
1096
|
-
live = next;
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
825
|
/**
|
|
1101
826
|
* The test references exemption evidence written in a test file makes: each is a read of
|
|
1102
827
|
* the declaration it would retain, made by the test file at the evidence's site.
|
|
@@ -1130,6 +855,22 @@ function evidenceReferences(
|
|
|
1130
855
|
});
|
|
1131
856
|
}
|
|
1132
857
|
|
|
858
|
+
/**
|
|
859
|
+
* The declarations a write the mode counts stores into, a write a test-support file
|
|
860
|
+
* makes being a test's.
|
|
861
|
+
*/
|
|
862
|
+
function countedWrites(
|
|
863
|
+
references: readonly Reference[],
|
|
864
|
+
support: ReadonlySet<string>,
|
|
865
|
+
mode: Mode,
|
|
866
|
+
): ReadonlySet<string> {
|
|
867
|
+
return new Set(
|
|
868
|
+
references.flatMap((reference) =>
|
|
869
|
+
reference.use === "write" && !withheldBy(mode, reference, support) ? [reference.to] : [],
|
|
870
|
+
),
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
|
|
1133
874
|
/**
|
|
1134
875
|
* The declarations every reference the mode counts stores into, a loaded consumer's
|
|
1135
876
|
* reference counting as a read: what the write-only kind would report but for a record.
|
|
@@ -1138,8 +879,9 @@ function writtenOnly<Extra>(read: ReadRun<Extra>, mode: Mode): ReadonlySet<strin
|
|
|
1138
879
|
const written = new Set<string>();
|
|
1139
880
|
const readSome = new Set<string>();
|
|
1140
881
|
for (const { configured } of read.projects) {
|
|
882
|
+
const support = new Set(configured.supportFiles ?? []);
|
|
1141
883
|
for (const reference of configured.references) {
|
|
1142
|
-
if (mode
|
|
884
|
+
if (withheldBy(mode, reference, support)) {
|
|
1143
885
|
continue;
|
|
1144
886
|
}
|
|
1145
887
|
if (reference.use === "write" && reference.consumer === undefined) {
|
|
@@ -1152,62 +894,27 @@ function writtenOnly<Extra>(read: ReadRun<Extra>, mode: Mode): ReadonlySet<strin
|
|
|
1152
894
|
return new Set([...written].filter((id) => !readSome.has(id)));
|
|
1153
895
|
}
|
|
1154
896
|
|
|
1155
|
-
/**
|
|
1156
|
-
* The sweep of a run read once, under one set of marks. Where a question went unanswered,
|
|
1157
|
-
* the run is swept once more without what that question could have kept live and without
|
|
1158
|
-
* the references that stood in for its answer, and every declaration that sweep judges
|
|
1159
|
-
* dead and this one judges live, or dead by another rule, is held by the gap too, as is
|
|
1160
|
-
* every declaration that makes such a reference.
|
|
1161
|
-
*/
|
|
897
|
+
/** The sweep of a run read once, under one set of marks. */
|
|
1162
898
|
function sweptOf<Extra>(
|
|
1163
899
|
read: ReadRun<Extra>,
|
|
1164
|
-
input: Pick<
|
|
900
|
+
input: Pick<SweepPolicy, "marked" | "mode">,
|
|
1165
901
|
): RunSweep {
|
|
1166
|
-
const
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
if (held.size > 0) {
|
|
1170
|
-
// What a declaration reads where the checker did not answer is unknown, so a rule
|
|
1171
|
-
// over what it reads, the test of dead code among them, cannot judge it.
|
|
1172
|
-
for (const { configured } of read.projects) {
|
|
1173
|
-
for (const reference of configured.references) {
|
|
1174
|
-
if (reference.resolution === "by-name") {
|
|
1175
|
-
held.add(reference.from);
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
const dead = new Map(result.candidates.map((candidate) => [candidate.id, candidate]));
|
|
1180
|
-
const answered = matrixOf(
|
|
1181
|
-
read.projects.map(({ configured }) => ({
|
|
1182
|
-
...configured,
|
|
1183
|
-
references: configured.references.filter((one) => one.resolution !== "by-name"),
|
|
1184
|
-
})),
|
|
1185
|
-
);
|
|
1186
|
-
const bare: SweepInput = {
|
|
1187
|
-
...swept,
|
|
1188
|
-
exempt: exempt.filter((record) => !isUnansweredRecord(record)),
|
|
1189
|
-
unanswered: [],
|
|
1190
|
-
};
|
|
1191
|
-
for (const candidate of sweepMatrix(answered, bare).candidates) {
|
|
1192
|
-
const kept = dead.get(candidate.id);
|
|
1193
|
-
if (
|
|
1194
|
-
kept?.testOfDeadCode !== candidate.testOfDeadCode ||
|
|
1195
|
-
kept.relation !== candidate.relation
|
|
1196
|
-
) {
|
|
1197
|
-
held.add(candidate.id);
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
902
|
+
const componentFiles = [...new Set(read.projects.flatMap((one) => one.componentFiles))].sort(
|
|
903
|
+
bytewise,
|
|
904
|
+
);
|
|
1201
905
|
return {
|
|
1202
906
|
matrix: read.matrix,
|
|
1203
|
-
sweep:
|
|
1204
|
-
|
|
1205
|
-
|
|
907
|
+
sweep: sweep(read.matrix, {
|
|
908
|
+
...input,
|
|
909
|
+
exempt: read.exempt,
|
|
910
|
+
unanswered: read.unansweredHeld,
|
|
911
|
+
componentFiles,
|
|
912
|
+
unseenCallers: !read.declaresConsumers,
|
|
913
|
+
writeOnly: writtenOnly(read, input.mode),
|
|
914
|
+
}),
|
|
1206
915
|
notBuilt: read.notBuilt,
|
|
1207
916
|
unanswered: read.unanswered,
|
|
1208
|
-
heldByUnanswered: [...held],
|
|
1209
917
|
skipped: read.projects.flatMap((one) => one.skipped),
|
|
1210
|
-
componentFiles: [...new Set(read.projects.flatMap((one) => one.componentFiles))].sort(compare),
|
|
1211
918
|
};
|
|
1212
919
|
}
|
|
1213
920
|
|
|
@@ -1223,8 +930,8 @@ export function runSweep(
|
|
|
1223
930
|
engine: Engine,
|
|
1224
931
|
host: Host,
|
|
1225
932
|
scope: Scope,
|
|
1226
|
-
config:
|
|
1227
|
-
input: Pick<
|
|
933
|
+
config: ResolvedConfig,
|
|
934
|
+
input: Pick<SweepPolicy, "marked" | "mode">,
|
|
1228
935
|
detectors: Detectors = DETECTORS,
|
|
1229
936
|
): RunSweep {
|
|
1230
937
|
return sweptOf(
|
|
@@ -1240,12 +947,27 @@ interface EmitterExtra {
|
|
|
1240
947
|
readonly needs: ReturnType<typeof projectNeeds>;
|
|
1241
948
|
readonly implementations: ReturnType<typeof implementations>;
|
|
1242
949
|
readonly heldByInclusion: readonly string[];
|
|
1243
|
-
readonly generated:
|
|
950
|
+
readonly generated: ReadonlyMap<string, GeneratedFact>;
|
|
951
|
+
readonly bindings: readonly BindingRecord[];
|
|
1244
952
|
readonly inOperands: readonly string[];
|
|
1245
953
|
readonly rooted: Roots;
|
|
1246
954
|
readonly directives: readonly InlineDirective[];
|
|
1247
955
|
readonly declarationsNamed: readonly boolean[];
|
|
1248
956
|
readonly parts: ProjectParts;
|
|
957
|
+
readonly unseenLoads: readonly UnseenLoad[];
|
|
958
|
+
readonly carriers: Carriers;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/** The project's own files below the target root that are no test file. */
|
|
962
|
+
function productionFiles<Brand>(
|
|
963
|
+
project: ProjectView<Brand>,
|
|
964
|
+
targetRoot: string,
|
|
965
|
+
testFiles: readonly string[],
|
|
966
|
+
): readonly SourceFile[] {
|
|
967
|
+
const tests = new Set(testFiles);
|
|
968
|
+
return [...sourceFilesOf(project, targetRoot).byPath].flatMap(([path, file]) =>
|
|
969
|
+
tests.has(path) ? [] : [file],
|
|
970
|
+
);
|
|
1249
971
|
}
|
|
1250
972
|
|
|
1251
973
|
/** Reads a run's projects with every per-project fact an emitter reads. */
|
|
@@ -1253,7 +975,7 @@ export function readEmitterRun(
|
|
|
1253
975
|
engine: Engine,
|
|
1254
976
|
host: Host,
|
|
1255
977
|
scope: Scope,
|
|
1256
|
-
config:
|
|
978
|
+
config: ResolvedConfig,
|
|
1257
979
|
mode: Mode,
|
|
1258
980
|
detectors: Detectors,
|
|
1259
981
|
): ReadRun<EmitterExtra> {
|
|
@@ -1265,15 +987,22 @@ export function readEmitterRun(
|
|
|
1265
987
|
config,
|
|
1266
988
|
mode,
|
|
1267
989
|
detectors,
|
|
1268
|
-
(project, read, references, testFiles) => ({
|
|
990
|
+
(project, read, references, testFiles, unseenLoads) => ({
|
|
1269
991
|
deprecation: deprecatedDeclarations(project, read.held),
|
|
1270
992
|
accessors: accessorsOf(project, read.held),
|
|
1271
|
-
needs: projectNeeds(
|
|
1272
|
-
|
|
993
|
+
needs: projectNeeds(
|
|
994
|
+
project,
|
|
995
|
+
read.held,
|
|
996
|
+
host,
|
|
997
|
+
targetRoot,
|
|
998
|
+
(fileName, text) => engine.parseSourceFile(fileName, text),
|
|
999
|
+
read.sources.configuration,
|
|
1000
|
+
read.sources.workflows,
|
|
1273
1001
|
),
|
|
1274
1002
|
implementations: implementations(project, read.held),
|
|
1275
1003
|
heldByInclusion: heldByInclusion(project, targetRoot),
|
|
1276
|
-
generated:
|
|
1004
|
+
generated: read.generated,
|
|
1005
|
+
bindings: read.bindings,
|
|
1277
1006
|
inOperands: inOperandNames(project, targetRoot, testFiles),
|
|
1278
1007
|
rooted: read.rooted,
|
|
1279
1008
|
directives: inlineDirectives(project, read.held, targetRoot).filter(
|
|
@@ -1281,9 +1010,12 @@ export function readEmitterRun(
|
|
|
1281
1010
|
),
|
|
1282
1011
|
declarationsNamed: declarationsNamed(project, read.held, configuredDeclarations(config)),
|
|
1283
1012
|
parts: projectParts(project, read.held, references, targetRoot),
|
|
1013
|
+
unseenLoads,
|
|
1014
|
+
// Only a closed world reports an unnecessary export, which is all the carriers decide.
|
|
1015
|
+
carriers: config.consumers.complete ? carriersOf(project, read.held) : NO_CARRIERS,
|
|
1284
1016
|
}),
|
|
1285
1017
|
);
|
|
1286
|
-
// Whether a declaration carries the marker decides its code, so one whose
|
|
1018
|
+
// Whether a declaration carries the marker decides its code, so one whose answer went
|
|
1287
1019
|
// unread is reported by nothing.
|
|
1288
1020
|
const unread = run.projects.flatMap((one) => one.extra.deprecation.unanswered);
|
|
1289
1021
|
return unread.length === 0
|
|
@@ -1335,24 +1067,19 @@ function judgedMembers(
|
|
|
1335
1067
|
|
|
1336
1068
|
/** The directory of the nearest `package.json` at or above a file, inside `root`, else `root`. */
|
|
1337
1069
|
function nearestManifestDir(host: Host, root: string, file: string): string {
|
|
1338
|
-
|
|
1339
|
-
if (host.kindOf(joinPath(dir, "package.json")) === "file") {
|
|
1340
|
-
return dir;
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
return root;
|
|
1070
|
+
return ancestors(dirnamePath(file), root).find((dir) => holdsManifest(host, dir)) ?? root;
|
|
1344
1071
|
}
|
|
1345
1072
|
|
|
1346
1073
|
/**
|
|
1347
1074
|
* The input every emitter reads over one sweep of a read run: the facts beside the sweep
|
|
1348
|
-
* each
|
|
1075
|
+
* each emitter reads, every per-project one read in the same session as the sweep.
|
|
1349
1076
|
*/
|
|
1350
1077
|
export function emitterInputOver(
|
|
1351
1078
|
host: Host,
|
|
1352
1079
|
scope: Scope,
|
|
1353
|
-
config:
|
|
1080
|
+
config: ResolvedConfig,
|
|
1354
1081
|
read: ReadRun<EmitterExtra>,
|
|
1355
|
-
input: Pick<
|
|
1082
|
+
input: Pick<SweepPolicy, "marked" | "mode">,
|
|
1356
1083
|
selfCheck: SelfCheckFacts,
|
|
1357
1084
|
): EmitterInput {
|
|
1358
1085
|
const targetRoot = scope.target.path;
|
|
@@ -1366,14 +1093,16 @@ export function emitterInputOver(
|
|
|
1366
1093
|
stores: storesOf(
|
|
1367
1094
|
projects.map((one) => ({
|
|
1368
1095
|
references: one.configured.references,
|
|
1096
|
+
support: new Set(one.configured.supportFiles ?? []),
|
|
1369
1097
|
accessors: one.extra.accessors,
|
|
1370
1098
|
})),
|
|
1371
|
-
swept.exempt,
|
|
1099
|
+
swept.sweep.exempt,
|
|
1372
1100
|
input.mode,
|
|
1373
1101
|
),
|
|
1374
1102
|
dependencies: dependenciesOf(
|
|
1375
1103
|
host,
|
|
1376
1104
|
targetRoot,
|
|
1105
|
+
read.workflows,
|
|
1377
1106
|
[...projects.map((one) => one.extra.needs), configurationNeeds(read.conventionUses)],
|
|
1378
1107
|
swept.sweep.candidates.map((candidate) => candidate.id),
|
|
1379
1108
|
members.read,
|
|
@@ -1384,8 +1113,19 @@ export function emitterInputOver(
|
|
|
1384
1113
|
files: {
|
|
1385
1114
|
tree: sourceTree(host, targetRoot),
|
|
1386
1115
|
heldByInclusion: new Set(projects.flatMap((one) => one.extra.heldByInclusion)),
|
|
1387
|
-
generated: new Set(projects.flatMap((one) => one.extra.generated)),
|
|
1116
|
+
generated: new Set(projects.flatMap((one) => [...one.extra.generated.keys()])),
|
|
1388
1117
|
inOperands: new Set(projects.flatMap((one) => one.extra.inOperands)),
|
|
1118
|
+
unseenLoads: projects.flatMap((one) => one.extra.unseenLoads),
|
|
1119
|
+
unwrittenRuns: new Set(
|
|
1120
|
+
projects.flatMap((one) =>
|
|
1121
|
+
one.heldScripts
|
|
1122
|
+
.filter((held) => held.unwritten)
|
|
1123
|
+
.map(
|
|
1124
|
+
(held) =>
|
|
1125
|
+
relativePath(resolvePath(host.workingDirectory(), targetRoot), held.dir) ?? ".",
|
|
1126
|
+
),
|
|
1127
|
+
),
|
|
1128
|
+
),
|
|
1389
1129
|
},
|
|
1390
1130
|
boundary: {
|
|
1391
1131
|
consumers: {
|
|
@@ -1394,12 +1134,25 @@ export function emitterInputOver(
|
|
|
1394
1134
|
},
|
|
1395
1135
|
encapsulated: readManifest(host, targetRoot).declaresExports,
|
|
1396
1136
|
edges: readEdgeSides(host, targetRoot),
|
|
1137
|
+
filledOutside: new Set(projects.flatMap((one) => one.filledOutside)),
|
|
1138
|
+
possiblyLoaded: new Set(projects.flatMap((one) => one.possiblyLoaded)),
|
|
1139
|
+
carriers: {
|
|
1140
|
+
named: new Map(
|
|
1141
|
+
[
|
|
1142
|
+
...Map.groupBy(
|
|
1143
|
+
projects.flatMap((one) => [...one.extra.carriers.named]),
|
|
1144
|
+
([id]) => id,
|
|
1145
|
+
),
|
|
1146
|
+
].map(([id, entries]) => [id, [...new Set(entries.flatMap(([, named]) => named))]]),
|
|
1147
|
+
),
|
|
1148
|
+
unread: new Set(projects.flatMap((one) => [...one.extra.carriers.unread])),
|
|
1149
|
+
},
|
|
1397
1150
|
},
|
|
1398
1151
|
selfCheck,
|
|
1399
1152
|
intraFunction: intraFunctionFacts(
|
|
1400
1153
|
projects.map((one) => one.extra.parts),
|
|
1401
1154
|
projects.flatMap((one) => one.configured.references),
|
|
1402
|
-
new Set([...swept.exempt.map((one) => one.id), ...swept.
|
|
1155
|
+
new Set([...swept.sweep.exempt.map((one) => one.id), ...swept.sweep.held]),
|
|
1403
1156
|
),
|
|
1404
1157
|
};
|
|
1405
1158
|
}
|
|
@@ -1429,14 +1182,14 @@ interface AnalysisReader {
|
|
|
1429
1182
|
* directives, the ignore file's entries and the baseline's rows are bound before any
|
|
1430
1183
|
* sweep, and the run is swept once under every bound record's mark and once under none,
|
|
1431
1184
|
* so a record is decided against the finding its code would have produced. The
|
|
1432
|
-
*
|
|
1185
|
+
* configuration family reports the refused suppressions and the roots that named nothing.
|
|
1433
1186
|
* Beside the inputs it answers the projects and test-file rules a report names.
|
|
1434
1187
|
*/
|
|
1435
1188
|
function readAnalysis(
|
|
1436
1189
|
engine: Engine,
|
|
1437
1190
|
host: Host,
|
|
1438
1191
|
scope: Scope,
|
|
1439
|
-
config:
|
|
1192
|
+
config: ResolvedConfig,
|
|
1440
1193
|
provenance: Provenance,
|
|
1441
1194
|
mode: Mode,
|
|
1442
1195
|
detectors: Detectors,
|
|
@@ -1457,7 +1210,7 @@ function readAnalysis(
|
|
|
1457
1210
|
configFile: one.configFile,
|
|
1458
1211
|
})),
|
|
1459
1212
|
testFileRules: testFileRulesOf(
|
|
1460
|
-
config.ts.
|
|
1213
|
+
config.ts.test_files,
|
|
1461
1214
|
read.projects.flatMap((one) => one.configured.testFiles),
|
|
1462
1215
|
read.projects.flatMap((one) => one.configured.supportFiles ?? []),
|
|
1463
1216
|
),
|
|
@@ -1474,8 +1227,16 @@ function readAnalysis(
|
|
|
1474
1227
|
unanswered: read.unanswered,
|
|
1475
1228
|
componentsUnread: read.componentsUnread,
|
|
1476
1229
|
librariesUnfound: read.librariesUnfound,
|
|
1230
|
+
unresolvedSpecifiers: read.unresolvedSpecifiers,
|
|
1231
|
+
unread: read.unread,
|
|
1477
1232
|
conventionsApplied: read.conventionsApplied,
|
|
1478
1233
|
unmappedEntries: unmappedEverywhere(read.projects),
|
|
1234
|
+
heldScripts: read.projects.flatMap((one) =>
|
|
1235
|
+
one.heldScripts.map((held) => ({ ...held, configFile: one.configFile })),
|
|
1236
|
+
),
|
|
1237
|
+
unseenLoads: read.projects.flatMap((one) => one.extra.unseenLoads),
|
|
1238
|
+
generated: new Map(read.projects.flatMap((one) => [...one.extra.generated])),
|
|
1239
|
+
bindings: distinctBindings(read.projects.flatMap((one) => one.extra.bindings)),
|
|
1479
1240
|
},
|
|
1480
1241
|
configured: read.projects.map((one) => one.configured),
|
|
1481
1242
|
symbols,
|
|
@@ -1487,7 +1248,7 @@ function readAnalysis(
|
|
|
1487
1248
|
function inputsOver(
|
|
1488
1249
|
host: Host,
|
|
1489
1250
|
scope: Scope,
|
|
1490
|
-
config:
|
|
1251
|
+
config: ResolvedConfig,
|
|
1491
1252
|
provenance: Provenance,
|
|
1492
1253
|
mode: Mode,
|
|
1493
1254
|
read: ReadRun<EmitterExtra>,
|
|
@@ -1501,7 +1262,7 @@ function inputsOver(
|
|
|
1501
1262
|
const facts: SelfCheckFacts = {
|
|
1502
1263
|
refusals: suppressions.refusals,
|
|
1503
1264
|
unmatchedRoots: unmatchedEverywhere(
|
|
1504
|
-
config.
|
|
1265
|
+
config.roots.patterns,
|
|
1505
1266
|
read.projects.map((one) => one.extra.rooted),
|
|
1506
1267
|
),
|
|
1507
1268
|
rootsDocument: documentOf(host, provenance, ROOTS_SETTING, targetRoot),
|
|
@@ -1570,10 +1331,22 @@ interface RunFacts {
|
|
|
1570
1331
|
readonly componentsUnread: readonly ComponentsUnread[];
|
|
1571
1332
|
/** Per analyzed configuration, each library it names that the compiler cannot find. */
|
|
1572
1333
|
readonly librariesUnfound: readonly LibraryUnfound[];
|
|
1334
|
+
/** The relative specifiers of the run's unchecked JavaScript files that resolve to no file. */
|
|
1335
|
+
readonly unresolvedSpecifiers: readonly UnresolvedSpecifier[];
|
|
1336
|
+
/** The inputs the run could not read. */
|
|
1337
|
+
readonly unread: readonly UnreadInput[];
|
|
1573
1338
|
/** The convention rows the run applied. */
|
|
1574
1339
|
readonly conventionsApplied: readonly AppliedConvention[];
|
|
1575
1340
|
/** The manifest entries no project of the run reads back to a file, each once. */
|
|
1576
1341
|
readonly unmappedEntries: readonly ManifestEntry[];
|
|
1342
|
+
/** Per project, by its compiler configuration file, each package whose command strings name files it holds. */
|
|
1343
|
+
readonly heldScripts: readonly (HeldScripts & { readonly configFile: string })[];
|
|
1344
|
+
/** The loads of production files whose target the run cannot resolve, per configuration. */
|
|
1345
|
+
readonly unseenLoads: readonly UnseenLoad[];
|
|
1346
|
+
/** Every generated file of the run, by its path below the target root, each once. */
|
|
1347
|
+
readonly generated: ReadonlyMap<string, GeneratedFact>;
|
|
1348
|
+
/** Every binding record the run's generated files publish, each once. */
|
|
1349
|
+
readonly bindings: readonly BindingRecord[];
|
|
1577
1350
|
}
|
|
1578
1351
|
|
|
1579
1352
|
/** One configuration whose component files a run cannot read. */
|
|
@@ -1582,13 +1355,6 @@ interface ComponentsUnread {
|
|
|
1582
1355
|
readonly reason: string;
|
|
1583
1356
|
}
|
|
1584
1357
|
|
|
1585
|
-
/** One library an analyzed configuration names that the compiler cannot find. */
|
|
1586
|
-
interface LibraryUnfound {
|
|
1587
|
-
readonly configFile: string;
|
|
1588
|
-
/** The compiler's error, rendered as a dropped configuration's is. */
|
|
1589
|
-
readonly error: string;
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
1358
|
/** The findings of one run, beside what a report states about the run itself. */
|
|
1593
1359
|
export interface RunAnalysis {
|
|
1594
1360
|
readonly result: PassResult;
|
|
@@ -1601,7 +1367,7 @@ export interface RunAnalysis {
|
|
|
1601
1367
|
|
|
1602
1368
|
/**
|
|
1603
1369
|
* The analysis of the run the scope and the configuration describe: the run read with its
|
|
1604
|
-
* suppressions bound, every
|
|
1370
|
+
* suppressions bound, every emitter's findings with the suppressions applied and the
|
|
1605
1371
|
* declared edges evaluated, the projects and test-file rules the report names, and the sweep
|
|
1606
1372
|
* an explanation reads.
|
|
1607
1373
|
*/
|
|
@@ -1609,7 +1375,7 @@ export function runAnalysis(
|
|
|
1609
1375
|
engine: Engine,
|
|
1610
1376
|
host: Host,
|
|
1611
1377
|
scope: Scope,
|
|
1612
|
-
config:
|
|
1378
|
+
config: ResolvedConfig,
|
|
1613
1379
|
provenance: Provenance,
|
|
1614
1380
|
mode: Mode,
|
|
1615
1381
|
detectors: Detectors = DETECTORS,
|
|
@@ -1621,14 +1387,22 @@ export function runAnalysis(
|
|
|
1621
1387
|
|
|
1622
1388
|
/**
|
|
1623
1389
|
* One count per configuration of the run in which the checker left a question unanswered:
|
|
1624
|
-
* the questions asked in its project,
|
|
1390
|
+
* the questions asked in its project, a formed program's manifest that does not parse or cannot
|
|
1391
|
+
* be read and a package whose command strings name files the project holds each counted as one, and the
|
|
1392
|
+
* declarations of its own the run holds for them.
|
|
1625
1393
|
*/
|
|
1626
1394
|
export function unansweredCounts(analysis: RunAnalysis): readonly UnansweredCount[] {
|
|
1627
|
-
const held = new Set(analysis.swept.
|
|
1395
|
+
const held = new Set(analysis.swept.sweep.held);
|
|
1628
1396
|
return analysis.run.projects.flatMap((project) => {
|
|
1629
|
-
const questions =
|
|
1630
|
-
(one) => one.configFile === project.configFile
|
|
1631
|
-
|
|
1397
|
+
const questions =
|
|
1398
|
+
analysis.run.unanswered.filter((one) => one.configFile === project.configFile).length +
|
|
1399
|
+
analysis.run.unread.filter(
|
|
1400
|
+
(one) => one.kind === "manifest" && one.configFile === project.configFile,
|
|
1401
|
+
).length +
|
|
1402
|
+
analysis.run.heldScripts.filter(
|
|
1403
|
+
(one) => one.configFile === project.configFile && one.files.length > 0,
|
|
1404
|
+
).length;
|
|
1405
|
+
|
|
1632
1406
|
if (questions === 0) {
|
|
1633
1407
|
return [];
|
|
1634
1408
|
}
|
|
@@ -1665,7 +1439,7 @@ export function runBaselineWrite(
|
|
|
1665
1439
|
engine: Engine,
|
|
1666
1440
|
host: Host,
|
|
1667
1441
|
scope: Scope,
|
|
1668
|
-
config:
|
|
1442
|
+
config: ResolvedConfig,
|
|
1669
1443
|
provenance: Provenance,
|
|
1670
1444
|
mode: Mode,
|
|
1671
1445
|
reason: string,
|