@cplieger/deadset-ts 7.2.0-dev.4 → 8.0.0-dev.10

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 (288) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/mapper-connection.js +2 -1
  3. package/dist/bin/node-host.js +24 -5
  4. package/dist/src/analysis.js +245 -309
  5. package/dist/src/augmentations.js +124 -18
  6. package/dist/src/automatic-types.js +170 -0
  7. package/dist/src/build-scripts.js +425 -0
  8. package/dist/src/component-layer.js +4 -2
  9. package/dist/src/components.js +9 -9
  10. package/dist/src/config.js +6 -81
  11. package/dist/src/configuration-files.js +78 -188
  12. package/dist/src/configured-declarations.js +15 -20
  13. package/dist/src/conformance-record.js +2 -2
  14. package/dist/src/consumers.js +3 -30
  15. package/dist/src/contextual-uses.js +56 -9
  16. package/dist/src/contract/config.generated.js +558 -0
  17. package/dist/src/contract/contract.generated.js +1244 -0
  18. package/dist/src/contract/report.generated.js +862 -0
  19. package/dist/src/convention-rows.js +146 -1
  20. package/dist/src/conventions.js +136 -70
  21. package/dist/src/decorator.js +21 -18
  22. package/dist/src/dependencies.js +280 -62
  23. package/dist/src/edges.js +38 -122
  24. package/dist/src/element-access.js +4 -6
  25. package/dist/src/entry-point-gaps.js +9 -18
  26. package/dist/src/entry-points.js +106 -21
  27. package/dist/src/enum-group.js +3 -10
  28. package/dist/src/erased-stores.js +4 -6
  29. package/dist/src/exempt-classes.js +1 -63
  30. package/dist/src/exempt.js +21 -40
  31. package/dist/src/failure.js +36 -0
  32. package/dist/src/file-facts.js +2 -25
  33. package/dist/src/findings/completion.js +225 -63
  34. package/dist/src/findings/dependencies-and-module-machinery.js +72 -27
  35. package/dist/src/findings/emitters.js +6 -6
  36. package/dist/src/findings/interfaces.js +4 -5
  37. package/dist/src/findings/intra-function.js +53 -19
  38. package/dist/src/findings/non-code-artifacts.js +71 -39
  39. package/dist/src/findings/reads-and-writes.js +16 -13
  40. package/dist/src/findings/self-check.js +10 -12
  41. package/dist/src/findings/unused-declarations.js +57 -28
  42. package/dist/src/findings/visibility-narrowing.js +40 -18
  43. package/dist/src/findings-pass.js +8 -15
  44. package/dist/src/framework-lifecycle.js +7 -7
  45. package/dist/src/fs/document.js +52 -0
  46. package/dist/src/fs/manifest.js +72 -0
  47. package/dist/src/fs/tree.js +88 -0
  48. package/dist/src/generated-file.js +18 -4
  49. package/dist/src/git-ignore.js +99 -0
  50. package/dist/src/graph.js +9 -4
  51. package/dist/src/html-entries.js +6 -33
  52. package/dist/src/import-bindings.js +97 -0
  53. package/dist/src/in-operands.js +2 -1
  54. package/dist/src/index.js +1 -1
  55. package/dist/src/indexed-access.js +130 -28
  56. package/dist/src/injection-container.js +1 -1
  57. package/dist/src/interface-satisfaction.js +30 -12
  58. package/dist/src/intra-function-parts.js +341 -69
  59. package/dist/src/inventory.js +54 -29
  60. package/dist/src/javascript-file.js +33 -0
  61. package/dist/src/json-document.js +198 -67
  62. package/dist/src/keyof-comparisons.js +4 -6
  63. package/dist/src/kinds.js +3 -366
  64. package/dist/src/load/classify.js +270 -0
  65. package/dist/src/load/diagnostics.js +80 -0
  66. package/dist/src/load/discover.js +277 -0
  67. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  68. package/dist/src/load/expected-module.js +136 -0
  69. package/dist/src/load/load.js +27 -0
  70. package/dist/src/load/module-lookup.js +37 -0
  71. package/dist/src/load/plan.js +313 -0
  72. package/dist/src/load/specifiers.js +115 -0
  73. package/dist/src/load/synthesize.js +140 -0
  74. package/dist/src/load/test-globals.js +207 -0
  75. package/dist/src/load/test-joins.js +82 -0
  76. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  77. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +88 -61
  78. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +60 -59
  79. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  80. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  81. package/dist/src/manifest.js +49 -54
  82. package/dist/src/matrix.js +94 -13
  83. package/dist/src/mdx-entries.js +174 -0
  84. package/dist/src/module-declarations.js +9 -13
  85. package/dist/src/outside-tests.js +1 -1
  86. package/dist/src/overrides.js +41 -10
  87. package/dist/src/partial.js +2 -1
  88. package/dist/src/paths.js +26 -15
  89. package/dist/src/position.js +2 -1
  90. package/dist/src/print.js +11 -78
  91. package/dist/src/product.js +13 -0
  92. package/dist/src/query.js +1 -0
  93. package/dist/src/ref.js +11 -0
  94. package/dist/src/references.js +52 -31
  95. package/dist/src/report-schema.js +51 -0
  96. package/dist/src/report.js +59 -41
  97. package/dist/src/reporters/annotations.js +15 -8
  98. package/dist/src/reporters/sarif.js +16 -10
  99. package/dist/src/reporters/template.js +4 -19
  100. package/dist/src/resolve.js +245 -727
  101. package/dist/src/roots.js +374 -116
  102. package/dist/src/run.js +66 -77
  103. package/dist/src/schema.js +320 -342
  104. package/dist/src/scope.js +38 -115
  105. package/dist/src/serialization-contract.js +649 -29
  106. package/dist/src/session.js +41 -29
  107. package/dist/src/source-files.js +40 -15
  108. package/dist/src/suppress-file.js +34 -29
  109. package/dist/src/suppress-inline.js +21 -4
  110. package/dist/src/suppress.js +40 -56
  111. package/dist/src/sweep.js +32 -17
  112. package/dist/src/symbol-keys.js +105 -6
  113. package/dist/src/template-field.js +9 -19
  114. package/dist/src/test-support.js +119 -18
  115. package/dist/src/text/compare.js +26 -0
  116. package/dist/src/text/glob.js +194 -0
  117. package/dist/src/text/named-files.js +54 -0
  118. package/dist/src/text/shell.js +159 -0
  119. package/dist/src/text/yaml.js +393 -0
  120. package/dist/src/type-errors.js +27 -221
  121. package/dist/src/type-parameter-reads.js +172 -0
  122. package/dist/src/unseen-loads.js +100 -0
  123. package/dist/src/unwrap.js +23 -0
  124. package/dist/src/usage.js +10 -0
  125. package/dist/src/verbs/analyze.js +181 -125
  126. package/dist/src/verbs/describe.js +9 -16
  127. package/dist/src/verbs/explain.js +14 -9
  128. package/dist/src/verbs/print-config.js +2 -1
  129. package/dist/src/verbs/print-projects.js +6 -4
  130. package/dist/src/verbs/print-retained.js +4 -2
  131. package/dist/src/verbs/print-roots.js +4 -2
  132. package/dist/src/verbs/verb.js +1 -5
  133. package/dist/src/verbs/version.js +14 -3
  134. package/dist/src/workflow-steps.js +128 -33
  135. package/jsr.json +1 -1
  136. package/package.json +5 -4
  137. package/src/analysis.ts +333 -457
  138. package/src/augmentations.ts +152 -23
  139. package/src/automatic-types.ts +228 -0
  140. package/src/build-scripts.ts +543 -0
  141. package/src/component-layer.ts +4 -2
  142. package/src/components.ts +9 -10
  143. package/src/config.ts +31 -299
  144. package/src/configuration-files.ts +100 -191
  145. package/src/configured-declarations.ts +18 -23
  146. package/src/conformance-record.ts +2 -2
  147. package/src/consumers.ts +6 -57
  148. package/src/contextual-uses.ts +64 -12
  149. package/src/contract/config.generated.ts +818 -0
  150. package/src/contract/contract.generated.ts +1308 -0
  151. package/src/contract/report.generated.ts +1237 -0
  152. package/src/convention-rows.ts +186 -1
  153. package/src/conventions.ts +166 -90
  154. package/src/decorator.ts +28 -18
  155. package/src/dependencies.ts +356 -78
  156. package/src/edges.ts +41 -140
  157. package/src/element-access.ts +4 -7
  158. package/src/entry-point-gaps.ts +11 -20
  159. package/src/entry-points.ts +124 -28
  160. package/src/enum-group.ts +2 -11
  161. package/src/erased-stores.ts +3 -7
  162. package/src/exempt-classes.ts +1 -75
  163. package/src/exempt.ts +36 -50
  164. package/src/failure.ts +63 -0
  165. package/src/file-facts.ts +9 -24
  166. package/src/finding.ts +24 -9
  167. package/src/findings/boundary.ts +2 -0
  168. package/src/findings/completion.ts +297 -77
  169. package/src/findings/dependencies-and-module-machinery.ts +90 -31
  170. package/src/findings/emitter.ts +8 -9
  171. package/src/findings/emitters.ts +8 -8
  172. package/src/findings/interfaces.ts +4 -6
  173. package/src/findings/intra-function.ts +64 -20
  174. package/src/findings/non-code-artifacts.ts +88 -50
  175. package/src/findings/reads-and-writes.ts +20 -16
  176. package/src/findings/self-check.ts +11 -17
  177. package/src/findings/unused-declarations.ts +65 -28
  178. package/src/findings/visibility-narrowing.ts +51 -19
  179. package/src/findings-pass.ts +10 -19
  180. package/src/framework-lifecycle.ts +7 -7
  181. package/src/fs/document.ts +70 -0
  182. package/src/fs/manifest.ts +92 -0
  183. package/src/fs/tree.ts +110 -0
  184. package/src/generated-file.ts +23 -4
  185. package/src/git-ignore.ts +122 -0
  186. package/src/graph.ts +11 -3
  187. package/src/host.ts +17 -14
  188. package/src/html-entries.ts +6 -33
  189. package/src/import-bindings.ts +128 -0
  190. package/src/in-operands.ts +2 -1
  191. package/src/index.ts +1 -1
  192. package/src/indexed-access.ts +152 -30
  193. package/src/injection-container.ts +1 -1
  194. package/src/interface-satisfaction.ts +33 -13
  195. package/src/intra-function-parts.ts +449 -85
  196. package/src/inventory.ts +73 -27
  197. package/src/javascript-file.ts +37 -0
  198. package/src/json-document.ts +241 -76
  199. package/src/keyof-comparisons.ts +3 -7
  200. package/src/kinds.ts +5 -413
  201. package/src/load/classify.ts +397 -0
  202. package/src/load/diagnostics.ts +144 -0
  203. package/src/load/discover.ts +455 -0
  204. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  205. package/src/load/expected-module.ts +188 -0
  206. package/src/load/load.ts +73 -0
  207. package/src/load/module-lookup.ts +50 -0
  208. package/src/load/plan.ts +504 -0
  209. package/src/load/specifiers.ts +168 -0
  210. package/src/load/synthesize.ts +211 -0
  211. package/src/load/test-globals.ts +251 -0
  212. package/src/load/test-joins.ts +98 -0
  213. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  214. package/src/{workspace-programs.ts → load/workspace-programs.ts} +127 -80
  215. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +73 -64
  216. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  217. package/src/{workspace.ts → load/workspace.ts} +90 -134
  218. package/src/manifest.ts +81 -75
  219. package/src/matrix.ts +154 -18
  220. package/src/mdx-entries.ts +218 -0
  221. package/src/module-declarations.ts +11 -13
  222. package/src/outside-tests.ts +1 -1
  223. package/src/overrides.ts +51 -12
  224. package/src/partial.ts +3 -2
  225. package/src/paths.ts +27 -15
  226. package/src/position.ts +2 -1
  227. package/src/print.ts +12 -91
  228. package/src/product.ts +18 -0
  229. package/src/query.ts +11 -0
  230. package/src/ref.ts +13 -0
  231. package/src/references.ts +62 -32
  232. package/src/report-schema.ts +68 -0
  233. package/src/report.ts +105 -215
  234. package/src/reporters/annotations.ts +22 -11
  235. package/src/reporters/json.ts +1 -1
  236. package/src/reporters/reporter.ts +2 -4
  237. package/src/reporters/reporters.ts +1 -1
  238. package/src/reporters/sarif.ts +29 -16
  239. package/src/reporters/template.ts +4 -20
  240. package/src/reporters/text.ts +3 -3
  241. package/src/resolve.ts +283 -1111
  242. package/src/roots.ts +490 -137
  243. package/src/run.ts +75 -91
  244. package/src/schema.ts +391 -387
  245. package/src/scope.ts +46 -138
  246. package/src/serialization-contract.ts +818 -26
  247. package/src/session.ts +77 -54
  248. package/src/source-files.ts +67 -17
  249. package/src/suppress-file.ts +36 -34
  250. package/src/suppress-inline.ts +20 -3
  251. package/src/suppress.ts +52 -63
  252. package/src/sweep.ts +53 -18
  253. package/src/symbol-keys.ts +131 -7
  254. package/src/template-field.ts +15 -25
  255. package/src/test-support.ts +155 -18
  256. package/src/text/compare.ts +27 -0
  257. package/src/text/glob.ts +210 -0
  258. package/src/text/named-files.inputs.json +1522 -0
  259. package/src/text/named-files.ts +68 -0
  260. package/src/text/shell.ts +161 -0
  261. package/src/text/yaml.ts +423 -0
  262. package/src/type-errors.ts +35 -273
  263. package/src/type-parameter-reads.ts +227 -0
  264. package/src/unseen-loads.ts +134 -0
  265. package/src/unwrap.ts +34 -0
  266. package/src/usage.ts +10 -0
  267. package/src/verbs/analyze.ts +245 -161
  268. package/src/verbs/describe.ts +14 -15
  269. package/src/verbs/explain.ts +15 -13
  270. package/src/verbs/print-config.ts +2 -1
  271. package/src/verbs/print-projects.ts +6 -4
  272. package/src/verbs/print-retained.ts +4 -2
  273. package/src/verbs/print-roots.ts +4 -2
  274. package/src/verbs/verb.ts +2 -8
  275. package/src/verbs/version.ts +15 -3
  276. package/src/workflow-steps.ts +149 -34
  277. package/dist/src/discover.js +0 -347
  278. package/dist/src/glob.js +0 -65
  279. package/dist/src/pnpm-workspace.js +0 -120
  280. package/dist/src/setup-failure.js +0 -23
  281. package/dist/src/test-joins.js +0 -101
  282. package/dist/src/version.js +0 -7
  283. package/src/discover.ts +0 -510
  284. package/src/glob.ts +0 -67
  285. package/src/pnpm-workspace.ts +0 -135
  286. package/src/setup-failure.ts +0 -39
  287. package/src/test-joins.ts +0 -120
  288. package/src/version.ts +0 -7
