@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
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The root set of one project: every declaration kept live without a reference, and why.
|
|
3
|
+
* Every root seeds reachability and none counts as a reference; a root of a kind that
|
|
4
|
+
* names a caller is live under reference counting too, which the sweep decides, so a
|
|
5
|
+
* published export, which only supposes a consumer, stays a reference-counting candidate.
|
|
6
|
+
*/
|
|
7
|
+
import { aliasChains } from "../alias-chain.js";
|
|
8
|
+
import { filesNamedBy, outsideChain } from "../entries/configuration-files.js";
|
|
9
|
+
import { relativeSpecifiers } from "../entries/static-module.js";
|
|
10
|
+
import { nodeKey } from "../inventory.js";
|
|
11
|
+
import { ancestors, dirnamePath, relativePath, resolvePath } from "../paths.js";
|
|
12
|
+
import { byPosition } from "../position.js";
|
|
13
|
+
import { UNANSWERED } from "../query.js";
|
|
14
|
+
import { sourceFilesOf } from "../source-files.js";
|
|
15
|
+
import { typeQueryAliases } from "../type-query-alias.js";
|
|
16
|
+
import { bytewise } from "../text/compare.js";
|
|
17
|
+
import { holdsManifest } from "../fs/manifest.js";
|
|
18
|
+
import { globExpression } from "../text/glob.js";
|
|
19
|
+
import { heldWords } from "../commands/held.js";
|
|
20
|
+
import { spelledFiles } from "../text/named-files.js";
|
|
21
|
+
import { extensionOf, OUTPUT_EXTENSIONS } from "../extensions.js";
|
|
22
|
+
import { publishedAPI, releaseTagged } from "./published-reach.js";
|
|
23
|
+
import { skippedRoots } from "../type-errors.js";
|
|
24
|
+
import { mergedGlobalInterfaces } from "../augmentations.js";
|
|
25
|
+
/** Whether one declaration is written below the directory of a published workspace member. */
|
|
26
|
+
function inPublishedMember(held, id, root, members) {
|
|
27
|
+
const path = held.symbols.find((symbol) => symbol.id === id)?.position.path;
|
|
28
|
+
if (path === undefined || members === undefined) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const file = resolvePath(root, path);
|
|
32
|
+
return [...members].some((dir) => file.startsWith(`${dir}/`));
|
|
33
|
+
}
|
|
34
|
+
/** The kind of root each role of a manifest entry makes. */
|
|
35
|
+
const ENTRY_KINDS = {
|
|
36
|
+
import: "manifest-entry",
|
|
37
|
+
run: "manifest-binary",
|
|
38
|
+
script: "script",
|
|
39
|
+
};
|
|
40
|
+
/** The rules whose rooted files a manifest target is read back to by name. */
|
|
41
|
+
const READ_BACK_RULES = new Set([
|
|
42
|
+
"configuration-file",
|
|
43
|
+
"configuration-string",
|
|
44
|
+
"html-entry",
|
|
45
|
+
]);
|
|
46
|
+
/** The extension a source file's name drops. */
|
|
47
|
+
const SOURCE_EXTENSION = /\.(?:d\.)?[cm]?[jt]sx?$/u;
|
|
48
|
+
/** Whether no `package.json` sits between one file and the manifest's directory, which holds it. */
|
|
49
|
+
function ofPackage(host, dir, file) {
|
|
50
|
+
const between = ancestors(dirnamePath(file), dir);
|
|
51
|
+
return between.length > 0 && !between.slice(0, -1).some((at) => holdsManifest(host, at));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The rooted files one manifest target reads back to by name: its path below the
|
|
55
|
+
* manifest's directory, past its first directory where it names one, without its output
|
|
56
|
+
* extension, is the name, and a rooted file of the manifest's own package is one whose
|
|
57
|
+
* path below the same directory, without its source extension, ends with that name at a
|
|
58
|
+
* directory boundary.
|
|
59
|
+
*/
|
|
60
|
+
function readBackByName(host, entry, rooted) {
|
|
61
|
+
const dir = resolvePath(host.workingDirectory(), entry.dir);
|
|
62
|
+
const below = relativePath(dir, resolvePath(host.workingDirectory(), entry.path));
|
|
63
|
+
if (below === undefined || below === "") {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const cut = below.indexOf("/");
|
|
67
|
+
const written = cut === -1 ? below : below.slice(cut + 1);
|
|
68
|
+
const name = written.slice(0, written.length - (extensionOf(written, OUTPUT_EXTENSIONS)?.length ?? 0));
|
|
69
|
+
if (name === "") {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
const found = new Map();
|
|
73
|
+
for (const file of rooted) {
|
|
74
|
+
const path = relativePath(dir, file.fileName)?.replace(SOURCE_EXTENSION, "");
|
|
75
|
+
if (path !== undefined &&
|
|
76
|
+
(path === name || path.endsWith(`/${name}`)) &&
|
|
77
|
+
ofPackage(host, dir, file.fileName)) {
|
|
78
|
+
found.set(file.fileName, file);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return [...found.values()];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The program files a manifest target no program holds reaches: the target is a file
|
|
85
|
+
* read as a configuration file outside the program is, and each file of the chain it
|
|
86
|
+
* starts loads the program files its relative specifiers name, read through the emit
|
|
87
|
+
* mapping, as a command's shim loads the compiled entry it runs.
|
|
88
|
+
*/
|
|
89
|
+
function throughOutside(options, targetRoot, files, entry) {
|
|
90
|
+
const cwd = options.host.workingDirectory();
|
|
91
|
+
const path = resolvePath(cwd, entry.path);
|
|
92
|
+
if (options.parse === undefined ||
|
|
93
|
+
options.runFiles?.has(path) === true ||
|
|
94
|
+
options.host.kindOf(path) !== "file") {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
const chain = outsideChain(options.host, targetRoot, files, options.parse, [
|
|
98
|
+
{ path, manifestDir: resolvePath(cwd, entry.dir) },
|
|
99
|
+
]);
|
|
100
|
+
const found = new Map();
|
|
101
|
+
for (const { file } of chain) {
|
|
102
|
+
for (const specifier of relativeSpecifiers(file)) {
|
|
103
|
+
for (const named of filesNamedBy(files, dirnamePath(file.fileName), specifier)) {
|
|
104
|
+
found.set(named.fileName, named);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return [...found.values()];
|
|
109
|
+
}
|
|
110
|
+
/** Whether a configured string carries either special character. */
|
|
111
|
+
function isPattern(text) {
|
|
112
|
+
return text.includes("*") || text.includes("?");
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Whether ref matches a pattern whose only special characters are `*`, which stands
|
|
116
|
+
* for any run of characters including the solidus, and `?`, which stands for exactly
|
|
117
|
+
* one character counted as a code point. A star keeps the position it last stood at,
|
|
118
|
+
* so the shortest run it can stand for is tried first.
|
|
119
|
+
*/
|
|
120
|
+
function matchGlob(pattern, ref) {
|
|
121
|
+
let next = 0;
|
|
122
|
+
let star = -1;
|
|
123
|
+
let resume = 0;
|
|
124
|
+
let at = 0;
|
|
125
|
+
while (at < ref.length) {
|
|
126
|
+
if (next < pattern.length && (pattern[next] === "?" || pattern[next] === ref[at])) {
|
|
127
|
+
next += 1;
|
|
128
|
+
at += 1;
|
|
129
|
+
}
|
|
130
|
+
else if (next < pattern.length && pattern[next] === "*") {
|
|
131
|
+
star = next;
|
|
132
|
+
resume = at;
|
|
133
|
+
next += 1;
|
|
134
|
+
}
|
|
135
|
+
else if (star >= 0) {
|
|
136
|
+
resume += 1;
|
|
137
|
+
next = star + 1;
|
|
138
|
+
at = resume;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
while (next < pattern.length && pattern[next] === "*") {
|
|
145
|
+
next += 1;
|
|
146
|
+
}
|
|
147
|
+
return next === pattern.length;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Whether one configured string names the symbol reference ref. A string carrying
|
|
151
|
+
* neither special character names only the reference it spells.
|
|
152
|
+
*
|
|
153
|
+
* Both sides are read as code points: a character outside the basic plane is two
|
|
154
|
+
* string units, and `?` stands for one character.
|
|
155
|
+
*/
|
|
156
|
+
export function matchRef(pattern, ref) {
|
|
157
|
+
if (!isPattern(pattern)) {
|
|
158
|
+
return pattern === ref;
|
|
159
|
+
}
|
|
160
|
+
return matchGlob(Array.from(pattern), Array.from(ref));
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Per package, the own files the words of its held texts name, as `spelledFiles` reads them,
|
|
164
|
+
* but those a root enters with all they export: a command can use no more of such a file than
|
|
165
|
+
* the root keeps live. A manifest's are its entries' held texts, and the target root's package
|
|
166
|
+
* has the workflow steps, git hooks and makefile recipes beside its own, with the values of
|
|
167
|
+
* each file they are read from. A package is listed too where a word that may write the file
|
|
168
|
+
* a command runs writes no path text.
|
|
169
|
+
*/
|
|
170
|
+
function scriptHolds(entries, files, entered, host, targetRoot, workflows) {
|
|
171
|
+
const rooted = new Set(entered.filter((one) => one.exports && one.names === undefined).map((one) => one.file.fileName));
|
|
172
|
+
const spelled = [...files.byName.values()]
|
|
173
|
+
.filter((file) => !rooted.has(file.fileName))
|
|
174
|
+
.map((file) => ({ file, paths: [file.fileName, ...files.writtenAs(file)] }));
|
|
175
|
+
const cwd = host.workingDirectory();
|
|
176
|
+
const root = resolvePath(cwd, targetRoot);
|
|
177
|
+
const commands = new Map([[root, [...workflows.held]]]);
|
|
178
|
+
for (const entry of entries) {
|
|
179
|
+
if (entry.held !== undefined) {
|
|
180
|
+
const dir = resolvePath(cwd, entry.dir);
|
|
181
|
+
commands.set(dir, [...(commands.get(dir) ?? []), ...entry.held]);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const held = [];
|
|
185
|
+
for (const [dir, texts] of commands) {
|
|
186
|
+
const named = spelledFiles(heldWords(texts), dir, root, spelled);
|
|
187
|
+
if (named.files.length > 0 || named.unwritten) {
|
|
188
|
+
const paths = named.files.map((file) => relativePath(targetRoot, file.fileName) ?? file.fileName);
|
|
189
|
+
held.push({ dir, files: paths, unwritten: named.unwritten });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return held;
|
|
193
|
+
}
|
|
194
|
+
/** The target's manifest entries, then those of its other packages. */
|
|
195
|
+
function packageEntries(options) {
|
|
196
|
+
return [
|
|
197
|
+
...options.manifest.entries.map((entry) => ({
|
|
198
|
+
entry,
|
|
199
|
+
publishes: options.publishedAPI &&
|
|
200
|
+
entry.published &&
|
|
201
|
+
(options.manifest.declaresExports ? entry.member.startsWith("exports") : true),
|
|
202
|
+
})),
|
|
203
|
+
...(options.otherPackages ?? []).map((entry) => ({
|
|
204
|
+
entry,
|
|
205
|
+
publishes: entry.published &&
|
|
206
|
+
(options.publishedAPI || options.publishedMembers?.has(entry.dir) === true),
|
|
207
|
+
})),
|
|
208
|
+
];
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* The program files one manifest entry names, read once per entry: its path, else its
|
|
212
|
+
* output's source, else a rooted file of `readBackTo` by name, else the chain it starts
|
|
213
|
+
* outside every program.
|
|
214
|
+
*/
|
|
215
|
+
function entryFileReader(options, targetRoot, files, readBackTo) {
|
|
216
|
+
const read = new Map();
|
|
217
|
+
const readEntry = (entry) => {
|
|
218
|
+
const named = files.named(entry.path);
|
|
219
|
+
if (named.length > 0 || entry.role === "script") {
|
|
220
|
+
return named;
|
|
221
|
+
}
|
|
222
|
+
const cwd = options.host.workingDirectory();
|
|
223
|
+
const shipped = files.namedAsOutput(resolvePath(cwd, entry.dir), resolvePath(cwd, entry.path));
|
|
224
|
+
if (shipped.length > 0) {
|
|
225
|
+
return shipped;
|
|
226
|
+
}
|
|
227
|
+
const byName = readBackByName(options.host, entry, readBackTo);
|
|
228
|
+
return byName.length > 0 ? byName : throughOutside(options, targetRoot, files, entry);
|
|
229
|
+
};
|
|
230
|
+
return (entry) => {
|
|
231
|
+
const known = read.get(entry) ?? readEntry(entry);
|
|
232
|
+
read.set(entry, known);
|
|
233
|
+
return known;
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/** The files `ts.entry_files` names, each with the pattern that names it. */
|
|
237
|
+
function patternedFiles(files, patterns) {
|
|
238
|
+
const patterned = [];
|
|
239
|
+
for (const pattern of patterns) {
|
|
240
|
+
const expression = globExpression(pattern);
|
|
241
|
+
for (const [path, file] of files.byPath) {
|
|
242
|
+
if (expression.test(path)) {
|
|
243
|
+
patterned.push({ file, pattern });
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return patterned;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* The files every root source enters, in the order manifest entries, entry-file patterns,
|
|
251
|
+
* entry sources; the files whose exports a consumer outside the target reaches; and the
|
|
252
|
+
* entries that name no file even read back by name to another entered file.
|
|
253
|
+
*/
|
|
254
|
+
function enteredFiles(options, targetRoot, files, entries) {
|
|
255
|
+
const points = options.sources.entered;
|
|
256
|
+
const scripted = entries.flatMap(({ entry }) => entry.role === "script" && entry.held === undefined ? files.named(entry.path) : []);
|
|
257
|
+
const entryFiles = entryFileReader(options, targetRoot, files, [
|
|
258
|
+
...scripted,
|
|
259
|
+
...points.filter((point) => READ_BACK_RULES.has(point.rule)).map((point) => point.file),
|
|
260
|
+
]);
|
|
261
|
+
const published = entries.flatMap(({ entry, publishes }) => (publishes ? entryFiles(entry) : []));
|
|
262
|
+
if (options.publishedAPI) {
|
|
263
|
+
// A library's bundle hands what its entry exports to every program that loads it.
|
|
264
|
+
published.push(...points.filter((point) => point.rule === "bundler-entry").map((point) => point.file));
|
|
265
|
+
}
|
|
266
|
+
const publishedNames = new Set(published.map((file) => file.fileName));
|
|
267
|
+
const patterned = patternedFiles(files, options.entryFiles);
|
|
268
|
+
const entered = [];
|
|
269
|
+
const unmapped = [];
|
|
270
|
+
const mapped = patterned.map(({ file }) => file);
|
|
271
|
+
for (const { entry } of entries) {
|
|
272
|
+
if (entry.held !== undefined) {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
const named = entryFiles(entry);
|
|
276
|
+
if (named.length === 0 && entry.role !== "script") {
|
|
277
|
+
unmapped.push(entry);
|
|
278
|
+
}
|
|
279
|
+
mapped.push(...named);
|
|
280
|
+
for (const file of named) {
|
|
281
|
+
const kind = ENTRY_KINDS[entry.role];
|
|
282
|
+
entered.push({
|
|
283
|
+
file,
|
|
284
|
+
kind,
|
|
285
|
+
source: entry.member,
|
|
286
|
+
exports: !publishedNames.has(file.fileName),
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
for (const { file, pattern } of patterned) {
|
|
291
|
+
entered.push({ file, kind: "entry-file", source: pattern, exports: true });
|
|
292
|
+
}
|
|
293
|
+
for (const point of points) {
|
|
294
|
+
entered.push({
|
|
295
|
+
file: point.file,
|
|
296
|
+
kind: point.rule,
|
|
297
|
+
source: point.source,
|
|
298
|
+
exports: point.exports,
|
|
299
|
+
...(point.names === undefined ? {} : { names: point.names }),
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
entered,
|
|
304
|
+
published,
|
|
305
|
+
unmappedEntries: unmapped.filter((entry) => readBackByName(options.host, entry, mapped).length === 0),
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
/** Every declaration and container of a `typeof import(...)` global, with the type's text. */
|
|
309
|
+
function typeQueryRoots(files, declared, add) {
|
|
310
|
+
for (const file of files.byPath.values()) {
|
|
311
|
+
for (const alias of typeQueryAliases(file)) {
|
|
312
|
+
const source = alias.type.getText().replace(/\s+/gu, " ");
|
|
313
|
+
for (const node of [alias.declaration, ...alias.containers]) {
|
|
314
|
+
const id = declared.get(nodeKey(file, node));
|
|
315
|
+
if (id !== undefined) {
|
|
316
|
+
add(id, "type-query-alias", source);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/** The roots in the order {@link Roots.liveUnderReachability} states. */
|
|
323
|
+
function orderedRoots(found, held) {
|
|
324
|
+
const sites = new Map(held.symbols.map((symbol) => [symbol.id, symbol.position]));
|
|
325
|
+
return [...found].sort((a, b) => {
|
|
326
|
+
const left = sites.get(a.id);
|
|
327
|
+
const right = sites.get(b.id);
|
|
328
|
+
const site = left === undefined || right === undefined ? 0 : byPosition(left, right);
|
|
329
|
+
return site || bytewise(a.kind, b.kind) || bytewise(a.source, b.source);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* The roots one project holds, and every configured string that named nothing in it. A
|
|
334
|
+
* file a manifest member, an entry-file pattern or a tool's configuration names is a root
|
|
335
|
+
* with each name of its export table and every re-export link to what it carries; in a
|
|
336
|
+
* library, the published API alone roots what a published file exports. A test file is a
|
|
337
|
+
* root by itself, and so is each declaration a type error's skip keeps and each global
|
|
338
|
+
* interface merging into one declared outside the project.
|
|
339
|
+
*/
|
|
340
|
+
export function rootSet(project, held, targetRoot, options) {
|
|
341
|
+
const files = sourceFilesOf(project, targetRoot);
|
|
342
|
+
const fileIds = new Map();
|
|
343
|
+
for (const file of files.byName.values()) {
|
|
344
|
+
const id = held.declarations.get(nodeKey(file, file));
|
|
345
|
+
if (id !== undefined) {
|
|
346
|
+
fileIds.set(file.fileName, id);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
const found = new Map();
|
|
350
|
+
const add = (id, kind, source) => {
|
|
351
|
+
found.set([id, kind, source].join("\u0000"), { id, kind, source });
|
|
352
|
+
};
|
|
353
|
+
const entries = packageEntries(options);
|
|
354
|
+
const { entered, published, unmappedEntries } = enteredFiles(options, targetRoot, files, entries);
|
|
355
|
+
const heldScripts = scriptHolds(entries.map(({ entry }) => entry), files, entered, options.host, targetRoot, options.sources.workflows);
|
|
356
|
+
const heldFiles = [...new Set(heldScripts.flatMap((one) => one.files))].flatMap((path) => files.byPath.get(path) ?? []);
|
|
357
|
+
typeQueryRoots(files, held.declarations, add);
|
|
358
|
+
const { tables: exportsOf, named, answered, } = exportTables(project, held, [
|
|
359
|
+
...entered.filter((entry) => entry.exports).map((entry) => entry.file),
|
|
360
|
+
...published,
|
|
361
|
+
...heldFiles,
|
|
362
|
+
]);
|
|
363
|
+
for (const entry of entered) {
|
|
364
|
+
const id = fileIds.get(entry.file.fileName);
|
|
365
|
+
if (id === undefined) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
add(id, entry.kind, entry.source);
|
|
369
|
+
if (entry.exports) {
|
|
370
|
+
const byName = named.get(entry.file.fileName);
|
|
371
|
+
const exported = entry.names === undefined || byName === undefined
|
|
372
|
+
? (exportsOf.get(entry.file.fileName) ?? [])
|
|
373
|
+
: entry.names.flatMap((name) => byName.get(name) ?? []);
|
|
374
|
+
for (const one of exported) {
|
|
375
|
+
add(one, entry.kind, entry.source);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const tagged = releaseTagged(held, files).filter((id) => options.publishedAPI || inPublishedMember(held, id, targetRoot, options.publishedMembers));
|
|
380
|
+
const api = published.length > 0 || tagged.length > 0
|
|
381
|
+
? publishedAPI(project, published, exportsOf, held, files.byPath, tagged)
|
|
382
|
+
: { ids: [], guessed: [] };
|
|
383
|
+
for (const id of api.ids) {
|
|
384
|
+
add(id, "published-api", "");
|
|
385
|
+
}
|
|
386
|
+
const unmatched = configured(held, options.patterns, add);
|
|
387
|
+
for (const id of skippedRoots(project, held, options.skips)) {
|
|
388
|
+
add(id, "type-error", "");
|
|
389
|
+
}
|
|
390
|
+
for (const id of mergedGlobalInterfaces(project, held, files).kept) {
|
|
391
|
+
add(id, "global-augmentation", "");
|
|
392
|
+
}
|
|
393
|
+
return {
|
|
394
|
+
liveUnderReachability: orderedRoots(found.values(), held),
|
|
395
|
+
unmatched,
|
|
396
|
+
unanswered: [
|
|
397
|
+
...(answered ? api.guessed : held.symbols.map((symbol) => symbol.id)),
|
|
398
|
+
// A command runs a held file and may read any export of it, so the file, which reaches its
|
|
399
|
+
// top level, and its exports are held; a declaration neither reaches is still dead.
|
|
400
|
+
...heldFiles.flatMap((file) => {
|
|
401
|
+
const id = fileIds.get(file.fileName);
|
|
402
|
+
return [...(id === undefined ? [] : [id]), ...(exportsOf.get(file.fileName) ?? [])];
|
|
403
|
+
}),
|
|
404
|
+
],
|
|
405
|
+
unmappedEntries,
|
|
406
|
+
heldScripts,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Every declaration each file's module exports, by the file's name: the declaration
|
|
411
|
+
* each name of the export table is, and every link of a re-export's chain. A name
|
|
412
|
+
* whose declaration is outside the project's own files names nothing here. One batch
|
|
413
|
+
* resolves every file to its module and one request per module reads its export
|
|
414
|
+
* table, star re-exports resolved into it. A file that is no module exports nothing.
|
|
415
|
+
* `answered` is false where the checker left a table or a link of a chain unanswered.
|
|
416
|
+
*/
|
|
417
|
+
function exportTables(project, held, wanted) {
|
|
418
|
+
const unique = [...new Map(wanted.map((file) => [file.fileName, file])).values()];
|
|
419
|
+
const tables = new Map();
|
|
420
|
+
const named = new Map();
|
|
421
|
+
let answered = true;
|
|
422
|
+
if (unique.length === 0) {
|
|
423
|
+
return { tables, named, answered };
|
|
424
|
+
}
|
|
425
|
+
const modules = project.symbolsAt(unique.map((file) => project.handle(file)));
|
|
426
|
+
const chains = aliasChains(project, held);
|
|
427
|
+
const topLevel = (file) => {
|
|
428
|
+
const fileId = held.declarations.get(nodeKey(file, file));
|
|
429
|
+
return held.symbols.filter((symbol) => symbol.parent === fileId).map((symbol) => symbol.id);
|
|
430
|
+
};
|
|
431
|
+
unique.forEach((file, index) => {
|
|
432
|
+
const module = modules[index];
|
|
433
|
+
if (module === undefined) {
|
|
434
|
+
tables.set(file.fileName, []);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const table = module === UNANSWERED ? UNANSWERED : project.queries.exportsOfModule(module);
|
|
438
|
+
if (table === UNANSWERED) {
|
|
439
|
+
answered = false;
|
|
440
|
+
tables.set(file.fileName, topLevel(file));
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const ids = new Set();
|
|
444
|
+
const byName = new Map();
|
|
445
|
+
for (const exported of table) {
|
|
446
|
+
for (const target of chains.chainOf(exported)) {
|
|
447
|
+
answered &&= !target.guessed;
|
|
448
|
+
ids.add(target.id);
|
|
449
|
+
byName.set(exported.name, [...(byName.get(exported.name) ?? []), target.id]);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
tables.set(file.fileName, [...ids]);
|
|
453
|
+
named.set(file.fileName, byName);
|
|
454
|
+
});
|
|
455
|
+
return { tables, named, answered };
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Keeps every declaration the configuration names and returns every string that
|
|
459
|
+
* named none, in configuration order. A string the configuration lists twice is one
|
|
460
|
+
* configured root.
|
|
461
|
+
*/
|
|
462
|
+
function configured(held, patterns, add) {
|
|
463
|
+
const unmatched = [];
|
|
464
|
+
for (const pattern of new Set(patterns)) {
|
|
465
|
+
const kind = isPattern(pattern) ? "pattern" : "configured";
|
|
466
|
+
let matched = false;
|
|
467
|
+
for (const symbol of held.symbols) {
|
|
468
|
+
if (matchRef(pattern, symbol.ref)) {
|
|
469
|
+
add(symbol.id, kind, pattern);
|
|
470
|
+
matched = true;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (!matched) {
|
|
474
|
+
unmatched.push(pattern);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return unmatched;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Every configured string that named no declaration in any project of the run, in
|
|
481
|
+
* configuration order and each once. The finding is about the configuration, so a string
|
|
482
|
+
* naming a declaration of one project has named something, and a run with no project
|
|
483
|
+
* names nothing with any of them.
|
|
484
|
+
*/
|
|
485
|
+
export function unmatchedEverywhere(patterns, perProject) {
|
|
486
|
+
return [...new Set(patterns)].filter((pattern) => perProject.every((project) => project.unmatched.includes(pattern)));
|
|
487
|
+
}
|