@cplieger/deadset-ts 8.0.0-dev.15 → 8.0.0-dev.17

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.
Files changed (207) hide show
  1. package/dist/src/alias-chain.js +0 -5
  2. package/dist/src/amd.js +81 -0
  3. package/dist/src/analysis.js +94 -54
  4. package/dist/src/augmentations.js +23 -24
  5. package/dist/src/bindings.js +382 -0
  6. package/dist/src/calls.js +25 -8
  7. package/dist/src/commands/read.js +6 -7
  8. package/dist/src/commands/tools.js +5 -9
  9. package/dist/src/component-files.js +3 -2
  10. package/dist/src/conformance-record.js +1 -1
  11. package/dist/src/consumers.js +9 -10
  12. package/dist/src/contextual-uses.js +1 -17
  13. package/dist/src/contract/config.generated.js +5 -2
  14. package/dist/src/contract/contract.generated.js +119 -2
  15. package/dist/src/contract/report.generated.js +6 -2
  16. package/dist/src/dependencies.js +98 -71
  17. package/dist/src/destructuring.js +1 -19
  18. package/dist/src/element-access.js +179 -164
  19. package/dist/src/entries/build-scripts.js +222 -0
  20. package/dist/src/{configuration-files.js → entries/configuration-files.js} +22 -64
  21. package/dist/src/{convention-rows.js → entries/convention-rows.js} +120 -27
  22. package/dist/src/entries/conventions.js +739 -0
  23. package/dist/src/{html-entries.js → entries/html-entries.js} +9 -12
  24. package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +3 -3
  25. package/dist/src/entries/run-directories.js +77 -0
  26. package/dist/src/entries/sources.js +144 -0
  27. package/dist/src/entries/static-module.js +670 -0
  28. package/dist/src/entries/test-runners.js +684 -0
  29. package/dist/src/{workflow-steps.js → entries/workflow-steps.js} +18 -8
  30. package/dist/src/extensions.js +37 -0
  31. package/dist/src/facts.js +38 -0
  32. package/dist/src/findings/completion.js +40 -4
  33. package/dist/src/findings/emitters.js +5 -8
  34. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  35. package/dist/src/{in-operands.js → findings/in-operands.js} +2 -2
  36. package/dist/src/findings/self-check.js +36 -20
  37. package/dist/src/findings-pass.js +5 -6
  38. package/dist/src/framework-lifecycle.js +42 -15
  39. package/dist/src/fs/manifest.js +15 -20
  40. package/dist/src/generated-file.js +172 -29
  41. package/dist/src/graph.js +14 -8
  42. package/dist/src/import-bindings.js +73 -28
  43. package/dist/src/index/sites.js +557 -0
  44. package/dist/src/index.js +1 -1
  45. package/dist/src/indexed-access.js +523 -478
  46. package/dist/src/injection-container.js +1 -1
  47. package/dist/src/interface-satisfaction.js +1 -1
  48. package/dist/src/inventory/commonjs.js +62 -17
  49. package/dist/src/inventory/enumerate.js +2 -1
  50. package/dist/src/javascript-file.js +26 -11
  51. package/dist/src/keyof-comparisons.js +124 -103
  52. package/dist/src/load/classify.js +28 -9
  53. package/dist/src/load/diagnostics.js +8 -1
  54. package/dist/src/load/discover.js +15 -7
  55. package/dist/src/load/expected-module.js +2 -2
  56. package/dist/src/load/plan.js +2 -2
  57. package/dist/src/load/specifiers.js +2 -4
  58. package/dist/src/load/synthesize.js +10 -5
  59. package/dist/src/load/workspace-manifests.js +1 -1
  60. package/dist/src/load/workspace-resolution.js +2 -2
  61. package/dist/src/matrix.js +12 -17
  62. package/dist/src/module-declarations.js +70 -85
  63. package/dist/src/overrides.js +134 -112
  64. package/dist/src/paths.js +56 -1
  65. package/dist/src/platform-calls.js +78 -0
  66. package/dist/src/platform-symbols.js +134 -0
  67. package/dist/src/references/read-rule.js +1 -0
  68. package/dist/src/references/read-rules.js +48 -0
  69. package/dist/src/references/sink.js +151 -0
  70. package/dist/src/references/sources.js +450 -0
  71. package/dist/src/references.js +111 -1116
  72. package/dist/src/resolve.js +1 -1
  73. package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +7 -4
  74. package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +5 -8
  75. package/dist/src/{manifest.js → roots/manifest.js} +4 -4
  76. package/dist/src/roots/published-reach.js +412 -0
  77. package/dist/src/roots/root-set.js +489 -0
  78. package/dist/src/roots/unseen-loads.js +236 -0
  79. package/dist/src/serialization-contract.js +9 -4
  80. package/dist/src/source-files.js +5 -9
  81. package/dist/src/stores.js +4 -2
  82. package/dist/src/suppress.js +30 -32
  83. package/dist/src/sweep.js +25 -13
  84. package/dist/src/symbol-keys.js +89 -83
  85. package/dist/src/tests/file-class.js +76 -0
  86. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  87. package/dist/src/{test-support.js → tests/support.js} +5 -12
  88. package/dist/src/type-parameter-reads.js +178 -139
  89. package/dist/src/unimplemented-callees.js +262 -242
  90. package/dist/src/verbs/analyze.js +15 -3
  91. package/dist/src/verbs/describe.js +5 -3
  92. package/dist/src/verbs/explain.js +50 -28
  93. package/dist/src/verbs/print-retained.js +2 -2
  94. package/jsr.json +1 -1
  95. package/package.json +3 -3
  96. package/src/alias-chain.ts +0 -7
  97. package/src/amd.ts +130 -0
  98. package/src/analysis.ts +156 -70
  99. package/src/augmentations.ts +41 -27
  100. package/src/automatic-types.ts +1 -1
  101. package/src/bindings.ts +460 -0
  102. package/src/calls.ts +25 -7
  103. package/src/commands/read.ts +6 -8
  104. package/src/commands/tools.ts +5 -11
  105. package/src/component-files.ts +4 -2
  106. package/src/conformance-record.ts +1 -1
  107. package/src/consumers.ts +12 -11
  108. package/src/contextual-uses.ts +2 -22
  109. package/src/contract/config.generated.ts +5 -2
  110. package/src/contract/contract.generated.ts +138 -2
  111. package/src/contract/report.generated.ts +6 -2
  112. package/src/dependencies.ts +117 -71
  113. package/src/destructuring.ts +1 -31
  114. package/src/element-access.ts +188 -182
  115. package/src/entries/build-scripts.ts +292 -0
  116. package/src/{configuration-files.ts → entries/configuration-files.ts} +33 -82
  117. package/src/{convention-rows.ts → entries/convention-rows.ts} +167 -28
  118. package/src/{conventions.ts → entries/conventions.ts} +349 -523
  119. package/src/{html-entries.ts → entries/html-entries.ts} +19 -18
  120. package/src/{mdx-entries.ts → entries/mdx-entries.ts} +5 -5
  121. package/src/entries/run-directories.ts +108 -0
  122. package/src/entries/sources.ts +266 -0
  123. package/src/entries/static-module.ts +858 -0
  124. package/src/entries/test-runners.ts +868 -0
  125. package/src/{workflow-steps.ts → entries/workflow-steps.ts} +29 -11
  126. package/src/exempt.ts +3 -2
  127. package/src/extensions.ts +45 -0
  128. package/src/facts.ts +46 -0
  129. package/src/file-facts.ts +1 -1
  130. package/src/findings/boundary.ts +2 -0
  131. package/src/findings/completion.ts +43 -4
  132. package/src/findings/emitter.ts +1 -1
  133. package/src/findings/emitters.ts +14 -10
  134. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  135. package/src/{in-operands.ts → findings/in-operands.ts} +3 -3
  136. package/src/findings/self-check.ts +41 -22
  137. package/src/findings/visibility-narrowing.ts +1 -1
  138. package/src/findings-pass.ts +5 -12
  139. package/src/framework-lifecycle.ts +43 -15
  140. package/src/fs/manifest.ts +25 -21
  141. package/src/generated-file.ts +240 -36
  142. package/src/graph.ts +27 -11
  143. package/src/import-bindings.ts +98 -29
  144. package/src/index/sites.ts +781 -0
  145. package/src/index.ts +1 -1
  146. package/src/indexed-access.ts +570 -527
  147. package/src/injection-container.ts +1 -1
  148. package/src/interface-satisfaction.ts +1 -1
  149. package/src/inventory/commonjs.ts +102 -17
  150. package/src/inventory/enumerate.ts +2 -1
  151. package/src/javascript-file.ts +29 -12
  152. package/src/keyof-comparisons.ts +131 -116
  153. package/src/load/classify.ts +49 -13
  154. package/src/load/diagnostics.ts +11 -1
  155. package/src/load/discover.ts +27 -11
  156. package/src/load/expected-module.ts +8 -2
  157. package/src/load/plan.ts +11 -2
  158. package/src/load/specifiers.ts +8 -5
  159. package/src/load/synthesize.ts +12 -6
  160. package/src/load/test-globals.ts +1 -1
  161. package/src/load/workspace-manifests.ts +1 -1
  162. package/src/load/workspace-resolution.ts +9 -2
  163. package/src/load/workspace-run.ts +1 -1
  164. package/src/matrix.ts +13 -17
  165. package/src/module-declarations.ts +74 -98
  166. package/src/overrides.ts +162 -134
  167. package/src/paths.ts +65 -1
  168. package/src/platform-calls.ts +119 -0
  169. package/src/platform-symbols.ts +189 -0
  170. package/src/references/read-rule.ts +60 -0
  171. package/src/references/read-rules.ts +55 -0
  172. package/src/references/sink.ts +213 -0
  173. package/src/references/sources.ts +632 -0
  174. package/src/references.ts +174 -1492
  175. package/src/report.ts +2 -2
  176. package/src/resolve.ts +1 -1
  177. package/src/{configured-declarations.ts → roots/configured-declarations.ts} +10 -7
  178. package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +5 -8
  179. package/src/{manifest.ts → roots/manifest.ts} +5 -5
  180. package/src/roots/published-reach.ts +481 -0
  181. package/src/{roots.ts → roots/root-set.ts} +203 -630
  182. package/src/roots/unseen-loads.ts +345 -0
  183. package/src/serialization-contract.ts +9 -4
  184. package/src/source-files.ts +5 -10
  185. package/src/stores.ts +13 -2
  186. package/src/suppress.ts +48 -33
  187. package/src/sweep.ts +37 -14
  188. package/src/symbol-keys.ts +102 -102
  189. package/src/tests/file-class.ts +118 -0
  190. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  191. package/src/{test-support.ts → tests/support.ts} +15 -21
  192. package/src/type-parameter-reads.ts +187 -158
  193. package/src/unimplemented-callees.ts +297 -280
  194. package/src/verbs/analyze.ts +19 -5
  195. package/src/verbs/describe.ts +5 -2
  196. package/src/verbs/explain.ts +75 -32
  197. package/src/verbs/print-retained.ts +2 -2
  198. package/dist/src/build-scripts.js +0 -418
  199. package/dist/src/conventions.js +0 -907
  200. package/dist/src/entry-points.js +0 -444
  201. package/dist/src/own-body.js +0 -28
  202. package/dist/src/roots.js +0 -865
  203. package/dist/src/unseen-loads.js +0 -189
  204. package/src/build-scripts.ts +0 -536
  205. package/src/entry-points.ts +0 -584
  206. package/src/own-body.ts +0 -42
  207. package/src/unseen-loads.ts +0 -282
