@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
|
@@ -3,29 +3,20 @@
|
|
|
3
3
|
* the code's row of the issue-kind vocabulary, and the dials that withhold a finding
|
|
4
4
|
* together with every finding that falls with a root they withhold.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { CODE, FAMILY_KEY_LENGTH, KIND_ROWS, } from "../contract/contract.generated.js";
|
|
7
|
+
import { componentId } from "../liveness/components.js";
|
|
8
|
+
import { deadComponents } from "../liveness/sweep.js";
|
|
9
|
+
import { OUTSIDE } from "../liveness/graph.js";
|
|
9
10
|
import { KINDS } from "../kinds.js";
|
|
10
11
|
import { byPosition, positionKey } from "../position.js";
|
|
11
12
|
import { declarationKey } from "../ref.js";
|
|
12
|
-
import { FAMILY_KEY_LENGTH } from "../resolve.js";
|
|
13
13
|
import { isPartSubject, isRowSubject } from "../suppress.js";
|
|
14
|
-
/** The unused-file code, whose deletion removes every use its file writes. */
|
|
15
|
-
const FILE_NEVER_IMPORTED = "DS1502";
|
|
16
14
|
/**
|
|
17
|
-
* The codes whose subject the run that counts test references holds live,
|
|
18
|
-
*
|
|
19
|
-
* none of a dead declaration's sweep facts.
|
|
15
|
+
* The codes whose subject the run that counts test references holds live, so a test
|
|
16
|
+
* file's candidate reported under one carries none of a dead declaration's sweep facts.
|
|
20
17
|
*/
|
|
21
|
-
const LIVE_SUBJECT = new Set(
|
|
22
|
-
|
|
23
|
-
"DS1102",
|
|
24
|
-
"DS1104",
|
|
25
|
-
"DS1204",
|
|
26
|
-
"DS1301",
|
|
27
|
-
]);
|
|
28
|
-
/** The fixability grammar/analysis.md "Fixability" gives a finding about a held declaration. */
|
|
18
|
+
const LIVE_SUBJECT = new Set(KIND_ROWS.filter((row) => row.holdsLive).map((row) => row.code));
|
|
19
|
+
/** The fixability grammar/analysis/fixability.md gives a finding about a held declaration. */
|
|
29
20
|
const MANUAL = "manual";
|
|
30
21
|
/** The member kinds an object property can declare, which an `in` expression tests by name. */
|
|
31
22
|
const IN_TESTED = new Set([
|
|
@@ -50,8 +41,9 @@ function everyDeclaredLoaded(boundary) {
|
|
|
50
41
|
* naming its family, else the code's default.
|
|
51
42
|
*/
|
|
52
43
|
function severityOf(input, code, fallback) {
|
|
53
|
-
const {
|
|
54
|
-
|
|
44
|
+
const { severity } = input.config;
|
|
45
|
+
const key = [code, code.slice(0, FAMILY_KEY_LENGTH)].find((one) => Object.hasOwn(severity, one));
|
|
46
|
+
return key === undefined ? fallback : (severity[key] ?? fallback);
|
|
55
47
|
}
|
|
56
48
|
/**
|
|
57
49
|
* The declarations the roots name as a library's published API, each public member of a
|
|
@@ -87,10 +79,13 @@ function testedByIn(input) {
|
|
|
87
79
|
* published API, a public member of a published type included, is `certain` where the
|
|
88
80
|
* run loaded every consumer the scope declared and declared one, `probable` where one did
|
|
89
81
|
* not load, and `possible` where it declared none, whatever the configuration says of the
|
|
90
|
-
* consumer set. A member an `in` expression tests by name
|
|
82
|
+
* consumer set. A member an `in` expression tests by name, one a function outside the
|
|
83
|
+
* analysis fills, and one {@link possiblyLoaded} names, is `possible`.
|
|
91
84
|
*/
|
|
92
|
-
function reachabilityClasses(input) {
|
|
85
|
+
export function reachabilityClasses(input) {
|
|
93
86
|
const tested = testedByIn(input);
|
|
87
|
+
const filled = input.boundary.filledOutside ?? new Set();
|
|
88
|
+
const possible = possiblyLoaded(input);
|
|
94
89
|
const published = publishedIds(input.swept.matrix.union);
|
|
95
90
|
const { declared } = input.boundary.consumers;
|
|
96
91
|
const outside = declared.length === 0
|
|
@@ -99,7 +94,7 @@ function reachabilityClasses(input) {
|
|
|
99
94
|
? "certain"
|
|
100
95
|
: "probable";
|
|
101
96
|
return (id) => {
|
|
102
|
-
if (tested.has(id)) {
|
|
97
|
+
if (tested.has(id) || filled.has(id) || possible.has(id)) {
|
|
103
98
|
return "possible";
|
|
104
99
|
}
|
|
105
100
|
return published.has(id) ? outside : "certain";
|
|
@@ -130,9 +125,38 @@ function testCeilings(input, classOf) {
|
|
|
130
125
|
? testTargets(union, id).reduce((lowest, target) => capped(lowest, classOf(target)), "certain")
|
|
131
126
|
: "certain";
|
|
132
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* What only a bundler's retry of an import Node leaves unresolved names (program.38), and each
|
|
130
|
+
* dead declaration that reaches through dead declarations, as confidence.20 reads what only
|
|
131
|
+
* tests reach: each is dead only while no loader the analysis does not see loads the file.
|
|
132
|
+
*/
|
|
133
|
+
function possiblyLoaded(input) {
|
|
134
|
+
const seeds = input.boundary.possiblyLoaded ?? new Set();
|
|
135
|
+
if (seeds.size === 0) {
|
|
136
|
+
return seeds;
|
|
137
|
+
}
|
|
138
|
+
const union = input.swept.matrix.union;
|
|
139
|
+
const dead = new Set(input.swept.sweep.candidates.map((one) => one.id));
|
|
140
|
+
const reached = new Set();
|
|
141
|
+
const pending = union.symbols.flatMap((symbol, at) => (seeds.has(symbol.id) ? [at] : []));
|
|
142
|
+
for (let at = pending.pop(); at !== undefined; at = pending.pop()) {
|
|
143
|
+
const symbol = union.symbols[at];
|
|
144
|
+
if (symbol === undefined || reached.has(symbol.id)) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
reached.add(symbol.id);
|
|
148
|
+
for (const edge of union.out[at] ?? []) {
|
|
149
|
+
const to = union.symbols[edge.to];
|
|
150
|
+
if (to !== undefined && dead.has(to.id)) {
|
|
151
|
+
pending.push(edge.to);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return reached;
|
|
156
|
+
}
|
|
133
157
|
/**
|
|
134
158
|
* The subjects dead only because production code only tests use is: each declaration the
|
|
135
|
-
* sweep marks test-used, each `
|
|
159
|
+
* sweep marks test-used, each `DS1602` file of such code, and each test of dead code every
|
|
136
160
|
* target of which is one. Nothing they hold references a dead declaration outside them, so
|
|
137
161
|
* the rest of a component they share is reported without them.
|
|
138
162
|
*/
|
|
@@ -151,13 +175,16 @@ function testUsedSubjects(input) {
|
|
|
151
175
|
}
|
|
152
176
|
/**
|
|
153
177
|
* The ceiling the roots the run found put on one dead subject: a subject other declarations
|
|
154
|
-
* reference, found dead only because no root reaches them, is `probable` unless
|
|
155
|
-
*
|
|
156
|
-
*
|
|
178
|
+
* reference, found dead only because no root reaches them, is `probable` unless the
|
|
179
|
+
* configuration declares the roots complete and no configuration holding the subject loads
|
|
180
|
+
* a module the analysis cannot resolve, because a root the analysis cannot see would make
|
|
181
|
+
* it live; every other declaration has none below `certain`.
|
|
157
182
|
*/
|
|
158
|
-
function rootsCeiling(input, finding, candidate) {
|
|
183
|
+
function rootsCeiling(input, finding, candidate, configurations) {
|
|
159
184
|
const unreachable = candidate?.relation === "reachability" || finding.unreachableOnly === true;
|
|
160
|
-
|
|
185
|
+
const unseen = new Set((input.files.unseenLoads ?? []).map((load) => load.configuration));
|
|
186
|
+
const complete = input.config.ts.roots_complete && !configurations.some((one) => unseen.has(one));
|
|
187
|
+
return unreachable && !complete ? "probable" : "certain";
|
|
161
188
|
}
|
|
162
189
|
/**
|
|
163
190
|
* The component each dead declaration of the run falls in, and none for a live one, with
|
|
@@ -170,8 +197,24 @@ function findingComponents(swept, components, cascade) {
|
|
|
170
197
|
held.set(member, component);
|
|
171
198
|
}
|
|
172
199
|
}
|
|
200
|
+
const listed = membersListed(swept);
|
|
201
|
+
return (id) => {
|
|
202
|
+
const component = held.get(id);
|
|
203
|
+
return component === undefined
|
|
204
|
+
? undefined
|
|
205
|
+
: {
|
|
206
|
+
id: component.id,
|
|
207
|
+
root: component.roots.includes(id),
|
|
208
|
+
symbolCount: component.members.length,
|
|
209
|
+
deletableLines: component.deletableLines,
|
|
210
|
+
...(cascade === "full" ? { members: listed(component.members) } : {}),
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/** The members of a component as the run lists them, positioned and in the canonical order. */
|
|
215
|
+
function membersListed(swept) {
|
|
173
216
|
const symbols = new Map(swept.matrix.union.symbols.map((symbol) => [symbol.id, symbol]));
|
|
174
|
-
|
|
217
|
+
return (members) => members
|
|
175
218
|
.flatMap((member) => {
|
|
176
219
|
const symbol = symbols.get(member);
|
|
177
220
|
return symbol === undefined
|
|
@@ -188,27 +231,15 @@ function findingComponents(swept, components, cascade) {
|
|
|
188
231
|
];
|
|
189
232
|
})
|
|
190
233
|
.sort((a, b) => byPosition(a.position, b.position));
|
|
191
|
-
return (id) => {
|
|
192
|
-
const component = held.get(id);
|
|
193
|
-
return component === undefined
|
|
194
|
-
? undefined
|
|
195
|
-
: {
|
|
196
|
-
id: component.id,
|
|
197
|
-
root: component.roots.includes(id),
|
|
198
|
-
symbolCount: component.members.length,
|
|
199
|
-
deletableLines: component.deletableLines,
|
|
200
|
-
...(cascade === "full" ? { members: listed(component) } : {}),
|
|
201
|
-
};
|
|
202
|
-
};
|
|
203
234
|
}
|
|
204
235
|
/**
|
|
205
|
-
* The run's dead components with each file a `
|
|
236
|
+
* The run's dead components with each file a `DS1602` finding reports dead among them, so
|
|
206
237
|
* the file's declarations fall with it, and with the components each subject that is no
|
|
207
238
|
* declaration falls with joined into one.
|
|
208
239
|
*/
|
|
209
240
|
function runComponents(swept, findings) {
|
|
210
241
|
const union = swept.matrix.union;
|
|
211
|
-
const reported = new Set(findings.filter((one) => one.code ===
|
|
242
|
+
const reported = new Set(findings.filter((one) => one.code === CODE.fileNeverImported).map((one) => one.position.path));
|
|
212
243
|
const files = new Map(union.symbols.flatMap((symbol, at) => symbol.kind === "file" && reported.has(symbol.position.path) ? [[at, symbol]] : []));
|
|
213
244
|
const computed = files.size === 0
|
|
214
245
|
? swept.sweep.components
|
|
@@ -267,6 +298,7 @@ export function completed(input, findings, kinds = KINDS) {
|
|
|
267
298
|
const union = swept.matrix.union;
|
|
268
299
|
const positions = new Map(union.symbols.map((symbol, at) => [declarationKey(symbol.ref, symbol.position.path), at]));
|
|
269
300
|
const candidates = new Map(swept.sweep.candidates.map((candidate) => [candidate.id, candidate]));
|
|
301
|
+
const fileIds = new Map(union.symbols.flatMap((one) => (one.kind === "file" ? [[one.position.path, one.id]] : [])));
|
|
270
302
|
const classOf = reachabilityClasses(input);
|
|
271
303
|
const ceilingOf = testCeilings(input, classOf);
|
|
272
304
|
const testUsed = testUsedSubjects(input);
|
|
@@ -277,11 +309,12 @@ export function completed(input, findings, kinds = KINDS) {
|
|
|
277
309
|
let minted = computed;
|
|
278
310
|
const dead = new Set(components.map((component) => component.id));
|
|
279
311
|
const fallingWith = new Map();
|
|
280
|
-
for (const { heldByTests } of swept.sweep.candidates) {
|
|
312
|
+
for (const { id, heldByTests } of swept.sweep.candidates) {
|
|
281
313
|
if (heldByTests !== undefined) {
|
|
282
|
-
fallingWith.set(heldByTests, (fallingWith.get(heldByTests) ??
|
|
314
|
+
fallingWith.set(heldByTests, [...(fallingWith.get(heldByTests) ?? []), id]);
|
|
283
315
|
}
|
|
284
316
|
}
|
|
317
|
+
const listed = membersListed(swept);
|
|
285
318
|
const done = findings.map((finding) => {
|
|
286
319
|
const row = kinds.get(finding.code);
|
|
287
320
|
if (row === undefined) {
|
|
@@ -307,7 +340,7 @@ export function completed(input, findings, kinds = KINDS) {
|
|
|
307
340
|
: candidates.get(judged.id);
|
|
308
341
|
const fallsWith = finding.fallsWith?.[0];
|
|
309
342
|
const joined = fallsWith === undefined ? undefined : componentOf(fallsWith);
|
|
310
|
-
const file = finding.code ===
|
|
343
|
+
const file = finding.code === CODE.fileNeverImported ? files.get(finding.position.path) : undefined;
|
|
311
344
|
const found = joined !== undefined
|
|
312
345
|
? { ...joined, root: false }
|
|
313
346
|
: file !== undefined
|
|
@@ -326,22 +359,45 @@ export function completed(input, findings, kinds = KINDS) {
|
|
|
326
359
|
let component = found;
|
|
327
360
|
if (component === undefined) {
|
|
328
361
|
minted += 1;
|
|
362
|
+
const falling = symbol?.kind === "interface" ? fallingWith.get(symbol.id) : undefined;
|
|
329
363
|
component = {
|
|
330
364
|
id: componentId(minted),
|
|
331
365
|
root: true,
|
|
332
|
-
symbolCount:
|
|
366
|
+
symbolCount: falling?.length ?? 1,
|
|
333
367
|
deletableLines: 0,
|
|
368
|
+
...(input.config.reporters.cascade !== "full"
|
|
369
|
+
? {}
|
|
370
|
+
: falling === undefined
|
|
371
|
+
? {
|
|
372
|
+
members: [
|
|
373
|
+
{
|
|
374
|
+
ref: finding.symbol.ref,
|
|
375
|
+
name: finding.symbol.name,
|
|
376
|
+
position: finding.position,
|
|
377
|
+
},
|
|
378
|
+
],
|
|
379
|
+
}
|
|
380
|
+
: { members: listed(falling) }),
|
|
334
381
|
};
|
|
335
382
|
}
|
|
336
383
|
const counts = candidate === undefined
|
|
337
384
|
? union.made[at]
|
|
338
385
|
: { production: candidate.productionRefs, test: candidate.testRefs };
|
|
339
|
-
const ownClass = judged
|
|
386
|
+
const ownClass = judged !== undefined
|
|
387
|
+
? classOf(judged.id)
|
|
388
|
+
: (finding.reachabilityClass ??
|
|
389
|
+
(finding.code === CODE.fileNeverImported
|
|
390
|
+
? classOf(fileIds.get(finding.position.path) ?? "")
|
|
391
|
+
: "certain"));
|
|
340
392
|
const used = judged !== undefined
|
|
341
393
|
? candidate !== undefined && testUsed.declarations.has(judged.id)
|
|
342
|
-
: finding.code ===
|
|
394
|
+
: finding.code === CODE.fileNeverImported && testUsed.files.has(finding.position.path);
|
|
343
395
|
const reachabilityClass = used && candidate?.testOfDeadCode !== true ? "possible" : ownClass;
|
|
344
|
-
const
|
|
396
|
+
const configurations = candidate?.configurations ??
|
|
397
|
+
(judged === undefined && !part
|
|
398
|
+
? swept.matrix.configurations
|
|
399
|
+
: (swept.matrix.heldIn[at] ?? swept.matrix.configurations));
|
|
400
|
+
const untested = capped(capped(capped(ownClass, row.maxClass), rootsCeiling(input, finding, candidate, configurations)), judged === undefined ? "certain" : ceilingOf(judged.id));
|
|
345
401
|
const generated = input.files.generated?.has(finding.position.path) === true;
|
|
346
402
|
const fixability = generated
|
|
347
403
|
? "none"
|
|
@@ -355,7 +411,7 @@ export function completed(input, findings, kinds = KINDS) {
|
|
|
355
411
|
? undefined
|
|
356
412
|
: candidate !== undefined
|
|
357
413
|
? input.dependencies.lastUses.get(candidate.id)
|
|
358
|
-
: finding.code ===
|
|
414
|
+
: finding.code === CODE.fileNeverImported
|
|
359
415
|
? input.dependencies.fileLastUses.get(finding.position.path)
|
|
360
416
|
: undefined;
|
|
361
417
|
return {
|
|
@@ -372,10 +428,7 @@ export function completed(input, findings, kinds = KINDS) {
|
|
|
372
428
|
generated,
|
|
373
429
|
component,
|
|
374
430
|
retainedBy: [],
|
|
375
|
-
configurations
|
|
376
|
-
(judged === undefined && !part
|
|
377
|
-
? swept.matrix.configurations
|
|
378
|
-
: (swept.matrix.heldIn[at] ?? swept.matrix.configurations)),
|
|
431
|
+
configurations,
|
|
379
432
|
consumersLoaded: input.boundary.consumers.loaded,
|
|
380
433
|
fixability,
|
|
381
434
|
severity: severityOf(input, finding.code, row.defaultSeverity),
|
|
@@ -431,7 +484,7 @@ function dialed(finding, minConfidence) {
|
|
|
431
484
|
* root withholds itself alone.
|
|
432
485
|
*/
|
|
433
486
|
export function dialsOf(input, findings) {
|
|
434
|
-
const minConfidence = input.config.analysis.
|
|
487
|
+
const minConfidence = input.config.analysis.min_confidence;
|
|
435
488
|
const components = new Set(findings
|
|
436
489
|
.filter((finding) => finding.component.root &&
|
|
437
490
|
dialed({ ...finding, confidence: componentConfidenceOf(finding) }, minConfidence))
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import { CODE } from "../contract/contract.generated.js";
|
|
1
2
|
import { declarationKey } from "../dependencies.js";
|
|
2
3
|
import { renderRef } from "../ref.js";
|
|
3
4
|
import { nonCodeArtifacts } from "./non-code-artifacts.js";
|
|
4
|
-
const UNUSED_DEPENDENCY = "DS1601";
|
|
5
|
-
const FILE_NEVER_IMPORTED = "DS1502";
|
|
6
5
|
const MESSAGES = {
|
|
7
6
|
dependency: "no import in the target needs the declared dependency",
|
|
8
7
|
"dev-dependency": "no import in the target needs the declared development dependency",
|
|
@@ -25,7 +24,7 @@ function deadCode(input) {
|
|
|
25
24
|
const reachedOnly = new Set(swept.sweep.candidates.filter((one) => one.relation === "reachability").map((one) => one.id));
|
|
26
25
|
for (const finding of nonCodeArtifacts(input)) {
|
|
27
26
|
const id = files.get(finding.position.path);
|
|
28
|
-
if (finding.code ===
|
|
27
|
+
if (finding.code === CODE.fileNeverImported && id !== undefined) {
|
|
29
28
|
dead.add(id);
|
|
30
29
|
if (finding.unreachableOnly === true) {
|
|
31
30
|
reachedOnly.add(id);
|
|
@@ -57,7 +56,7 @@ function unusedDependencies(input, dependencies) {
|
|
|
57
56
|
const atPossible = unbuilt || users?.some((id) => published.has(id)) === true;
|
|
58
57
|
return [
|
|
59
58
|
{
|
|
60
|
-
code:
|
|
59
|
+
code: CODE.unusedDependency,
|
|
61
60
|
position: dependency.position,
|
|
62
61
|
symbol: {
|
|
63
62
|
ref: renderRef(dependency.manifest, {
|
|
@@ -80,5 +79,5 @@ function unusedDependencies(input, dependencies) {
|
|
|
80
79
|
];
|
|
81
80
|
});
|
|
82
81
|
}
|
|
83
|
-
/** The findings of the dependencies
|
|
82
|
+
/** The findings of the dependencies family, `DS1700` to `DS1799`. */
|
|
84
83
|
export const dependenciesAndModuleMachinery = (input) => unusedDependencies(input, input.dependencies);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { evaluateEdges } from "../edges.js";
|
|
2
|
-
import { liveFilesAt } from "../matrix.js";
|
|
3
2
|
import { declarationKey } from "../ref.js";
|
|
4
3
|
import { ledgerOf } from "../suppress.js";
|
|
5
4
|
import { insideSkipped } from "../type-errors.js";
|
|
@@ -8,11 +7,11 @@ import { dependenciesAndModuleMachinery } from "./dependencies-and-module-machin
|
|
|
8
7
|
import { interfaces } from "./interfaces.js";
|
|
9
8
|
import { intraFunction } from "./intra-function.js";
|
|
10
9
|
import { nonCodeArtifacts } from "./non-code-artifacts.js";
|
|
11
|
-
import { readsAndWrites } from "./reads-and-writes.js";
|
|
10
|
+
import { fallingWithWrites, readsAndWrites } from "./reads-and-writes.js";
|
|
12
11
|
import { selfCheck } from "./self-check.js";
|
|
13
12
|
import { fallenMembers, unusedDeclarations } from "./unused-declarations.js";
|
|
14
13
|
import { visibilityNarrowing } from "./visibility-narrowing.js";
|
|
15
|
-
/** Every
|
|
14
|
+
/** Every emitter this analyzer runs, by the name its tests select it by. */
|
|
16
15
|
export const EMITTERS = new Map([
|
|
17
16
|
["unused-declarations", unusedDeclarations],
|
|
18
17
|
["visibility-narrowing", visibilityNarrowing],
|
|
@@ -23,37 +22,25 @@ export const EMITTERS = new Map([
|
|
|
23
22
|
["self-check", selfCheck],
|
|
24
23
|
["intra-function", intraFunction],
|
|
25
24
|
]);
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
*/
|
|
30
|
-
function heldKeys(input) {
|
|
31
|
-
const held = new Set(input.swept.heldByUnanswered);
|
|
32
|
-
if (held.size === 0) {
|
|
33
|
-
return held;
|
|
34
|
-
}
|
|
25
|
+
/** The keys of the declarations the identifiers name, as {@link findingKey} keys a finding. */
|
|
26
|
+
function keysOf(input, ids) {
|
|
27
|
+
const named = new Set(ids);
|
|
35
28
|
return new Set(input.swept.matrix.union.symbols
|
|
36
|
-
.filter((symbol) =>
|
|
29
|
+
.filter((symbol) => named.has(symbol.id))
|
|
37
30
|
.map((symbol) => declarationKey(symbol.ref, symbol.position.path)));
|
|
38
31
|
}
|
|
32
|
+
/** The key of the declaration a finding is about, or of the one holding the part it is about. */
|
|
33
|
+
function findingKey(finding) {
|
|
34
|
+
return declarationKey(finding.symbol.holder ?? finding.symbol.ref, finding.position.path);
|
|
35
|
+
}
|
|
39
36
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
37
|
+
* Every emitter's findings over one sweep, and those of any further emitter, completed by
|
|
38
|
+
* one step, but none about a declaration that falls with a write-only subject: that
|
|
39
|
+
* subject's finding names it, so no finding about it exists for a record to match.
|
|
43
40
|
*/
|
|
44
|
-
function markupKeys(input) {
|
|
45
|
-
const { swept } = input;
|
|
46
|
-
if (swept.componentFiles.length === 0) {
|
|
47
|
-
return new Set();
|
|
48
|
-
}
|
|
49
|
-
const live = new Set(liveFilesAt(swept.matrix, swept.sweep, new Set(swept.componentFiles)).map((symbol) => symbol.id));
|
|
50
|
-
return new Set(swept.matrix.union.symbols
|
|
51
|
-
.filter((symbol) => live.has(symbol.parent))
|
|
52
|
-
.map((symbol) => declarationKey(symbol.ref, symbol.position.path)));
|
|
53
|
-
}
|
|
54
|
-
/** Every family's findings over one sweep, and those of any further emitter, completed by one step. */
|
|
55
41
|
function completedOver(input, ...more) {
|
|
56
|
-
|
|
42
|
+
const falls = keysOf(input, fallingWithWrites(input));
|
|
43
|
+
return completed(input, [...EMITTERS.values(), ...more].flatMap((emit) => emit(input))).filter((finding) => !falls.has(findingKey(finding)));
|
|
57
44
|
}
|
|
58
45
|
/**
|
|
59
46
|
* The dials over the findings a record could name, each read against the sweep that
|
|
@@ -70,8 +57,8 @@ function dialsOver(input, found, suppressed, unmarked) {
|
|
|
70
57
|
}
|
|
71
58
|
/**
|
|
72
59
|
* Every finding of one run swept under its suppressions' marks, decided in one pass: each
|
|
73
|
-
*
|
|
74
|
-
* finding each record claims withheld, the rest withheld by the dials, so a root one
|
|
60
|
+
* emitter's findings completed by one step, so every component number is minted once, the
|
|
61
|
+
* finding each record claims withheld, the rest withheld by the dials, so a root one emitter
|
|
75
62
|
* reports withholds what another reports in its component, and every declared edge
|
|
76
63
|
* evaluated over what remains, so a pending finding is in its evaluation alone.
|
|
77
64
|
*/
|
|
@@ -86,7 +73,7 @@ function atPossible(input) {
|
|
|
86
73
|
const { config } = input;
|
|
87
74
|
return {
|
|
88
75
|
...input,
|
|
89
|
-
config: { ...config, analysis: { ...config.analysis,
|
|
76
|
+
config: { ...config, analysis: { ...config.analysis, min_confidence: "possible" } },
|
|
90
77
|
};
|
|
91
78
|
}
|
|
92
79
|
/**
|
|
@@ -96,16 +83,15 @@ function atPossible(input) {
|
|
|
96
83
|
*/
|
|
97
84
|
function dialledOver(input, suppressed, found, unmarked) {
|
|
98
85
|
const would = [...unmarked, ...found];
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
86
|
+
const { sweep } = input.swept;
|
|
87
|
+
// A hold is a gap of the analysis, which leaves a record it touches dormant; a live
|
|
88
|
+
// component file's markup is no gap, so a record on one of its bindings stays in effect.
|
|
89
|
+
const unanswered = keysOf(input, sweep.held);
|
|
90
|
+
const markup = keysOf(input, sweep.bindings);
|
|
91
|
+
const heldIds = new Set(sweep.held);
|
|
92
|
+
const held = (finding) => unanswered.has(findingKey(finding)) || insideSkipped(input.swept.skipped, finding.position);
|
|
93
|
+
const ledger = ledgerOf(suppressed.records, would, dialsOver(input, found, suppressed, unmarked), { withholds: held, holdsRecord: (record) => heldIds.has(record.bound) });
|
|
94
|
+
const candidates = found.filter((finding) => !ledger.withheld(finding) && !held(finding) && !markup.has(findingKey(finding)));
|
|
109
95
|
const kept = reportable(input, candidates);
|
|
110
96
|
const evaluated = evaluateEdges(kept, input.boundary.edges, input.swept.matrix.union.symbols);
|
|
111
97
|
return {
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { isClassDeclaration, isHeritageClause, isInterfaceDeclaration, isMethodDeclaration, SyntaxKind, } from "@typescript/native/ast";
|
|
9
9
|
import { SymbolFlags } from "@typescript/native/sync";
|
|
10
|
-
import { aliasChains } from "
|
|
11
|
-
import { nodeKey } from "
|
|
12
|
-
import { must, Unanswerable } from "
|
|
10
|
+
import { aliasChains } from "../alias-chain.js";
|
|
11
|
+
import { nodeKey } from "../inventory.js";
|
|
12
|
+
import { must, Unanswerable } from "../query.js";
|
|
13
13
|
/** The interfaces, the classes and the `implements` entries of one project's own files. */
|
|
14
14
|
function walk(project, held) {
|
|
15
15
|
const interfaces = [];
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* links the read to a declaration, so only a text match can tell which member it reads.
|
|
5
5
|
*/
|
|
6
6
|
import { isBinaryExpression, isNoSubstitutionTemplateLiteral, isStringLiteral, SyntaxKind, } from "@typescript/native/ast";
|
|
7
|
-
import { sourceFilesOf } from "
|
|
7
|
+
import { sourceFilesOf } from "../source-files.js";
|
|
8
|
+
import { bytewise } from "../text/compare.js";
|
|
8
9
|
/**
|
|
9
10
|
* The text of each string literal, or template literal with no substitution, written as
|
|
10
11
|
* the left operand of an `in` expression in a file of the project that is no test file.
|
|
@@ -26,5 +27,5 @@ export function inOperandNames(project, targetRoot, testFiles) {
|
|
|
26
27
|
file.forEachChild(visit);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
|
-
return [...found].sort();
|
|
30
|
+
return [...found].sort(bytewise);
|
|
30
31
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
import { CODE } from "../contract/contract.generated.js";
|
|
1
2
|
import { byPosition } from "../position.js";
|
|
2
|
-
const UNUSED_INTERFACE = "DS1201";
|
|
3
|
-
const UNCALLED_INTERFACE_METHOD = "DS1203";
|
|
4
3
|
/** What each finding says, by what the sweep found about the subject's references. */
|
|
5
4
|
const UNUSED_MESSAGE = "nothing in the target names the interface as a type";
|
|
6
5
|
const UNUSED_DEAD_MESSAGE = "the interface is named as a type only from declarations that are themselves dead";
|
|
@@ -45,7 +44,7 @@ function findingOf(code, symbol, message, implementations) {
|
|
|
45
44
|
}
|
|
46
45
|
/**
|
|
47
46
|
* The findings of the interfaces family, `DS1200` to `DS1299`: `DS1201`, a dead
|
|
48
|
-
* interface, whose members fall with it unreported; and `
|
|
47
|
+
* interface, whose members fall with it unreported; and `DS1202`, a method of a live
|
|
49
48
|
* interface no reference names, unless it is a marker, a method whose every
|
|
50
49
|
* implementation has an empty body. A test file's declaration is neither kind's subject,
|
|
51
50
|
* because a production sweep counts none of the references it can have, save an interface
|
|
@@ -60,7 +59,7 @@ export const interfaces = (input) => {
|
|
|
60
59
|
continue;
|
|
61
60
|
}
|
|
62
61
|
if (symbol.kind === "interface") {
|
|
63
|
-
found.push(findingOf(
|
|
62
|
+
found.push(findingOf(CODE.unusedInterface, symbol, unusedMessage(candidate), run.implementationsOf(candidate.id)));
|
|
64
63
|
continue;
|
|
65
64
|
}
|
|
66
65
|
if (symbol.kind !== "interface-method" ||
|
|
@@ -69,7 +68,7 @@ export const interfaces = (input) => {
|
|
|
69
68
|
marker(input, candidate.id)) {
|
|
70
69
|
continue;
|
|
71
70
|
}
|
|
72
|
-
found.push(findingOf(
|
|
71
|
+
found.push(findingOf(CODE.uncalledInterfaceMethod, symbol, UNCALLED_MESSAGE, run.implementationsOf(symbol.parent)));
|
|
73
72
|
}
|
|
74
73
|
return found;
|
|
75
74
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { CODE } from "../contract/contract.generated.js";
|
|
1
2
|
import { KINDS } from "../kinds.js";
|
|
2
3
|
import { parameterRef } from "../ref.js";
|
|
3
|
-
import {
|
|
4
|
-
import { reachedWithTheTests } from "../sweep.js";
|
|
4
|
+
import {} from "../intra-function-parts.js";
|
|
5
|
+
import { reachedWithTheTests } from "../liveness/sweep.js";
|
|
5
6
|
/** A list of rules as a sentence names them. */
|
|
6
7
|
function spelled(rules) {
|
|
7
8
|
if (rules.length < 2) {
|
|
@@ -28,7 +29,8 @@ function overlapClause(overlap, part) {
|
|
|
28
29
|
* caller may pass a function used as a value more arguments than it declares, so there one
|
|
29
30
|
* a read parameter follows is renamed to an underscore name, which the compilers read as
|
|
30
31
|
* declared unread, and one no read parameter follows is deleted: kept where the call's
|
|
31
|
-
* inference may read its annotation, at `probable` where nothing reads the annotation
|
|
32
|
+
* inference may read its annotation, at `probable` where nothing reads the annotation or
|
|
33
|
+
* where it is a name a contextually typed object pattern binds.
|
|
32
34
|
*/
|
|
33
35
|
function parameterVerdict(part, free, freeButValued) {
|
|
34
36
|
const place = part.parameter;
|
|
@@ -45,7 +47,8 @@ function parameterVerdict(part, free, freeButValued) {
|
|
|
45
47
|
if (place?.annotated === "steers") {
|
|
46
48
|
return undefined;
|
|
47
49
|
}
|
|
48
|
-
|
|
50
|
+
const unseen = place?.annotated === "free" || place?.contextualPattern === true;
|
|
51
|
+
return { fix: "delete", confidence: unseen ? "probable" : "certain" };
|
|
49
52
|
}
|
|
50
53
|
/**
|
|
51
54
|
* Whether one part is reported. A parameter needs its function's signature free to
|
|
@@ -60,9 +63,9 @@ function reported(input, part, callersUnknown) {
|
|
|
60
63
|
}
|
|
61
64
|
const { free, freeButValued, discardedEverywhere } = input.intraFunction;
|
|
62
65
|
switch (part.code) {
|
|
63
|
-
case
|
|
66
|
+
case CODE.unusedParameter:
|
|
64
67
|
return parameterVerdict(part, free, freeButValued) !== undefined;
|
|
65
|
-
case
|
|
68
|
+
case CODE.unusedResult:
|
|
66
69
|
return (free.has(part.declaration) &&
|
|
67
70
|
discardedEverywhere.has(part.declaration) &&
|
|
68
71
|
!callersUnknown.has(part.declaration));
|
|
@@ -71,7 +74,7 @@ function reported(input, part, callersUnknown) {
|
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
/**
|
|
74
|
-
* The findings of the
|
|
77
|
+
* The findings of the inside-functions family, `DS1401` to `DS1406`, each about a part of
|
|
75
78
|
* the declaration its reference names, at the part's own position, whatever the sweep
|
|
76
79
|
* decided about a production declaration. A part of test code is reported only where the
|
|
77
80
|
* run that counts test references reaches its declaration and that is no test of dead
|
|
@@ -81,8 +84,8 @@ export const intraFunction = (input) => {
|
|
|
81
84
|
const union = input.swept.matrix.union;
|
|
82
85
|
const byId = new Map(union.symbols.map((symbol) => [symbol.id, symbol]));
|
|
83
86
|
const reached = reachedWithTheTests(union, [
|
|
84
|
-
...input.swept.exempt.map((record) => record.id),
|
|
85
|
-
...input.swept.
|
|
87
|
+
...input.swept.sweep.exempt.map((record) => record.id),
|
|
88
|
+
...input.swept.sweep.held,
|
|
86
89
|
]);
|
|
87
90
|
const testsOfDeadCode = new Set(input.swept.sweep.candidates.filter((one) => one.testOfDeadCode).map((one) => one.id));
|
|
88
91
|
const judged = (id) => {
|
|
@@ -95,7 +98,7 @@ export const intraFunction = (input) => {
|
|
|
95
98
|
return symbol === undefined ? [] : [symbol.id];
|
|
96
99
|
}));
|
|
97
100
|
const { declared, loaded } = input.boundary.consumers;
|
|
98
|
-
const closed = input.config.
|
|
101
|
+
const closed = input.config.consumers.complete && declared.every((id) => loaded.includes(id));
|
|
99
102
|
const published = (id) => {
|
|
100
103
|
const symbol = byId.get(id);
|
|
101
104
|
return (symbol !== undefined &&
|
|
@@ -112,11 +115,11 @@ export const intraFunction = (input) => {
|
|
|
112
115
|
const found = [];
|
|
113
116
|
for (const part of input.intraFunction.parts) {
|
|
114
117
|
const declaration = byId.get(part.declaration);
|
|
115
|
-
const overlap = KINDS.get(part.code)?.overlap ?? [];
|
|
118
|
+
const overlap = KINDS.get(part.code)?.overlap?.ts ?? [];
|
|
116
119
|
if (declaration === undefined || !judged(declaration.id) || !reported(input, part, unknown)) {
|
|
117
120
|
continue;
|
|
118
121
|
}
|
|
119
|
-
const verdict = part.code ===
|
|
122
|
+
const verdict = part.code === CODE.unusedParameter
|
|
120
123
|
? parameterVerdict(part, input.intraFunction.free, input.intraFunction.freeButValued)
|
|
121
124
|
: undefined;
|
|
122
125
|
const message = verdict?.fix === "rename"
|
|
@@ -126,7 +129,7 @@ export const intraFunction = (input) => {
|
|
|
126
129
|
code: part.code,
|
|
127
130
|
position: part.position,
|
|
128
131
|
symbol: {
|
|
129
|
-
...(part.code ===
|
|
132
|
+
...(part.code === CODE.unusedParameter
|
|
130
133
|
? { ref: parameterRef(declaration.ref, part.name), holder: declaration.ref }
|
|
131
134
|
: { ref: declaration.ref }),
|
|
132
135
|
kind: part.kind,
|