package/src/references.ts CHANGED
@@ -15,7 +15,10 @@ import {
15
15
  isIdentifier,
16
16
  isImportDeclaration,
17
17
  isImportEqualsDeclaration,
18
+ isInterfaceDeclaration,
18
19
  isMetaProperty,
20
+ isModuleBlock,
21
+ isModuleDeclaration,
19
22
  isNewExpression,
20
23
  isNamespaceExport,
21
24
  isNoSubstitutionTemplateLiteral,
@@ -35,13 +38,13 @@ import {
35
38
  type ParameterDeclaration,
36
39
  type SourceFile,
37
40
  } from "@typescript/native/ast";
41
+ import { parenthesesRemoved } from "./unwrap.ts";
38
42
  import type { Symbol as TSSymbol } from "@typescript/native/sync";
39
43
  import { aliasChains, type ChainTarget } from "./alias-chain.ts";
40
44
  import { contextualUses, type FlowAt, type LiteralAt } from "./contextual-uses.ts";
41
45
  import { destructuring, propertyReadsOf, type PropertyRead } from "./destructuring.ts";
42
46
  import { specifierCandidates } from "./configuration-files.ts";
43
47
  import { namespaceUses } from "./namespace-objects.ts";
44
- import { globExpression } from "./glob.ts";
45
48
  import {
46
49
  declarationsByName,
47
50
  isParameterProperty,
@@ -49,7 +52,7 @@ import {
49
52
  type Inventory,
50
53
  type InventorySymbol,
51
54
  } from "./inventory.ts";
52
- import { augmentationReferences } from "./augmentations.ts";
55
+ import { ambientGlobalInterfaces, augmentationReferences } from "./augmentations.ts";
53
56
  import { elementAccessReferences } from "./element-access.ts";
54
57
  import { indexedAccessReferences } from "./indexed-access.ts";
55
58
  import { keyofComparisonReferences } from "./keyof-comparisons.ts";
@@ -60,9 +63,18 @@ import { dirnamePath, queriedModulePath, relativePath, resolvePath } from "./pat
60
63
  import { byPosition, isComponentFile, renderPosition, type Position } from "./position.ts";
61
64
  import { DEFAULT_BATCH_CAP, propertyTables, UNANSWERED, type Answer } from "./query.ts";
62
65
  import type { ProjectView } from "./session.ts";
66
+ import { typeParameterReads } from "./type-parameter-reads.ts";
63
67
  import { typeQueryAliases } from "./type-query-alias.ts";
64
- import { computedKeyNames, keyNameOf, keyedUses, type KeyedAccess } from "./symbol-keys.ts";
68
+ import {
69
+ computedKeyNames,
70
+ iterationReferences,
71
+ keyNameOf,
72
+ keyedUses,
73
+ type KeyedAccess,
74
+ } from "./symbol-keys.ts";
65
75
  import { handedOn, valuesOf } from "./value-flow.ts";
76
+ import { bytewise } from "./text/compare.ts";
77
+ import { globExpression } from "./text/glob.ts";
66
78
 
67
79
  /**
68
80
  * Every use one project's own files make of the project's own declarations.
@@ -305,15 +317,6 @@ function isName(node: Node): boolean {
305
317
  return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PrivateIdentifier;
306
318
  }
307
319
 
308
- /** The expression one node is, through however many parentheses are written around it. */
309
- function unparenthesized(node: Node): Node {
310
- let held = node;
311
- while (isParenthesizedExpression(held)) {
312
- held = held.expression;
313
- }
314
- return held;
315
- }
316
-
317
320
  /**
318
321
  * Records the name one store writes into.
319
322
  *
@@ -323,7 +326,7 @@ function unparenthesized(node: Node): Node {
323
326
  * target writes each name it binds, through its spreads and nested patterns.
324
327
  */
325
328
  function markWrite(target: Node, writes: Set<number>, accesses: Set<Node>): void {
326
- const held = unparenthesized(target);
329
+ const held = parenthesesRemoved(target);
327
330
  if (isName(held)) {
328
331
  writes.add(held.pos);
329
332
  return;
@@ -338,7 +341,7 @@ function markWrite(target: Node, writes: Set<number>, accesses: Set<Node>): void
338
341
  accesses.add(held);
339
342
  // A store through a member's value lands in storage every holder of the value
340
343
  // reads, so it reads the member; a variable only ever stored into stays written.
341
- if (!isPropertyAccessExpression(unparenthesized(held.expression))) {
344
+ if (!isPropertyAccessExpression(parenthesesRemoved(held.expression))) {
342
345
  markWrite(held.expression, writes, accesses);
343
346
  }
344
347
  return;
@@ -514,7 +517,7 @@ interface FileSites {
514
517
 
515
518
  /** Whether one node is `import.meta.url`. */
516
519
  function isImportMetaURL(node: Node): boolean {
517
- const at = unparenthesized(node);
520
+ const at = parenthesesRemoved(node);
518
521
  return (
519
522
  isPropertyAccessExpression(at) &&
520
523
  isMetaProperty(at.expression) &&
@@ -526,7 +529,7 @@ function isImportMetaURL(node: Node): boolean {
526
529
  /** The module URL one node builds, where it builds one. */
527
530
  function moduleURLOf(node: Node): ModuleURL | undefined {
528
531
  const relative = (argument: Node | undefined): string | undefined => {
529
- const at = argument === undefined ? undefined : unparenthesized(argument);
532
+ const at = argument === undefined ? undefined : parenthesesRemoved(argument);
530
533
  return at !== undefined &&
531
534
  (isStringLiteral(at) || isNoSubstitutionTemplateLiteral(at)) &&
532
535
  /^\.\.?\//u.test(at.text)
@@ -541,7 +544,7 @@ function moduleURLOf(node: Node): ModuleURL | undefined {
541
544
  : undefined;
542
545
  }
543
546
  if (isCallExpression(node)) {
544
- const callee = unparenthesized(node.expression);
547
+ const callee = parenthesesRemoved(node.expression);
545
548
  const specifier = relative(node.arguments[0]);
546
549
  if (
547
550
  specifier !== undefined &&
@@ -859,7 +862,7 @@ export function testFileRulesOf(
859
862
  };
860
863
  }),
861
864
  ...(support === 0 ? [] : [{ rule: TEST_SUPPORT_RULE, matched: support }]),
862
- ].sort((a, b) => compare(a.rule, b.rule));
865
+ ].sort((a, b) => bytewise(a.rule, b.rule));
863
866
  }
864
867
 
865
868
  const importedCache = new WeakMap<
@@ -993,7 +996,7 @@ function aloneIn(
993
996
  nodes.every((node) => sameTarget.some((one) => inside(node, one.value))),
994
997
  )
995
998
  .map(([name]) => name)
996
- .sort(compare);
999
+ .sort(bytewise);
997
1000
  if (names.length > 0) {
998
1001
  result.push({ index: write.index, names });
999
1002
  }
@@ -1001,14 +1004,6 @@ function aloneIn(
1001
1004
  return result;
1002
1005
  }
1003
1006
 
1004
- /** Two strings ordered bytewise, which is the order every set of a run is read in. */
1005
- function compare(a: string, b: string): number {
1006
- if (a === b) {
1007
- return 0;
1008
- }
1009
- return a < b ? -1 : 1;
1010
- }
1011
-
1012
1007
  /**
1013
1008
  * Every reference one project's own files make to the project's own declarations, in
1014
1009
  * position order, and the files the test-file rules classified.
@@ -1603,6 +1598,39 @@ export function references<Brand>(
1603
1598
  }
1604
1599
  }
1605
1600
 
1601
+ /** The ambient global interfaces of the walked files that merge into a declaration outside the project's own files. */
1602
+ const libraryMerged = (scripts: ReadonlySet<string>): ReadonlySet<string> => {
1603
+ const names = new Map<string, Node>();
1604
+ const visit = (node: Node): void => {
1605
+ if (isInterfaceDeclaration(node)) {
1606
+ const id = declaredAt(node);
1607
+ if (id !== undefined) {
1608
+ names.set(id, node.name);
1609
+ }
1610
+ } else if (isModuleDeclaration(node) || isModuleBlock(node)) {
1611
+ node.forEachChild(visit);
1612
+ }
1613
+ };
1614
+ for (const { file } of walked) {
1615
+ file.forEachChild(visit);
1616
+ }
1617
+ const global = new Set(ambientGlobalInterfaces(held, [...names.keys()], scripts));
1618
+ const asked = [...names].filter(([id]) => global.has(id));
1619
+ if (asked.length === 0) {
1620
+ return new Set();
1621
+ }
1622
+ const answers = project.symbolsAt(asked.map(([, name]) => project.handle(name)));
1623
+ return new Set(
1624
+ asked.flatMap(([id], at) => {
1625
+ const symbol = answers[at];
1626
+ return typeof symbol === "object" &&
1627
+ symbol.declarations.some((handle) => !ownPaths.has(handle.path))
1628
+ ? [id]
1629
+ : [];
1630
+ }),
1631
+ );
1632
+ };
1633
+
1606
1634
  const usesOf = new Map(walked.map((one) => [one.file, one.uses]));
1607
1635
  for (const [file, writes] of valued) {
1608
1636
  const uses = usesOf.get(file) ?? [];
@@ -1621,6 +1649,8 @@ export function references<Brand>(
1621
1649
  found.push(...indexedAccessReferences(project, held, chains, root, new Set(tests)));
1622
1650
  found.push(...elementAccessReferences(project, held, chains, root, new Set(tests)));
1623
1651
  found.push(...keyofComparisonReferences(project, held, chains, root, new Set(tests)));
1652
+ found.push(...iterationReferences(project, held, chains, root, new Set(tests)));
1653
+ found.push(...typeParameterReads(project, held, chains, root, new Set(tests)));
1624
1654
  found.push(...unimplementedCalleeReads(project, held, chains, root, new Set(tests)));
1625
1655
  found.push(...moduleDeclarationReferences(project, held, root, new Set(tests)));
1626
1656
  typedLookups = (options.requestCount?.() ?? 0) - before;
@@ -1628,13 +1658,13 @@ export function references<Brand>(
1628
1658
  const scripts = new Set(
1629
1659
  walked.filter((one) => one.file.externalModuleIndicator === undefined).map((one) => one.fileId),
1630
1660
  );
1631
- found.push(...augmentationReferences(held, found, scripts));
1661
+ found.push(...augmentationReferences(held, found, scripts, libraryMerged(scripts)));
1632
1662
  found.sort(
1633
1663
  (a, b) =>
1634
1664
  byPosition(a.position, b.position) ||
1635
- compare(a.to, b.to) ||
1636
- compare(a.from, b.from) ||
1637
- compare(a.use, b.use),
1665
+ bytewise(a.to, b.to) ||
1666
+ bytewise(a.from, b.from) ||
1667
+ bytewise(a.use, b.use),
1638
1668
  );
1639
1669
 
1640
1670
  return {
@@ -1642,7 +1672,7 @@ export function references<Brand>(
1642
1672
  consumer === undefined
1643
1673
  ? found
1644
1674
  : found.map((reference) => ({ ...reference, consumer: consumer.id })),
1645
- testFilePaths: tests.sort(compare),
1675
+ testFilePaths: tests.sort(bytewise),
1646
1676
  cost: {
1647
1677
  batched,
1648
1678
  fileBatches,
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Holds a report to `contract/report.schema.json` and `contract/finding.schema.json`
3
+ * before it is written, reading the schemas the generator copies from the Contract, so
4
+ * this analyzer never writes a document a reader refuses.
5
+ */
6
+
7
+ import { REPORT_SCHEMAS, type Report } from "./contract/report.generated.ts";
8
+ import { schemaRefusals, type SchemaRefusal } from "./schema.ts";
9
+
10
+ const reportSchema = schemaRefusals(REPORT_SCHEMAS, "report.schema.json");
11
+
12
+ /**
13
+ * What the report schema refuses in one report document, none for an instance, and, as
14
+ * no schema keyword can state it, a components listing that is not one entry per
15
+ * component a finding or an edge evaluation's finding names.
16
+ */
17
+ export function reportRefusals(document: unknown): readonly SchemaRefusal[] {
18
+ const found = reportSchema(document);
19
+ return found.length > 0 ? found : listingRefusals(document as Report);
20
+ }
21
+
22
+ /** The components listing held to the components the findings name, once each. */
23
+ function listingRefusals(report: Report): readonly SchemaRefusal[] {
24
+ if (report.components === undefined) {
25
+ return [];
26
+ }
27
+ const refuse = (pointer: string, reason: string): SchemaRefusal[] => [
28
+ { pointer, keyword: "components", reason, member: "" },
29
+ ];
30
+ const listed = new Set<string>();
31
+ for (const [i, entry] of report.components.entries()) {
32
+ if (listed.has(entry.id)) {
33
+ return refuse(
34
+ `/components/${String(i)}`,
35
+ `the entry lists component ${entry.id} a second time`,
36
+ );
37
+ }
38
+ listed.add(entry.id);
39
+ }
40
+ const named = [
41
+ ...report.findings.map(
42
+ (finding, i) => [`/findings/${String(i)}`, finding.component.id] as const,
43
+ ),
44
+ ...report.edge_evaluations.flatMap((one, i) =>
45
+ one.finding === undefined
46
+ ? []
47
+ : [[`/edge_evaluations/${String(i)}/finding`, one.finding.component.id] as const],
48
+ ),
49
+ ];
50
+ for (const [pointer, id] of named) {
51
+ if (!listed.has(id)) {
52
+ return refuse(
53
+ pointer,
54
+ `the finding names component ${id}, which the components listing lacks`,
55
+ );
56
+ }
57
+ }
58
+ const ids = new Set(named.map(([, id]) => id));
59
+ for (const [i, entry] of report.components.entries()) {
60
+ if (!ids.has(entry.id)) {
61
+ return refuse(
62
+ `/components/${String(i)}`,
63
+ `the entry lists component ${entry.id}, which no finding names`,
64
+ );
65
+ }
66
+ }
67
+ return [];
68
+ }