@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
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one syntax walk of a file every reference source and read rule shares: it finds the
|
|
3
|
+
* name nodes that are uses, the stores, the re-exports, the evaluated modules, the module
|
|
4
|
+
* URLs, the workers, the load calls, the decorators, the parameter properties and the keyed
|
|
5
|
+
* accesses, and offers every node to the read rules with its enclosing declaration.
|
|
6
|
+
*/
|
|
7
|
+
import { isArrayLiteralExpression, isAsExpression, isBinaryExpression, isCallExpression, isDecorator, isDeleteExpression, isElementAccessExpression, isExportDeclaration, isExpressionStatement, isExternalModuleReference, isForInStatement, isForOfStatement, isForStatement, isIdentifier, isImportDeclaration, isImportEqualsDeclaration, isMetaProperty, isNamespaceExport, isNewExpression, isNoSubstitutionTemplateLiteral, isObjectLiteralExpression, isParenthesizedExpression, isPostfixUnaryExpression, isPrefixUnaryExpression, isPropertyAccessExpression, isPropertyAssignment, isShorthandPropertyAssignment, isSpreadAssignment, isSpreadElement, isStringLiteral, isVoidExpression, SyntaxKind, } from "@typescript/native/ast";
|
|
8
|
+
import { amdLoadOf } from "../amd.js";
|
|
9
|
+
import { writtenValue } from "../entries/static-module.js";
|
|
10
|
+
import { propertyReadsOf } from "../destructuring.js";
|
|
11
|
+
import { isParameterProperty, nodeKey } from "../inventory.js";
|
|
12
|
+
import { namespaceUses } from "../namespace-objects.js";
|
|
13
|
+
import { startsRelativePath } from "../paths.js";
|
|
14
|
+
import { writtenName } from "../platform-calls.js";
|
|
15
|
+
import { isLoadCall } from "../roots/unseen-loads.js";
|
|
16
|
+
import { keyNameOf } from "../symbol-keys.js";
|
|
17
|
+
import { parenthesesRemoved } from "../unwrap.js";
|
|
18
|
+
import { handedOn, valuesOf } from "./values.js";
|
|
19
|
+
/**
|
|
20
|
+
* The operators whose left side one assignment stores into. A compound assignment is
|
|
21
|
+
* among them: where its value is discarded it reads its target only to write the result
|
|
22
|
+
* back, so nothing else receives what it read.
|
|
23
|
+
*/
|
|
24
|
+
const ASSIGNMENTS = new Set([
|
|
25
|
+
SyntaxKind.EqualsToken,
|
|
26
|
+
SyntaxKind.PlusEqualsToken,
|
|
27
|
+
SyntaxKind.MinusEqualsToken,
|
|
28
|
+
SyntaxKind.AsteriskEqualsToken,
|
|
29
|
+
SyntaxKind.AsteriskAsteriskEqualsToken,
|
|
30
|
+
SyntaxKind.SlashEqualsToken,
|
|
31
|
+
SyntaxKind.PercentEqualsToken,
|
|
32
|
+
SyntaxKind.LessThanLessThanEqualsToken,
|
|
33
|
+
SyntaxKind.GreaterThanGreaterThanEqualsToken,
|
|
34
|
+
SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken,
|
|
35
|
+
SyntaxKind.AmpersandEqualsToken,
|
|
36
|
+
SyntaxKind.BarEqualsToken,
|
|
37
|
+
SyntaxKind.BarBarEqualsToken,
|
|
38
|
+
SyntaxKind.AmpersandAmpersandEqualsToken,
|
|
39
|
+
SyntaxKind.QuestionQuestionEqualsToken,
|
|
40
|
+
SyntaxKind.CaretEqualsToken,
|
|
41
|
+
]);
|
|
42
|
+
/**
|
|
43
|
+
* The assignments that read their target to decide whether to store at all, so the read
|
|
44
|
+
* carries information out whatever becomes of the result.
|
|
45
|
+
*/
|
|
46
|
+
const LOGICAL_ASSIGNMENTS = new Set([
|
|
47
|
+
SyntaxKind.BarBarEqualsToken,
|
|
48
|
+
SyntaxKind.AmpersandAmpersandEqualsToken,
|
|
49
|
+
SyntaxKind.QuestionQuestionEqualsToken,
|
|
50
|
+
]);
|
|
51
|
+
/**
|
|
52
|
+
* Whether the value of one store expression is discarded: it is a statement of its own, a
|
|
53
|
+
* clause of a `for` loop, the operand of `void`, or the left operand of a comma.
|
|
54
|
+
*/
|
|
55
|
+
function valueDiscarded(node) {
|
|
56
|
+
let child = node;
|
|
57
|
+
let parent = node.parent;
|
|
58
|
+
while (isParenthesizedExpression(parent)) {
|
|
59
|
+
child = parent;
|
|
60
|
+
parent = parent.parent;
|
|
61
|
+
}
|
|
62
|
+
if (isExpressionStatement(parent) || isVoidExpression(parent)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (isForStatement(parent)) {
|
|
66
|
+
return parent.initializer === child || parent.incrementor === child;
|
|
67
|
+
}
|
|
68
|
+
return (isBinaryExpression(parent) &&
|
|
69
|
+
parent.operatorToken.kind === SyntaxKind.CommaToken &&
|
|
70
|
+
parent.left === child);
|
|
71
|
+
}
|
|
72
|
+
/** Whether one node is an identifier or a private name, the two forms a name takes. */
|
|
73
|
+
function isName(node) {
|
|
74
|
+
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PrivateIdentifier;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Records the name one store writes into.
|
|
78
|
+
*
|
|
79
|
+
* A property access writes the member it names. An element access writes the collection
|
|
80
|
+
* it stores into, since a collection a module only stores into holds nothing anything
|
|
81
|
+
* reads, and joins `accesses` for the member a unique-symbol key selects. A destructuring
|
|
82
|
+
* target writes each name it binds, through its spreads and nested patterns.
|
|
83
|
+
*/
|
|
84
|
+
function markWrite(target, writes, accesses) {
|
|
85
|
+
const held = parenthesesRemoved(target);
|
|
86
|
+
if (isName(held)) {
|
|
87
|
+
writes.add(held.pos);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (isPropertyAccessExpression(held)) {
|
|
91
|
+
if (isName(held.name)) {
|
|
92
|
+
writes.add(held.name.pos);
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (isElementAccessExpression(held)) {
|
|
97
|
+
accesses.add(held);
|
|
98
|
+
// A store through a member's value lands in storage every holder of the value
|
|
99
|
+
// reads, so it reads the member; a variable only ever stored into stays written.
|
|
100
|
+
if (!isPropertyAccessExpression(parenthesesRemoved(held.expression))) {
|
|
101
|
+
markWrite(held.expression, writes, accesses);
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (isArrayLiteralExpression(held)) {
|
|
106
|
+
for (const element of held.elements) {
|
|
107
|
+
markWrite(element, writes, accesses);
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (isObjectLiteralExpression(held)) {
|
|
112
|
+
for (const property of held.properties) {
|
|
113
|
+
if (isPropertyAssignment(property)) {
|
|
114
|
+
markWrite(property.initializer, writes, accesses);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (isShorthandPropertyAssignment(property)) {
|
|
118
|
+
markWrite(property.name, writes, accesses);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (isSpreadAssignment(property)) {
|
|
122
|
+
markWrite(property.expression, writes, accesses);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (isSpreadElement(held)) {
|
|
128
|
+
markWrite(held.expression, writes, accesses);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Records every store one node performs: an assignment, a compound assignment, an
|
|
133
|
+
* increment or a decrement, a `delete`, and an iteration that assigns to a name declared
|
|
134
|
+
* elsewhere. An iteration that declares its own name stores into nothing the inventory
|
|
135
|
+
* holds. A store that reads its target as well records it in `reads`: a logical
|
|
136
|
+
* assignment, and a compound assignment, an increment or a decrement whose value is used.
|
|
137
|
+
*/
|
|
138
|
+
function markStores(node, writes, reads, accesses) {
|
|
139
|
+
if (isBinaryExpression(node)) {
|
|
140
|
+
const operator = node.operatorToken.kind;
|
|
141
|
+
if (ASSIGNMENTS.has(operator)) {
|
|
142
|
+
markWrite(node.left, writes, accesses.written);
|
|
143
|
+
if (LOGICAL_ASSIGNMENTS.has(operator) ||
|
|
144
|
+
(operator !== SyntaxKind.EqualsToken && !valueDiscarded(node))) {
|
|
145
|
+
markWrite(node.left, reads, accesses.read);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (isPrefixUnaryExpression(node) || isPostfixUnaryExpression(node)) {
|
|
151
|
+
if (node.operator === SyntaxKind.PlusPlusToken ||
|
|
152
|
+
node.operator === SyntaxKind.MinusMinusToken) {
|
|
153
|
+
markWrite(node.operand, writes, accesses.written);
|
|
154
|
+
if (!valueDiscarded(node)) {
|
|
155
|
+
markWrite(node.operand, reads, accesses.read);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (isDeleteExpression(node)) {
|
|
161
|
+
markWrite(node.expression, writes, accesses.written);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (isForInStatement(node) || isForOfStatement(node)) {
|
|
165
|
+
if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) {
|
|
166
|
+
markWrite(node.initializer, writes, accesses.written);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** Whether one node is `import.meta.url`. */
|
|
171
|
+
function isImportMetaURL(node) {
|
|
172
|
+
const at = parenthesesRemoved(node);
|
|
173
|
+
return (isPropertyAccessExpression(at) &&
|
|
174
|
+
isMetaProperty(at.expression) &&
|
|
175
|
+
at.expression.keywordToken === SyntaxKind.ImportKeyword &&
|
|
176
|
+
at.name.text === "url");
|
|
177
|
+
}
|
|
178
|
+
/** The module URL one node builds, where it builds one. */
|
|
179
|
+
function moduleURLOf(node) {
|
|
180
|
+
const literal = (argument) => {
|
|
181
|
+
const at = argument === undefined ? undefined : parenthesesRemoved(argument);
|
|
182
|
+
return isLiteralText(at) ? at.text : undefined;
|
|
183
|
+
};
|
|
184
|
+
const constructor = isNewExpression(node) ? writtenName(node.expression) : undefined;
|
|
185
|
+
if (isNewExpression(node) && constructor !== undefined) {
|
|
186
|
+
const [reference, base] = node.arguments ?? [];
|
|
187
|
+
const specifier = literal(reference);
|
|
188
|
+
return specifier !== undefined && base !== undefined && isImportMetaURL(base)
|
|
189
|
+
? { specifier, constructor, at: node }
|
|
190
|
+
: undefined;
|
|
191
|
+
}
|
|
192
|
+
if (isCallExpression(node)) {
|
|
193
|
+
const callee = parenthesesRemoved(node.expression);
|
|
194
|
+
const specifier = literal(node.arguments[0]);
|
|
195
|
+
if (specifier !== undefined &&
|
|
196
|
+
startsRelativePath(specifier) &&
|
|
197
|
+
isPropertyAccessExpression(callee) &&
|
|
198
|
+
isMetaProperty(callee.expression) &&
|
|
199
|
+
callee.expression.keywordToken === SyntaxKind.ImportKeyword &&
|
|
200
|
+
callee.name.text === "resolve") {
|
|
201
|
+
return { specifier, constructor: undefined, at: node };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
/** The constructors whose first argument addresses a worker. */
|
|
207
|
+
export const WORKER_CONSTRUCTORS = new Set(["Worker", "SharedWorker"]);
|
|
208
|
+
/** Whether an options argument is an object literal whose `eval` member is written as anything but `false`. */
|
|
209
|
+
function evaluatesCode(options) {
|
|
210
|
+
const at = options === undefined ? undefined : parenthesesRemoved(options);
|
|
211
|
+
return (at !== undefined &&
|
|
212
|
+
isObjectLiteralExpression(at) &&
|
|
213
|
+
at.properties.some((property) => (isShorthandPropertyAssignment(property) &&
|
|
214
|
+
isIdentifier(property.name) &&
|
|
215
|
+
property.name.text === "eval") ||
|
|
216
|
+
(isPropertyAssignment(property) &&
|
|
217
|
+
(isIdentifier(property.name) || isStringLiteral(property.name)) &&
|
|
218
|
+
property.name.text === "eval" &&
|
|
219
|
+
parenthesesRemoved(property.initializer).kind !== SyntaxKind.FalseKeyword)));
|
|
220
|
+
}
|
|
221
|
+
/** The worker one node starts by a literal address or a path of its own directory, where it starts one. */
|
|
222
|
+
function workerOf(node) {
|
|
223
|
+
if (isNewExpression(node)) {
|
|
224
|
+
const constructor = writtenName(node.expression);
|
|
225
|
+
const [address, options] = node.arguments ?? [];
|
|
226
|
+
const literal = address === undefined ? undefined : parenthesesRemoved(address);
|
|
227
|
+
const value = literal === undefined ? undefined : writtenValue(literal);
|
|
228
|
+
const ownDirectory = value?.kind === "directory";
|
|
229
|
+
const text = value?.kind === "directory"
|
|
230
|
+
? value.segments.join("/")
|
|
231
|
+
: isLiteralText(literal)
|
|
232
|
+
? literal.text
|
|
233
|
+
: undefined;
|
|
234
|
+
// A thread's constructor may be imported under another name, whose path is relative.
|
|
235
|
+
if (constructor === undefined ||
|
|
236
|
+
text === undefined ||
|
|
237
|
+
(!WORKER_CONSTRUCTORS.has(constructor.text) && !ownDirectory && !startsRelativePath(text))) {
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
240
|
+
const callee = parenthesesRemoved(node.expression);
|
|
241
|
+
const holder = isPropertyAccessExpression(callee)
|
|
242
|
+
? parenthesesRemoved(callee.expression)
|
|
243
|
+
: undefined;
|
|
244
|
+
return {
|
|
245
|
+
address: text,
|
|
246
|
+
ownDirectory,
|
|
247
|
+
constructor,
|
|
248
|
+
holder: holder !== undefined && isIdentifier(holder) ? holder : undefined,
|
|
249
|
+
evaluated: evaluatesCode(options),
|
|
250
|
+
at: node,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
if (!isCallExpression(node)) {
|
|
254
|
+
return undefined;
|
|
255
|
+
}
|
|
256
|
+
const callee = parenthesesRemoved(node.expression);
|
|
257
|
+
const registry = isPropertyAccessExpression(callee) && callee.name.text === "register"
|
|
258
|
+
? parenthesesRemoved(callee.expression)
|
|
259
|
+
: undefined;
|
|
260
|
+
const navigator = registry !== undefined &&
|
|
261
|
+
isPropertyAccessExpression(registry) &&
|
|
262
|
+
registry.name.text === "serviceWorker"
|
|
263
|
+
? writtenName(registry.expression)
|
|
264
|
+
: undefined;
|
|
265
|
+
const [address] = node.arguments;
|
|
266
|
+
const literal = address === undefined ? undefined : parenthesesRemoved(address);
|
|
267
|
+
return navigator?.text === "navigator" && isLiteralText(literal)
|
|
268
|
+
? {
|
|
269
|
+
address: literal.text,
|
|
270
|
+
ownDirectory: false,
|
|
271
|
+
constructor: navigator,
|
|
272
|
+
holder: undefined,
|
|
273
|
+
evaluated: false,
|
|
274
|
+
at: node,
|
|
275
|
+
}
|
|
276
|
+
: undefined;
|
|
277
|
+
}
|
|
278
|
+
/** Whether one node is a string literal or a template literal with no substitution. */
|
|
279
|
+
export function isLiteralText(node) {
|
|
280
|
+
return node !== undefined && (isStringLiteral(node) || isNoSubstitutionTemplateLiteral(node));
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* The module specifier of the module one node evaluates, if it evaluates one: an import
|
|
284
|
+
* declaration, an import-equals declaration of an external module, an export
|
|
285
|
+
* declaration that names a module, an `import()` call whose argument is literal text, and
|
|
286
|
+
* a call that may be a `require()` of literal text: one written as the name `require`, or
|
|
287
|
+
* one of a relative specifier through another name. A type-only form evaluates nothing.
|
|
288
|
+
* An `import()` of a computed argument names no module this pass can know.
|
|
289
|
+
*/
|
|
290
|
+
function evaluationOf(node) {
|
|
291
|
+
if (isCallExpression(node) && node.expression.kind !== SyntaxKind.ImportKeyword) {
|
|
292
|
+
const [argument] = node.arguments;
|
|
293
|
+
const require = writtenName(node.expression);
|
|
294
|
+
if (require === undefined ||
|
|
295
|
+
!isLiteralText(argument) ||
|
|
296
|
+
(require.text !== "require" && !startsRelativePath(argument.text))) {
|
|
297
|
+
return undefined;
|
|
298
|
+
}
|
|
299
|
+
return { node: argument, require, whole: !discarded(node) };
|
|
300
|
+
}
|
|
301
|
+
const specifier = evaluatedBy(node);
|
|
302
|
+
return specifier === undefined ? undefined : { node: specifier };
|
|
303
|
+
}
|
|
304
|
+
/** Whether an expression's value is thrown away: it is a statement of its own, or `void`'s operand. */
|
|
305
|
+
function discarded(expression) {
|
|
306
|
+
let at = expression.parent;
|
|
307
|
+
while (isParenthesizedExpression(at)) {
|
|
308
|
+
at = at.parent;
|
|
309
|
+
}
|
|
310
|
+
return isExpressionStatement(at) || isVoidExpression(at);
|
|
311
|
+
}
|
|
312
|
+
function evaluatedBy(node) {
|
|
313
|
+
if (isImportDeclaration(node)) {
|
|
314
|
+
return node.importClause?.phaseModifier === SyntaxKind.TypeKeyword
|
|
315
|
+
? undefined
|
|
316
|
+
: node.moduleSpecifier;
|
|
317
|
+
}
|
|
318
|
+
if (isExportDeclaration(node)) {
|
|
319
|
+
return node.isTypeOnly ? undefined : node.moduleSpecifier;
|
|
320
|
+
}
|
|
321
|
+
if (isImportEqualsDeclaration(node)) {
|
|
322
|
+
const reference = node.moduleReference;
|
|
323
|
+
return !node.isTypeOnly && isExternalModuleReference(reference)
|
|
324
|
+
? reference.expression
|
|
325
|
+
: undefined;
|
|
326
|
+
}
|
|
327
|
+
if (isCallExpression(node) && node.expression.kind === SyntaxKind.ImportKeyword) {
|
|
328
|
+
const [argument] = node.arguments;
|
|
329
|
+
return isLiteralText(argument) ? argument : undefined;
|
|
330
|
+
}
|
|
331
|
+
return undefined;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* The re-exports one node writes, if it is an export declaration. A specifier and a
|
|
335
|
+
* namespace export are declarations whose names are where they are written, so no use is
|
|
336
|
+
* read from them; each references what it carries forward instead. A bare star declares
|
|
337
|
+
* nothing, so the declaration enclosing it, at the top level the file, references the
|
|
338
|
+
* module it names.
|
|
339
|
+
*/
|
|
340
|
+
function linksOf(file, node, declarations, enclosing) {
|
|
341
|
+
if (!isExportDeclaration(node)) {
|
|
342
|
+
return [];
|
|
343
|
+
}
|
|
344
|
+
const clause = node.exportClause;
|
|
345
|
+
const specifier = node.moduleSpecifier;
|
|
346
|
+
if (clause === undefined) {
|
|
347
|
+
return specifier === undefined
|
|
348
|
+
? []
|
|
349
|
+
: [{ node: specifier, at: specifier, from: enclosing, alias: false }];
|
|
350
|
+
}
|
|
351
|
+
if (isNamespaceExport(clause)) {
|
|
352
|
+
const from = declarations.get(nodeKey(file, clause));
|
|
353
|
+
return from === undefined
|
|
354
|
+
? []
|
|
355
|
+
: [{ node: clause.name, at: specifier ?? clause.name, from, alias: true }];
|
|
356
|
+
}
|
|
357
|
+
const found = [];
|
|
358
|
+
for (const element of clause.elements) {
|
|
359
|
+
const from = declarations.get(nodeKey(file, element));
|
|
360
|
+
if (from !== undefined) {
|
|
361
|
+
found.push({
|
|
362
|
+
node: element.name,
|
|
363
|
+
at: element.propertyName ?? element.name,
|
|
364
|
+
from,
|
|
365
|
+
alias: true,
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return found;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Whether one object literal is a destructuring target, written on the left of an
|
|
373
|
+
* assignment or as a `for` loop's initializer, through the literals and spreads it nests in.
|
|
374
|
+
*/
|
|
375
|
+
function isAssignmentPattern(node) {
|
|
376
|
+
let child = node;
|
|
377
|
+
let parent = node.parent;
|
|
378
|
+
while (isParenthesizedExpression(parent) ||
|
|
379
|
+
isArrayLiteralExpression(parent) ||
|
|
380
|
+
isObjectLiteralExpression(parent) ||
|
|
381
|
+
isSpreadElement(parent) ||
|
|
382
|
+
isSpreadAssignment(parent) ||
|
|
383
|
+
(isPropertyAssignment(parent) && parent.initializer === child)) {
|
|
384
|
+
child = parent;
|
|
385
|
+
parent = parent.parent;
|
|
386
|
+
}
|
|
387
|
+
if (isBinaryExpression(parent)) {
|
|
388
|
+
return parent.operatorToken.kind === SyntaxKind.EqualsToken && parent.left === child;
|
|
389
|
+
}
|
|
390
|
+
return (isForInStatement(parent) || isForOfStatement(parent)) && parent.initializer === child;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Every name node one file holds that is a use rather than a declaration, in source
|
|
394
|
+
* order, each with its enclosing declaration and its use, and every re-export the file
|
|
395
|
+
* writes. One walk answers all of it, because a second would have to agree with this one
|
|
396
|
+
* about which nodes are names. A declaration's own declared name is left out, which is
|
|
397
|
+
* what makes a declaration referenced only from its own site an unreferenced one, and so
|
|
398
|
+
* is every node of `unread`, a subtree that is no use.
|
|
399
|
+
*/
|
|
400
|
+
export function sitesOf(file, declarations, fileId, unread, offer) {
|
|
401
|
+
const found = [];
|
|
402
|
+
const reads = [];
|
|
403
|
+
const links = [];
|
|
404
|
+
const evaluations = [];
|
|
405
|
+
const wholes = [];
|
|
406
|
+
const urls = [];
|
|
407
|
+
const workers = [];
|
|
408
|
+
const loadCalls = [];
|
|
409
|
+
const decorated = [];
|
|
410
|
+
const parameterWrites = [];
|
|
411
|
+
const namespaces = namespaceUses(file);
|
|
412
|
+
const literals = [];
|
|
413
|
+
const flows = [];
|
|
414
|
+
const writes = new Set();
|
|
415
|
+
const alsoRead = new Set();
|
|
416
|
+
const accesses = { written: new Set(), read: new Set() };
|
|
417
|
+
const keyed = [];
|
|
418
|
+
const declared = new Set();
|
|
419
|
+
const shorthands = new Map();
|
|
420
|
+
let enclosing = fileId;
|
|
421
|
+
const markNames = (node) => {
|
|
422
|
+
if (isShorthandPropertyAssignment(node)) {
|
|
423
|
+
shorthands.set(node.name.pos, node);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
// A property access carries the member it names where a declaration carries its
|
|
427
|
+
// declared name, and it is the one form of the grammar that does.
|
|
428
|
+
if (isPropertyAccessExpression(node)) {
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
const named = node;
|
|
432
|
+
for (const name of [named.name, named.propertyName]) {
|
|
433
|
+
if (name !== undefined && isName(name)) {
|
|
434
|
+
declared.add(name.pos);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
// A read rule sees every node, an unread subtree's too, each with its enclosing declaration.
|
|
439
|
+
const offerAll = (node) => {
|
|
440
|
+
offer(node, enclosing);
|
|
441
|
+
node.forEachChild(offerAll);
|
|
442
|
+
};
|
|
443
|
+
const visit = (node) => {
|
|
444
|
+
if (unread.has(node)) {
|
|
445
|
+
offerAll(node);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
offer(node, enclosing);
|
|
449
|
+
const namespace = namespaces.get(node);
|
|
450
|
+
if (namespace?.kind === "whole") {
|
|
451
|
+
wholes.push({ specifier: namespace.specifier, at: node, from: enclosing });
|
|
452
|
+
}
|
|
453
|
+
else if (namespace?.kind === "indexed") {
|
|
454
|
+
found.push({ node: namespace.literal, shorthand: undefined, from: enclosing, use: "read" });
|
|
455
|
+
}
|
|
456
|
+
if (isName(node)) {
|
|
457
|
+
if (!declared.has(node.pos)) {
|
|
458
|
+
const site = { node, shorthand: shorthands.get(node.pos), from: enclosing };
|
|
459
|
+
if (writes.has(node.pos)) {
|
|
460
|
+
found.push({ ...site, use: "write" });
|
|
461
|
+
}
|
|
462
|
+
if (!writes.has(node.pos) || alsoRead.has(node.pos)) {
|
|
463
|
+
found.push({ ...site, use: "read" });
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
markNames(node);
|
|
469
|
+
markStores(node, writes, alsoRead, accesses);
|
|
470
|
+
const key = isElementAccessExpression(node) ? keyNameOf(node.argumentExpression) : undefined;
|
|
471
|
+
if (key !== undefined && isElementAccessExpression(node)) {
|
|
472
|
+
const written = accesses.written.has(node);
|
|
473
|
+
keyed.push({
|
|
474
|
+
access: node,
|
|
475
|
+
key,
|
|
476
|
+
from: enclosing,
|
|
477
|
+
use: written ? (accesses.read.has(node) ? "both" : "write") : "read",
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
if (isObjectLiteralExpression(node) && !isAssignmentPattern(node)) {
|
|
481
|
+
literals.push({ literal: node, from: enclosing });
|
|
482
|
+
}
|
|
483
|
+
// An assertion needs only comparability, so no member of its operand is read by it.
|
|
484
|
+
for (const written of isAsExpression(node) ? [] : handedOn(node)) {
|
|
485
|
+
flows.push(...valuesOf(written).map((value) => ({ value, from: enclosing })));
|
|
486
|
+
}
|
|
487
|
+
for (const read of propertyReadsOf(node)) {
|
|
488
|
+
reads.push({ ...read, from: enclosing });
|
|
489
|
+
}
|
|
490
|
+
links.push(...linksOf(file, node, declarations, enclosing));
|
|
491
|
+
const evaluated = evaluationOf(node);
|
|
492
|
+
if (evaluated !== undefined) {
|
|
493
|
+
evaluations.push({ ...evaluated, from: enclosing });
|
|
494
|
+
}
|
|
495
|
+
const amd = amdLoadOf(node);
|
|
496
|
+
if (amd !== undefined) {
|
|
497
|
+
const { callee, ids } = amd;
|
|
498
|
+
for (const { id, received } of ids) {
|
|
499
|
+
evaluations.push({
|
|
500
|
+
node: id,
|
|
501
|
+
require: callee,
|
|
502
|
+
whole: received,
|
|
503
|
+
amd: true,
|
|
504
|
+
from: enclosing,
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
const url = moduleURLOf(node);
|
|
509
|
+
if (url !== undefined) {
|
|
510
|
+
urls.push({ ...url, from: enclosing });
|
|
511
|
+
}
|
|
512
|
+
const worker = workerOf(node);
|
|
513
|
+
if (worker !== undefined) {
|
|
514
|
+
workers.push({ ...worker, from: enclosing });
|
|
515
|
+
}
|
|
516
|
+
if (isLoadCall(node)) {
|
|
517
|
+
loadCalls.push({ call: node, from: enclosing });
|
|
518
|
+
}
|
|
519
|
+
const held = declarations.get(nodeKey(file, node));
|
|
520
|
+
const outer = enclosing;
|
|
521
|
+
// A parameter property's annotation, initializer and decorators stay with the
|
|
522
|
+
// parameter when the member goes, so they are written inside the constructor's class.
|
|
523
|
+
if (held !== undefined && isParameterProperty(node)) {
|
|
524
|
+
parameterWrites.push({
|
|
525
|
+
name: node.name,
|
|
526
|
+
from: outer,
|
|
527
|
+
member: held,
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
else if (held !== undefined) {
|
|
531
|
+
enclosing = held;
|
|
532
|
+
for (const modifier of node.modifiers ?? []) {
|
|
533
|
+
if (isDecorator(modifier)) {
|
|
534
|
+
decorated.push({ decorator: modifier, declaration: held });
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
node.forEachChild(visit);
|
|
539
|
+
enclosing = outer;
|
|
540
|
+
};
|
|
541
|
+
file.forEachChild(visit);
|
|
542
|
+
return {
|
|
543
|
+
uses: found,
|
|
544
|
+
literals,
|
|
545
|
+
flows,
|
|
546
|
+
reads,
|
|
547
|
+
links,
|
|
548
|
+
evaluations,
|
|
549
|
+
wholes,
|
|
550
|
+
urls,
|
|
551
|
+
workers,
|
|
552
|
+
loadCalls,
|
|
553
|
+
decorated,
|
|
554
|
+
parameterWrites,
|
|
555
|
+
keyed,
|
|
556
|
+
};
|
|
557
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a written expression evaluates to, the one definition every pass shares: the
|
|
3
|
+
* values it can be, the values a call's argument carries inside the literals it writes,
|
|
4
|
+
* and the positions a program hands a value to that the checker types from their context.
|
|
5
|
+
*/
|
|
6
|
+
import { isArrayLiteralExpression, isArrowFunction, isAsExpression, isBinaryExpression, isCallExpression, isConditionalExpression, isIdentifier, isNewExpression, isNonNullExpression, isObjectLiteralExpression, isOmittedExpression, isParameterDeclaration, isParenthesizedExpression, isPropertyAccessExpression, isPropertyAssignment, isPropertyDeclaration, isReturnStatement, isSatisfiesExpression, isShorthandPropertyAssignment, isSpreadAssignment, isSpreadElement, isVariableDeclaration, SyntaxKind, } from "@typescript/native/ast";
|
|
7
|
+
/** The operators of an assignment whose right side is stored into the left side's type. */
|
|
8
|
+
const STORES = new Set([
|
|
9
|
+
SyntaxKind.EqualsToken,
|
|
10
|
+
SyntaxKind.QuestionQuestionEqualsToken,
|
|
11
|
+
SyntaxKind.BarBarEqualsToken,
|
|
12
|
+
SyntaxKind.AmpersandAmpersandEqualsToken,
|
|
13
|
+
]);
|
|
14
|
+
/** Whether a declaration writes its type, so its initializer is read in that type's context. */
|
|
15
|
+
function writesType(node) {
|
|
16
|
+
return node.type !== undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The expressions one written value can evaluate to, each read alone because the checker
|
|
20
|
+
* reduces a union by subtype, so the type at the whole drops a class another branch's
|
|
21
|
+
* extends: the operand of a spread, of parentheses and of `!`, each branch of a
|
|
22
|
+
* conditional, each operand of `??` and `||`, and the right operand of `&&` and of a
|
|
23
|
+
* comma. The left operand of `&&` is its value only where it is falsy, which no object
|
|
24
|
+
* is. An assertion is a value of its own, whose type its reader decides.
|
|
25
|
+
*/
|
|
26
|
+
export function valuesOf(expression) {
|
|
27
|
+
if (isSpreadElement(expression) || isParenthesizedExpression(expression)) {
|
|
28
|
+
return valuesOf(expression.expression);
|
|
29
|
+
}
|
|
30
|
+
if (isNonNullExpression(expression)) {
|
|
31
|
+
return valuesOf(expression.expression);
|
|
32
|
+
}
|
|
33
|
+
if (isConditionalExpression(expression)) {
|
|
34
|
+
return [...valuesOf(expression.whenTrue), ...valuesOf(expression.whenFalse)];
|
|
35
|
+
}
|
|
36
|
+
if (isBinaryExpression(expression)) {
|
|
37
|
+
const operator = expression.operatorToken.kind;
|
|
38
|
+
if (operator === SyntaxKind.QuestionQuestionToken || operator === SyntaxKind.BarBarToken) {
|
|
39
|
+
return [...valuesOf(expression.left), ...valuesOf(expression.right)];
|
|
40
|
+
}
|
|
41
|
+
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.CommaToken) {
|
|
42
|
+
return valuesOf(expression.right);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return [expression];
|
|
46
|
+
}
|
|
47
|
+
/** The name node a callee, a decorator expression or a value resolves through, where it has one. */
|
|
48
|
+
export function nameOf(expression) {
|
|
49
|
+
if (isParenthesizedExpression(expression)) {
|
|
50
|
+
return nameOf(expression.expression);
|
|
51
|
+
}
|
|
52
|
+
if (isPropertyAccessExpression(expression)) {
|
|
53
|
+
return expression.name;
|
|
54
|
+
}
|
|
55
|
+
return isIdentifier(expression) ? expression : undefined;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The values one argument carries: each value it can be ({@link valuesOf}), or what an
|
|
59
|
+
* array or object literal it can be holds, at any depth, through spreads and shorthand
|
|
60
|
+
* properties. Each value is read inside every assertion around it.
|
|
61
|
+
*/
|
|
62
|
+
export function carriedValues(argument) {
|
|
63
|
+
return valuesOf(argument).flatMap((value) => {
|
|
64
|
+
let at = value;
|
|
65
|
+
while (isAsExpression(at) || isSatisfiesExpression(at)) {
|
|
66
|
+
at = at.expression;
|
|
67
|
+
}
|
|
68
|
+
if (at !== value) {
|
|
69
|
+
return carriedValues(at);
|
|
70
|
+
}
|
|
71
|
+
if (isArrayLiteralExpression(value)) {
|
|
72
|
+
return value.elements.flatMap(carriedValues);
|
|
73
|
+
}
|
|
74
|
+
if (isObjectLiteralExpression(value)) {
|
|
75
|
+
return value.properties.flatMap((property) => {
|
|
76
|
+
if (isPropertyAssignment(property)) {
|
|
77
|
+
return carriedValues(property.initializer);
|
|
78
|
+
}
|
|
79
|
+
if (isSpreadAssignment(property)) {
|
|
80
|
+
return carriedValues(property.expression);
|
|
81
|
+
}
|
|
82
|
+
return isShorthandPropertyAssignment(property)
|
|
83
|
+
? [{ site: property.name, name: property, shorthand: true }]
|
|
84
|
+
: [];
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return isOmittedExpression(value)
|
|
88
|
+
? []
|
|
89
|
+
: [{ site: value, name: nameOf(value), shorthand: false }];
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** The expressions one node hands to a position typed by its context. */
|
|
93
|
+
export function handedOn(node) {
|
|
94
|
+
if ((isVariableDeclaration(node) || isPropertyDeclaration(node) || isParameterDeclaration(node)) &&
|
|
95
|
+
node.initializer !== undefined &&
|
|
96
|
+
writesType(node)) {
|
|
97
|
+
return [node.initializer];
|
|
98
|
+
}
|
|
99
|
+
if (isBinaryExpression(node) && STORES.has(node.operatorToken.kind)) {
|
|
100
|
+
return [node.right];
|
|
101
|
+
}
|
|
102
|
+
if (isCallExpression(node) || isNewExpression(node)) {
|
|
103
|
+
return (node.arguments ?? []).filter((argument) => !isSpreadElement(argument));
|
|
104
|
+
}
|
|
105
|
+
if (isReturnStatement(node)) {
|
|
106
|
+
return node.expression === undefined ? [] : [node.expression];
|
|
107
|
+
}
|
|
108
|
+
if (isArrowFunction(node)) {
|
|
109
|
+
return node.body.kind === SyntaxKind.Block ? [] : [node.body];
|
|
110
|
+
}
|
|
111
|
+
if (isArrayLiteralExpression(node)) {
|
|
112
|
+
return node.elements.filter((element) => !isSpreadElement(element) && element.kind !== SyntaxKind.OmittedExpression);
|
|
113
|
+
}
|
|
114
|
+
if (isPropertyAssignment(node)) {
|
|
115
|
+
return [node.initializer];
|
|
116
|
+
}
|
|
117
|
+
if (isShorthandPropertyAssignment(node)) {
|
|
118
|
+
return isIdentifier(node.name) ? [node.name] : [];
|
|
119
|
+
}
|
|
120
|
+
if (isAsExpression(node) || isSatisfiesExpression(node)) {
|
|
121
|
+
return [node.expression];
|
|
122
|
+
}
|
|
123
|
+
return [];
|
|
124
|
+
}
|
package/dist/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { run, SETTING_OPTIONS } from "./run.js";
|
|
2
|
-
export { DECLINED_CONVENTIONS } from "./entry-point-gaps.js";
|
|
2
|
+
export { DECLINED_CONVENTIONS } from "./roots/entry-point-gaps.js";
|
|
3
3
|
export { byPosition, positionKey, PositionError, renderPosition, } from "./position.js";
|
|
4
4
|
export { computedComponent, isRef, nameComponent, REF_EXPRESSIONS, renderRef, } from "./ref.js";
|
|
5
|
-
export { CONTRACT_VERSION } from "./
|
|
5
|
+
export { CONTRACT_VERSION } from "./contract/contract.generated.js";
|