@cplieger/deadset-ts 8.0.0-dev.2 → 8.0.0-dev.21
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 +35 -9
- package/dist/src/amd.js +81 -0
- package/dist/src/analysis.js +274 -496
- 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/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 +2 -2
- 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 +1370 -0
- package/dist/src/contract/report.generated.js +866 -0
- package/dist/src/dependencies.js +165 -122
- 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/exemptions/argument-places.js +131 -0
- package/dist/src/exemptions/calls.js +338 -0
- package/dist/src/exemptions/classes.js +13 -0
- package/dist/src/{decorator.js → exemptions/decorator.js} +19 -30
- package/dist/src/exemptions/detectors.js +48 -0
- package/dist/src/{enum-group.js → exemptions/enum-group.js} +9 -16
- package/dist/src/{erased-stores.js → exemptions/erased-stores.js} +7 -11
- package/dist/src/{framework-lifecycle.js → exemptions/framework-lifecycle.js} +76 -54
- package/dist/src/exemptions/generated-file.js +241 -0
- package/dist/src/{injection-container.js → exemptions/injection-container.js} +20 -26
- package/dist/src/exemptions/installed-globals.js +173 -0
- package/dist/src/{interface-satisfaction.js → exemptions/interface-satisfaction.js} +52 -121
- package/dist/src/exemptions/lifecycle.js +150 -0
- package/dist/src/{reflective-lookup.js → exemptions/reflective-lookup.js} +3 -3
- package/dist/src/exemptions/serialization-contract.js +1276 -0
- package/dist/src/exemptions/sites.js +182 -0
- package/dist/src/{template-field.js → exemptions/template-field.js} +13 -23
- package/dist/src/{value-reach.js → exemptions/value-reach.js} +14 -7
- 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/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +67 -0
- package/dist/src/fs/tree.js +88 -0
- 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/values.js +124 -0
- package/dist/src/index.js +2 -2
- package/dist/src/indexed-access.js +523 -478
- 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 +95 -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/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/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 +30 -6
- 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 +40 -11
- package/src/amd.ts +130 -0
- package/src/analysis.ts +426 -733
- package/src/augmentations.ts +93 -4
- package/src/automatic-types.ts +12 -30
- package/src/bindings.ts +460 -0
- 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 +2 -2
- 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 +1453 -0
- package/src/contract/report.generated.ts +1241 -0
- package/src/dependencies.ts +223 -128
- 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/exemptions/argument-places.ts +198 -0
- package/src/exemptions/calls.ts +483 -0
- package/src/exemptions/classes.ts +49 -0
- package/src/exemptions/decorator.ts +56 -0
- package/src/exemptions/detectors.ts +75 -0
- package/src/{enum-group.ts → exemptions/enum-group.ts} +10 -19
- package/src/{erased-stores.ts → exemptions/erased-stores.ts} +7 -14
- package/src/{framework-lifecycle.ts → exemptions/framework-lifecycle.ts} +85 -66
- package/src/exemptions/generated-file.ts +318 -0
- package/src/{injection-container.ts → exemptions/injection-container.ts} +29 -34
- package/src/exemptions/installed-globals.ts +255 -0
- package/src/{interface-satisfaction.ts → exemptions/interface-satisfaction.ts} +69 -160
- package/src/exemptions/lifecycle.ts +286 -0
- package/src/{reflective-lookup.ts → exemptions/reflective-lookup.ts} +5 -5
- package/src/exemptions/serialization-contract.ts +1729 -0
- package/src/exemptions/sites.ts +293 -0
- package/src/{template-field.ts → exemptions/template-field.ts} +22 -32
- package/src/{value-reach.ts → exemptions/value-reach.ts} +16 -8
- 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/fs/document.ts +70 -0
- package/src/fs/manifest.ts +96 -0
- package/src/fs/tree.ts +110 -0
- 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/values.ts +170 -0
- package/src/index.ts +2 -2
- package/src/indexed-access.ts +570 -527
- 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 +201 -10
- 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} +26 -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/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/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 +36 -6
- 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/calls.js +0 -155
- 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/exempt-classes.js +0 -75
- package/dist/src/exempt.js +0 -209
- package/dist/src/generated-file.js +0 -95
- 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/serialization-contract.js +0 -611
- 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/value-flow.js +0 -74
- package/dist/src/version.js +0 -7
- package/dist/src/workflow-steps.js +0 -185
- package/src/base-url.ts +0 -24
- package/src/calls.ts +0 -225
- package/src/decorator.ts +0 -78
- package/src/discover.ts +0 -653
- package/src/entry-points.ts +0 -687
- package/src/exempt-classes.ts +0 -123
- package/src/exempt.ts +0 -323
- package/src/generated-file.ts +0 -111
- 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/serialization-contract.ts +0 -849
- package/src/setup-failure.ts +0 -39
- package/src/sweep.ts +0 -347
- package/src/test-joins.ts +0 -120
- package/src/value-flow.ts +0 -104
- package/src/version.ts +0 -7
- package/src/workflow-steps.ts +0 -216
package/dist/src/roots.js
DELETED
|
@@ -1,672 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The root set of one project: every declaration the analysis keeps live without a
|
|
3
|
-
* reference, and why.
|
|
4
|
-
*
|
|
5
|
-
* Every root seeds REACHABILITY, and no root counts as a reference. A root of a kind
|
|
6
|
-
* that names a caller is live under reference counting as well, which the sweep
|
|
7
|
-
* decides; the published API only supposes a consumer, so a published export is live
|
|
8
|
-
* under reachability and still a candidate under reference counting.
|
|
9
|
-
*/
|
|
10
|
-
import { isExpressionWithTypeArguments, isFunctionLikeDeclaration, isPropertyAccessExpression, isQualifiedName, isTypeQueryNode, isTypeReferenceNode, isPropertyDeclaration, isVariableDeclaration, isVariableStatement, } from "@typescript/native/ast";
|
|
11
|
-
import { aliasChains } from "./alias-chain.js";
|
|
12
|
-
import { filesNamedBy, outsideChain, relativeSpecifiers, } from "./configuration-files.js";
|
|
13
|
-
import { conventionEntries } from "./conventions.js";
|
|
14
|
-
import { entryPoints } from "./entry-points.js";
|
|
15
|
-
import { globExpression } from "./glob.js";
|
|
16
|
-
import { nodeKey } from "./inventory.js";
|
|
17
|
-
import { dirnamePath, joinPath, relativePath, resolvePath } from "./paths.js";
|
|
18
|
-
import { byPosition } from "./position.js";
|
|
19
|
-
import { UNANSWERED } from "./query.js";
|
|
20
|
-
import { sourceFilesOf } from "./source-files.js";
|
|
21
|
-
import { typeQueryAliases } from "./type-query-alias.js";
|
|
22
|
-
/** Whether one declaration is written below the directory of a published workspace member. */
|
|
23
|
-
function inPublishedMember(held, id, root, members) {
|
|
24
|
-
const path = held.symbols.find((symbol) => symbol.id === id)?.position.path;
|
|
25
|
-
if (path === undefined || members === undefined) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
const file = resolvePath(root, path);
|
|
29
|
-
return [...members].some((dir) => file.startsWith(`${dir}/`));
|
|
30
|
-
}
|
|
31
|
-
/** The kind of root each role of a manifest entry makes. */
|
|
32
|
-
const ENTRY_KINDS = {
|
|
33
|
-
import: "manifest-entry",
|
|
34
|
-
run: "manifest-binary",
|
|
35
|
-
script: "script",
|
|
36
|
-
};
|
|
37
|
-
/** The rules whose rooted files a manifest target is read back to by name. */
|
|
38
|
-
const READ_BACK_RULES = new Set([
|
|
39
|
-
"configuration-file",
|
|
40
|
-
"configuration-string",
|
|
41
|
-
"html-entry",
|
|
42
|
-
]);
|
|
43
|
-
/** The extensions a manifest target's name drops: the ones a build writes. */
|
|
44
|
-
const OUTPUT_EXTENSION = /\.(?:d\.ts|d\.mts|d\.cts|js|mjs|cjs|jsx)$/u;
|
|
45
|
-
/** The extension a source file's name drops. */
|
|
46
|
-
const SOURCE_EXTENSION = /\.(?:d\.)?[cm]?[jt]sx?$/u;
|
|
47
|
-
/** Whether no `package.json` sits between one file and the manifest's directory, which holds it. */
|
|
48
|
-
function ofPackage(host, dir, file) {
|
|
49
|
-
for (let at = dirnamePath(file); at !== dir; at = dirnamePath(at)) {
|
|
50
|
-
if (relativePath(dir, at) === undefined ||
|
|
51
|
-
host.kindOf(joinPath(at, "package.json")) === "file") {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* The rooted files one manifest target reads back to by name: its path below the
|
|
59
|
-
* manifest's directory, past its first directory where it names one, without its output
|
|
60
|
-
* extension, is the name, and a rooted file of the manifest's own package is one whose
|
|
61
|
-
* path below the same directory, without its source extension, ends with that name at a
|
|
62
|
-
* directory boundary.
|
|
63
|
-
*/
|
|
64
|
-
function readBackByName(host, entry, rooted) {
|
|
65
|
-
const dir = resolvePath(host.workingDirectory(), entry.dir);
|
|
66
|
-
const below = relativePath(dir, resolvePath(host.workingDirectory(), entry.path));
|
|
67
|
-
if (below === undefined || below === "") {
|
|
68
|
-
return [];
|
|
69
|
-
}
|
|
70
|
-
const cut = below.indexOf("/");
|
|
71
|
-
const name = (cut === -1 ? below : below.slice(cut + 1)).replace(OUTPUT_EXTENSION, "");
|
|
72
|
-
if (name === "") {
|
|
73
|
-
return [];
|
|
74
|
-
}
|
|
75
|
-
const found = new Map();
|
|
76
|
-
for (const file of rooted) {
|
|
77
|
-
const path = relativePath(dir, file.fileName)?.replace(SOURCE_EXTENSION, "");
|
|
78
|
-
if (path !== undefined &&
|
|
79
|
-
(path === name || path.endsWith(`/${name}`)) &&
|
|
80
|
-
ofPackage(host, dir, file.fileName)) {
|
|
81
|
-
found.set(file.fileName, file);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return [...found.values()];
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* The program files a manifest target no program holds reaches: the target is a file
|
|
88
|
-
* read as a configuration file outside the program is, and each file of the chain it
|
|
89
|
-
* starts loads the program files its relative specifiers name, read through the emit
|
|
90
|
-
* mapping, as a command's shim loads the compiled entry it runs.
|
|
91
|
-
*/
|
|
92
|
-
function throughOutside(options, targetRoot, files, entry) {
|
|
93
|
-
const cwd = options.host.workingDirectory();
|
|
94
|
-
const path = resolvePath(cwd, entry.path);
|
|
95
|
-
if (options.parse === undefined ||
|
|
96
|
-
options.runFiles?.has(path) === true ||
|
|
97
|
-
options.host.kindOf(path) !== "file") {
|
|
98
|
-
return [];
|
|
99
|
-
}
|
|
100
|
-
const chain = outsideChain(options.host, targetRoot, files, options.parse, [
|
|
101
|
-
{ path, manifestDir: resolvePath(cwd, entry.dir) },
|
|
102
|
-
]);
|
|
103
|
-
const found = new Map();
|
|
104
|
-
for (const { file } of chain) {
|
|
105
|
-
for (const specifier of relativeSpecifiers(file)) {
|
|
106
|
-
for (const named of filesNamedBy(files, dirnamePath(file.fileName), specifier)) {
|
|
107
|
-
found.set(named.fileName, named);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return [...found.values()];
|
|
112
|
-
}
|
|
113
|
-
/** Whether a configured string carries either special character. */
|
|
114
|
-
function isPattern(text) {
|
|
115
|
-
return text.includes("*") || text.includes("?");
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Whether ref matches a pattern whose only special characters are `*`, which stands
|
|
119
|
-
* for any run of characters including the solidus, and `?`, which stands for exactly
|
|
120
|
-
* one character counted as a code point. A star keeps the position it last stood at,
|
|
121
|
-
* so the shortest run it can stand for is tried first.
|
|
122
|
-
*/
|
|
123
|
-
function matchGlob(pattern, ref) {
|
|
124
|
-
let next = 0;
|
|
125
|
-
let star = -1;
|
|
126
|
-
let resume = 0;
|
|
127
|
-
let at = 0;
|
|
128
|
-
while (at < ref.length) {
|
|
129
|
-
if (next < pattern.length && (pattern[next] === "?" || pattern[next] === ref[at])) {
|
|
130
|
-
next += 1;
|
|
131
|
-
at += 1;
|
|
132
|
-
}
|
|
133
|
-
else if (next < pattern.length && pattern[next] === "*") {
|
|
134
|
-
star = next;
|
|
135
|
-
resume = at;
|
|
136
|
-
next += 1;
|
|
137
|
-
}
|
|
138
|
-
else if (star >= 0) {
|
|
139
|
-
resume += 1;
|
|
140
|
-
next = star + 1;
|
|
141
|
-
at = resume;
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
while (next < pattern.length && pattern[next] === "*") {
|
|
148
|
-
next += 1;
|
|
149
|
-
}
|
|
150
|
-
return next === pattern.length;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Whether one configured string names the symbol reference ref. A string carrying
|
|
154
|
-
* neither special character names only the reference it spells.
|
|
155
|
-
*
|
|
156
|
-
* Both sides are read as code points: a character outside the basic plane is two
|
|
157
|
-
* string units, and `?` stands for one character.
|
|
158
|
-
*/
|
|
159
|
-
export function matchRef(pattern, ref) {
|
|
160
|
-
if (!isPattern(pattern)) {
|
|
161
|
-
return pattern === ref;
|
|
162
|
-
}
|
|
163
|
-
return matchGlob(Array.from(pattern), Array.from(ref));
|
|
164
|
-
}
|
|
165
|
-
/** Two strings ordered bytewise, which is the order every set of a run is read in. */
|
|
166
|
-
function compare(a, b) {
|
|
167
|
-
if (a === b) {
|
|
168
|
-
return 0;
|
|
169
|
-
}
|
|
170
|
-
return a < b ? -1 : 1;
|
|
171
|
-
}
|
|
172
|
-
/** The members of one declaration, indexed by the container that holds them. */
|
|
173
|
-
function childrenOf(held) {
|
|
174
|
-
const byParent = new Map();
|
|
175
|
-
for (const symbol of held.symbols) {
|
|
176
|
-
const siblings = byParent.get(symbol.parent);
|
|
177
|
-
if (siblings === undefined) {
|
|
178
|
-
byParent.set(symbol.parent, [symbol]);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
siblings.push(symbol);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return byParent;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* The roots one project holds, and every configured string that named nothing in it.
|
|
188
|
-
*
|
|
189
|
-
* A file a manifest member, an entry-file pattern or a tool's configuration names
|
|
190
|
-
* is a root with everything its module exports: each name of the module's export
|
|
191
|
-
* table, and where a name is a re-export, every link of the chain to the declaration
|
|
192
|
-
* it carries, so a re-exported declaration is a root of the file that publishes it.
|
|
193
|
-
* In a library, what a published file exports is rooted by the published API alone.
|
|
194
|
-
* A file a runtime executes without reading its exports, a test file or a worker, is
|
|
195
|
-
* a root by itself.
|
|
196
|
-
*/
|
|
197
|
-
export function roots(project, held, targetRoot, options) {
|
|
198
|
-
const files = sourceFilesOf(project, targetRoot);
|
|
199
|
-
const declared = held.declarations;
|
|
200
|
-
const fileIds = new Map();
|
|
201
|
-
for (const file of files.byName.values()) {
|
|
202
|
-
const id = declared.get(nodeKey(file, file));
|
|
203
|
-
if (id !== undefined) {
|
|
204
|
-
fileIds.set(file.fileName, id);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
const found = new Map();
|
|
208
|
-
const add = (id, kind, source) => {
|
|
209
|
-
found.set([id, kind, source].join("\u0000"), { id, kind, source });
|
|
210
|
-
};
|
|
211
|
-
const entered = [];
|
|
212
|
-
const enter = (file, kind, source, exports, names) => {
|
|
213
|
-
entered.push({ file, kind, source, exports, ...(names === undefined ? {} : { names }) });
|
|
214
|
-
};
|
|
215
|
-
const points = entryPoints(project, files, options.testFiles, options.host, targetRoot, options.parse, options.conventions?.selected);
|
|
216
|
-
const published = [];
|
|
217
|
-
const entries = [
|
|
218
|
-
...options.manifest.entries.map((entry) => ({
|
|
219
|
-
entry,
|
|
220
|
-
publishes: options.publishedAPI &&
|
|
221
|
-
entry.published &&
|
|
222
|
-
(options.manifest.declaresExports ? entry.member.startsWith("exports") : true),
|
|
223
|
-
})),
|
|
224
|
-
...(options.otherPackages ?? []).map((entry) => ({
|
|
225
|
-
entry,
|
|
226
|
-
publishes: entry.published &&
|
|
227
|
-
(options.publishedAPI || options.publishedMembers?.has(entry.dir) === true),
|
|
228
|
-
})),
|
|
229
|
-
];
|
|
230
|
-
const scripted = entries.flatMap(({ entry }) => entry.role === "script" ? files.named(entry.path) : []);
|
|
231
|
-
const readBackTo = [
|
|
232
|
-
...scripted,
|
|
233
|
-
...points.filter((point) => READ_BACK_RULES.has(point.rule)).map((point) => point.file),
|
|
234
|
-
];
|
|
235
|
-
const entryFilesOf = new Map();
|
|
236
|
-
const entryFiles = (entry) => {
|
|
237
|
-
const known = entryFilesOf.get(entry);
|
|
238
|
-
if (known !== undefined) {
|
|
239
|
-
return known;
|
|
240
|
-
}
|
|
241
|
-
const found = readEntryFiles(entry);
|
|
242
|
-
entryFilesOf.set(entry, found);
|
|
243
|
-
return found;
|
|
244
|
-
};
|
|
245
|
-
const readEntryFiles = (entry) => {
|
|
246
|
-
const named = files.named(entry.path);
|
|
247
|
-
if (named.length > 0 || entry.role === "script") {
|
|
248
|
-
return named;
|
|
249
|
-
}
|
|
250
|
-
const cwd = options.host.workingDirectory();
|
|
251
|
-
const shipped = files.namedAsOutput(resolvePath(cwd, entry.dir), resolvePath(cwd, entry.path));
|
|
252
|
-
if (shipped.length > 0) {
|
|
253
|
-
return shipped;
|
|
254
|
-
}
|
|
255
|
-
const byName = readBackByName(options.host, entry, readBackTo);
|
|
256
|
-
return byName.length > 0 ? byName : throughOutside(options, targetRoot, files, entry);
|
|
257
|
-
};
|
|
258
|
-
for (const { entry, publishes } of entries) {
|
|
259
|
-
if (publishes) {
|
|
260
|
-
published.push(...entryFiles(entry));
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
const publishedNames = new Set(published.map((file) => file.fileName));
|
|
264
|
-
const patterned = [];
|
|
265
|
-
for (const pattern of options.entryFiles) {
|
|
266
|
-
const expression = globExpression(pattern);
|
|
267
|
-
for (const [path, file] of files.byPath) {
|
|
268
|
-
if (expression.test(path)) {
|
|
269
|
-
patterned.push({ file, pattern });
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
const unmapped = [];
|
|
274
|
-
const mapped = patterned.map(({ file }) => file);
|
|
275
|
-
for (const { entry } of entries) {
|
|
276
|
-
const named = entryFiles(entry);
|
|
277
|
-
if (named.length === 0 && entry.role !== "script") {
|
|
278
|
-
unmapped.push(entry);
|
|
279
|
-
}
|
|
280
|
-
mapped.push(...named);
|
|
281
|
-
for (const file of named) {
|
|
282
|
-
const kind = ENTRY_KINDS[entry.role];
|
|
283
|
-
enter(file, kind, entry.member, !publishedNames.has(file.fileName));
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
const unmappedEntries = unmapped.filter((entry) => readBackByName(options.host, entry, mapped).length === 0);
|
|
287
|
-
for (const { file, pattern } of patterned) {
|
|
288
|
-
enter(file, "entry-file", pattern, true);
|
|
289
|
-
}
|
|
290
|
-
for (const { file, row } of options.conventions === undefined
|
|
291
|
-
? []
|
|
292
|
-
: conventionEntries(options.conventions, files)) {
|
|
293
|
-
enter(file, "convention", row, true);
|
|
294
|
-
}
|
|
295
|
-
for (const point of points) {
|
|
296
|
-
enter(point.file, point.rule, point.source, point.exports, point.names);
|
|
297
|
-
}
|
|
298
|
-
for (const file of files.byPath.values()) {
|
|
299
|
-
for (const alias of typeQueryAliases(file)) {
|
|
300
|
-
const source = alias.type.getText().replace(/\s+/gu, " ");
|
|
301
|
-
for (const node of [alias.declaration, ...alias.containers]) {
|
|
302
|
-
const id = declared.get(nodeKey(file, node));
|
|
303
|
-
if (id !== undefined) {
|
|
304
|
-
add(id, "type-query-alias", source);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
const { tables: exportsOf, named, answered, } = exportTables(project, held, [
|
|
310
|
-
...entered.filter((entry) => entry.exports).map((entry) => entry.file),
|
|
311
|
-
...published,
|
|
312
|
-
]);
|
|
313
|
-
for (const entry of entered) {
|
|
314
|
-
const id = fileIds.get(entry.file.fileName);
|
|
315
|
-
if (id === undefined) {
|
|
316
|
-
continue;
|
|
317
|
-
}
|
|
318
|
-
add(id, entry.kind, entry.source);
|
|
319
|
-
if (entry.exports) {
|
|
320
|
-
const byName = named.get(entry.file.fileName);
|
|
321
|
-
const exported = entry.names === undefined || byName === undefined
|
|
322
|
-
? (exportsOf.get(entry.file.fileName) ?? [])
|
|
323
|
-
: entry.names.flatMap((name) => byName.get(name) ?? []);
|
|
324
|
-
for (const one of exported) {
|
|
325
|
-
add(one, entry.kind, entry.source);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
const tagged = releaseTagged(held, files).filter((id) => options.publishedAPI || inPublishedMember(held, id, targetRoot, options.publishedMembers));
|
|
330
|
-
const api = published.length > 0 || tagged.length > 0
|
|
331
|
-
? publishedAPI(project, published, exportsOf, held, files.byPath, tagged)
|
|
332
|
-
: { ids: [], guessed: [] };
|
|
333
|
-
for (const id of api.ids) {
|
|
334
|
-
add(id, "published-api", "");
|
|
335
|
-
}
|
|
336
|
-
const unmatched = configured(held, options.patterns, add);
|
|
337
|
-
const sites = new Map(held.symbols.map((symbol) => [symbol.id, symbol.position]));
|
|
338
|
-
const ordered = [...found.values()].sort((a, b) => {
|
|
339
|
-
const left = sites.get(a.id);
|
|
340
|
-
const right = sites.get(b.id);
|
|
341
|
-
const site = left === undefined || right === undefined ? 0 : byPosition(left, right);
|
|
342
|
-
return site || compare(a.kind, b.kind) || compare(a.source, b.source);
|
|
343
|
-
});
|
|
344
|
-
return {
|
|
345
|
-
liveUnderReachability: ordered,
|
|
346
|
-
unmatched,
|
|
347
|
-
unanswered: answered ? api.guessed : held.symbols.map((symbol) => symbol.id),
|
|
348
|
-
unmappedEntries,
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Every declaration each file's module exports, by the file's name: the declaration
|
|
353
|
-
* each name of the export table is, and every link of a re-export's chain. A name
|
|
354
|
-
* whose declaration is outside the project's own files names nothing here. One batch
|
|
355
|
-
* resolves every file to its module and one request per module reads its export
|
|
356
|
-
* table, star re-exports resolved into it. A file that is no module exports nothing.
|
|
357
|
-
* `answered` is false where the checker left a table or a link of a chain unanswered.
|
|
358
|
-
*/
|
|
359
|
-
function exportTables(project, held, wanted) {
|
|
360
|
-
const unique = [...new Map(wanted.map((file) => [file.fileName, file])).values()];
|
|
361
|
-
const tables = new Map();
|
|
362
|
-
const named = new Map();
|
|
363
|
-
let answered = true;
|
|
364
|
-
if (unique.length === 0) {
|
|
365
|
-
return { tables, named, answered };
|
|
366
|
-
}
|
|
367
|
-
const modules = project.symbolsAt(unique.map((file) => project.handle(file)));
|
|
368
|
-
const chains = aliasChains(project, held);
|
|
369
|
-
const topLevel = (file) => {
|
|
370
|
-
const fileId = held.declarations.get(nodeKey(file, file));
|
|
371
|
-
return held.symbols.filter((symbol) => symbol.parent === fileId).map((symbol) => symbol.id);
|
|
372
|
-
};
|
|
373
|
-
unique.forEach((file, index) => {
|
|
374
|
-
const module = modules[index];
|
|
375
|
-
if (module === undefined) {
|
|
376
|
-
tables.set(file.fileName, []);
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
const table = module === UNANSWERED ? UNANSWERED : project.queries.exportsOfModule(module);
|
|
380
|
-
if (table === UNANSWERED) {
|
|
381
|
-
answered = false;
|
|
382
|
-
tables.set(file.fileName, topLevel(file));
|
|
383
|
-
return;
|
|
384
|
-
}
|
|
385
|
-
const ids = new Set();
|
|
386
|
-
const byName = new Map();
|
|
387
|
-
for (const exported of table) {
|
|
388
|
-
for (const target of chains.chainOf(exported)) {
|
|
389
|
-
answered &&= !target.guessed;
|
|
390
|
-
ids.add(target.id);
|
|
391
|
-
byName.set(exported.name, [...(byName.get(exported.name) ?? []), target.id]);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
tables.set(file.fileName, [...ids]);
|
|
395
|
-
named.set(file.fileName, byName);
|
|
396
|
-
});
|
|
397
|
-
return { tables, named, answered };
|
|
398
|
-
}
|
|
399
|
-
/** A release tag of a documentation comment: `@` and its name, between white space or the ends. */
|
|
400
|
-
const RELEASE_TAG = /(?:^|\s)@(?:public|beta|alpha)(?=\s|$)/u;
|
|
401
|
-
/**
|
|
402
|
-
* Whether the documentation comment of the statement that starts at `start`, the last
|
|
403
|
-
* `/** *\/` comment before it with only white space between the two, holds a release tag.
|
|
404
|
-
*/
|
|
405
|
-
function releaseTagIn(text, from, start) {
|
|
406
|
-
const leading = text.slice(from, start);
|
|
407
|
-
const open = leading.lastIndexOf("/**");
|
|
408
|
-
const close = open < 0 ? -1 : leading.indexOf("*/", open + 3);
|
|
409
|
-
if (close < 0 || leading.slice(close + 2).trim() !== "") {
|
|
410
|
-
return false;
|
|
411
|
-
}
|
|
412
|
-
return RELEASE_TAG.test(leading.slice(open + 3, close));
|
|
413
|
-
}
|
|
414
|
-
/** The exported top-level declarations of the program's files a release tag marks. */
|
|
415
|
-
function releaseTagged(held, files) {
|
|
416
|
-
const exported = new Set(held.symbols.filter((symbol) => symbol.exported).map((one) => one.id));
|
|
417
|
-
const found = [];
|
|
418
|
-
for (const file of files.byPath.values()) {
|
|
419
|
-
for (const statement of file.statements) {
|
|
420
|
-
if (!releaseTagIn(file.text, statement.pos, statement.getStart())) {
|
|
421
|
-
continue;
|
|
422
|
-
}
|
|
423
|
-
const nodes = isVariableStatement(statement)
|
|
424
|
-
? statement.declarationList.declarations
|
|
425
|
-
: [statement];
|
|
426
|
-
for (const node of nodes) {
|
|
427
|
-
const id = held.declarations.get(nodeKey(file, node));
|
|
428
|
-
if (id !== undefined && exported.has(id)) {
|
|
429
|
-
found.push(id);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
return found;
|
|
435
|
-
}
|
|
436
|
-
/** The kinds of container whose export table, not its members' visibility, says what it publishes. */
|
|
437
|
-
const EXPORTING_CONTAINERS = new Set(["file", "namespace"]);
|
|
438
|
-
/**
|
|
439
|
-
* Every declaration a consumer of the library can name: what the published files export,
|
|
440
|
-
* and below each the members a consumer writes, a namespace's exported ones and any other
|
|
441
|
-
* declaration's public and protected ones. A declaration a published one's type names is
|
|
442
|
-
* published too, and so is an exported declaration a release tag marks. A type name the
|
|
443
|
-
* checker leaves unanswered publishes every declaration spelled as it is, as `guessed`. A
|
|
444
|
-
* published file is not itself published.
|
|
445
|
-
*/
|
|
446
|
-
function publishedAPI(project, published, exportsOf, held, byPath, tagged) {
|
|
447
|
-
const byId = new Map(held.symbols.map((symbol) => [symbol.id, symbol]));
|
|
448
|
-
const children = childrenOf(held);
|
|
449
|
-
const nodes = declarationNodes(held, byPath);
|
|
450
|
-
const chains = aliasChains(project, held);
|
|
451
|
-
const reached = new Set();
|
|
452
|
-
const entered = new Set();
|
|
453
|
-
const guessed = new Set();
|
|
454
|
-
const pending = [];
|
|
455
|
-
const reach = (id) => {
|
|
456
|
-
const file = byId.get(id)?.kind === "file";
|
|
457
|
-
if (!(file ? entered : reached).has(id)) {
|
|
458
|
-
(file ? entered : reached).add(id);
|
|
459
|
-
pending.push(id);
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
for (const id of tagged) {
|
|
463
|
-
reach(id);
|
|
464
|
-
}
|
|
465
|
-
for (const file of published) {
|
|
466
|
-
for (const id of exportsOf.get(file.fileName) ?? []) {
|
|
467
|
-
reach(id);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
while (pending.length > 0) {
|
|
471
|
-
const round = [];
|
|
472
|
-
for (let next = pending.shift(); next !== undefined; next = pending.shift()) {
|
|
473
|
-
round.push(next);
|
|
474
|
-
const exporting = EXPORTING_CONTAINERS.has(byId.get(next)?.kind ?? "");
|
|
475
|
-
for (const member of children.get(next) ?? []) {
|
|
476
|
-
const reachable = exporting
|
|
477
|
-
? member.exported
|
|
478
|
-
: member.visibility !== "private" && member.visibility !== "private-name";
|
|
479
|
-
if (member.kind !== "type-parameter" && reachable) {
|
|
480
|
-
reach(member.id);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
const named = round.flatMap((id) => {
|
|
485
|
-
const symbol = byId.get(id);
|
|
486
|
-
return symbol === undefined || symbol.kind === "file" ? [] : nodes.typeNamesOf(symbol);
|
|
487
|
-
});
|
|
488
|
-
for (const symbol of inferredTypeSymbols(project, round.flatMap((id) => {
|
|
489
|
-
const symbol = byId.get(id);
|
|
490
|
-
return symbol === undefined ? [] : nodes.nodesOf(symbol);
|
|
491
|
-
}))) {
|
|
492
|
-
for (const target of chains.chainOf(symbol)) {
|
|
493
|
-
reach(target.id);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
project.symbolsAt(named.map((node) => project.handle(node))).forEach((symbol, index) => {
|
|
497
|
-
if (symbol === UNANSWERED) {
|
|
498
|
-
for (const id of held.byName.get(named[index]?.getText() ?? "") ?? []) {
|
|
499
|
-
guessed.add(id);
|
|
500
|
-
reach(id);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
else if (symbol !== undefined) {
|
|
504
|
-
for (const target of chains.chainOf(symbol)) {
|
|
505
|
-
reach(target.id);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
|
-
}
|
|
510
|
-
return { ids: [...reached], guessed: [...guessed] };
|
|
511
|
-
}
|
|
512
|
-
/** The type names declarations of the inventory write, each file walked once, when first asked. */
|
|
513
|
-
function declarationNodes(held, byPath) {
|
|
514
|
-
const walked = new Map();
|
|
515
|
-
const nodesIn = (path) => {
|
|
516
|
-
const known = walked.get(path);
|
|
517
|
-
if (known !== undefined) {
|
|
518
|
-
return known;
|
|
519
|
-
}
|
|
520
|
-
const found = { byId: new Map(), nodes: new Set() };
|
|
521
|
-
const file = byPath.get(path);
|
|
522
|
-
if (file !== undefined) {
|
|
523
|
-
const visit = (node) => {
|
|
524
|
-
const id = held.declarations.get(nodeKey(file, node));
|
|
525
|
-
if (id !== undefined) {
|
|
526
|
-
found.nodes.add(node);
|
|
527
|
-
found.byId.set(id, [...(found.byId.get(id) ?? []), node]);
|
|
528
|
-
}
|
|
529
|
-
node.forEachChild(visit);
|
|
530
|
-
};
|
|
531
|
-
visit(file);
|
|
532
|
-
}
|
|
533
|
-
walked.set(path, found);
|
|
534
|
-
return found;
|
|
535
|
-
};
|
|
536
|
-
return {
|
|
537
|
-
typeNamesOf: (symbol) => {
|
|
538
|
-
const { byId, nodes } = nodesIn(symbol.position.path);
|
|
539
|
-
return (byId.get(symbol.id) ?? []).flatMap((declaration) => typeNamesOf(declaration, nodes));
|
|
540
|
-
},
|
|
541
|
-
nodesOf: (symbol) => nodesIn(symbol.position.path).byId.get(symbol.id) ?? [],
|
|
542
|
-
};
|
|
543
|
-
}
|
|
544
|
-
/** How deep the type arguments and constituents of an inferred type are followed. */
|
|
545
|
-
const INFERRED_DEPTH = 4;
|
|
546
|
-
/**
|
|
547
|
-
* The declarations of the types the compiler infers where a declaration writes none: the
|
|
548
|
-
* type of a variable or a property with no annotation, and the result of a function or a
|
|
549
|
-
* method with no result annotation, each with the types its type arguments and its union
|
|
550
|
-
* or intersection constituents name, to a fixed depth. A question the checker leaves
|
|
551
|
-
* unanswered names nothing.
|
|
552
|
-
*/
|
|
553
|
-
function inferredTypeSymbols(project, declarations) {
|
|
554
|
-
const { queries } = project;
|
|
555
|
-
const valued = declarations.flatMap((node) => (isVariableDeclaration(node) || isPropertyDeclaration(node)) &&
|
|
556
|
-
node.type === undefined &&
|
|
557
|
-
!isFunctionLikeDeclaration(node.initializer ?? node)
|
|
558
|
-
? [node.name]
|
|
559
|
-
: []);
|
|
560
|
-
const types = [];
|
|
561
|
-
queries.typesAt(valued).forEach((type) => {
|
|
562
|
-
if (type !== UNANSWERED && type !== undefined) {
|
|
563
|
-
types.push(type);
|
|
564
|
-
}
|
|
565
|
-
});
|
|
566
|
-
for (const node of declarations) {
|
|
567
|
-
const signature = isFunctionLikeDeclaration(node)
|
|
568
|
-
? node
|
|
569
|
-
: isVariableDeclaration(node) &&
|
|
570
|
-
node.type === undefined &&
|
|
571
|
-
node.initializer !== undefined &&
|
|
572
|
-
isFunctionLikeDeclaration(node.initializer)
|
|
573
|
-
? node.initializer
|
|
574
|
-
: undefined;
|
|
575
|
-
if (signature === undefined || signature.type !== undefined || signature.body === undefined) {
|
|
576
|
-
continue;
|
|
577
|
-
}
|
|
578
|
-
const typed = queries.signatureOf(signature);
|
|
579
|
-
const result = typed === UNANSWERED || typed === undefined ? undefined : queries.returnTypeOf(typed);
|
|
580
|
-
if (result !== UNANSWERED && result !== undefined) {
|
|
581
|
-
types.push(result);
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
const found = new Map();
|
|
585
|
-
const seen = new Set();
|
|
586
|
-
const visit = (type, depth) => {
|
|
587
|
-
if (depth > INFERRED_DEPTH || seen.has(type)) {
|
|
588
|
-
return;
|
|
589
|
-
}
|
|
590
|
-
seen.add(type);
|
|
591
|
-
const symbol = queries.symbolOfType(type);
|
|
592
|
-
if (symbol !== UNANSWERED && symbol !== undefined) {
|
|
593
|
-
found.set(symbol.id, symbol);
|
|
594
|
-
}
|
|
595
|
-
const parts = queries.constituents(type);
|
|
596
|
-
const args = queries.typeArguments(type);
|
|
597
|
-
for (const next of [
|
|
598
|
-
...(parts === UNANSWERED || (parts.length === 1 && parts[0] === type) ? [] : parts),
|
|
599
|
-
...(args === UNANSWERED ? [] : args),
|
|
600
|
-
]) {
|
|
601
|
-
visit(next, depth + 1);
|
|
602
|
-
}
|
|
603
|
-
};
|
|
604
|
-
types.forEach((type) => {
|
|
605
|
-
visit(type, 0);
|
|
606
|
-
});
|
|
607
|
-
return [...found.values()];
|
|
608
|
-
}
|
|
609
|
-
/**
|
|
610
|
-
* The names of types one declaration's own syntax writes: in a type reference, a
|
|
611
|
-
* heritage clause or a type query. A function body is not read, and neither is a
|
|
612
|
-
* declaration nested in this one, which `nested` holds and which is read on its own.
|
|
613
|
-
*/
|
|
614
|
-
function typeNamesOf(declaration, nested) {
|
|
615
|
-
const found = [];
|
|
616
|
-
const visit = (node) => {
|
|
617
|
-
if (node !== declaration && nested.has(node)) {
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
if (isTypeReferenceNode(node)) {
|
|
621
|
-
found.push(isQualifiedName(node.typeName) ? node.typeName.right : node.typeName);
|
|
622
|
-
}
|
|
623
|
-
else if (isExpressionWithTypeArguments(node)) {
|
|
624
|
-
found.push(isPropertyAccessExpression(node.expression) ? node.expression.name : node.expression);
|
|
625
|
-
}
|
|
626
|
-
else if (isTypeQueryNode(node)) {
|
|
627
|
-
found.push(isQualifiedName(node.exprName) ? node.exprName.right : node.exprName);
|
|
628
|
-
}
|
|
629
|
-
const body = isFunctionLikeDeclaration(node) ? node.body : undefined;
|
|
630
|
-
node.forEachChild((child) => {
|
|
631
|
-
if (child !== body) {
|
|
632
|
-
visit(child);
|
|
633
|
-
}
|
|
634
|
-
});
|
|
635
|
-
};
|
|
636
|
-
visit(declaration);
|
|
637
|
-
return found;
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* Keeps every declaration the configuration names and returns every string that
|
|
641
|
-
* named none, in configuration order. A string the configuration lists twice is one
|
|
642
|
-
* configured root.
|
|
643
|
-
*/
|
|
644
|
-
function configured(held, patterns, add) {
|
|
645
|
-
const unmatched = [];
|
|
646
|
-
for (const pattern of new Set(patterns)) {
|
|
647
|
-
const kind = isPattern(pattern) ? "pattern" : "configured";
|
|
648
|
-
let matched = false;
|
|
649
|
-
for (const symbol of held.symbols) {
|
|
650
|
-
if (matchRef(pattern, symbol.ref)) {
|
|
651
|
-
add(symbol.id, kind, pattern);
|
|
652
|
-
matched = true;
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
if (!matched) {
|
|
656
|
-
unmatched.push(pattern);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
return unmatched;
|
|
660
|
-
}
|
|
661
|
-
/**
|
|
662
|
-
* Every configured string that named no declaration in ANY project of the run, in
|
|
663
|
-
* configuration order and each once.
|
|
664
|
-
*
|
|
665
|
-
* A finding about a configured root is about the configuration and not about a
|
|
666
|
-
* declaration, so there is one per run: a string that names a declaration of one
|
|
667
|
-
* project has named something, and the projects it named nothing in are not a
|
|
668
|
-
* finding. A run with no project names nothing with any of them.
|
|
669
|
-
*/
|
|
670
|
-
export function unmatchedEverywhere(patterns, perProject) {
|
|
671
|
-
return [...new Set(patterns)].filter((pattern) => perProject.every((project) => project.unmatched.includes(pattern)));
|
|
672
|
-
}
|