package/src/analysis.ts CHANGED
@@ -14,18 +14,21 @@ import {
14
14
  configuredDeclarations,
15
15
  configuredRef,
16
16
  declarationsNamed,
17
- } from "./configured-declarations.ts";
17
+ } from "./roots/configured-declarations.ts";
18
18
  import { decorator } from "./decorator.ts";
19
19
  import { configurationNeeds, dependenciesOf, projectNeeds } from "./dependencies.ts";
20
20
  import { deprecatedDeclarations, type Deprecation } from "./deprecation.ts";
21
21
  import { moduleIdentity, type LoadedConsumer, type NotBuilt } from "./load/discover.ts";
22
22
  import type { LibraryUnfound } from "./load/classify.ts";
23
23
  import { loadRun, type LoadedRun } from "./load/load.ts";
24
- import { generatedFiles, type AppliedConvention } from "./conventions.ts";
24
+ import type { AppliedConvention } from "./entries/conventions.ts";
25
+ import { readSources, type SourceFacts } from "./entries/sources.ts";
26
+ import { readWorkflows, type Workflows } from "./entries/workflow-steps.ts";
25
27
  import { readEdgeSides } from "./edges.ts";
26
28
  import { enumGroup } from "./enum-group.ts";
27
- import { generatedFile, generatedFilesOf } from "./generated-file.ts";
28
- import { inOperandNames } from "./in-operands.ts";
29
+ import { bindingsOf, distinctBindings, type BindingRecord } from "./bindings.ts";
30
+ import { generatedFile, generatedFilesOf, type GeneratedFact } from "./generated-file.ts";
31
+ import { inOperandNames } from "./findings/in-operands.ts";
29
32
  import { sourceFilesOf } from "./source-files.ts";
