@cplieger/deadset-ts 8.0.0-dev.2 → 8.0.0-dev.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/THIRD_PARTY_NOTICES.md +27 -0
- package/dist/bin/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/alias-chain.js +2 -7
- package/dist/src/amd.js +81 -0
- package/dist/src/analysis.js +269 -432
- package/dist/src/augmentations.js +64 -3
- package/dist/src/automatic-types.js +10 -29
- package/dist/src/bindings.js +382 -0
- package/dist/src/calls.js +279 -43
- package/dist/src/commands/held.js +499 -0
- package/dist/src/commands/read.js +161 -0
- package/dist/src/commands/shell.js +169 -0
- package/dist/src/commands/tools.js +1847 -0
- package/dist/src/component-files.js +3 -2
- package/dist/src/component-layer.js +4 -2
- package/dist/src/config.js +6 -82
- package/dist/src/conformance-record.js +1 -1
- package/dist/src/consumers.js +10 -38
- package/dist/src/contextual-uses.js +57 -26
- package/dist/src/contract/config.generated.js +561 -0
- package/dist/src/contract/contract.generated.js +1369 -0
- package/dist/src/contract/report.generated.js +866 -0
- package/dist/src/dependencies.js +164 -121
- package/dist/src/destructuring.js +1 -19
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +181 -168
- package/dist/src/entries/build-scripts.js +222 -0
- package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
- package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
- package/dist/src/entries/conventions.js +740 -0
- package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
- package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
- package/dist/src/entries/run-directories.js +77 -0
- package/dist/src/entries/sources.js +144 -0
- package/dist/src/entries/static-module.js +670 -0
- package/dist/src/entries/test-runners.js +650 -0
- package/dist/src/entries/workflow-steps.js +345 -0
- package/dist/src/enum-group.js +3 -10
- package/dist/src/erased-stores.js +4 -6
- package/dist/src/exempt-classes.js +1 -63
- package/dist/src/exempt.js +21 -66
- package/dist/src/exposure.js +400 -0
- package/dist/src/extensions.js +37 -0
- package/dist/src/facts.js +38 -0
- package/dist/src/failure.js +36 -0
- package/dist/src/file-facts.js +3 -26
- package/dist/src/findings/completion.js +109 -56
- package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
- package/dist/src/findings/emitters.js +27 -41
- package/dist/src/{implementations.js → findings/implementations.js} +3 -3
- package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +16 -13
- package/dist/src/findings/non-code-artifacts.js +17 -12
- package/dist/src/findings/reads-and-writes.js +86 -27
- package/dist/src/findings/self-check.js +44 -30
- package/dist/src/findings/unused-declarations.js +29 -45
- package/dist/src/findings/visibility-narrowing.js +23 -31
- package/dist/src/findings-pass.js +13 -21
- package/dist/src/framework-lifecycle.js +46 -19
- package/dist/src/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +67 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/generated-file.js +174 -28
- package/dist/src/git-ignore.js +39 -26
- package/dist/src/import-bindings.js +73 -28
- package/dist/src/index/sites.js +557 -0
- package/dist/src/index.js +2 -2
- package/dist/src/indexed-access.js +523 -478
- package/dist/src/injection-container.js +2 -2
- package/dist/src/interface-satisfaction.js +1 -1
- package/dist/src/intra-function-parts.js +63 -43
- package/dist/src/inventory/commonjs.js +507 -0
- package/dist/src/inventory/enumerate.js +167 -0
- package/dist/src/inventory/syntax.js +236 -0
- package/dist/src/inventory.js +323 -724
- package/dist/src/javascript-file.js +48 -0
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +126 -107
- package/dist/src/kinds.js +3 -366
- package/dist/src/{components.js → liveness/components.js} +2 -3
- package/dist/src/{graph.js → liveness/graph.js} +52 -28
- package/dist/src/liveness/matrix.js +99 -0
- package/dist/src/liveness/sweep.js +558 -0
- package/dist/src/load/classify.js +289 -0
- package/dist/src/load/diagnostics.js +87 -0
- package/dist/src/load/discover.js +285 -0
- package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
- package/dist/src/load/expected-module.js +136 -0
- package/dist/src/load/load.js +27 -0
- package/dist/src/load/module-lookup.js +37 -0
- package/dist/src/load/package-scope.js +56 -0
- package/dist/src/load/plan.js +313 -0
- package/dist/src/load/specifiers.js +113 -0
- package/dist/src/load/synthesize.js +152 -0
- package/dist/src/load/test-globals.js +207 -0
- package/dist/src/load/test-joins.js +82 -0
- package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
- package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
- package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
- package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
- package/dist/src/{workspace.js → load/workspace.js} +62 -124
- package/dist/src/module-declarations.js +70 -85
- package/dist/src/overrides.js +134 -112
- package/dist/src/partial.js +2 -1
- package/dist/src/paths.js +82 -16
- package/dist/src/platform-calls.js +78 -0
- package/dist/src/platform-symbols.js +134 -0
- package/dist/src/position.js +43 -1
- package/dist/src/print.js +11 -79
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +47 -0
- package/dist/src/ref.js +12 -20
- package/dist/src/references/read-rule.js +1 -0
- package/dist/src/references/read-rules.js +48 -0
- package/dist/src/references/sink.js +237 -0
- package/dist/src/references/sources.js +450 -0
- package/dist/src/references.js +117 -1074
- package/dist/src/report-schema.js +51 -0
- package/dist/src/report.js +57 -41
- package/dist/src/reporters/annotations.js +15 -8
- package/dist/src/reporters/sarif.js +16 -10
- package/dist/src/reporters/template.js +4 -19
- package/dist/src/resolve.js +246 -730
- package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
- package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
- package/dist/src/roots/manifest.js +216 -0
- package/dist/src/roots/published-reach.js +412 -0
- package/dist/src/roots/root-set.js +487 -0
- package/dist/src/roots/unseen-loads.js +236 -0
- package/dist/src/run.js +66 -77
- package/dist/src/schema.js +320 -343
- package/dist/src/scope.js +38 -115
- package/dist/src/serialization-contract.js +601 -22
- package/dist/src/session.js +37 -29
- package/dist/src/source-files.js +6 -10
- package/dist/src/stores.js +4 -2
- package/dist/src/suppress-file.js +25 -28
- package/dist/src/suppress-inline.js +36 -83
- package/dist/src/suppress.js +50 -71
- package/dist/src/symbol-keys.js +92 -88
- package/dist/src/template-field.js +9 -19
- package/dist/src/tests/file-class.js +76 -0
- package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
- package/dist/src/{test-support.js → tests/support.js} +5 -12
- package/dist/src/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/named-files.js +298 -0
- package/dist/src/text/yaml.js +684 -0
- package/dist/src/type-errors.js +11 -232
- package/dist/src/type-parameter-reads.js +178 -139
- package/dist/src/unimplemented-callees.js +262 -242
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/vendor/unbash/ansi-c.js +132 -0
- package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
- package/dist/src/vendor/unbash/arithmetic.js +591 -0
- package/dist/src/vendor/unbash/assignment.js +131 -0
- package/dist/src/vendor/unbash/chars.js +48 -0
- package/dist/src/vendor/unbash/command.js +41 -0
- package/dist/src/vendor/unbash/expansion.js +80 -0
- package/dist/src/vendor/unbash/glob.js +268 -0
- package/dist/src/vendor/unbash/heredoc.js +27 -0
- package/dist/src/vendor/unbash/internal-types.js +1 -0
- package/dist/src/vendor/unbash/lexer.js +4274 -0
- package/dist/src/vendor/unbash/limits.js +3 -0
- package/dist/src/vendor/unbash/parser.js +1366 -0
- package/dist/src/vendor/unbash/parts.js +57 -0
- package/dist/src/vendor/unbash/substitution-context.js +8 -0
- package/dist/src/vendor/unbash/traversal.js +212 -0
- package/dist/src/vendor/unbash/types.js +1 -0
- package/dist/src/vendor/unbash/word-value.js +61 -0
- package/dist/src/vendor/unbash/word.js +40 -0
- package/dist/src/verbs/analyze.js +194 -127
- package/dist/src/verbs/describe.js +13 -18
- package/dist/src/verbs/explain.js +85 -139
- package/dist/src/verbs/print-config.js +2 -1
- package/dist/src/verbs/print-projects.js +6 -4
- package/dist/src/verbs/print-retained.js +7 -5
- package/dist/src/verbs/print-roots.js +4 -2
- package/dist/src/verbs/verb.js +1 -5
- package/dist/src/verbs/version.js +14 -3
- package/jsr.json +2 -1
- package/package.json +14 -8
- package/src/alias-chain.ts +2 -9
- package/src/amd.ts +130 -0
- package/src/analysis.ts +424 -650
- package/src/augmentations.ts +93 -4
- package/src/automatic-types.ts +12 -30
- package/src/bindings.ts +460 -0
- package/src/calls.ts +338 -46
- package/src/commands/held.ts +632 -0
- package/src/commands/read.ts +242 -0
- package/src/commands/shell.ts +228 -0
- package/src/commands/tools.ts +2382 -0
- package/src/component-files.ts +4 -2
- package/src/component-layer.ts +4 -2
- package/src/config.ts +31 -302
- package/src/conformance-record.ts +1 -1
- package/src/consumers.ts +16 -66
- package/src/contextual-uses.ts +66 -34
- package/src/contract/config.generated.ts +821 -0
- package/src/contract/contract.generated.ts +1452 -0
- package/src/contract/report.generated.ts +1241 -0
- package/src/dependencies.ts +222 -127
- package/src/destructuring.ts +1 -31
- package/src/edges.ts +41 -140
- package/src/element-access.ts +190 -187
- package/src/entries/build-scripts.ts +292 -0
- package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
- package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
- package/src/{conventions.ts → entries/conventions.ts} +367 -583
- package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
- package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
- package/src/entries/run-directories.ts +108 -0
- package/src/entries/sources.ts +266 -0
- package/src/entries/static-module.ts +858 -0
- package/src/entries/test-runners.ts +835 -0
- package/src/entries/workflow-steps.ts +432 -0
- package/src/enum-group.ts +2 -11
- package/src/erased-stores.ts +3 -7
- package/src/exempt-classes.ts +1 -75
- package/src/exempt.ts +70 -98
- package/src/exposure.ts +492 -0
- package/src/extensions.ts +45 -0
- package/src/facts.ts +46 -0
- package/src/failure.ts +63 -0
- package/src/file-facts.ts +15 -25
- package/src/finding.ts +10 -10
- package/src/findings/boundary.ts +11 -0
- package/src/findings/completion.ts +133 -64
- package/src/findings/dependencies-and-module-machinery.ts +4 -7
- package/src/findings/emitter.ts +9 -10
- package/src/findings/emitters.ts +38 -52
- package/src/{implementations.ts → findings/implementations.ts} +4 -4
- package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
- package/src/findings/interfaces.ts +7 -9
- package/src/findings/intra-function.ts +16 -14
- package/src/findings/non-code-artifacts.ts +24 -15
- package/src/findings/reads-and-writes.ts +118 -41
- package/src/findings/self-check.ts +51 -38
- package/src/findings/unused-declarations.ts +31 -49
- package/src/findings/visibility-narrowing.ts +36 -40
- package/src/findings-pass.ts +15 -31
- package/src/framework-lifecycle.ts +47 -19
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +96 -0
- package/src/fs/tree.ts +110 -0
- package/src/generated-file.ts +242 -35
- package/src/git-ignore.ts +50 -26
- package/src/host.ts +12 -5
- package/src/import-bindings.ts +98 -29
- package/src/index/sites.ts +781 -0
- package/src/index.ts +2 -2
- package/src/indexed-access.ts +570 -527
- package/src/injection-container.ts +2 -2
- package/src/interface-satisfaction.ts +2 -2
- package/src/intra-function-parts.ts +73 -44
- package/src/inventory/commonjs.ts +696 -0
- package/src/inventory/enumerate.ts +203 -0
- package/src/inventory/syntax.ts +311 -0
- package/src/inventory.ts +442 -895
- package/src/javascript-file.ts +54 -0
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +133 -122
- package/src/kinds.ts +5 -413
- package/src/{components.ts → liveness/components.ts} +4 -6
- package/src/{graph.ts → liveness/graph.ts} +100 -35
- package/src/liveness/matrix.ts +162 -0
- package/src/liveness/sweep.ts +855 -0
- package/src/load/classify.ts +433 -0
- package/src/load/diagnostics.ts +154 -0
- package/src/load/discover.ts +471 -0
- package/src/{emit-map.ts → load/emit-map.ts} +1 -1
- package/src/load/expected-module.ts +194 -0
- package/src/load/load.ts +73 -0
- package/src/load/module-lookup.ts +50 -0
- package/src/load/package-scope.ts +74 -0
- package/src/load/plan.ts +513 -0
- package/src/load/specifiers.ts +171 -0
- package/src/load/synthesize.ts +230 -0
- package/src/load/test-globals.ts +251 -0
- package/src/load/test-joins.ts +98 -0
- package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
- package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
- package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
- package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
- package/src/{workspace.ts → load/workspace.ts} +90 -134
- package/src/module-declarations.ts +74 -98
- package/src/overrides.ts +162 -134
- package/src/partial.ts +3 -2
- package/src/paths.ts +92 -16
- package/src/platform-calls.ts +119 -0
- package/src/platform-symbols.ts +189 -0
- package/src/position.ts +44 -1
- package/src/print.ts +12 -92
- package/src/product.ts +18 -0
- package/src/query.ts +92 -0
- package/src/ref.ts +12 -20
- package/src/references/read-rule.ts +60 -0
- package/src/references/read-rules.ts +55 -0
- package/src/references/sink.ts +314 -0
- package/src/references/sources.ts +632 -0
- package/src/references.ts +187 -1450
- package/src/report-schema.ts +68 -0
- package/src/report.ts +103 -226
- package/src/reporters/annotations.ts +22 -11
- package/src/reporters/json.ts +1 -1
- package/src/reporters/reporter.ts +2 -4
- package/src/reporters/reporters.ts +1 -1
- package/src/reporters/sarif.ts +29 -16
- package/src/reporters/template.ts +4 -20
- package/src/reporters/text.ts +3 -3
- package/src/resolve.ts +284 -1115
- package/src/{configured-declarations.ts → roots/configured-declarations.ts} +27 -29
- package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
- package/src/roots/manifest.ts +303 -0
- package/src/roots/published-reach.ts +486 -0
- package/src/{roots.ts → roots/root-set.ts} +286 -469
- package/src/roots/unseen-loads.ts +345 -0
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -388
- package/src/scope.ts +46 -138
- package/src/serialization-contract.ts +769 -23
- package/src/session.ts +87 -55
- package/src/source-files.ts +6 -11
- package/src/stores.ts +15 -3
- package/src/suppress-file.ts +24 -33
- package/src/suppress-inline.ts +55 -91
- package/src/suppress.ts +78 -79
- package/src/symbol-keys.ts +104 -107
- package/src/template-field.ts +15 -25
- package/src/tests/file-class.ts +135 -0
- package/src/{outside-tests.ts → tests/outside.ts} +16 -10
- package/src/{test-support.ts → tests/support.ts} +15 -21
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/named-files.ts +388 -0
- package/src/text/yaml.ts +747 -0
- package/src/type-errors.ts +18 -288
- package/src/type-parameter-reads.ts +187 -158
- package/src/unimplemented-callees.ts +297 -280
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/vendor/unbash/LICENSE +15 -0
- package/src/vendor/unbash/VENDORED.md +16 -0
- package/src/vendor/unbash/ansi-c.ts +132 -0
- package/src/vendor/unbash/arithmetic-parts.ts +53 -0
- package/src/vendor/unbash/arithmetic.ts +641 -0
- package/src/vendor/unbash/assignment.ts +163 -0
- package/src/vendor/unbash/chars.ts +48 -0
- package/src/vendor/unbash/command.ts +47 -0
- package/src/vendor/unbash/expansion.ts +144 -0
- package/src/vendor/unbash/glob.ts +284 -0
- package/src/vendor/unbash/heredoc.ts +34 -0
- package/src/vendor/unbash/internal-types.ts +94 -0
- package/src/vendor/unbash/lexer.ts +4352 -0
- package/src/vendor/unbash/limits.ts +3 -0
- package/src/vendor/unbash/parser.ts +1612 -0
- package/src/vendor/unbash/parts.ts +96 -0
- package/src/vendor/unbash/substitution-context.ts +20 -0
- package/src/vendor/unbash/traversal.ts +182 -0
- package/src/vendor/unbash/types.ts +660 -0
- package/src/vendor/unbash/word-value.ts +64 -0
- package/src/vendor/unbash/word.ts +50 -0
- package/src/verbs/analyze.ts +255 -164
- package/src/verbs/describe.ts +19 -17
- package/src/verbs/explain.ts +93 -169
- package/src/verbs/print-config.ts +2 -1
- package/src/verbs/print-projects.ts +6 -4
- package/src/verbs/print-retained.ts +7 -5
- package/src/verbs/print-roots.ts +4 -2
- package/src/verbs/verb.ts +2 -8
- package/src/verbs/version.ts +15 -3
- package/dist/src/base-url.js +0 -18
- package/dist/src/conventions.js +0 -937
- package/dist/src/discover.js +0 -468
- package/dist/src/entry-points.js +0 -529
- package/dist/src/glob.js +0 -65
- package/dist/src/manifest.js +0 -165
- package/dist/src/matrix.js +0 -246
- package/dist/src/pnpm-workspace.js +0 -120
- package/dist/src/roots.js +0 -672
- package/dist/src/setup-failure.js +0 -23
- package/dist/src/sweep.js +0 -224
- package/dist/src/test-joins.js +0 -101
- package/dist/src/version.js +0 -7
- package/dist/src/workflow-steps.js +0 -185
- package/src/base-url.ts +0 -24
- package/src/discover.ts +0 -653
- package/src/entry-points.ts +0 -687
- package/src/glob.ts +0 -67
- package/src/manifest.ts +0 -234
- package/src/matrix.ts +0 -423
- package/src/pnpm-workspace.ts +0 -135
- package/src/setup-failure.ts +0 -39
- package/src/sweep.ts +0 -347
- package/src/test-joins.ts +0 -120
- package/src/version.ts +0 -7
- package/src/workflow-steps.ts +0 -216
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { isNoSubstitutionTemplateLiteral, isStringLiteral, } from "@typescript/native/ast";
|
|
2
|
+
import { packageOfSpecifier } from "../dependencies.js";
|
|
3
|
+
import { MANIFEST } from "../fs/manifest.js";
|
|
4
|
+
import { entriesOf } from "../fs/tree.js";
|
|
5
|
+
import { cannotStartPackageName, dirnamePath, joinPath, relativePath, resolvePath, } from "../paths.js";
|
|
6
|
+
import { dependencySpecifiers, installedPackage, manifestsAbove } from "./module-lookup.js";
|
|
7
|
+
/** The string literal holding one offset, innermost first, a doc comment's included. */
|
|
8
|
+
function literalAt(file, offset) {
|
|
9
|
+
let found;
|
|
10
|
+
const visit = (node) => {
|
|
11
|
+
if (offset < node.pos || offset >= node.end) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (isStringLiteral(node) || isNoSubstitutionTemplateLiteral(node)) {
|
|
15
|
+
found = node.text;
|
|
16
|
+
}
|
|
17
|
+
// `forEachChild` does not enter a doc comment, where a JavaScript file imports types.
|
|
18
|
+
for (const doc of node.jsDoc ?? []) {
|
|
19
|
+
visit(doc);
|
|
20
|
+
}
|
|
21
|
+
node.forEachChild(visit);
|
|
22
|
+
};
|
|
23
|
+
file.forEachChild(visit);
|
|
24
|
+
return found;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* What one `paths` key's `*` matches in one specifier, `""` for a key with no `*` that
|
|
28
|
+
* is the specifier, or `undefined` where the key does not match it.
|
|
29
|
+
*/
|
|
30
|
+
function mappedBy(key, specifier) {
|
|
31
|
+
const star = key.indexOf("*");
|
|
32
|
+
if (star < 0) {
|
|
33
|
+
return key === specifier ? "" : undefined;
|
|
34
|
+
}
|
|
35
|
+
const prefix = key.slice(0, star);
|
|
36
|
+
const suffix = key.slice(star + 1);
|
|
37
|
+
return specifier.length >= prefix.length + suffix.length &&
|
|
38
|
+
specifier.startsWith(prefix) &&
|
|
39
|
+
specifier.endsWith(suffix)
|
|
40
|
+
? specifier.slice(prefix.length, specifier.length - suffix.length)
|
|
41
|
+
: undefined;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* One `paths` target, its first `*` replaced by `star` taken literally, as the compiler does:
|
|
45
|
+
* https://github.com/microsoft/typescript-go/blob/89d5d5b2849a0db0957065889ca58536fa6d2e4a/internal/module/resolver.go#L1282
|
|
46
|
+
*/
|
|
47
|
+
function substituted(target, star) {
|
|
48
|
+
const at = target.indexOf("*");
|
|
49
|
+
return at < 0 ? target : target.slice(0, at) + star + target.slice(at + 1);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Whether a path names something on disk, as written or with any extension; under
|
|
53
|
+
* `fileOnly`, only a file counts.
|
|
54
|
+
*/
|
|
55
|
+
function provided(host, path, fileOnly) {
|
|
56
|
+
const counts = (at) => fileOnly ? host.kindOf(at) === "file" : host.kindOf(at) !== "absent";
|
|
57
|
+
if (counts(path)) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
const dir = dirnamePath(path);
|
|
61
|
+
const stem = `${path.slice(dir.length + 1)}.`;
|
|
62
|
+
return entriesOf(host, dir).some((entry) => entry.name.startsWith(stem) && counts(joinPath(dir, entry.name)));
|
|
63
|
+
}
|
|
64
|
+
/** The manifest at or above `dir`, no higher than the target root, that declares `name`. */
|
|
65
|
+
function declaringManifest(host, dir, targetRoot, name) {
|
|
66
|
+
for (const { dir: at, manifest } of manifestsAbove(host, dir, targetRoot)) {
|
|
67
|
+
if (dependencySpecifiers(manifest, name).length > 0) {
|
|
68
|
+
return joinPath(at, MANIFEST);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Why one import that the compiler cannot resolve names a module the project expects,
|
|
75
|
+
* with the fix, or undefined where the module is one the project does not expect.
|
|
76
|
+
*/
|
|
77
|
+
function expectedModule(context, importer, specifier) {
|
|
78
|
+
const { host, targetRoot } = context;
|
|
79
|
+
const fix = "run the generator or the build that writes it";
|
|
80
|
+
if (cannotStartPackageName(specifier)) {
|
|
81
|
+
return provided(host, resolvePath(dirnamePath(importer), specifier), false)
|
|
82
|
+
? undefined
|
|
83
|
+
: `which names no file of the target: ${fix}`;
|
|
84
|
+
}
|
|
85
|
+
if (specifier.startsWith("#")) {
|
|
86
|
+
return `which the manifest's imports map to no file: ${fix}`;
|
|
87
|
+
}
|
|
88
|
+
const mapped = context.paths.entries.flatMap(({ key, targets }) => {
|
|
89
|
+
const star = mappedBy(key, specifier);
|
|
90
|
+
return star === undefined
|
|
91
|
+
? []
|
|
92
|
+
: targets.map((target) => resolvePath(context.paths.base, substituted(target, star)));
|
|
93
|
+
});
|
|
94
|
+
const name = packageOfSpecifier(specifier);
|
|
95
|
+
// The compiler looks up in `node_modules` what `paths` does not resolve, so the error
|
|
96
|
+
// of an installed package's import is the import's own, a subpath its exports omit:
|
|
97
|
+
// https://github.com/microsoft/typescript-go/blob/89d5d5b2849a0db0957065889ca58536fa6d2e4a/internal/module/resolver.go#L548-L575
|
|
98
|
+
if (name !== undefined && installedPackage(host, dirnamePath(importer), name) !== undefined) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
if (mapped.length > 0) {
|
|
102
|
+
return mapped.some((path) => provided(host, path, true))
|
|
103
|
+
? undefined
|
|
104
|
+
: `which the compiler configuration's paths map to no file: ${fix}`;
|
|
105
|
+
}
|
|
106
|
+
const manifest = name === undefined
|
|
107
|
+
? undefined
|
|
108
|
+
: declaringManifest(host, dirnamePath(importer), targetRoot, name);
|
|
109
|
+
// No run requires a nested package that is no workspace member to be installed.
|
|
110
|
+
if (manifest === undefined ||
|
|
111
|
+
(dirnamePath(manifest) !== targetRoot && !context.member(manifest))) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
const where = relativePath(targetRoot, manifest) ?? manifest;
|
|
115
|
+
return `a dependency ${where} declares that is not installed: run the package manager's install`;
|
|
116
|
+
}
|
|
117
|
+
/** The `paths` mapping of the configuration at `configFile` whose parse answered `options`. */
|
|
118
|
+
export function pathsOf(configFile, options) {
|
|
119
|
+
// The parse answers `pathsBasePath`, the directory of the configuration that writes
|
|
120
|
+
// `paths` (an extended one included), though the client's option type omits it:
|
|
121
|
+
// https://github.com/microsoft/typescript-go/blob/89d5d5b2849a0db0957065889ca58536fa6d2e4a/internal/tsoptions/tsconfigparsing.go#L1120
|
|
122
|
+
const declaredAt = options.pathsBasePath;
|
|
123
|
+
return {
|
|
124
|
+
base: typeof declaredAt === "string" ? declaredAt : dirnamePath(configFile),
|
|
125
|
+
entries: Object.entries(options.paths ?? {}).map(([key, targets]) => ({ key, targets })),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Why one import the compiler cannot resolve, at `offset` of `file`, names a module the project
|
|
130
|
+
* expects and nothing provides, with the fix; undefined where the project does not expect it.
|
|
131
|
+
*/
|
|
132
|
+
export function missingModule(context, file, offset) {
|
|
133
|
+
const specifier = literalAt(file, offset);
|
|
134
|
+
const reason = specifier === undefined ? undefined : expectedModule(context, file.fileName, specifier);
|
|
135
|
+
return specifier === undefined || reason === undefined ? undefined : { specifier, reason };
|
|
136
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { resolvePath } from "../paths.js";
|
|
2
|
+
import { openSession } from "../session.js";
|
|
3
|
+
import { classify } from "./classify.js";
|
|
4
|
+
import { planRun, programBuilds } from "./plan.js";
|
|
5
|
+
/**
|
|
6
|
+
* Plans the run, opens every configuration in one snapshot of one client, classifies every
|
|
7
|
+
* project, and hands the analyzed and the consumer projects to `read` while the client answers.
|
|
8
|
+
* A run that cannot be analyzed ends with one {@link FailureExit} before `read` is called.
|
|
9
|
+
*/
|
|
10
|
+
export function loadRun(engine, host, scope, config, read) {
|
|
11
|
+
const plan = planRun(engine, host, scope, config);
|
|
12
|
+
return openSession(engine, plan.plans.map((one) => one.configFile), { programs: programBuilds(host, plan.plans) }, (session, unanswered) => {
|
|
13
|
+
const classified = classify(engine, host, plan, new Map(session.views.map((view) => [view.configFile, view])));
|
|
14
|
+
const formed = new Set(plan.plans.filter((one) => one.written !== undefined).map((one) => one.configFile));
|
|
15
|
+
const runFiles = new Set(session.views
|
|
16
|
+
.filter((view) => !formed.has(view.configFile))
|
|
17
|
+
.flatMap((view) => view
|
|
18
|
+
.ownSourceFiles()
|
|
19
|
+
.map((file) => resolvePath(host.workingDirectory(), file.fileName))));
|
|
20
|
+
return {
|
|
21
|
+
plan,
|
|
22
|
+
classified,
|
|
23
|
+
result: read({ plan, classified, runFiles }),
|
|
24
|
+
unanswered: unanswered(),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a package an import names is installed and which manifests above an importer declare
|
|
3
|
+
* it: the leaf both the expected-module reading and the workspace resolution read.
|
|
4
|
+
*/
|
|
5
|
+
import { DEPENDENCY_SECTIONS, INSTALLED_PACKAGES, manifestAt } from "../fs/manifest.js";
|
|
6
|
+
import { isRecord } from "../json-document.js";
|
|
7
|
+
import { ancestors, joinPath } from "../paths.js";
|
|
8
|
+
/**
|
|
9
|
+
* The directory `node_modules/<name>` holds for an importer in `dir`: the nearest one at or
|
|
10
|
+
* above `dir`, above any target root too, that is a directory, a link to one included, as the
|
|
11
|
+
* compiler looks a package up. Undefined where no ancestor installs it.
|
|
12
|
+
*/
|
|
13
|
+
export function installedPackage(host, dir, name) {
|
|
14
|
+
return ancestors(dir)
|
|
15
|
+
.map((at) => joinPath(at, INSTALLED_PACKAGES, name))
|
|
16
|
+
.find((candidate) => host.kindOf(candidate) === "directory");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The manifests at or above `dir` and no higher than `top`, nearest first; a directory outside
|
|
20
|
+
* `top` reads its own manifest alone.
|
|
21
|
+
*/
|
|
22
|
+
export function* manifestsAbove(host, dir, top) {
|
|
23
|
+
const chain = ancestors(dir, top);
|
|
24
|
+
for (const at of chain.length > 0 ? chain : [dir]) {
|
|
25
|
+
const manifest = manifestAt(host, at);
|
|
26
|
+
if (manifest !== undefined) {
|
|
27
|
+
yield { dir: at, manifest };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** The specifiers one manifest depends on `name` with, one per dependency section naming it. */
|
|
32
|
+
export function dependencySpecifiers(manifest, name) {
|
|
33
|
+
return DEPENDENCY_SECTIONS.flatMap((section) => {
|
|
34
|
+
const declared = manifest[section];
|
|
35
|
+
return isRecord(declared) && Object.hasOwn(declared, name) ? [declared[name]] : [];
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { manifestAt } from "../fs/manifest.js";
|
|
2
|
+
import { dirnamePath, joinPath } from "../paths.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolves each file's package scope: the name of the nearest manifest at or above its
|
|
5
|
+
* directory up to the target root, and the file's path below that manifest. Where no
|
|
6
|
+
* manifest up to the root carries a name, the package is a single dot and the path is read
|
|
7
|
+
* from the root, which cannot collide, because a package name never starts with a dot. One
|
|
8
|
+
* directory is read at most once.
|
|
9
|
+
*/
|
|
10
|
+
export function packageScope(host, root) {
|
|
11
|
+
const named = new Map();
|
|
12
|
+
const manifestName = (dir) => {
|
|
13
|
+
const name = manifestAt(host, joinPath(root, dir))?.["name"];
|
|
14
|
+
return typeof name === "string" && name !== "" ? name : undefined;
|
|
15
|
+
};
|
|
16
|
+
const nearest = (dir) => {
|
|
17
|
+
if (named.has(dir)) {
|
|
18
|
+
return named.get(dir);
|
|
19
|
+
}
|
|
20
|
+
const name = manifestName(dir);
|
|
21
|
+
const found = name !== undefined ? { name, at: dir } : dir === "" ? undefined : nearest(parentOf(dir));
|
|
22
|
+
named.set(dir, found);
|
|
23
|
+
return found;
|
|
24
|
+
};
|
|
25
|
+
return (path) => {
|
|
26
|
+
const found = nearest(parentOf(path));
|
|
27
|
+
if (found === undefined) {
|
|
28
|
+
return { package: ".", path };
|
|
29
|
+
}
|
|
30
|
+
return { package: found.name, path: found.at === "" ? path : path.slice(found.at.length + 1) };
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Whether Node reads each file's `.js` siblings as ECMAScript modules: the `type` of the
|
|
35
|
+
* nearest manifest at or above its directory up to the target root is `module`
|
|
36
|
+
* (https://nodejs.org/api/packages.html#type). One directory is read at most once.
|
|
37
|
+
*/
|
|
38
|
+
export function packageTypeIsModule(host, root) {
|
|
39
|
+
const typed = new Map();
|
|
40
|
+
const nearest = (dir) => {
|
|
41
|
+
const known = typed.get(dir);
|
|
42
|
+
if (known !== undefined) {
|
|
43
|
+
return known;
|
|
44
|
+
}
|
|
45
|
+
const manifest = manifestAt(host, joinPath(root, dir));
|
|
46
|
+
const found = manifest !== undefined ? manifest["type"] === "module" : dir !== "" && nearest(parentOf(dir));
|
|
47
|
+
typed.set(dir, found);
|
|
48
|
+
return found;
|
|
49
|
+
};
|
|
50
|
+
return (path) => nearest(parentOf(path));
|
|
51
|
+
}
|
|
52
|
+
/** The directory one path below the root sits in, and the root itself as the empty path. */
|
|
53
|
+
function parentOf(path) {
|
|
54
|
+
const dir = dirnamePath(path);
|
|
55
|
+
return dir === "." ? "" : dir;
|
|
56
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { readConventions, } from "../entries/conventions.js";
|
|
2
|
+
import { holdsManifest, inInstalledPackages, MANIFEST, readManifestAt } from "../fs/manifest.js";
|
|
3
|
+
import { gitIgnored } from "../git-ignore.js";
|
|
4
|
+
import { packageEntries, readManifest, } from "../roots/manifest.js";
|
|
5
|
+
import { ancestors, dirnamePath, joinPath, normalizePath, relativePath, resolvePath, } from "../paths.js";
|
|
6
|
+
import { bytewise } from "../text/compare.js";
|
|
7
|
+
import { globExpression } from "../text/glob.js";
|
|
8
|
+
import { consumerWithoutSources, discoverProjects, isTargetConfiguration, targetWithoutSources, } from "./discover.js";
|
|
9
|
+
import { FailureExit } from "../failure.js";
|
|
10
|
+
import { bundlingManifests, candidateFiles, formedGroups, formedPrograms, packageOf, } from "./synthesize.js";
|
|
11
|
+
import { joinedTestFiles, joinedTests } from "./test-joins.js";
|
|
12
|
+
import { testGlobals } from "./test-globals.js";
|
|
13
|
+
import { findWorkspace, withFormed } from "./workspace.js";
|
|
14
|
+
import { workspacePrograms, writtenConfiguration, writtenFileOf } from "./workspace-programs.js";
|
|
15
|
+
import { workspaceResolver } from "./workspace-resolution.js";
|
|
16
|
+
import { layoutOf, workspaceRun } from "./workspace-run.js";
|
|
17
|
+
/**
|
|
18
|
+
* The `paths` one configuration's resolved options map under the compilers before version
|
|
19
|
+
* 7, each target absolute: a target is read against the effective `baseUrl`, and a specifier
|
|
20
|
+
* no other pattern maps is looked up below it. Undefined where no `baseUrl` is set, so the
|
|
21
|
+
* options' own `paths` stand. Version 7 reads no `baseUrl`:
|
|
22
|
+
* https://github.com/microsoft/TypeScript/issues/62207
|
|
23
|
+
*/
|
|
24
|
+
export function baseUrlPaths(options) {
|
|
25
|
+
const baseUrl = Reflect.get(options, "baseUrl");
|
|
26
|
+
if (typeof baseUrl !== "string") {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
return Object.fromEntries(Object.entries({ "*": ["*"], ...options.paths }).map(([key, targets]) => [
|
|
30
|
+
key,
|
|
31
|
+
targets.map((target) => resolvePath(baseUrl, target)),
|
|
32
|
+
]));
|
|
33
|
+
}
|
|
34
|
+
function planned(configuration) {
|
|
35
|
+
const { options } = configuration.parsed;
|
|
36
|
+
if (configuration.written !== undefined) {
|
|
37
|
+
return {
|
|
38
|
+
...configuration,
|
|
39
|
+
options,
|
|
40
|
+
build: { kind: "configuration", value: configuration.written },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const paths = baseUrlPaths(options);
|
|
44
|
+
return {
|
|
45
|
+
...configuration,
|
|
46
|
+
options: paths === undefined ? options : { ...options, paths },
|
|
47
|
+
build: paths === undefined
|
|
48
|
+
? { kind: "project" }
|
|
49
|
+
: {
|
|
50
|
+
kind: "configuration",
|
|
51
|
+
value: { extends: configuration.configFile, compilerOptions: { paths } },
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The nested packages of a run: each directory below the target root, in no `node_modules`
|
|
57
|
+
* directory and none of `known`, that holds a `package.json` and lies at or above one of
|
|
58
|
+
* `files`, in path order.
|
|
59
|
+
*/
|
|
60
|
+
function nestedPackageDirs(host, targetRoot, files, known) {
|
|
61
|
+
const seen = new Set();
|
|
62
|
+
const found = [];
|
|
63
|
+
for (const file of files) {
|
|
64
|
+
for (const dir of ancestors(dirnamePath(file), targetRoot)) {
|
|
65
|
+
if (seen.has(dir) || relativePath(targetRoot, dir) === undefined) {
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
seen.add(dir);
|
|
69
|
+
const below = relativePath(targetRoot, dir) ?? "";
|
|
70
|
+
if (!inInstalledPackages(below) && !known.has(dir) && holdsManifest(host, dir)) {
|
|
71
|
+
found.push(dir);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return found.sort(bytewise);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The manifests conventions are applied from below `root`: its own, then each member's and
|
|
79
|
+
* each nested package's, each once.
|
|
80
|
+
*/
|
|
81
|
+
function conventionManifests(host, root, members, nested) {
|
|
82
|
+
const found = new Map();
|
|
83
|
+
if (holdsManifest(host, root)) {
|
|
84
|
+
found.set(root, { dir: root, path: MANIFEST });
|
|
85
|
+
}
|
|
86
|
+
for (const [dirs, isNested] of [
|
|
87
|
+
[members, false],
|
|
88
|
+
[nested, true],
|
|
89
|
+
]) {
|
|
90
|
+
for (const dir of dirs) {
|
|
91
|
+
const below = relativePath(root, dir);
|
|
92
|
+
if (below !== undefined && !found.has(dir)) {
|
|
93
|
+
found.set(dir, { dir, path: `${below}/${MANIFEST}`, nested: isNested });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return [...found.values()];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The workspace one consumer sits in, read from its own root with `parse` reading its members'
|
|
101
|
+
* configurations, the target's reused, and any other given the programs of `formed` as
|
|
102
|
+
* {@link withFormed} does.
|
|
103
|
+
*/
|
|
104
|
+
function consumerWorkspace(host, consumer, target, parse, formed) {
|
|
105
|
+
try {
|
|
106
|
+
const found = findWorkspace(host, consumer.path, parse, target);
|
|
107
|
+
return {
|
|
108
|
+
workspace: found === undefined || found === target ? found : withFormed(host, found, formed),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (!(error instanceof FailureExit)) {
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
return { fault: error.failures[0].detail };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* How the snapshot builds each program formed for a consumer that sits in a workspace, its
|
|
120
|
+
* member imports read from source as the target's are. A consumer's configuration read from a
|
|
121
|
+
* file resolves a member through what is installed, as the compiler does.
|
|
122
|
+
*/
|
|
123
|
+
function consumerPrograms(engine, host, plans, places) {
|
|
124
|
+
const byRoot = new Map();
|
|
125
|
+
for (const plan of plans) {
|
|
126
|
+
const place = plan.consumer === undefined ? undefined : places.get(plan.consumer.path);
|
|
127
|
+
if (plan.written === undefined || place === undefined || !("workspace" in place)) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const { workspace } = place;
|
|
131
|
+
if (workspace !== undefined) {
|
|
132
|
+
const held = byRoot.get(workspace.root) ?? { workspace, plans: [] };
|
|
133
|
+
held.plans.push(plan);
|
|
134
|
+
byRoot.set(workspace.root, held);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return new Map([...byRoot.values()].flatMap(({ workspace, plans: held }) => [
|
|
138
|
+
...workspacePrograms(engine, host, held, workspaceResolver(host, workspace)).programs,
|
|
139
|
+
]));
|
|
140
|
+
}
|
|
141
|
+
function outputsOf({ parsed }) {
|
|
142
|
+
return [parsed.options.outDir, parsed.options.declarationDir].filter((dir) => dir !== undefined);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The plan of one run: the configurations discovery names and the programs formed for the
|
|
146
|
+
* JavaScript files none lists, each built through the steps in order (the `baseUrl` paths,
|
|
147
|
+
* the workspace members read from source, the test runner's globals, the joined test files),
|
|
148
|
+
* the package set and the convention rows. A formed program's files wait for the joins and
|
|
149
|
+
* the rows, and its module system is fixed before any workspace round reads it. A nested
|
|
150
|
+
* package is one at or above a file a target configuration lists, joins or is formed over.
|
|
151
|
+
*/
|
|
152
|
+
export function planRun(engine, host, scope, config) {
|
|
153
|
+
const discovery = discoverProjects(engine, host, scope, config.analysis.configurations);
|
|
154
|
+
const root = resolvePath(host.workingDirectory(), scope.target.path);
|
|
155
|
+
const parse = (fileName, text) => engine.parseSourceFile(fileName, text);
|
|
156
|
+
const disabled = config.ts.disabled_conventions;
|
|
157
|
+
const outputs = discovery.configurations.flatMap(outputsOf);
|
|
158
|
+
const unread = [];
|
|
159
|
+
const ignoredBelow = (dir) => gitIgnored(host, dir, (path, reason) => {
|
|
160
|
+
if (!unread.some((one) => one.kind === "ignore-file" && one.path === path)) {
|
|
161
|
+
unread.push({ kind: "ignore-file", path, reason });
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
// Before any target step, so a consumer's failure is the one named, as discoverProjects orders them.
|
|
165
|
+
const consumerFormed = discovery.unconfigured.flatMap((consumer) => {
|
|
166
|
+
const consumerRoot = resolvePath(host.workingDirectory(), consumer.path);
|
|
167
|
+
const files = candidateFiles(host, consumerRoot, {
|
|
168
|
+
covered: new Set(),
|
|
169
|
+
outputs,
|
|
170
|
+
ignored: ignoredBelow(consumerRoot),
|
|
171
|
+
});
|
|
172
|
+
const rows = readConventions(host, parse, conventionManifests(host, consumerRoot, [], [...new Set(files.map((file) => packageOf(host, consumerRoot, file)))].filter((dir) => dir !== consumerRoot)), disabled);
|
|
173
|
+
const programs = formedPrograms(engine, host, formedGroups(host, consumerRoot, files, rows), {
|
|
174
|
+
root: consumerRoot,
|
|
175
|
+
origin: "consumer",
|
|
176
|
+
bundling: bundlingManifests(rows),
|
|
177
|
+
idOf: (path) => path ?? consumerRoot,
|
|
178
|
+
});
|
|
179
|
+
if (programs.length === 0) {
|
|
180
|
+
throw consumerWithoutSources(consumer.path);
|
|
181
|
+
}
|
|
182
|
+
return programs.map((one) => ({ ...one, configuration: { ...one.configuration, consumer } }));
|
|
183
|
+
});
|
|
184
|
+
const readTargets = discovery.configurations.filter(isTargetConfiguration);
|
|
185
|
+
const manifest = readManifest(host, scope.target.path);
|
|
186
|
+
const found = findWorkspace(host, root, (configFile) => layoutOf(engine, configFile));
|
|
187
|
+
const joins = discovery.mode === "derived"
|
|
188
|
+
? joinedTestFiles(host, root, readTargets, config.ts.test_files.map(globExpression))
|
|
189
|
+
: new Map();
|
|
190
|
+
const targetIgnored = ignoredBelow(root);
|
|
191
|
+
const covered = new Set([
|
|
192
|
+
...readTargets.flatMap(({ parsed }) => parsed.fileNames),
|
|
193
|
+
...[...joins.values()].flat(),
|
|
194
|
+
]);
|
|
195
|
+
const trees = discovery.targets.flatMap((target) => {
|
|
196
|
+
if (target.kind === "configuration") {
|
|
197
|
+
return [];
|
|
198
|
+
}
|
|
199
|
+
const dir = target.kind === "derived" ? root : dirnamePath(target.manifest);
|
|
200
|
+
const files = candidateFiles(host, dir, { covered, outputs, ignored: targetIgnored });
|
|
201
|
+
return [
|
|
202
|
+
{
|
|
203
|
+
target,
|
|
204
|
+
dir,
|
|
205
|
+
files: target.kind === "derived"
|
|
206
|
+
? files
|
|
207
|
+
: files.filter((file) => packageOf(host, dir, file) === dir),
|
|
208
|
+
},
|
|
209
|
+
];
|
|
210
|
+
});
|
|
211
|
+
const members = found?.members.map((member) => member.dir) ?? [];
|
|
212
|
+
const nested = nestedPackageDirs(host, normalizePath(root), [
|
|
213
|
+
...readTargets.flatMap((plan) => [
|
|
214
|
+
plan.configFile,
|
|
215
|
+
...plan.parsed.fileNames,
|
|
216
|
+
...(joins.get(plan.configFile) ?? []),
|
|
217
|
+
]),
|
|
218
|
+
...trees.flatMap(({ files }) => files),
|
|
219
|
+
], new Set(members));
|
|
220
|
+
const conventions = readConventions(host, parse, conventionManifests(host, root, members, nested), disabled);
|
|
221
|
+
const bundling = bundlingManifests(conventions);
|
|
222
|
+
const formedFor = new Map(trees.map(({ target, dir, files }) => {
|
|
223
|
+
const groups = formedGroups(host, dir, files, conventions);
|
|
224
|
+
const programs = formedPrograms(engine, host, target.kind === "declared"
|
|
225
|
+
? [groups[0] ?? { dir, manifest: readManifestAt(host, dir), files: [] }]
|
|
226
|
+
: groups, {
|
|
227
|
+
root,
|
|
228
|
+
origin: target.kind,
|
|
229
|
+
bundling,
|
|
230
|
+
idOf: (path) => target.kind === "declared"
|
|
231
|
+
? target.id
|
|
232
|
+
: path === undefined
|
|
233
|
+
? "."
|
|
234
|
+
: (relativePath(root, path) ?? path),
|
|
235
|
+
});
|
|
236
|
+
return [target, programs];
|
|
237
|
+
}));
|
|
238
|
+
const targetFormed = [...formedFor.values()].flat();
|
|
239
|
+
if (readTargets.length + targetFormed.length === 0 && discovery.notBuilt.length === 0) {
|
|
240
|
+
throw targetWithoutSources(scope.target.path);
|
|
241
|
+
}
|
|
242
|
+
for (const { configuration, group } of [...targetFormed, ...consumerFormed]) {
|
|
243
|
+
if (group.manifest.kind === "malformed" || group.manifest.kind === "unread") {
|
|
244
|
+
unread.push({
|
|
245
|
+
kind: "manifest",
|
|
246
|
+
configFile: configuration.configFile,
|
|
247
|
+
manifest: joinPath(group.dir, MANIFEST),
|
|
248
|
+
reason: group.manifest.kind === "unread" ? group.manifest.reason : undefined,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
let plans = [
|
|
253
|
+
...discovery.targets.flatMap((target) => target.kind === "configuration"
|
|
254
|
+
? [target.configuration]
|
|
255
|
+
: (formedFor.get(target) ?? []).map(({ configuration }) => configuration)),
|
|
256
|
+
...discovery.configurations.filter((one) => !isTargetConfiguration(one)),
|
|
257
|
+
...consumerFormed.map(({ configuration }) => configuration),
|
|
258
|
+
].map(planned);
|
|
259
|
+
const formedLayouts = new Map();
|
|
260
|
+
for (const { configuration, group } of [...targetFormed, ...consumerFormed]) {
|
|
261
|
+
formedLayouts.set(group.dir, [
|
|
262
|
+
...(formedLayouts.get(group.dir) ?? []),
|
|
263
|
+
{ fileNames: configuration.parsed.fileNames },
|
|
264
|
+
]);
|
|
265
|
+
}
|
|
266
|
+
const workspace = workspaceRun(engine, host, root, plans.filter(isTargetConfiguration), manifest, found === undefined ? undefined : withFormed(host, found, formedLayouts));
|
|
267
|
+
const consumerWorkspaces = new Map(discovery.consumers.map((consumer) => [
|
|
268
|
+
consumer.path,
|
|
269
|
+
consumerWorkspace(host, consumer, workspace?.workspace, discovery.unconfigured.includes(consumer)
|
|
270
|
+
? (configFile) => layoutOf(engine, configFile)
|
|
271
|
+
: () => undefined, formedLayouts),
|
|
272
|
+
]));
|
|
273
|
+
const consumerBuilds = consumerPrograms(engine, host, plans, consumerWorkspaces);
|
|
274
|
+
plans = plans.map((plan) => {
|
|
275
|
+
const build = workspace?.programs.get(plan.configFile) ?? consumerBuilds.get(plan.configFile);
|
|
276
|
+
return build === undefined ? plan : { ...plan, build };
|
|
277
|
+
});
|
|
278
|
+
plans = testGlobals(host, parse, plans);
|
|
279
|
+
plans = joinedTests(plans, joins);
|
|
280
|
+
const packages = {
|
|
281
|
+
manifest: workspace?.manifest ?? manifest,
|
|
282
|
+
members,
|
|
283
|
+
nested,
|
|
284
|
+
entries: [...(workspace?.entries ?? []), ...packageEntries(host, normalizePath(root), nested)],
|
|
285
|
+
published: new Set((workspace?.entries ?? []).filter((entry) => entry.published).map((entry) => entry.dir)),
|
|
286
|
+
};
|
|
287
|
+
return {
|
|
288
|
+
discovery,
|
|
289
|
+
plans,
|
|
290
|
+
packages,
|
|
291
|
+
conventions,
|
|
292
|
+
workspace,
|
|
293
|
+
consumerWorkspaces,
|
|
294
|
+
root,
|
|
295
|
+
outputs,
|
|
296
|
+
unread,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
/** How the snapshot builds each planned configuration other than by opening its project. */
|
|
300
|
+
export function programBuilds(host, plans) {
|
|
301
|
+
const builds = new Map();
|
|
302
|
+
const formed = new Set(plans.filter((plan) => plan.written !== undefined).map((plan) => plan.configFile));
|
|
303
|
+
for (const plan of plans) {
|
|
304
|
+
const { configFile, build } = plan;
|
|
305
|
+
if (build.kind === "program") {
|
|
306
|
+
builds.set(configFile, build);
|
|
307
|
+
}
|
|
308
|
+
else if (build.kind === "configuration") {
|
|
309
|
+
builds.set(configFile, writtenConfiguration(writtenFileOf(host, plan, formed), build.value));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return builds;
|
|
313
|
+
}
|