@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,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The files a bundler's JavaScript API builds from, read from the build scripts a
|
|
3
|
+
* manifest's scripts run: the strings an options object passes as the bundler's entries.
|
|
4
|
+
* A script is read without running it, so a value that is not written out, a computed
|
|
5
|
+
* path or an options object built at run time among them, names nothing.
|
|
6
|
+
*/
|
|
7
|
+
import { isArrowFunction, isCallExpression, isConstructorDeclaration, isFunctionDeclaration, isFunctionExpression, isGetAccessorDeclaration, isIdentifier, isMethodDeclaration, isNewExpression, isSetAccessorDeclaration, isVariableDeclaration, } from "@typescript/native/ast";
|
|
8
|
+
import { declarationOf, membersNamed, staticModule } from "./static-module.js";
|
|
9
|
+
import { filesNamedBy } from "./configuration-files.js";
|
|
10
|
+
import { ancestors, dirnamePath, isExplicitPath, relativePath, resolvePath } from "../paths.js";
|
|
11
|
+
import { bytewise } from "../text/compare.js";
|
|
12
|
+
import { unwrapped } from "../unwrap.js";
|
|
13
|
+
import { holdsManifest, inInstalledPackages, manifestAt } from "../fs/manifest.js";
|
|
14
|
+
import { globExpression } from "../text/glob.js";
|
|
15
|
+
import { pathsNamed, readCommands } from "../commands/read.js";
|
|
16
|
+
import { manifestCommands } from "../roots/manifest.js";
|
|
17
|
+
import { extensionOf, MODULE_EXTENSIONS } from "../extensions.js";
|
|
18
|
+
/**
|
|
19
|
+
* The bundlers whose build call names its entries: esbuild resolves `entryPoints` against
|
|
20
|
+
* `absWorkingDir` (https://esbuild.github.io/api/#working-directory), webpack `entry`
|
|
21
|
+
* against `context` (https://webpack.js.org/configuration/entry-context/), and Rollup
|
|
22
|
+
* `input` against the working directory, each the manifest's directory when its script runs.
|
|
23
|
+
*/
|
|
24
|
+
const BUNDLERS = [
|
|
25
|
+
{
|
|
26
|
+
module: "esbuild",
|
|
27
|
+
calls: ["build", "buildSync", "context"],
|
|
28
|
+
option: "entryPoints",
|
|
29
|
+
base: "absWorkingDir",
|
|
30
|
+
paths: true,
|
|
31
|
+
},
|
|
32
|
+
{ module: "webpack", calls: ["default"], option: "entry", base: "context", paths: false },
|
|
33
|
+
{ module: "rollup", calls: ["rollup", "watch"], option: "input", base: "", paths: true },
|
|
34
|
+
];
|
|
35
|
+
/** The one value an object writes last for a key, undefined where it writes none or may hide it. */
|
|
36
|
+
function lastMember(object, key) {
|
|
37
|
+
return membersNamed(object, key)?.at(-1);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The path one entry value writes, read against `dir`: a literal, or a join of the
|
|
41
|
+
* script's own directory and literals, read against that directory.
|
|
42
|
+
*/
|
|
43
|
+
function pathOf(value, dir, scriptDir) {
|
|
44
|
+
if (value.kind === "text") {
|
|
45
|
+
const { text } = value;
|
|
46
|
+
const request = !isExplicitPath(text);
|
|
47
|
+
return { path: resolvePath(dir, text), text, request };
|
|
48
|
+
}
|
|
49
|
+
if (value.kind === "directory") {
|
|
50
|
+
const joined = value.segments.join("/");
|
|
51
|
+
return { path: resolvePath(scriptDir, joined), text: joined, request: false };
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
/** The entry values one entries option writes: a value, an array of them, an object of them. */
|
|
56
|
+
function entryValues(value) {
|
|
57
|
+
if (value.kind === "array") {
|
|
58
|
+
return value.elements.flatMap(entryValues);
|
|
59
|
+
}
|
|
60
|
+
if (value.kind === "object") {
|
|
61
|
+
const imported = lastMember(value, "import") ?? lastMember(value, "in");
|
|
62
|
+
if (imported !== undefined) {
|
|
63
|
+
return entryValues(imported);
|
|
64
|
+
}
|
|
65
|
+
return value.members.flatMap((member) => entryValues(member.value));
|
|
66
|
+
}
|
|
67
|
+
return [value];
|
|
68
|
+
}
|
|
69
|
+
/** The own files one entry string names, read as `api` reads it. */
|
|
70
|
+
function entriesNamed(files, api, entry) {
|
|
71
|
+
if (!api.paths && entry.request) {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
if (api.paths && /[*?[{]/u.test(entry.text)) {
|
|
75
|
+
const expression = globExpression(entry.path);
|
|
76
|
+
return [...files.byName.values()].filter((file) => expression.test(file.fileName));
|
|
77
|
+
}
|
|
78
|
+
const dir = dirnamePath(entry.path);
|
|
79
|
+
return filesNamedBy(files, dir, entry.path.slice(dir.length + 1));
|
|
80
|
+
}
|
|
81
|
+
/** Whether one node is a function, whose body runs only where something calls it. */
|
|
82
|
+
function isFunction(node) {
|
|
83
|
+
return (isFunctionDeclaration(node) ||
|
|
84
|
+
isFunctionExpression(node) ||
|
|
85
|
+
isArrowFunction(node) ||
|
|
86
|
+
isMethodDeclaration(node) ||
|
|
87
|
+
isConstructorDeclaration(node) ||
|
|
88
|
+
isGetAccessorDeclaration(node) ||
|
|
89
|
+
isSetAccessorDeclaration(node));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The calls one build script runs: those of its top level, and those of each function a
|
|
93
|
+
* call it runs calls or passes on, as a callee, an argument or a function called where it
|
|
94
|
+
* is written, a name read through to the function it declares.
|
|
95
|
+
*/
|
|
96
|
+
function runCalls(file, each) {
|
|
97
|
+
const ran = new Set();
|
|
98
|
+
const run = (fn) => {
|
|
99
|
+
if (!ran.has(fn)) {
|
|
100
|
+
ran.add(fn);
|
|
101
|
+
fn.forEachChild(visit);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const runs = (node) => {
|
|
105
|
+
const at = unwrapped(node);
|
|
106
|
+
const declared = isIdentifier(at) ? declarationOf(at) : undefined;
|
|
107
|
+
const fn = declared !== undefined && isVariableDeclaration(declared) && declared.initializer
|
|
108
|
+
? unwrapped(declared.initializer)
|
|
109
|
+
: (declared ?? at);
|
|
110
|
+
if (isFunction(fn)) {
|
|
111
|
+
run(fn);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const visit = (node) => {
|
|
115
|
+
if (isFunction(node)) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (isCallExpression(node) || isNewExpression(node)) {
|
|
119
|
+
if (isCallExpression(node)) {
|
|
120
|
+
each(node);
|
|
121
|
+
}
|
|
122
|
+
runs(node.expression);
|
|
123
|
+
for (const argument of node.arguments ?? []) {
|
|
124
|
+
runs(argument);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
node.forEachChild(visit);
|
|
128
|
+
};
|
|
129
|
+
file.forEachChild(visit);
|
|
130
|
+
}
|
|
131
|
+
/** The entries every bundler call one build script runs names, read against `dir`. */
|
|
132
|
+
function scriptEntries(file, dir, files) {
|
|
133
|
+
const module = staticModule(file);
|
|
134
|
+
const building = new Map();
|
|
135
|
+
for (const api of BUNDLERS) {
|
|
136
|
+
for (const one of module.calls(api.module)) {
|
|
137
|
+
if (api.calls.includes(one.export)) {
|
|
138
|
+
building.set(one.call, api);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const scriptDir = dirnamePath(file.fileName);
|
|
143
|
+
const found = [];
|
|
144
|
+
runCalls(file, (call) => {
|
|
145
|
+
const api = building.get(call);
|
|
146
|
+
if (api === undefined) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
for (const options of module.argument(call)) {
|
|
150
|
+
const entries = lastMember(options, api.option);
|
|
151
|
+
const base = api.base === "" ? undefined : lastMember(options, api.base);
|
|
152
|
+
const against = base === undefined ? { path: dir } : pathOf(base, dir, scriptDir);
|
|
153
|
+
if (entries === undefined || against === undefined) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
for (const value of entryValues(entries)) {
|
|
157
|
+
const named = pathOf(value, against.path, scriptDir);
|
|
158
|
+
if (named === undefined) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
for (const entry of entriesNamed(files, api, named)) {
|
|
162
|
+
found.push({ file: entry, source: named.text });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
return found;
|
|
168
|
+
}
|
|
169
|
+
/** The modules one manifest's command strings run or name, by absolute path, each below the target root. */
|
|
170
|
+
function scriptModules(host, root, dir) {
|
|
171
|
+
const manifest = manifestAt(host, dir);
|
|
172
|
+
const found = new Set();
|
|
173
|
+
for (const { command } of manifest === undefined ? [] : manifestCommands(host, dir, manifest)) {
|
|
174
|
+
for (const { path } of pathsNamed(readCommands(command, dir))) {
|
|
175
|
+
if (extensionOf(path, MODULE_EXTENSIONS) !== undefined &&
|
|
176
|
+
relativePath(root, path) !== undefined &&
|
|
177
|
+
!inInstalledPackages(path) &&
|
|
178
|
+
host.kindOf(path) === "file") {
|
|
179
|
+
found.add(path);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return [...found].sort(bytewise);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Every own file of one project a build script names as a bundler's entry: a module a
|
|
187
|
+
* script of a manifest at or above an own file runs, below the target root, read from
|
|
188
|
+
* the program where it holds the module and parsed alone otherwise, where a parser is given.
|
|
189
|
+
*/
|
|
190
|
+
export function buildScriptEntries(host, targetRoot, files, parse) {
|
|
191
|
+
const root = resolvePath(host.workingDirectory(), targetRoot);
|
|
192
|
+
const dirs = new Set([root]);
|
|
193
|
+
for (const file of files.byName.values()) {
|
|
194
|
+
for (const dir of ancestors(dirnamePath(file.fileName), root)) {
|
|
195
|
+
if (dirs.has(dir)) {
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
dirs.add(dir);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const found = [];
|
|
202
|
+
for (const dir of [...dirs].sort(bytewise)) {
|
|
203
|
+
if (!holdsManifest(host, dir)) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
for (const path of scriptModules(host, root, dir)) {
|
|
207
|
+
let script = files.byName.get(path);
|
|
208
|
+
if (script === undefined && parse !== undefined) {
|
|
209
|
+
try {
|
|
210
|
+
script = parse(path, host.readFile(path));
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (script !== undefined) {
|
|
217
|
+
found.push(...scriptEntries(script, dir, files));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return found;
|
|
222
|
+
}
|
|
@@ -6,29 +6,32 @@
|
|
|
6
6
|
* every string either holds as it likes, so each one that spells a declared dependency
|
|
7
7
|
* uses it and each relative one that names a source file of the program roots the file.
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
9
|
+
import { isNoSubstitutionTemplateLiteral, isStringLiteral, } from "@typescript/native/ast";
|
|
10
|
+
import { relativeSpecifiers } from "./static-module.js";
|
|
11
|
+
import { ancestors, dirnamePath, isAbsolutePath, joinPath, relativePath, resolvePath, startsRelativePath, } from "../paths.js";
|
|
12
|
+
import { bytewise } from "../text/compare.js";
|
|
13
|
+
import { isRecord } from "../json-document.js";
|
|
14
|
+
import { filesIn } from "../fs/tree.js";
|
|
15
|
+
import { DEPENDENCY_SECTIONS, holdsManifest, inInstalledPackages, manifestAt, readJSON, } from "../fs/manifest.js";
|
|
16
|
+
import { readCommands } from "../commands/read.js";
|
|
17
|
+
import { manifestCommands } from "../roots/manifest.js";
|
|
18
|
+
import { APPENDED_EXTENSIONS, extensionOf, MODULE_EXTENSIONS } from "../extensions.js";
|
|
19
|
+
/** The extensions of a configuration module, as an expression's alternatives. */
|
|
20
|
+
const MODULE_NAME = MODULE_EXTENSIONS.map((one) => one.slice(1)).join("|");
|
|
12
21
|
/** A configuration module's name, each form with the spelling a root reports it by. */
|
|
13
22
|
const MODULE_FORMS = [
|
|
14
|
-
{ name: /^[\w-]+\.config\.(?:js|mjs|cjs|ts|mts|cts)$/u, form: "<stem>.config.<ext>" },
|
|
15
23
|
{
|
|
16
|
-
name:
|
|
24
|
+
name: new RegExp(String.raw `^[\w-]+\.config\.(?:${MODULE_NAME})$`, "u"),
|
|
25
|
+
form: "<stem>.config.<ext>",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: new RegExp(String.raw `^[\w-]+\.[\w-]+\.config\.(?:${MODULE_NAME})$`, "u"),
|
|
17
29
|
form: "<stem>.<qualifier>.config.<ext>",
|
|
18
30
|
},
|
|
19
31
|
{ name: /^\.[\w-]+rc\.(?:js|mjs|cjs)$/u, form: ".<stem>rc.<ext>" },
|
|
20
32
|
];
|
|
21
33
|
/** A JSON configuration file's name. */
|
|
22
34
|
const DOCUMENT_NAME = /^(?:[\w-]+(?:\.[\w-]+)?\.config\.json|\.[\w-]+rc(?:\.json)?)$/u;
|
|
23
|
-
/** The manifest members a dependency is declared in. */
|
|
24
|
-
const DEPENDENCY_MEMBERS = [
|
|
25
|
-
"dependencies",
|
|
26
|
-
"devDependencies",
|
|
27
|
-
"peerDependencies",
|
|
28
|
-
"optionalDependencies",
|
|
29
|
-
];
|
|
30
|
-
/** The prefixes a string names a file with, relative to the file that writes it. */
|
|
31
|
-
const RELATIVE_PREFIXES = ["./", "../"];
|
|
32
35
|
/** The JavaScript extensions a relative specifier from a configuration file stands for TypeScript under. */
|
|
33
36
|
const COUNTERPARTS = [
|
|
34
37
|
[".js", [".ts", ".tsx"]],
|
|
@@ -36,8 +39,6 @@ const COUNTERPARTS = [
|
|
|
36
39
|
[".mjs", [".mts"]],
|
|
37
40
|
[".cjs", [".cts"]],
|
|
38
41
|
];
|
|
39
|
-
/** The extensions appended to a relative specifier from a configuration file, in order. */
|
|
40
|
-
const APPENDED = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
|
|
41
42
|
/** The extensions the program's module resolution appends to a specifier written without one. */
|
|
42
43
|
export const RESOLVED_EXTENSIONS = [
|
|
43
44
|
".ts",
|
|
@@ -50,18 +51,14 @@ export const RESOLVED_EXTENSIONS = [
|
|
|
50
51
|
".mjs",
|
|
51
52
|
".cjs",
|
|
52
53
|
];
|
|
53
|
-
/** The directory a package manager installs packages into, whose files are no project's own. */
|
|
54
|
-
const MODULES_DIR = "node_modules";
|
|
55
54
|
/** The file's name, the last segment of its path. */
|
|
56
55
|
function basename(path) {
|
|
57
56
|
return path.slice(path.lastIndexOf("/") + 1);
|
|
58
57
|
}
|
|
59
58
|
/** Whether one path is the project's own: below the target root and in no `node_modules`. */
|
|
60
59
|
function isProjectPath(root, path) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
function isRecord(value) {
|
|
64
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
60
|
+
const below = relativePath(root, path);
|
|
61
|
+
return below !== undefined && !inInstalledPackages(below);
|
|
65
62
|
}
|
|
66
63
|
/** The form one file name is as a configuration module, or undefined where it is none. */
|
|
67
64
|
export function configurationModuleForm(name) {
|
|
@@ -71,161 +68,26 @@ export function configurationModuleForm(name) {
|
|
|
71
68
|
export function isConfigurationDocumentName(name) {
|
|
72
69
|
return DOCUMENT_NAME.test(name);
|
|
73
70
|
}
|
|
74
|
-
/** The flags a tool's command line names its configuration file with. */
|
|
75
|
-
const CONFIG_FLAGS = new Set(["--config", "-c"]);
|
|
76
|
-
/** The extensions of a module a configuration flag may name. */
|
|
77
|
-
const MODULE_EXTENSIONS = [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"];
|
|
78
|
-
/** The characters that end a word outside quotes and separate nothing: blanks. */
|
|
79
|
-
// Stryker disable next-line Regex: its \v to \V mutant is no valid escape under the u flag, so the whole module fails to parse
|
|
80
|
-
const BLANK = /[ \t\r\f\v]/u;
|
|
81
|
-
/** The characters that end a word outside quotes and begin an operator: newline included. */
|
|
82
|
-
const OPERATOR = /[\n;&|()<>]/u;
|
|
83
|
-
/** The characters a backslash escapes inside double quotes; before any other it stands for itself. */
|
|
84
|
-
const DOUBLE_QUOTE_ESCAPES = new Set(["$", "`", '"', "\\"]);
|
|
85
|
-
/**
|
|
86
|
-
* The words of one command line, as POSIX token recognition reads quotes, backslashes,
|
|
87
|
-
* line continuations, comments and operators. A word an expansion may change (an unquoted
|
|
88
|
-
* `$`, backquote, glob character or leading `~`, or a `$` or backquote in double quotes)
|
|
89
|
-
* is computed, and so is the rest of a line whose quote is never closed. A computed word
|
|
90
|
-
* and each operator are undefined, so a flag's file is never read across them.
|
|
91
|
-
*/
|
|
92
|
-
function shellWords(command) {
|
|
93
|
-
const words = [];
|
|
94
|
-
let word;
|
|
95
|
-
let computed = false;
|
|
96
|
-
const end = () => {
|
|
97
|
-
if (word !== undefined) {
|
|
98
|
-
words.push(computed ? undefined : word);
|
|
99
|
-
}
|
|
100
|
-
word = undefined;
|
|
101
|
-
computed = false;
|
|
102
|
-
};
|
|
103
|
-
for (let at = 0; at < command.length; at += 1) {
|
|
104
|
-
const char = command.charAt(at);
|
|
105
|
-
if (char === "\\" && command.charAt(at + 1) === "\n") {
|
|
106
|
-
at += 1;
|
|
107
|
-
}
|
|
108
|
-
else if (BLANK.test(char)) {
|
|
109
|
-
end();
|
|
110
|
-
}
|
|
111
|
-
else if (OPERATOR.test(char)) {
|
|
112
|
-
end();
|
|
113
|
-
words.push(undefined);
|
|
114
|
-
}
|
|
115
|
-
else if (char === "#" && word === undefined) {
|
|
116
|
-
const newline = command.indexOf("\n", at);
|
|
117
|
-
at = newline < 0 ? command.length : newline - 1;
|
|
118
|
-
}
|
|
119
|
-
else if (char === "\\") {
|
|
120
|
-
at += 1;
|
|
121
|
-
word = (word ?? "") + command.charAt(at);
|
|
122
|
-
}
|
|
123
|
-
else if (char === "'" || char === '"') {
|
|
124
|
-
const close = closingQuote(command, at);
|
|
125
|
-
if (close < 0) {
|
|
126
|
-
word ??= "";
|
|
127
|
-
computed = true;
|
|
128
|
-
break;
|
|
129
|
-
}
|
|
130
|
-
const quoted = char === "'"
|
|
131
|
-
? { text: command.slice(at + 1, close), computed: false }
|
|
132
|
-
: doubleQuoted(command.slice(at + 1, close));
|
|
133
|
-
word = (word ?? "") + quoted.text;
|
|
134
|
-
computed ||= quoted.computed;
|
|
135
|
-
at = close;
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
computed ||= /[$`*?[]/u.test(char) || (char === "~" && word === undefined);
|
|
139
|
-
word = (word ?? "") + char;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
end();
|
|
143
|
-
return words;
|
|
144
|
-
}
|
|
145
|
-
/** The text between one pair of double quotes, unescaped, and whether an expansion may change it. */
|
|
146
|
-
function doubleQuoted(inner) {
|
|
147
|
-
let text = "";
|
|
148
|
-
let computed = false;
|
|
149
|
-
for (let at = 0; at < inner.length; at += 1) {
|
|
150
|
-
const char = inner.charAt(at);
|
|
151
|
-
const next = inner.charAt(at + 1);
|
|
152
|
-
if (char === "\\" && next === "\n") {
|
|
153
|
-
at += 1;
|
|
154
|
-
}
|
|
155
|
-
else if (char === "\\" && DOUBLE_QUOTE_ESCAPES.has(next)) {
|
|
156
|
-
text += next;
|
|
157
|
-
at += 1;
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
computed ||= char === "$" || char === "`";
|
|
161
|
-
text += char;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return { text, computed };
|
|
165
|
-
}
|
|
166
|
-
/** The index of the quote that closes the one at `open`, or -1 where none does. */
|
|
167
|
-
function closingQuote(command, open) {
|
|
168
|
-
const quote = command.charAt(open);
|
|
169
|
-
for (let at = open + 1; at < command.length; at += 1) {
|
|
170
|
-
const char = command.charAt(at);
|
|
171
|
-
if (char === quote) {
|
|
172
|
-
return at;
|
|
173
|
-
}
|
|
174
|
-
if (quote === '"' && char === "\\") {
|
|
175
|
-
at += 1;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return -1;
|
|
179
|
-
}
|
|
180
71
|
/**
|
|
181
|
-
* The files the
|
|
182
|
-
*
|
|
183
|
-
* the target root and in no `node_modules`.
|
|
72
|
+
* The files the command strings of the manifest in one directory name after a configuration
|
|
73
|
+
* flag, as `commands/read.ts` reads them against the directory each command runs in, each a
|
|
74
|
+
* JSON file or a module below the target root and in no `node_modules`.
|
|
184
75
|
*/
|
|
185
76
|
function scriptConfigurations(host, root, dir) {
|
|
186
|
-
|
|
187
|
-
try {
|
|
188
|
-
const manifest = JSON.parse(host.readFile(joinPath(dir, MANIFEST)));
|
|
189
|
-
scripts = isRecord(manifest) ? manifest["scripts"] : undefined;
|
|
190
|
-
}
|
|
191
|
-
catch {
|
|
192
|
-
return [];
|
|
193
|
-
}
|
|
194
|
-
if (!isRecord(scripts)) {
|
|
195
|
-
return [];
|
|
196
|
-
}
|
|
77
|
+
const manifest = manifestAt(host, dir);
|
|
197
78
|
const found = [];
|
|
198
|
-
for (const command of
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const words = shellWords(command);
|
|
203
|
-
words.forEach((word, at) => {
|
|
204
|
-
const named = word !== undefined && CONFIG_FLAGS.has(word)
|
|
205
|
-
? words[at + 1]
|
|
206
|
-
: word === undefined
|
|
207
|
-
? undefined
|
|
208
|
-
: /^--config=(.+)$/su.exec(word)?.[1];
|
|
209
|
-
const path = named === undefined ? undefined : resolvePath(dir, named);
|
|
210
|
-
if (path !== undefined &&
|
|
211
|
-
[".json", ...MODULE_EXTENSIONS].some((extension) => path.endsWith(extension)) &&
|
|
79
|
+
for (const { command } of manifest === undefined ? [] : manifestCommands(host, dir, manifest)) {
|
|
80
|
+
for (const { dir: runs, written } of readCommands(command, dir).configurations) {
|
|
81
|
+
const path = resolvePath(runs, written);
|
|
82
|
+
if ([".json", ...MODULE_EXTENSIONS].some((extension) => path.endsWith(extension)) &&
|
|
212
83
|
isProjectPath(root, path) &&
|
|
213
84
|
host.kindOf(path) === "file") {
|
|
214
85
|
found.push(path);
|
|
215
86
|
}
|
|
216
|
-
}
|
|
87
|
+
}
|
|
217
88
|
}
|
|
218
89
|
return found;
|
|
219
90
|
}
|
|
220
|
-
/** The decoded value of one JSON file, or undefined where it cannot be read or parsed. */
|
|
221
|
-
function readDocument(host, path) {
|
|
222
|
-
try {
|
|
223
|
-
return JSON.parse(host.readFile(path));
|
|
224
|
-
}
|
|
225
|
-
catch {
|
|
226
|
-
return undefined;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
91
|
/** Every string value one decoded JSON value holds at any depth. */
|
|
230
92
|
export function documentStrings(value) {
|
|
231
93
|
if (typeof value === "string") {
|
|
@@ -258,10 +120,10 @@ export function moduleStrings(file) {
|
|
|
258
120
|
export function configurationFiles(host, targetRoot, files, parse) {
|
|
259
121
|
const root = resolvePath(host.workingDirectory(), targetRoot);
|
|
260
122
|
const manifests = new Map();
|
|
261
|
-
const
|
|
123
|
+
const manifestHeld = (dir) => {
|
|
262
124
|
let held = manifests.get(dir);
|
|
263
125
|
if (held === undefined) {
|
|
264
|
-
held = host
|
|
126
|
+
held = holdsManifest(host, dir);
|
|
265
127
|
manifests.set(dir, held);
|
|
266
128
|
}
|
|
267
129
|
return held;
|
|
@@ -271,30 +133,23 @@ export function configurationFiles(host, targetRoot, files, parse) {
|
|
|
271
133
|
for (const file of files.byPath.values()) {
|
|
272
134
|
const form = configurationModuleForm(basename(file.fileName));
|
|
273
135
|
const fileDir = dirnamePath(file.fileName);
|
|
274
|
-
if (form !== undefined &&
|
|
136
|
+
if (form !== undefined && manifestHeld(fileDir)) {
|
|
275
137
|
modules.push({ file, form, manifestDir: fileDir });
|
|
276
138
|
}
|
|
277
|
-
for (
|
|
139
|
+
for (const dir of ancestors(dirnamePath(file.fileName), root)) {
|
|
140
|
+
if (dirs.has(dir)) {
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
278
143
|
dirs.add(dir);
|
|
279
144
|
}
|
|
280
145
|
}
|
|
281
146
|
const pending = [];
|
|
282
147
|
const named = [];
|
|
283
|
-
for (const dir of [...dirs].sort()) {
|
|
284
|
-
if (!
|
|
148
|
+
for (const dir of [...dirs].sort(bytewise)) {
|
|
149
|
+
if (!manifestHeld(dir)) {
|
|
285
150
|
continue;
|
|
286
151
|
}
|
|
287
|
-
|
|
288
|
-
try {
|
|
289
|
-
names = host
|
|
290
|
-
.readDirectory(dir)
|
|
291
|
-
.filter((entry) => !entry.directory && isConfigurationDocumentName(entry.name))
|
|
292
|
-
.map((entry) => entry.name)
|
|
293
|
-
.sort();
|
|
294
|
-
}
|
|
295
|
-
catch {
|
|
296
|
-
names = [];
|
|
297
|
-
}
|
|
152
|
+
const names = filesIn(host, dir, isConfigurationDocumentName);
|
|
298
153
|
pending.push(...names.map((name) => ({ path: joinPath(dir, name), manifestDir: dir })));
|
|
299
154
|
for (const path of scriptConfigurations(host, root, dir)) {
|
|
300
155
|
const held = files.byName.get(path);
|
|
@@ -318,7 +173,7 @@ export function configurationFiles(host, targetRoot, files, parse) {
|
|
|
318
173
|
continue;
|
|
319
174
|
}
|
|
320
175
|
if (document === undefined) {
|
|
321
|
-
const value =
|
|
176
|
+
const value = readJSON(host, next.path);
|
|
322
177
|
if (value === undefined) {
|
|
323
178
|
unreadable.add(next.path);
|
|
324
179
|
continue;
|
|
@@ -328,9 +183,7 @@ export function configurationFiles(host, targetRoot, files, parse) {
|
|
|
328
183
|
}
|
|
329
184
|
document.manifestDirs.push(next.manifestDir);
|
|
330
185
|
for (const text of document.strings) {
|
|
331
|
-
const path =
|
|
332
|
-
? resolvePath(dirnamePath(next.path), text)
|
|
333
|
-
: undefined;
|
|
186
|
+
const path = startsRelativePath(text) ? resolvePath(dirnamePath(next.path), text) : undefined;
|
|
334
187
|
if (path?.endsWith(".json") === true &&
|
|
335
188
|
isProjectPath(root, path) &&
|
|
336
189
|
host.kindOf(path) === "file") {
|
|
@@ -343,50 +196,9 @@ export function configurationFiles(host, targetRoot, files, parse) {
|
|
|
343
196
|
documents: [...documents.values()],
|
|
344
197
|
outside: parse === undefined
|
|
345
198
|
? []
|
|
346
|
-
: outsideModules(host, root, [...dirs], files,
|
|
199
|
+
: outsideModules(host, root, [...dirs], files, manifestHeld, parse, named),
|
|
347
200
|
};
|
|
348
201
|
}
|
|
349
|
-
/** The literal module specifier one `require(...)` or `import(...)` call names, if any. */
|
|
350
|
-
function calledSpecifier(node) {
|
|
351
|
-
if (!isCallExpression(node) || node.arguments.length !== 1) {
|
|
352
|
-
return undefined;
|
|
353
|
-
}
|
|
354
|
-
const callee = node.expression;
|
|
355
|
-
const loads = callee.kind === SyntaxKind.ImportKeyword || (isIdentifier(callee) && callee.text === "require");
|
|
356
|
-
return loads ? node.arguments[0] : undefined;
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* The relative specifiers one file's imports and re-exports name, and those its
|
|
360
|
-
* `require(...)` and `import(...)` calls name by a literal.
|
|
361
|
-
*/
|
|
362
|
-
export function relativeSpecifiers(file) {
|
|
363
|
-
const known = specifiersOf.get(file);
|
|
364
|
-
if (known !== undefined) {
|
|
365
|
-
return known;
|
|
366
|
-
}
|
|
367
|
-
const found = [];
|
|
368
|
-
const named = (specifier) => {
|
|
369
|
-
if (specifier !== undefined &&
|
|
370
|
-
(isStringLiteral(specifier) || isNoSubstitutionTemplateLiteral(specifier)) &&
|
|
371
|
-
RELATIVE_PREFIXES.some((prefix) => specifier.text.startsWith(prefix))) {
|
|
372
|
-
found.push(specifier.text);
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
const visit = (node) => {
|
|
376
|
-
named(calledSpecifier(node));
|
|
377
|
-
node.forEachChild(visit);
|
|
378
|
-
};
|
|
379
|
-
for (const statement of file.statements) {
|
|
380
|
-
named(isImportDeclaration(statement) || isExportDeclaration(statement)
|
|
381
|
-
? statement.moduleSpecifier
|
|
382
|
-
: undefined);
|
|
383
|
-
visit(statement);
|
|
384
|
-
}
|
|
385
|
-
specifiersOf.set(file, found);
|
|
386
|
-
return found;
|
|
387
|
-
}
|
|
388
|
-
/** What {@link relativeSpecifiers} found in each file, which every project of a run reads alike. */
|
|
389
|
-
const specifiersOf = new WeakMap();
|
|
390
202
|
/**
|
|
391
203
|
* The files no program holds that a chain from `seeds` reads: each seed, and each file
|
|
392
204
|
* below the target root one imports, re-exports or loads by a relative specifier that no
|
|
@@ -407,7 +219,7 @@ export function outsideChain(host, targetRoot, files, parse, seeds) {
|
|
|
407
219
|
export function specifierCandidates(dir, specifier) {
|
|
408
220
|
const path = resolvePath(dir, specifier);
|
|
409
221
|
const candidates = [];
|
|
410
|
-
if (
|
|
222
|
+
if (extensionOf(path, APPENDED_EXTENSIONS) !== undefined) {
|
|
411
223
|
candidates.push(path);
|
|
412
224
|
}
|
|
413
225
|
for (const [extension, counterparts] of COUNTERPARTS) {
|
|
@@ -416,8 +228,8 @@ export function specifierCandidates(dir, specifier) {
|
|
|
416
228
|
candidates.push(...counterparts.map((one) => stem + one));
|
|
417
229
|
}
|
|
418
230
|
}
|
|
419
|
-
candidates.push(...
|
|
420
|
-
candidates.push(...
|
|
231
|
+
candidates.push(...APPENDED_EXTENSIONS.map((extension) => path + extension));
|
|
232
|
+
candidates.push(...APPENDED_EXTENSIONS.map((extension) => joinPath(path, `index${extension}`)));
|
|
421
233
|
return candidates;
|
|
422
234
|
}
|
|
423
235
|
/** The file on disk one relative specifier from a configuration file reaches, or undefined. */
|
|
@@ -429,23 +241,13 @@ export function resolveRelativeSpecifier(host, dir, specifier) {
|
|
|
429
241
|
* does not hold, and the project files below `root` they import by a relative specifier,
|
|
430
242
|
* until no further file joins. A file that cannot be read is skipped.
|
|
431
243
|
*/
|
|
432
|
-
function outsideModules(host, root, dirs, files,
|
|
244
|
+
function outsideModules(host, root, dirs, files, manifestHeld, parse, named) {
|
|
433
245
|
const pending = [...named];
|
|
434
|
-
for (const dir of [...dirs].sort()) {
|
|
435
|
-
if (!
|
|
436
|
-
continue;
|
|
437
|
-
}
|
|
438
|
-
let names;
|
|
439
|
-
try {
|
|
440
|
-
names = host
|
|
441
|
-
.readDirectory(dir)
|
|
442
|
-
.filter((entry) => !entry.directory && configurationModuleForm(entry.name) !== undefined)
|
|
443
|
-
.map((entry) => entry.name)
|
|
444
|
-
.sort();
|
|
445
|
-
}
|
|
446
|
-
catch {
|
|
246
|
+
for (const dir of [...dirs].sort(bytewise)) {
|
|
247
|
+
if (!manifestHeld(dir)) {
|
|
447
248
|
continue;
|
|
448
249
|
}
|
|
250
|
+
const names = filesIn(host, dir, (name) => configurationModuleForm(name) !== undefined);
|
|
449
251
|
pending.push(...names.map((name) => ({ path: joinPath(dir, name), manifestDir: dir })));
|
|
450
252
|
}
|
|
451
253
|
const found = new Map();
|
|
@@ -481,18 +283,12 @@ function outsideModules(host, root, dirs, files, holdsManifest, parse, named) {
|
|
|
481
283
|
}
|
|
482
284
|
/** Every dependency the manifest in one directory declares, or none where it holds none to read. */
|
|
483
285
|
export function declaredIn(host, dir) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
value = JSON.parse(host.readFile(joinPath(dir, MANIFEST)));
|
|
487
|
-
}
|
|
488
|
-
catch {
|
|
489
|
-
return [];
|
|
490
|
-
}
|
|
491
|
-
if (!isRecord(value)) {
|
|
286
|
+
const value = manifestAt(host, dir);
|
|
287
|
+
if (value === undefined) {
|
|
492
288
|
return [];
|
|
493
289
|
}
|
|
494
290
|
const names = new Set();
|
|
495
|
-
for (const member of
|
|
291
|
+
for (const member of DEPENDENCY_SECTIONS) {
|
|
496
292
|
const section = value[member];
|
|
497
293
|
if (isRecord(section)) {
|
|
498
294
|
Object.keys(section).forEach((name) => names.add(name));
|
|
@@ -511,7 +307,7 @@ export function dependenciesNamed(text, declared) {
|
|
|
511
307
|
* none.
|
|
512
308
|
*/
|
|
513
309
|
export function filesNamedBy(files, dir, text) {
|
|
514
|
-
if (text === "" || text
|
|
310
|
+
if (text === "" || isAbsolutePath(text) || /[*?[{]/u.test(text)) {
|
|
515
311
|
return [];
|
|
516
312
|
}
|
|
517
313
|
const path = resolvePath(dir, text);
|