@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
|
@@ -17,13 +17,13 @@ import {
|
|
|
17
17
|
type Node,
|
|
18
18
|
} from "@typescript/native/ast";
|
|
19
19
|
import { SymbolFlags, type NodeHandle, type Symbol as TSSymbol } from "@typescript/native/sync";
|
|
20
|
-
import type { AliasChains } from "
|
|
21
|
-
import { resolvedTargets } from "
|
|
22
|
-
import type {
|
|
23
|
-
import { declaredComponent, type Inventory } from "
|
|
24
|
-
import { must, Unanswerable } from "
|
|
25
|
-
import { nameComponent } from "
|
|
26
|
-
import type { ProjectView } from "
|
|
20
|
+
import type { AliasChains } from "../alias-chain.ts";
|
|
21
|
+
import { resolvedTargets } from "../calls.ts";
|
|
22
|
+
import type { DeclarationEntry, ResolvedConfig } from "../config.ts";
|
|
23
|
+
import { declaredComponent, type Inventory } from "../inventory.ts";
|
|
24
|
+
import { must, Unanswerable } from "../query.ts";
|
|
25
|
+
import { nameComponent } from "../ref.ts";
|
|
26
|
+
import type { ProjectView } from "../session.ts";
|
|
27
27
|
|
|
28
28
|
/** The meanings a name of the global scope is looked up under: any of them. */
|
|
29
29
|
const ANY_MEANING: SymbolFlags = SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace;
|
|
@@ -204,6 +204,9 @@ function modulesNamed<Brand>(
|
|
|
204
204
|
project: ProjectView<Brand>,
|
|
205
205
|
specifiers: ReadonlySet<string>,
|
|
206
206
|
): ReadonlyMap<string, TSSymbol> {
|
|
207
|
+
if (specifiers.size === 0) {
|
|
208
|
+
return new Map();
|
|
209
|
+
}
|
|
207
210
|
const written = new Map<string, Node>();
|
|
208
211
|
for (const file of project.ownSourceFiles()) {
|
|
209
212
|
const visit = (node: Node): void => {
|
|
@@ -252,21 +255,21 @@ export function resolveEntries<Brand>(
|
|
|
252
255
|
}
|
|
253
256
|
const modules = modulesNamed(
|
|
254
257
|
project,
|
|
255
|
-
new Set(entries.flatMap((entry) => (
|
|
258
|
+
new Set(entries.flatMap((entry) => ("module" in entry ? [entry.module] : []))),
|
|
256
259
|
);
|
|
257
260
|
return entries.map((entry) => {
|
|
258
|
-
if (
|
|
261
|
+
if ("symbol" in entry) {
|
|
259
262
|
return { entry, handles: new Set<string>(), ids: new Set(byRef.get(entry.symbol) ?? []) };
|
|
260
263
|
}
|
|
261
264
|
const { components, static: isStatic } = componentsOf(
|
|
262
|
-
|
|
265
|
+
"module" in entry ? entry.name : entry.global,
|
|
263
266
|
);
|
|
264
267
|
const [first = "", ...rest] = components;
|
|
265
268
|
let start: TSSymbol | undefined;
|
|
266
269
|
if (isStatic && rest.length === 0) {
|
|
267
270
|
// Only a member is static, and a path of one component names no member.
|
|
268
271
|
start = undefined;
|
|
269
|
-
} else if (
|
|
272
|
+
} else if ("module" in entry) {
|
|
270
273
|
const module = modules.get(entry.module);
|
|
271
274
|
start = module === undefined ? undefined : memberOf(project, module, first, false);
|
|
272
275
|
} else if (nameComponent(first) === first) {
|
|
@@ -329,14 +332,10 @@ export function entriesAt<Brand>(
|
|
|
329
332
|
* program the display name the inventory gives it.
|
|
330
333
|
*/
|
|
331
334
|
export function spelledEntry(entry: DeclarationEntry, held: Inventory): string {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
return held.symbols.find((symbol) => symbol.ref === entry.symbol)?.name ?? entry.symbol;
|
|
335
|
-
case "module":
|
|
336
|
-
return entry.name;
|
|
337
|
-
case "global":
|
|
338
|
-
return entry.global;
|
|
335
|
+
if ("symbol" in entry) {
|
|
336
|
+
return held.symbols.find((symbol) => symbol.ref === entry.symbol)?.name ?? entry.symbol;
|
|
339
337
|
}
|
|
338
|
+
return "module" in entry ? entry.name : entry.global;
|
|
340
339
|
}
|
|
341
340
|
|
|
342
341
|
/** One entry of a configuration key that names a declaration, and the key's dotted path. */
|
|
@@ -353,14 +352,17 @@ const LIFECYCLE_KEY = "ts.lifecycle_contracts";
|
|
|
353
352
|
* the injection registrations, each lifecycle contract's components and then its bases,
|
|
354
353
|
* and the serializers.
|
|
355
354
|
*/
|
|
356
|
-
export function configuredDeclarations(config:
|
|
355
|
+
export function configuredDeclarations(config: ResolvedConfig): readonly ConfiguredDeclaration[] {
|
|
357
356
|
return [
|
|
358
|
-
...config.ts.
|
|
357
|
+
...config.ts.injection_registrations.map((entry) => ({
|
|
359
358
|
key: "ts.injection_registrations",
|
|
360
359
|
entry,
|
|
361
360
|
})),
|
|
362
|
-
...config.ts.
|
|
363
|
-
[...contract.components, ...contract.bases].map((entry) => ({
|
|
361
|
+
...config.ts.lifecycle_contracts.flatMap((contract) =>
|
|
362
|
+
[...(contract.components ?? []), ...(contract.bases ?? [])].map((entry) => ({
|
|
363
|
+
key: LIFECYCLE_KEY,
|
|
364
|
+
entry,
|
|
365
|
+
})),
|
|
364
366
|
),
|
|
365
367
|
...config.ts.serializers.map((entry) => ({ key: "ts.serializers", entry })),
|
|
366
368
|
];
|
|
@@ -396,12 +398,8 @@ export function declarationsNamed<Brand>(
|
|
|
396
398
|
* sign and its name, and a global entry's path after a number sign.
|
|
397
399
|
*/
|
|
398
400
|
export function configuredRef(entry: DeclarationEntry): string {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
return entry.symbol;
|
|
402
|
-
case "module":
|
|
403
|
-
return `${entry.module}#${entry.name}`;
|
|
404
|
-
case "global":
|
|
405
|
-
return `#${entry.global}`;
|
|
401
|
+
if ("symbol" in entry) {
|
|
402
|
+
return entry.symbol;
|
|
406
403
|
}
|
|
404
|
+
return "module" in entry ? `${entry.module}#${entry.name}` : `#${entry.global}`;
|
|
407
405
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Every entry-point convention this analyzer declines, each with
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Every row carries a reason, because the list is read where the rows are shown
|
|
8
|
-
* one at a time: beside a finding, or in a report's declared gaps.
|
|
2
|
+
* Every entry-point convention this analyzer declines, each with its tool and why. A file only
|
|
3
|
+
* a declined convention enters is reported as never imported, so a project relying on one names
|
|
4
|
+
* the file in `ts.entry_files` or `roots.patterns`, and this list tells it to. Every row carries
|
|
5
|
+
* a reason, since rows are shown one at a time, beside a finding or in a report's declared gaps.
|
|
9
6
|
*/
|
|
10
7
|
|
|
8
|
+
import { bytewise } from "../text/compare.ts";
|
|
9
|
+
|
|
11
10
|
/** One declined entry-point convention. */
|
|
12
11
|
export interface DeclinedConvention {
|
|
13
12
|
/** The tool the convention belongs to, by the name of the package or service. */
|
|
@@ -323,16 +322,8 @@ const PARTLY_ENTERED: readonly DeclinedConvention[] = [
|
|
|
323
322
|
},
|
|
324
323
|
];
|
|
325
324
|
|
|
326
|
-
/** Two strings ordered bytewise. */
|
|
327
|
-
function compare(a: string, b: string): number {
|
|
328
|
-
if (a === b) {
|
|
329
|
-
return 0;
|
|
330
|
-
}
|
|
331
|
-
return a < b ? -1 : 1;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
325
|
/** Every declined entry-point convention, ordered by tool and then by convention. */
|
|
335
326
|
export const DECLINED_CONVENTIONS: readonly DeclinedConvention[] = [
|
|
336
327
|
...UNREAD_TOOLS.map((tool) => ({ tool, convention: EVERY_CONVENTION, reason: UNREAD })),
|
|
337
328
|
...PARTLY_ENTERED,
|
|
338
|
-
].sort((a, b) =>
|
|
329
|
+
].sort((a, b) => bytewise(a.tool, b.tool) || bytewise(a.convention, b.convention));
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The entry points a package manifest names, which are roots because something
|
|
3
|
+
* outside the analyzed program reaches them: a consumer importing the package, or a
|
|
4
|
+
* shell running its command or one of its scripts. {@link readManifest} reads one
|
|
5
|
+
* directory's manifest, {@link packageEntries} those of the packages below the target root.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Host } from "../host.ts";
|
|
9
|
+
import { isAbsolutePath, joinPath, relativePath, resolvePath } from "../paths.ts";
|
|
10
|
+
import { isRecord } from "../json-document.ts";
|
|
11
|
+
import { MANIFEST, manifestAt, readJSON } from "../fs/manifest.ts";
|
|
12
|
+
import type { HeldText } from "../commands/held.ts";
|
|
13
|
+
import { pathsNamed, readCommands } from "../commands/read.ts";
|
|
14
|
+
|
|
15
|
+
/** The three members that name an entry point beside `exports` and `bin`. */
|
|
16
|
+
const LEGACY_MEMBERS = ["main", "module", "types"] as const;
|
|
17
|
+
|
|
18
|
+
/** What reaches one entry the manifest names. */
|
|
19
|
+
type EntryRole =
|
|
20
|
+
/** A consumer importing the package, which is a caller the analysis cannot see. */
|
|
21
|
+
| "import"
|
|
22
|
+
/** A shell running the package's command, which is a caller that exists. */
|
|
23
|
+
| "run"
|
|
24
|
+
/** A path one of the package's scripts names or runs, or a text layer 3 holds for the package. */
|
|
25
|
+
| "script";
|
|
26
|
+
|
|
27
|
+
/** One entry point the manifest names, or one text layer 3 holds for the package. */
|
|
28
|
+
export interface ManifestEntry {
|
|
29
|
+
/**
|
|
30
|
+
* The member that named it as a maintainer edits it, `main`, `bin["deadset-ts"]` or
|
|
31
|
+
* `exports["."]["import"]`: what a root reports as the string that named it.
|
|
32
|
+
*/
|
|
33
|
+
readonly member: string;
|
|
34
|
+
/** The target the member carries, resolved against the manifest's directory, or that directory for a held text. */
|
|
35
|
+
readonly path: string;
|
|
36
|
+
readonly role: EntryRole;
|
|
37
|
+
/**
|
|
38
|
+
* Whether the member declares what a consumer may import, the surface a library's published
|
|
39
|
+
* API is read from: `exports`, `browser` and the three members that preceded `exports`.
|
|
40
|
+
*/
|
|
41
|
+
readonly published: boolean;
|
|
42
|
+
/** The directory of the manifest that names it, which `path` was resolved against. */
|
|
43
|
+
readonly dir: string;
|
|
44
|
+
/**
|
|
45
|
+
* On an entry that names no entry point, whose path is the manifest's directory, the texts
|
|
46
|
+
* layer 3 reads: a whole command string the package runs, or the values of nodemon's
|
|
47
|
+
* configuration one is read from. Rooting enters no file for it and holds each file
|
|
48
|
+
* `spelledFiles` reads their words to name.
|
|
49
|
+
*/
|
|
50
|
+
readonly held?: readonly HeldText[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Whether one member's value names a file of this package rather than another
|
|
55
|
+
* package or a URL. A target written with no leading dot is a path too, which is
|
|
56
|
+
* how the members that preceded `exports` are written.
|
|
57
|
+
*/
|
|
58
|
+
function isTarget(value: string, requireDot: boolean): boolean {
|
|
59
|
+
if (value === "" || isAbsolutePath(value) || value.includes("://")) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return !requireDot || value.startsWith("./");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** One member's spelling below another: `exports` then `exports["."]`. */
|
|
66
|
+
function below(member: string, key: string): string {
|
|
67
|
+
return `${member}[${JSON.stringify(key)}]`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The whole text of nodemon's configuration, the manifest's `nodemonConfig` member and the
|
|
72
|
+
* `nodemon.json` beside it, by the member each is. The dependency rule reads it whole, and
|
|
73
|
+
* layer 3 each of its values, because nodemon runs commands from keys besides `exec`, `events`
|
|
74
|
+
* among them: https://github.com/remy/nodemon#config-files
|
|
75
|
+
*/
|
|
76
|
+
export function nodemonTexts(
|
|
77
|
+
host: Host,
|
|
78
|
+
dir: string,
|
|
79
|
+
manifest: Record<string, unknown>,
|
|
80
|
+
): readonly { readonly member: string; readonly text: string }[] {
|
|
81
|
+
const member = manifest["nodemonConfig"];
|
|
82
|
+
let file: string | undefined;
|
|
83
|
+
try {
|
|
84
|
+
file = host.readFile(joinPath(dir, "nodemon.json"));
|
|
85
|
+
} catch {
|
|
86
|
+
file = undefined;
|
|
87
|
+
}
|
|
88
|
+
return [
|
|
89
|
+
...(member === undefined ? [] : [{ member: "nodemonConfig", text: JSON.stringify(member) }]),
|
|
90
|
+
...(file === undefined ? [] : [{ member: "nodemon.json", text: file }]),
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The texts layer 3 reads of one text of nodemon's configuration: each value of it but its
|
|
96
|
+
* `exec` command, which is read as a command string of its own, those under `events` read as
|
|
97
|
+
* command strings too, and the whole text where it does not parse. Its keys are never read.
|
|
98
|
+
*/
|
|
99
|
+
function nodemonValues(text: string): readonly HeldText[] {
|
|
100
|
+
let config: unknown;
|
|
101
|
+
try {
|
|
102
|
+
config = JSON.parse(text);
|
|
103
|
+
} catch {
|
|
104
|
+
return [{ text, shell: false }];
|
|
105
|
+
}
|
|
106
|
+
const found: HeldText[] = [];
|
|
107
|
+
const visit = (value: unknown, shell: boolean): void => {
|
|
108
|
+
if (Array.isArray(value) || isRecord(value)) {
|
|
109
|
+
for (const one of Object.values(value)) {
|
|
110
|
+
visit(one, shell);
|
|
111
|
+
}
|
|
112
|
+
} else if (
|
|
113
|
+
typeof value === "string" ||
|
|
114
|
+
typeof value === "number" ||
|
|
115
|
+
typeof value === "boolean"
|
|
116
|
+
) {
|
|
117
|
+
found.push({ text: String(value), shell });
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
for (const [key, value] of Object.entries(isRecord(config) ? config : { "": config })) {
|
|
121
|
+
if (key !== "exec" || typeof value !== "string") {
|
|
122
|
+
visit(value, key === "events");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return found;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The command strings one manifest runs, each at the member it is written under: each of its
|
|
130
|
+
* `scripts`, and the `exec` command of nodemon's configuration, in the manifest's `nodemonConfig`
|
|
131
|
+
* or the `nodemon.json` beside it, which nodemon runs the watched script with:
|
|
132
|
+
* https://github.com/remy/nodemon#config-files
|
|
133
|
+
*/
|
|
134
|
+
export function manifestCommands(
|
|
135
|
+
host: Host,
|
|
136
|
+
dir: string,
|
|
137
|
+
manifest: Record<string, unknown>,
|
|
138
|
+
): readonly { readonly member: string; readonly command: string }[] {
|
|
139
|
+
const scripts = manifest["scripts"];
|
|
140
|
+
const nodemon = {
|
|
141
|
+
nodemonConfig: manifest["nodemonConfig"],
|
|
142
|
+
"nodemon.json": readJSON(host, joinPath(dir, "nodemon.json")),
|
|
143
|
+
};
|
|
144
|
+
const written = [
|
|
145
|
+
...Object.entries(isRecord(scripts) ? scripts : {}).map(
|
|
146
|
+
([name, value]) => [below("scripts", name), value] as const,
|
|
147
|
+
),
|
|
148
|
+
...Object.entries(nodemon).map(
|
|
149
|
+
([member, config]) =>
|
|
150
|
+
[below(member, "exec"), isRecord(config) ? config["exec"] : undefined] as const,
|
|
151
|
+
),
|
|
152
|
+
];
|
|
153
|
+
return written.flatMap(([member, command]) =>
|
|
154
|
+
typeof command === "string" ? [{ member, command }] : [],
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Every target one `exports` value carries, at the member each is written under. Every level of
|
|
160
|
+
* strings, subpath or condition objects and alternative arrays is walked, because each condition
|
|
161
|
+
* names its own entry file; a `null` blocks a subpath, and a key's meaning is never read.
|
|
162
|
+
*/
|
|
163
|
+
function exportTargets(value: unknown, member: string, found: Omit<ManifestEntry, "dir">[]): void {
|
|
164
|
+
if (typeof value === "string") {
|
|
165
|
+
if (isTarget(value, true)) {
|
|
166
|
+
found.push({ member, path: value, role: "import", published: true });
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (Array.isArray(value)) {
|
|
171
|
+
value.forEach((alternative, index) => {
|
|
172
|
+
exportTargets(alternative, below(member, String(index)), found);
|
|
173
|
+
});
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (!isRecord(value)) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
for (const [key, held] of Object.entries(value)) {
|
|
180
|
+
exportTargets(held, below(member, key), found);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** What one manifest declares about where its package is entered. */
|
|
185
|
+
export interface Manifest {
|
|
186
|
+
/**
|
|
187
|
+
* Every entry the manifest names, by absolute path, in the order read: the entry points `main`,
|
|
188
|
+
* `module`, `types`, `browser` and each file it maps, each `bin` command, every `exports` target,
|
|
189
|
+
* and per command string {@link manifestCommands} reads each path `pathsNamed` reads, which
|
|
190
|
+
* names a file only where one is at it, then one entry of its whole text, and one entry of
|
|
191
|
+
* each of {@link nodemonTexts}, which are no entry point.
|
|
192
|
+
*/
|
|
193
|
+
readonly entries: readonly ManifestEntry[];
|
|
194
|
+
/**
|
|
195
|
+
* Whether an `exports` member is written: then the published API is what `exports` reaches,
|
|
196
|
+
* and otherwise whatever the members that preceded it name.
|
|
197
|
+
*/
|
|
198
|
+
readonly declaresExports: boolean;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* What the manifest in `targetRoot` declares about where its package is entered.
|
|
203
|
+
*
|
|
204
|
+
* A target is taken as written. It is not resolved to a source file here, because
|
|
205
|
+
* which file a target names is a fact about the compiler configuration that emits
|
|
206
|
+
* it and there is one such configuration per project, while there is one manifest.
|
|
207
|
+
*/
|
|
208
|
+
export function readManifest(host: Host, targetRoot: string): Manifest {
|
|
209
|
+
const manifest = manifestAt(host, targetRoot);
|
|
210
|
+
if (manifest === undefined) {
|
|
211
|
+
return { entries: [], declaresExports: false };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const found: Omit<ManifestEntry, "dir">[] = [];
|
|
215
|
+
for (const member of LEGACY_MEMBERS) {
|
|
216
|
+
const value = manifest[member];
|
|
217
|
+
if (typeof value === "string" && isTarget(value, false)) {
|
|
218
|
+
found.push({ member, path: value, role: "import", published: true });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// A `browser` string replaces `main` in a browser bundle, and an object replaces each
|
|
223
|
+
// module it maps with the file it names: https://github.com/defunctzombie/package-browser-field-spec
|
|
224
|
+
const browser = manifest["browser"];
|
|
225
|
+
if (typeof browser === "string" && isTarget(browser, false)) {
|
|
226
|
+
found.push({ member: "browser", path: browser, role: "import", published: true });
|
|
227
|
+
} else if (isRecord(browser)) {
|
|
228
|
+
for (const [replaced, value] of Object.entries(browser)) {
|
|
229
|
+
if (typeof value === "string" && isTarget(value, true)) {
|
|
230
|
+
found.push({
|
|
231
|
+
member: below("browser", replaced),
|
|
232
|
+
path: value,
|
|
233
|
+
role: "import",
|
|
234
|
+
published: true,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const bin = manifest["bin"];
|
|
241
|
+
if (typeof bin === "string" && isTarget(bin, false)) {
|
|
242
|
+
found.push({ member: "bin", path: bin, role: "run", published: false });
|
|
243
|
+
} else if (isRecord(bin)) {
|
|
244
|
+
for (const [command, value] of Object.entries(bin)) {
|
|
245
|
+
if (typeof value === "string" && isTarget(value, false)) {
|
|
246
|
+
found.push({ member: below("bin", command), path: value, role: "run", published: false });
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
exportTargets(manifest["exports"], "exports", found);
|
|
252
|
+
|
|
253
|
+
for (const { member, command } of manifestCommands(host, targetRoot, manifest)) {
|
|
254
|
+
// Read against ".", so each path stays relative until the entries are resolved below.
|
|
255
|
+
for (const path of new Set(pathsNamed(readCommands(command, ".")).map((one) => one.path))) {
|
|
256
|
+
found.push({ member, path, role: "script", published: false });
|
|
257
|
+
}
|
|
258
|
+
found.push({
|
|
259
|
+
member,
|
|
260
|
+
path: ".",
|
|
261
|
+
role: "script",
|
|
262
|
+
published: false,
|
|
263
|
+
held: [{ text: command, shell: true, tested: member.startsWith("scripts[") }],
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
for (const { member, text } of nodemonTexts(host, targetRoot, manifest)) {
|
|
267
|
+
const held = nodemonValues(text);
|
|
268
|
+
if (held.length > 0) {
|
|
269
|
+
found.push({ member, path: ".", role: "script", published: false, held });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
entries: found.map((entry) => ({
|
|
275
|
+
...entry,
|
|
276
|
+
path: resolvePath(targetRoot, entry.path),
|
|
277
|
+
dir: targetRoot,
|
|
278
|
+
})),
|
|
279
|
+
declaresExports: manifest["exports"] !== undefined,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* The entry points the manifests of the nested packages in `dirs` name. Each entry is
|
|
285
|
+
* spelled under its manifest's path below the target root, and is published by its own
|
|
286
|
+
* manifest's rule, as the target's own entries are.
|
|
287
|
+
*/
|
|
288
|
+
export function packageEntries(
|
|
289
|
+
host: Host,
|
|
290
|
+
targetRoot: string,
|
|
291
|
+
dirs: readonly string[],
|
|
292
|
+
): readonly ManifestEntry[] {
|
|
293
|
+
return dirs.flatMap((dir) => {
|
|
294
|
+
const manifest = readManifest(host, dir);
|
|
295
|
+
const where = `${relativePath(targetRoot, dir) ?? dir}/${MANIFEST}`;
|
|
296
|
+
return manifest.entries.map((entry) => ({
|
|
297
|
+
...entry,
|
|
298
|
+
member: `${where} ${entry.member}`,
|
|
299
|
+
published:
|
|
300
|
+
entry.published && (!manifest.declaresExports || entry.member.startsWith("exports")),
|
|
301
|
+
}));
|
|
302
|
+
});
|
|
303
|
+
}
|