30
33
  import {
31
34
  evidenceRecords,
@@ -47,13 +50,13 @@ import type { EmitterInput } from "./findings/emitter.ts";
47
50
  import { unmatchedRootFindings, type SelfCheckFacts } from "./findings/self-check.ts";
48
51
  import { frameworkLifecycle } from "./framework-lifecycle.ts";
49
52
  import type { Host } from "./host.ts";
50
- import { implementations, mergeImplementations } from "./implementations.ts";
53
+ import { implementations, mergeImplementations } from "./findings/implementations.ts";
51
54
  import { injectionContainer } from "./injection-container.ts";
52
55
  import { interfaceSatisfaction, settledSatisfaction } from "./interface-satisfaction.ts";
53
56
  import { intraFunctionFacts, projectParts, type ProjectParts } from "./intra-function-parts.ts";
54
57
  import { type Inventory, type InventorySymbol } from "./inventory.ts";
55
58
  import { inventory } from "./inventory/enumerate.ts";
56
- import { readManifest, type ManifestEntry } from "./manifest.ts";
59
+ import { readManifest, type ManifestEntry } from "./roots/manifest.ts";
57
60
  import {
58
61
  liveFilesAt,
59
62
  matrixOf,
@@ -74,26 +77,32 @@ import {
74
77
  import type { UnansweredQuestion } from "./query.ts";
75
78
  import { byPosition, isComponentFile, type Position } from "./position.ts";
76
79
  import type { TypeErrorSkip, UnansweredCount } from "./report.ts";
77
- import { skippedRoots, skippedUnits, type SkippedUnit } from "./type-errors.ts";
80
+ import { skippedUnits, type SkippedUnit } from "./type-errors.ts";
78
81
  import { reflectiveLookup } from "./reflective-lookup.ts";
79
- import { references, testFileRulesOf, type Reference, type TestFileRule } from "./references.ts";
82
+ import { references, type Reference } from "./references.ts";
80
83
  import {
81
- roots,
84
+ rootSet,
82
85
  unmatchedEverywhere,
83
- type Root,
84
86
  type RootKind,
85
87
  type Roots,
86
88
  type HeldScripts,
87
- } from "./roots.ts";
89
+ } from "./roots/root-set.ts";
88
90
  import type { Scope } from "./scope.ts";
89
91
  import { decodedMembers, serializationContract, type Decoded } from "./serialization-contract.ts";
90
- import { outsideTestReferences, testFilesAt, type OutsideTest } from "./outside-tests.ts";
91
- import { mergedGlobalInterfaces } from "./augmentations.ts";
92
- import { unseenLoadsOf, type UnseenLoad } from "./unseen-loads.ts";
92
+ import { outsideTestReferences, testFilesAt, type OutsideTest } from "./tests/outside.ts";
93
+ import type { UnseenLoad } from "./roots/unseen-loads.ts";
93
94
  import type { UnresolvedSpecifier } from "./load/specifiers.ts";
95
+ import { formedForNode } from "./load/synthesize.ts";
94
96
  import type { UnreadInput } from "./load/plan.ts";
95
97
  import { GLOBALS_RUNNER, namesTestGlobals } from "./load/test-globals.ts";
96
- import { supportReferences, testSupportFiles, type TestEvidence } from "./test-support.ts";
98
+ import {
99
+ targetTestFile,
100
+ testFilePaths,
101
+ testFileRulesOf,
102
+ withheldBy,
103
+ type TestFileRule,
104
+ } from "./tests/file-class.ts";
105
+ import { testSupportFiles, type TestEvidence } from "./tests/support.ts";
97
106
  import type { Engine, ProjectView } from "./session.ts";
98
107
  import { accessorsOf, storesOf } from "./stores.ts";
99
108
  import { isPartKind, type SuppressionRecord, type Suppressions, type Verdict } from "./suppress.ts";
@@ -103,6 +112,7 @@ import type { Exemption, Mode, SweepInput } from "./sweep.ts";
103
112
  import { readTemplates, templateField } from "./template-field.ts";
104
113
  import { bytewise } from "./text/compare.ts";
105
114
  import { holdsManifest, manifestAt } from "./fs/manifest.ts";
115
+ import { runDirectories } from "./entries/run-directories.ts";
106
116
  import { globExpression } from "./text/glob.ts";
107
117
 
108
118
  /** The setting whose source decides where a finding about a configured root sits. */
@@ -176,10 +186,14 @@ interface ProjectRead {
176
186
  readonly typeErrorSkips: readonly TypeErrorSkip[];
177
187
  /** The lines each of those skips withholds every finding on. */
178
188
  readonly skipped: readonly SkippedUnit[];
179
- /** The project's generated files, by path below the target root, each with the detail its retentions name. */
180
- readonly generated: ReadonlyMap<string, string>;
181
- /** The files, absolute, an applied convention row names as test files. */
182
- readonly testFileNames: ReadonlySet<string>;
189
+ /** The project's generated files, by path below the target root, each with what decided it. */
190
+ readonly generated: ReadonlyMap<string, GeneratedFact>;
191
+ /** The binding identities its generated files publish (`bindings.6`, `bindings.7`). */
192
+ readonly bindings: readonly BindingRecord[];
193
+ /** What the project's entry sources enter and name, read once. */
194
+ readonly sources: SourceFacts;
195
+ /** Whether the run formed the program to resolve its modules as Node does (program.36). */
196
+ readonly formedForNode: boolean;
183
197
  }
184
198
 
185
199
  /** One target project the run analyzes, as its stage is handed it. */
@@ -194,8 +208,12 @@ interface ProjectsRead<Answer> {
194
208
  readonly answers: readonly Answer[];
195
209
  /** Every reference a consumer makes to a declaration of the target, each once. */
196
210
  readonly references: readonly Reference[];
211
+ /** The declarations a consumer's read rules held, each once. */
212
+ readonly consumerHeld: readonly string[];
197
213
  /** The test files below the target root no project the run reads holds, parsed. */
198
214
  readonly outsideTests: readonly OutsideTest[];
215
+ /** The target root's workflow steps, git hooks and makefile, read once for every project. */
216
+ readonly workflows: Workflows;
199
217
  }
200
218
 
201
219
  /**
@@ -216,14 +234,13 @@ function readProjects<Answer>(
216
234
  const parse = (fileName: string, text: string) => engine.parseSourceFile(fileName, text);
217
235
  return loadRun(engine, host, scope, config, ({ plan, classified, runFiles }) => {
218
236
  const { packages, conventions } = plan;
237
+ const workflows = readWorkflows(host, targetRoot);
219
238
  const options = {
220
239
  host,
221
240
  manifest: packages.manifest,
222
241
  otherPackages: packages.entries,
223
242
  patterns: config.roots.patterns,
224
243
  entryFiles: config.ts.entry_files,
225
- conventions,
226
- testFiles: config.ts.test_files,
227
244
  parse,
228
245
  publishedAPI: config.target.kind !== undefined && kindOf(config.target.kind) === "library",
229
246
  publishedMembers: packages.published,
@@ -233,19 +250,18 @@ function readProjects<Answer>(
233
250
  const answers = classified.analyzed.map(({ plan: planned, project, skips, referenceOnly }) => {
234
251
  const read = (): ProjectRead => {
235
252
  const held = inventory(project, host, targetRoot);
236
- const found = roots(project, held, targetRoot, options);
237
- const kept = skippedRoots(project, held, skips);
238
- const rooted =
239
- kept.length === 0
240
- ? found
241
- : {
242
- ...found,
243
- liveUnderReachability: [
244
- ...found.liveUnderReachability,
245
- ...kept.map((id) => ({ id, kind: "type-error" as const, source: "" })),
246
- ],
247
- };
248
253
  const own = sourceFilesOf(project, targetRoot);
254
+ const sources = readSources({
255
+ host,
256
+ targetRoot,
257
+ files: own,
258
+ parse,
259
+ testFiles: config.ts.test_files,
260
+ conventions,
261
+ workflows,
262
+ });
263
+ const rooted = rootSet(project, held, targetRoot, { ...options, sources, skips });
264
+ const generated = generatedFilesOf(own, sources.generated);
249
265
  return {
250
266
  configuration: planned.id,
251
267
  configFile: project.configFile,
@@ -257,8 +273,18 @@ function readProjects<Answer>(
257
273
  .ownSourceFiles()
258
274
  .filter((file) => referenceOnly(file.fileName))
259
275
  .flatMap((file) => relativePath(absoluteRoot, file.fileName) ?? []),
260
- generated: generatedFilesOf(own, generatedFiles(conventions, own)),
261
- testFileNames: conventions.testFiles,
276
+ generated,
277
+ bindings: bindingsOf(
278
+ own.byPath,
279
+ generated,
280
+ new Map(
281
+ held.symbols
282
+ .filter((one) => one.kind === "file")
283
+ .map((one) => [one.position.path, one.ref]),
284
+ ),
285
+ ),
286
+ sources,
287
+ formedForNode: formedForNode(planned),
262
288
  };
263
289
  };
264
290
  for (const file of project.ownSourceFiles()) {
@@ -267,11 +293,16 @@ function readProjects<Answer>(
267
293
  return stage(project, { configuration: planned.id, read });
268
294
  });
269
295
  const consumed = new Map<string, Reference>();
296
+ const consumerHeld = new Set<string>();
270
297
  for (const { project, consumer } of classified.consumed) {
271
298
  const side = { id: consumer.id, root: consumer.path };
272
- for (const reference of consumerReferences(project, host, targetRoot, side, config)) {
299
+ const read = consumerReferences(project, host, targetRoot, side, config, parse);
300
+ for (const reference of read.references) {
273
301
  consumed.set(referenceKey(reference), reference);
274
302
  }
303
+ for (const id of read.held) {
304
+ consumerHeld.add(id);
305
+ }
275
306
  }
276
307
  const outsideTests = testFilesAt(
277
308
  host,
@@ -281,7 +312,13 @@ function readProjects<Answer>(
281
312
  ),
282
313
  parse,
283
314
  );
284
- return { answers, references: [...consumed.values()], outsideTests };
315
+ return {
316
+ answers,
317
+ references: [...consumed.values()],
318
+ consumerHeld: [...consumerHeld],
319
+ outsideTests,
320
+ workflows,
321
+ };
285
322
  });
286
323
  }
287
324
 
@@ -386,6 +423,14 @@ export function runRoots(
386
423
  };
387
424
  }
388
425
 
426
+ /** The production mode a configuration sets: a consumer's test reference is classed as `analysis.consumer_tests` says. */
427
+ export function productionMode(config: PartialConfig): Mode {
428
+ return {
429
+ production: true,
430
+ consumerTestsProduction: config.analysis.consumer_tests === "production",
431
+ };
432
+ }
433
+
389
434
  /** The run's sweep, beside the matrix it judged. */
390
435
  export interface RunSweep {
391
436
  readonly matrix: Matrix;
@@ -442,6 +487,8 @@ interface SweptProject<Extra> {
442
487
  readonly unanswered: readonly string[];
443
488
  /** The data members a generic declared outside the analysis fills, which it may read. */
444
489
  readonly filledOutside: readonly string[];
490
+ /** What only a bundler's retry of an import Node leaves unresolved names (program.38). */
491
+ readonly possiblyLoaded: readonly string[];
445
492
  readonly typeErrorSkips: readonly TypeErrorSkip[];
446
493
  readonly skipped: readonly SkippedUnit[];
447
494
  /** The component files the project holds of its own, by path below the target root. */
@@ -457,14 +504,15 @@ interface SweptProject<Extra> {
457
504
  interface ReadProject<Extra> {
458
505
  readonly projectRead: ProjectRead;
459
506
  readonly references: readonly Reference[];
507
+ /** The declarations its read rules held where the checker did not answer. */
508
+ readonly held: readonly string[];
509
+ readonly possiblyLoaded: readonly string[];
460
510
  readonly testFiles: readonly string[];
461
511
  readonly evidence: readonly Exemption[];
462
512
  readonly componentFiles: readonly string[];
463
513
  readonly componentWarnings: readonly ComponentWarning[];
464
514
  /** Per own file below the target root, the module specifiers its imports write. */
465
515
  readonly imports: ReadonlyMap<string, readonly string[]>;
466
- /** The global augmentations a declaration outside the project names. */
467
- readonly augmented: readonly Root[];
468
516
  /** The data members its production code decodes into. */
469
517
  readonly decoded: Decoded;
470
518
  readonly extra: Extra;
@@ -499,6 +547,8 @@ interface ReadRun<Extra> {
499
547
  readonly memberDirs: readonly string[];
500
548
  /** The directory of every nested package, absolute. */
501
549
  readonly nestedDirs: readonly string[];
550
+ /** The target root's workflow steps, git hooks and makefile, read once. */
551
+ readonly workflows: Workflows;
502
552
  }
503
553
 
504
554
  /** The manifest section of a package test evidence counts, and the sections that keep one out of it. */
@@ -564,6 +614,7 @@ function readRun<Extra>(
564
614
  read: ProjectRead,
565
615
  references: readonly Reference[],
566
616
  testFiles: readonly string[],
617
+ unseenLoads: readonly UnseenLoad[],
567
618
  ) => Extra,
568
619
  ): ReadRun<Extra> {
569
620
  const targetRoot = scope.target.path;
@@ -572,12 +623,18 @@ function readRun<Extra>(
572
623
  ? { delimiters: config.analysis.template_delimiters, files: [] }
573
624
  : readTemplates(host, targetRoot, config.analysis);
574
625
  const consumers = scope.consumers.map((consumer) => consumer.path);
626
+ const directories = runDirectories(host, targetRoot, (fileName, text) =>
627
+ engine.parseSourceFile(fileName, text),
628
+ );
575
629
  const read = readProjects<ReadProject<Extra>>(engine, host, scope, config, (project, opened) => {
576
630
  const projectRead = opened.read();
631
+ const testFile = targetTestFile(projectRead.sources.testFiles);
577
632
  const resolved = references(project, projectRead.held, targetRoot, {
578
- testFiles: config.ts.test_files,
579
- testFileNames: projectRead.testFileNames,
633
+ testFile,
634
+ directories,
635
+ formedForNode: projectRead.formedForNode,
580
636
  });
637
+ const testFiles = testFilePaths(project, targetRoot, testFile);
581
638
  const evidence = evidenceRecords(
582
639
  {
583
640
  project,
@@ -602,14 +659,11 @@ function readRun<Extra>(
602
659
  return {
603
660
  projectRead,
604
661
  references: resolved.references,
605
- testFiles: resolved.testFilePaths,
662
+ held: resolved.held,
663
+ possiblyLoaded: resolved.possiblyLoaded,
664
+ testFiles,
606
665
  evidence,
607
666
  componentFiles: components.map(pathOf),
608
- augmented: mergedGlobalInterfaces(
609
- project,
610
- projectRead.held,
611
- sourceFilesOf(project, targetRoot),
612
- ).map((id): Root => ({ id, kind: "global-augmentation", source: "" })),
613
667
  imports: new Map(
614
668
  project.ownSourceFiles().flatMap((file) => {
615
669
  const path = relativePath(targetRoot, file.fileName);
@@ -638,10 +692,19 @@ function readRun<Extra>(
638
692
  decoded: decodedMembers(
639
693
  project,
640
694
  projectRead.held,
641
- productionFiles(project, targetRoot, resolved.testFilePaths),
695
+ productionFiles(project, targetRoot, testFiles),
642
696
  consumers,
643
697
  ),
644
- extra: extra(project, projectRead, resolved.references, resolved.testFilePaths),
698
+ extra: extra(
699
+ project,
700
+ projectRead,
701
+ resolved.references,
702
+ testFiles,
703
+ resolved.unseenLoads.map((position) => ({
704
+ configuration: projectRead.configuration,
705
+ position,
706
+ })),
707
+ ),
645
708
  };
646
709
  });
647
710
  const outsidePaths = read.result.outsideTests.map((one) => one.path);
@@ -658,7 +721,12 @@ function readRun<Extra>(
658
721
  const { support, testUsed } = testSupportFiles(
659
722
  withOutside.flatMap((one) => one.projectRead.held.symbols),
660
723
  withOutside.flatMap((one) => one.references),
661
- withOutside.flatMap((one) => one.projectRead.rooted.liveUnderReachability),
724
+ // An outside declaration naming a global augmentation calls nothing of its file.
725
+ withOutside.flatMap((one) =>
726
+ one.projectRead.rooted.liveUnderReachability.filter(
727
+ (root) => root.kind !== "global-augmentation",
728
+ ),
729
+ ),
662
730
  withOutside.flatMap((one) => one.testFiles),
663
731
  testEvidence(host, targetRoot, withOutside),
664
732
  );
@@ -691,7 +759,7 @@ function readRun<Extra>(
691
759
  testFiles: new Set([...one.testFiles, ...support]),
692
760
  });
693
761
  const exempt = detected.records;
694
- const made = supportReferences([...one.references, ...(satisfied?.references ?? [])], support);
762
+ const made = [...one.references, ...(satisfied?.references ?? [])];
695
763
  const held = new Set(projectRead.held.symbols.map((symbol) => symbol.position.path));
696
764
  const supportFiles = [...support].filter((path) => held.has(path)).sort(bytewise);
697
765
  const testUsedFiles = [...testUsed].filter((path) => held.has(path)).sort(bytewise);
@@ -699,9 +767,7 @@ function readRun<Extra>(
699
767
  configuration: projectRead.configuration,
700
768
  symbols: projectRead.held.symbols,
701
769
  references: [...made, ...evidenceReferences(projectRead.held.symbols, detected.inTestFiles)],
702
- // The augmentations are rooted after test support is read: an outside declaration
703
- // naming one calls nothing of its file.
704
- roots: [...projectRead.rooted.liveUnderReachability, ...one.augmented],
770
+ roots: projectRead.rooted.liveUnderReachability,
705
771
  testFiles: [...one.testFiles, ...supportFiles],
706
772
  ...(supportFiles.length === 0 ? {} : { supportFiles }),
707
773
  ...(testUsedFiles.length === 0 ? {} : { testUsedFiles }),
@@ -720,13 +786,13 @@ function readRun<Extra>(
720
786
  unanswered: [
721
787
  ...projectRead.held.unanswered,
722
788
  ...projectRead.rooted.unanswered,
723
- ...made
724
- .filter((reference) => reference.resolution === "by-name")
725
- .map((reference) => reference.to),
789
+ ...made.filter((reference) => reference.guessed === true).map((reference) => reference.to),
790
+ ...one.held,
726
791
  ...exempt.filter(isUnansweredRecord).map((record) => record.id),
727
792
  ...one.decoded.unanswered,
728
793
  ],
729
794
  filledOutside: one.decoded.filled,
795
+ possiblyLoaded: one.possiblyLoaded,
730
796
  typeErrorSkips: projectRead.typeErrorSkips,
731
797
  unmappedEntries: projectRead.rooted.unmappedEntries,
732
798
  heldScripts: projectRead.rooted.heldScripts,
@@ -754,7 +820,8 @@ function readRun<Extra>(
754
820
  unansweredHeld: [
755
821
  ...new Set([
756
822
  ...answers.flatMap((one) => one.unanswered),
757
- ...consumed.filter((one) => one.resolution === "by-name").map((one) => one.to),
823
+ ...consumed.filter((one) => one.guessed === true).map((one) => one.to),
824
+ ...read.result.consumerHeld,
758
825
  ]),
759
826
  ],
760
827
  projects,
@@ -769,6 +836,7 @@ function readRun<Extra>(
769
836
  conventionUses: read.plan.conventions.uses,
770
837
  memberDirs: read.plan.packages.members,
771
838
  nestedDirs: read.plan.packages.nested,
839
+ workflows: read.result.workflows,
772
840
  };
773
841
  }
774
842
 
@@ -842,8 +910,8 @@ function countedWrites(
842
910
  mode: Mode,
843
911
  ): ReadonlySet<string> {
844
912
  return new Set(
845
- supportReferences(references, support).flatMap((reference) =>
846
- reference.use === "write" && !(mode.production && reference.test) ? [reference.to] : [],
913
+ references.flatMap((reference) =>
914
+ reference.use === "write" && !withheldBy(mode, reference, support) ? [reference.to] : [],
847
915
  ),
848
916
  );
849
917
  }
@@ -856,8 +924,9 @@ function writtenOnly<Extra>(read: ReadRun<Extra>, mode: Mode): ReadonlySet<strin
856
924
  const written = new Set<string>();
857
925
  const readSome = new Set<string>();
858
926
  for (const { configured } of read.projects) {
927
+ const support = new Set(configured.supportFiles ?? []);
859
928
  for (const reference of configured.references) {
860
- if (mode.production && reference.test) {
929
+ if (withheldBy(mode, reference, support)) {
861
930
  continue;
862
931
  }
863
932
  if (reference.use === "write" && reference.consumer === undefined) {
@@ -889,7 +958,7 @@ function sweptOf<Extra>(
889
958
  // over what it reads, the test of dead code among them, cannot judge it.
890
959
  for (const { configured } of read.projects) {
891
960
  for (const reference of configured.references) {
892
- if (reference.resolution === "by-name") {
961
+ if (reference.guessed === true) {
893
962
  held.add(reference.from);
894
963
  }
895
964
  }
@@ -898,7 +967,7 @@ function sweptOf<Extra>(
898
967
  const answered = matrixOf(
899
968
  read.projects.map(({ configured }) => ({
900
969
  ...configured,
901
- references: configured.references.filter((one) => one.resolution !== "by-name"),
970
+ references: configured.references.filter((one) => one.guessed !== true),
902
971
  })),
903
972
  );
904
973
  const bare: SweepInput = {
@@ -958,7 +1027,8 @@ interface EmitterExtra {
958
1027
  readonly needs: ReturnType<typeof projectNeeds>;
959
1028
  readonly implementations: ReturnType<typeof implementations>;
960
1029
  readonly heldByInclusion: readonly string[];
961
- readonly generated: readonly string[];
1030
+ readonly generated: ReadonlyMap<string, GeneratedFact>;
1031
+ readonly bindings: readonly BindingRecord[];
962
1032
  readonly inOperands: readonly string[];
963
1033
  readonly rooted: Roots;
964
1034
  readonly directives: readonly InlineDirective[];
@@ -996,15 +1066,22 @@ export function readEmitterRun(
996
1066
  config,
997
1067
  mode,
998
1068
  detectors,
999
- (project, read, references, testFiles) => ({
1069
+ (project, read, references, testFiles, unseenLoads) => ({
1000
1070
  deprecation: deprecatedDeclarations(project, read.held),
1001
1071
  accessors: accessorsOf(project, read.held),
1002
- needs: projectNeeds(project, read.held, host, targetRoot, (fileName, text) =>
1003
- engine.parseSourceFile(fileName, text),
1072
+ needs: projectNeeds(
1073
+ project,
1074
+ read.held,
1075
+ host,
1076
+ targetRoot,
1077
+ (fileName, text) => engine.parseSourceFile(fileName, text),
1078
+ read.sources.configuration,
1079
+ read.sources.workflows,
1004
1080
  ),
1005
1081
  implementations: implementations(project, read.held),
1006
1082
  heldByInclusion: heldByInclusion(project, targetRoot),
1007
- generated: [...read.generated.keys()],
1083
+ generated: read.generated,
1084
+ bindings: read.bindings,
1008
1085
  inOperands: inOperandNames(project, targetRoot, testFiles),
1009
1086
  rooted: read.rooted,
1010
1087
  directives: inlineDirectives(project, read.held, targetRoot).filter(
@@ -1012,7 +1089,7 @@ export function readEmitterRun(
1012
1089
  ),
1013
1090
  declarationsNamed: declarationsNamed(project, read.held, configuredDeclarations(config)),
1014
1091
  parts: projectParts(project, read.held, references, targetRoot),
1015
- unseenLoads: unseenLoadsOf(project, read.configuration, targetRoot, testFiles),
1092
+ unseenLoads,
1016
1093
  }),
1017
1094
  );
1018
1095
  // Whether a declaration carries the marker decides its code, so one whose answer went
@@ -1093,6 +1170,7 @@ export function emitterInputOver(
1093
1170
  stores: storesOf(
1094
1171
  projects.map((one) => ({
1095
1172
  references: one.configured.references,
1173
+ support: new Set(one.configured.supportFiles ?? []),
1096
1174
  accessors: one.extra.accessors,
1097
1175
  })),
1098
1176
  swept.exempt,
@@ -1101,6 +1179,7 @@ export function emitterInputOver(
1101
1179
  dependencies: dependenciesOf(
1102
1180
  host,
1103
1181
  targetRoot,
1182
+ read.workflows,
1104
1183
  [...projects.map((one) => one.extra.needs), configurationNeeds(read.conventionUses)],
1105
1184
  swept.sweep.candidates.map((candidate) => candidate.id),
1106
1185
  members.read,
@@ -1111,7 +1190,7 @@ export function emitterInputOver(
1111
1190
  files: {
1112
1191
  tree: sourceTree(host, targetRoot),
1113
1192
  heldByInclusion: new Set(projects.flatMap((one) => one.extra.heldByInclusion)),
1114
- generated: new Set(projects.flatMap((one) => one.extra.generated)),
1193
+ generated: new Set(projects.flatMap((one) => [...one.extra.generated.keys()])),
1115
1194
  inOperands: new Set(projects.flatMap((one) => one.extra.inOperands)),
1116
1195
  unseenLoads: projects.flatMap((one) => one.extra.unseenLoads),
1117
1196
  },
@@ -1123,6 +1202,7 @@ export function emitterInputOver(
1123
1202
  encapsulated: readManifest(host, targetRoot).declaresExports,
1124
1203
  edges: readEdgeSides(host, targetRoot),
1125
1204
  filledOutside: new Set(projects.flatMap((one) => one.filledOutside)),
1205
+ possiblyLoaded: new Set(projects.flatMap((one) => one.possiblyLoaded)),
1126
1206
  },
1127
1207
  selfCheck,
1128
1208
  intraFunction: intraFunctionFacts(
@@ -1211,6 +1291,8 @@ function readAnalysis(
1211
1291
  one.heldScripts.map((held) => ({ ...held, configFile: one.configFile })),
1212
1292
  ),
1213
1293
  unseenLoads: read.projects.flatMap((one) => one.extra.unseenLoads),
1294
+ generated: new Map(read.projects.flatMap((one) => [...one.extra.generated])),
1295
+ bindings: distinctBindings(read.projects.flatMap((one) => one.extra.bindings)),
1214
1296
  },
1215
1297
  configured: read.projects.map((one) => one.configured),
1216
1298
  symbols,
@@ -1317,6 +1399,10 @@ interface RunFacts {
1317
1399
  readonly heldScripts: readonly (HeldScripts & { readonly configFile: string })[];
1318
1400
  /** The loads of production files whose target the run cannot resolve, per configuration. */
1319
1401
  readonly unseenLoads: readonly UnseenLoad[];
1402
+ /** Every generated file of the run, by its path below the target root, each once. */
1403
+ readonly generated: ReadonlyMap<string, GeneratedFact>;
1404
+ /** Every binding record the run's generated files publish, each once. */
1405
+ readonly bindings: readonly BindingRecord[];
1320
1406
  }
1321
1407
 
1322
1408
  /** One configuration whose component files a run cannot read. */
@@ -78,7 +78,7 @@ function holdersOf(
78
78
  * file or a `declare` holds that a `declare global` block, or the top level of a file in
79
79
  * `scripts`, declares, directly or inside a namespace there.
80
80
  */
81
- export function ambientGlobalInterfaces(
81
+ function ambientGlobalInterfaces(
82
82
  held: Inventory,
83
83
  interfaces: readonly string[],
84
84
  scripts: ReadonlySet<string>,
@@ -89,19 +89,31 @@ export function ambientGlobalInterfaces(
89
89
  : interfaces.filter((id) => held.ambient.has(id) && holders(id).global);
90
90
  }
91
91
 
92
+ /** The ambient global interfaces of a project's own files that merge into a declaration outside them. */
93
+ interface GlobalMerges {
94
+ /** The files that are no module, by identifier. */
95
+ readonly scripts: ReadonlySet<string>;
96
+ /** Each such interface, by identifier. */
97
+ readonly interfaces: ReadonlySet<string>;
98
+ /**
99
+ * Each such interface with every interface, namespace and block between it and the global
100
+ * scope: the outside declaration names it wherever a value is typed by it. Where every
101
+ * outside declaration is a package's, not the compiler's library, and declares no member,
102
+ * each member it declares as well: such an interface is a slot the package reads by type,
103
+ * as `keyof` does, in declarations the analysis does not walk.
104
+ */
105
+ readonly kept: readonly string[];
106
+ }
107
+
92
108
  /**
93
- * Each ambient global interface of the project's own files that merges into an interface
94
- * declared outside them, with every interface, namespace and block between it and the
95
- * global scope: the outside declaration names it wherever a value is typed by it. Where
96
- * every outside declaration is a package's, not the compiler's library, and declares no
97
- * member, each member it declares as well: such an interface is a slot the package reads
98
- * by type, as `keyof` does, in declarations the analysis does not walk.
109
+ * Which ambient global interfaces of the project's own files, `files`, merge into an interface
110
+ * declared outside them, and what each merge keeps.
99
111
  */
100
112
  export function mergedGlobalInterfaces<Brand>(
101
113
  project: ProjectView<Brand>,
102
114
  held: Inventory,
103
115
  files: SourceFiles,
104
- ): readonly string[] {
116
+ ): GlobalMerges {
105
117
  const scripts = new Set<string>();
106
118
  const names = new Map<string, Node>();
107
119
  for (const file of files.byName.values()) {
@@ -124,7 +136,7 @@ export function mergedGlobalInterfaces<Brand>(
124
136
  const global = new Set(ambientGlobalInterfaces(held, [...names.keys()], scripts));
125
137
  const asked = [...names].filter(([id]) => global.has(id));
126
138
  if (asked.length === 0) {
127
- return [];
139
+ return { scripts, interfaces: new Set(), kept: [] };
128
140
  }
129
141
  const answers = project.symbolsAt(asked.map(([, name]) => project.handle(name)));
130
142
  const holders = holdersOf(held, scripts);
@@ -135,24 +147,26 @@ export function mergedGlobalInterfaces<Brand>(
135
147
  const node = project.declarationAt(handle)?.node;
136
148
  return node !== undefined && isInterfaceDeclaration(node) && node.members.length === 0;
137
149
  };
138
- return [
139
- ...new Set(
140
- asked.flatMap(([id], at) => {
141
- const symbol = answers[at];
142
- if (typeof symbol !== "object") {
143
- return [];
144
- }
145
- const outside = symbol.declarations.filter((handle) => !files.byName.has(handle.path));
146
- if (outside.length === 0) {
147
- return [];
148
- }
149
- const members = outside.every(empty)
150
- ? held.symbols.filter((one) => one.parent === id).map((one) => one.id)
151
- : [];
152
- return [id, ...(holders?.(id).ids ?? []), ...members];
153
- }),
154
- ),
155
- ];
150
+ const interfaces = new Set<string>();
151
+ const kept = new Set<string>();
152
+ asked.forEach(([id], at) => {
153
+ const symbol = answers[at];
154
+ const outside =
155
+ typeof symbol === "object"
156
+ ? symbol.declarations.filter((handle) => !files.byName.has(handle.path))
157
+ : [];
158
+ if (outside.length === 0) {
159
+ return;
160
+ }
161
+ interfaces.add(id);
162
+ const members = outside.every(empty)
163
+ ? held.symbols.filter((one) => one.parent === id).map((one) => one.id)
164
+ : [];
165
+ for (const one of [id, ...(holders?.(id).ids ?? []), ...members]) {
166
+ kept.add(one);
167
+ }
168
+ });
169
+ return { scripts, interfaces, kept: [...kept] };
156
170
  }
157
171
 
158
172
  /**
@@ -25,7 +25,7 @@ import {
25
25
  type SourceFile,
26
26
  type Statement,
27
27
  } from "@typescript/native/ast";
28
- import type { ParseFile } from "./configuration-files.ts";
28
+ import type { ParseFile } from "./entries/configuration-files.ts";
29
29
  import type { Host } from "./host.ts";
30
30
  import { ancestors, dirnamePath, joinPath, resolvePath } from "./paths.ts";
31
31
  import { entriesOf } from "./fs/tree.ts";