@cplieger/deadset-ts 8.0.0-dev.1 → 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 (276) 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 +181 -341
  5. package/dist/src/augmentations.js +106 -13
  6. package/dist/src/automatic-types.js +10 -29
  7. package/dist/src/build-scripts.js +425 -0
  8. package/dist/src/component-layer.js +4 -2
  9. package/dist/src/components.js +2 -3
  10. package/dist/src/config.js +6 -82
  11. package/dist/src/configuration-files.js +28 -176
  12. package/dist/src/configured-declarations.js +15 -20
  13. package/dist/src/conformance-record.js +1 -1
  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 +73 -3
  20. package/dist/src/conventions.js +36 -66
  21. package/dist/src/dependencies.js +103 -40
  22. package/dist/src/edges.js +38 -122
  23. package/dist/src/element-access.js +4 -6
  24. package/dist/src/entry-point-gaps.js +2 -8
  25. package/dist/src/entry-points.js +11 -27
  26. package/dist/src/enum-group.js +3 -10
  27. package/dist/src/erased-stores.js +4 -6
  28. package/dist/src/exempt-classes.js +1 -63
  29. package/dist/src/exempt.js +21 -40
  30. package/dist/src/failure.js +36 -0
  31. package/dist/src/file-facts.js +2 -25
  32. package/dist/src/findings/completion.js +139 -72
  33. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  34. package/dist/src/findings/emitters.js +5 -5
  35. package/dist/src/findings/interfaces.js +4 -5
  36. package/dist/src/findings/intra-function.js +13 -10
  37. package/dist/src/findings/non-code-artifacts.js +7 -8
  38. package/dist/src/findings/reads-and-writes.js +16 -13
  39. package/dist/src/findings/self-check.js +10 -12
  40. package/dist/src/findings/unused-declarations.js +41 -32
  41. package/dist/src/findings/visibility-narrowing.js +19 -16
  42. package/dist/src/findings-pass.js +8 -15
  43. package/dist/src/framework-lifecycle.js +7 -7
  44. package/dist/src/fs/document.js +52 -0
  45. package/dist/src/fs/manifest.js +72 -0
  46. package/dist/src/fs/tree.js +88 -0
  47. package/dist/src/generated-file.js +7 -4
  48. package/dist/src/git-ignore.js +39 -26
  49. package/dist/src/graph.js +5 -3
  50. package/dist/src/html-entries.js +6 -33
  51. package/dist/src/in-operands.js +2 -1
  52. package/dist/src/index.js +1 -1
  53. package/dist/src/injection-container.js +1 -1
  54. package/dist/src/intra-function-parts.js +63 -43
  55. package/dist/src/inventory.js +2 -21
  56. package/dist/src/javascript-file.js +33 -0
  57. package/dist/src/json-document.js +198 -67
  58. package/dist/src/keyof-comparisons.js +4 -6
  59. package/dist/src/kinds.js +3 -366
  60. package/dist/src/load/classify.js +270 -0
  61. package/dist/src/load/diagnostics.js +80 -0
  62. package/dist/src/load/discover.js +277 -0
  63. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  64. package/dist/src/load/expected-module.js +136 -0
  65. package/dist/src/load/load.js +27 -0
  66. package/dist/src/load/module-lookup.js +37 -0
  67. package/dist/src/load/plan.js +313 -0
  68. package/dist/src/load/specifiers.js +115 -0
  69. package/dist/src/load/synthesize.js +140 -0
  70. package/dist/src/load/test-globals.js +207 -0
  71. package/dist/src/load/test-joins.js +82 -0
  72. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  73. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  74. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +23 -65
  75. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  76. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  77. package/dist/src/manifest.js +49 -54
  78. package/dist/src/matrix.js +76 -4
  79. package/dist/src/mdx-entries.js +3 -26
  80. package/dist/src/outside-tests.js +1 -1
  81. package/dist/src/partial.js +2 -1
  82. package/dist/src/paths.js +26 -15
  83. package/dist/src/position.js +2 -1
  84. package/dist/src/print.js +11 -79
  85. package/dist/src/product.js +13 -0
  86. package/dist/src/query.js +1 -0
  87. package/dist/src/ref.js +1 -0
  88. package/dist/src/references.js +48 -30
  89. package/dist/src/report-schema.js +51 -0
  90. package/dist/src/report.js +57 -41
  91. package/dist/src/reporters/annotations.js +15 -8
  92. package/dist/src/reporters/sarif.js +16 -10
  93. package/dist/src/reporters/template.js +4 -19
  94. package/dist/src/resolve.js +245 -729
  95. package/dist/src/roots.js +273 -87
  96. package/dist/src/run.js +66 -77
  97. package/dist/src/schema.js +320 -343
  98. package/dist/src/scope.js +38 -115
  99. package/dist/src/serialization-contract.js +595 -21
  100. package/dist/src/session.js +34 -29
  101. package/dist/src/source-files.js +1 -1
  102. package/dist/src/suppress-file.js +25 -28
  103. package/dist/src/suppress-inline.js +3 -2
  104. package/dist/src/suppress.js +33 -51
  105. package/dist/src/sweep.js +7 -9
  106. package/dist/src/symbol-keys.js +3 -5
  107. package/dist/src/template-field.js +9 -19
  108. package/dist/src/test-support.js +8 -11
  109. package/dist/src/text/compare.js +26 -0
  110. package/dist/src/text/glob.js +194 -0
  111. package/dist/src/text/named-files.js +54 -0
  112. package/dist/src/text/shell.js +159 -0
  113. package/dist/src/text/yaml.js +393 -0
  114. package/dist/src/type-errors.js +11 -232
  115. package/dist/src/unseen-loads.js +100 -0
  116. package/dist/src/unwrap.js +23 -0
  117. package/dist/src/usage.js +10 -0
  118. package/dist/src/verbs/analyze.js +166 -126
  119. package/dist/src/verbs/describe.js +9 -16
  120. package/dist/src/verbs/explain.js +10 -7
  121. package/dist/src/verbs/print-config.js +2 -1
  122. package/dist/src/verbs/print-projects.js +6 -4
  123. package/dist/src/verbs/print-retained.js +4 -2
  124. package/dist/src/verbs/print-roots.js +4 -2
  125. package/dist/src/verbs/verb.js +1 -5
  126. package/dist/src/verbs/version.js +14 -3
  127. package/dist/src/workflow-steps.js +62 -64
  128. package/jsr.json +1 -1
  129. package/package.json +4 -3
  130. package/src/analysis.ts +245 -502
  131. package/src/augmentations.ts +135 -17
  132. package/src/automatic-types.ts +11 -29
  133. package/src/build-scripts.ts +543 -0
  134. package/src/component-layer.ts +4 -2
  135. package/src/components.ts +2 -4
  136. package/src/config.ts +31 -302
  137. package/src/configuration-files.ts +34 -179
  138. package/src/configured-declarations.ts +18 -23
  139. package/src/conformance-record.ts +1 -1
  140. package/src/consumers.ts +6 -57
  141. package/src/contextual-uses.ts +64 -12
  142. package/src/contract/config.generated.ts +818 -0
  143. package/src/contract/contract.generated.ts +1308 -0
  144. package/src/contract/report.generated.ts +1237 -0
  145. package/src/convention-rows.ts +85 -3
  146. package/src/conventions.ts +46 -84
  147. package/src/dependencies.ts +118 -46
  148. package/src/edges.ts +41 -140
  149. package/src/element-access.ts +4 -7
  150. package/src/entry-point-gaps.ts +3 -9
  151. package/src/entry-points.ts +12 -38
  152. package/src/enum-group.ts +2 -11
  153. package/src/erased-stores.ts +3 -7
  154. package/src/exempt-classes.ts +1 -75
  155. package/src/exempt.ts +36 -50
  156. package/src/failure.ts +63 -0
  157. package/src/file-facts.ts +9 -24
  158. package/src/finding.ts +14 -9
  159. package/src/findings/boundary.ts +2 -0
  160. package/src/findings/completion.ts +181 -84
  161. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  162. package/src/findings/emitter.ts +8 -9
  163. package/src/findings/emitters.ts +7 -7
  164. package/src/findings/interfaces.ts +4 -6
  165. package/src/findings/intra-function.ts +13 -11
  166. package/src/findings/non-code-artifacts.ts +9 -11
  167. package/src/findings/reads-and-writes.ts +20 -16
  168. package/src/findings/self-check.ts +11 -17
  169. package/src/findings/unused-declarations.ts +45 -32
  170. package/src/findings/visibility-narrowing.ts +20 -17
  171. package/src/findings-pass.ts +10 -19
  172. package/src/framework-lifecycle.ts +7 -7
  173. package/src/fs/document.ts +70 -0
  174. package/src/fs/manifest.ts +92 -0
  175. package/src/fs/tree.ts +110 -0
  176. package/src/generated-file.ts +7 -4
  177. package/src/git-ignore.ts +50 -26
  178. package/src/graph.ts +5 -3
  179. package/src/host.ts +12 -5
  180. package/src/html-entries.ts +6 -33
  181. package/src/in-operands.ts +2 -1
  182. package/src/index.ts +1 -1
  183. package/src/injection-container.ts +1 -1
  184. package/src/intra-function-parts.ts +73 -44
  185. package/src/inventory.ts +2 -20
  186. package/src/javascript-file.ts +37 -0
  187. package/src/json-document.ts +241 -76
  188. package/src/keyof-comparisons.ts +3 -7
  189. package/src/kinds.ts +5 -413
  190. package/src/load/classify.ts +397 -0
  191. package/src/load/diagnostics.ts +144 -0
  192. package/src/load/discover.ts +455 -0
  193. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  194. package/src/load/expected-module.ts +188 -0
  195. package/src/load/load.ts +73 -0
  196. package/src/load/module-lookup.ts +50 -0
  197. package/src/load/plan.ts +504 -0
  198. package/src/load/specifiers.ts +168 -0
  199. package/src/load/synthesize.ts +211 -0
  200. package/src/load/test-globals.ts +251 -0
  201. package/src/load/test-joins.ts +98 -0
  202. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  203. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  204. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +33 -76
  205. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  206. package/src/{workspace.ts → load/workspace.ts} +90 -134
  207. package/src/manifest.ts +81 -75
  208. package/src/matrix.ts +122 -4
  209. package/src/mdx-entries.ts +3 -26
  210. package/src/outside-tests.ts +1 -1
  211. package/src/partial.ts +3 -2
  212. package/src/paths.ts +27 -15
  213. package/src/position.ts +2 -1
  214. package/src/print.ts +12 -92
  215. package/src/product.ts +18 -0
  216. package/src/query.ts +11 -0
  217. package/src/ref.ts +1 -0
  218. package/src/references.ts +52 -31
  219. package/src/report-schema.ts +68 -0
  220. package/src/report.ts +101 -224
  221. package/src/reporters/annotations.ts +22 -11
  222. package/src/reporters/json.ts +1 -1
  223. package/src/reporters/reporter.ts +2 -4
  224. package/src/reporters/reporters.ts +1 -1
  225. package/src/reporters/sarif.ts +29 -16
  226. package/src/reporters/template.ts +4 -20
  227. package/src/reporters/text.ts +3 -3
  228. package/src/resolve.ts +283 -1114
  229. package/src/roots.ts +339 -104
  230. package/src/run.ts +75 -91
  231. package/src/schema.ts +391 -388
  232. package/src/scope.ts +46 -138
  233. package/src/serialization-contract.ts +763 -22
  234. package/src/session.ts +70 -54
  235. package/src/source-files.ts +1 -1
  236. package/src/suppress-file.ts +24 -33
  237. package/src/suppress-inline.ts +2 -2
  238. package/src/suppress.ts +43 -58
  239. package/src/sweep.ts +23 -9
  240. package/src/symbol-keys.ts +2 -5
  241. package/src/template-field.ts +15 -25
  242. package/src/test-support.ts +17 -13
  243. package/src/text/compare.ts +27 -0
  244. package/src/text/glob.ts +210 -0
  245. package/src/text/named-files.inputs.json +1522 -0
  246. package/src/text/named-files.ts +68 -0
  247. package/src/text/shell.ts +161 -0
  248. package/src/text/yaml.ts +423 -0
  249. package/src/type-errors.ts +18 -288
  250. package/src/unseen-loads.ts +134 -0
  251. package/src/unwrap.ts +34 -0
  252. package/src/usage.ts +10 -0
  253. package/src/verbs/analyze.ts +224 -162
  254. package/src/verbs/describe.ts +14 -15
  255. package/src/verbs/explain.ts +10 -11
  256. package/src/verbs/print-config.ts +2 -1
  257. package/src/verbs/print-projects.ts +6 -4
  258. package/src/verbs/print-retained.ts +4 -2
  259. package/src/verbs/print-roots.ts +4 -2
  260. package/src/verbs/verb.ts +2 -8
  261. package/src/verbs/version.ts +15 -3
  262. package/src/workflow-steps.ts +74 -64
  263. package/dist/src/base-url.js +0 -18
  264. package/dist/src/discover.js +0 -468
  265. package/dist/src/glob.js +0 -65
  266. package/dist/src/pnpm-workspace.js +0 -120
  267. package/dist/src/setup-failure.js +0 -23
  268. package/dist/src/test-joins.js +0 -101
  269. package/dist/src/version.js +0 -7
  270. package/src/base-url.ts +0 -24
  271. package/src/discover.ts +0 -653
  272. package/src/glob.ts +0 -67
  273. package/src/pnpm-workspace.ts +0 -135
  274. package/src/setup-failure.ts +0 -39
  275. package/src/test-joins.ts +0 -120
  276. package/src/version.ts +0 -7
@@ -1,8 +1,8 @@
1
- import type { Confidence } from "../config.ts";
1
+ import { CODE, type Confidence } from "../contract/contract.generated.ts";
2
2
  import type { Finding } from "../finding.ts";
3
3
  import { KINDS } from "../kinds.ts";
4
4
  import { parameterRef } from "../ref.ts";
5
- import { UNUSED_PARAMETER, UNUSED_RESULT, type PartFact } from "../intra-function-parts.ts";
5
+ import { type PartFact } from "../intra-function-parts.ts";
6
6
  import { reachedWithTheTests } from "../sweep.ts";
7
7
  import type { Emitter, EmitterInput } from "./emitter.ts";
8
8
 
@@ -42,7 +42,8 @@ type ParameterVerdict =
42
42
  * caller may pass a function used as a value more arguments than it declares, so there one
43
43
  * a read parameter follows is renamed to an underscore name, which the compilers read as
44
44
  * declared unread, and one no read parameter follows is deleted: kept where the call's
45
- * inference may read its annotation, at `probable` where nothing reads the annotation.
45
+ * inference may read its annotation, at `probable` where nothing reads the annotation or
46
+ * where it is a name a contextually typed object pattern binds.
46
47
  */
47
48
  function parameterVerdict(
48
49
  part: PartFact,
@@ -63,7 +64,8 @@ function parameterVerdict(
63
64
  if (place?.annotated === "steers") {
64
65
  return undefined;
65
66
  }
66
- return { fix: "delete", confidence: place?.annotated === "free" ? "probable" : "certain" };
67
+ const unseen = place?.annotated === "free" || place?.contextualPattern === true;
68
+ return { fix: "delete", confidence: unseen ? "probable" : "certain" };
67
69
  }
68
70
 
69
71
  /**
@@ -83,9 +85,9 @@ function reported(
83
85
  }
84
86
  const { free, freeButValued, discardedEverywhere } = input.intraFunction;
85
87
  switch (part.code) {
86
- case UNUSED_PARAMETER:
88
+ case CODE.unusedParameter:
87
89
  return parameterVerdict(part, free, freeButValued) !== undefined;
88
- case UNUSED_RESULT:
90
+ case CODE.unusedResult:
89
91
  return (
90
92
  free.has(part.declaration) &&
91
93
  discardedEverywhere.has(part.declaration) &&
@@ -97,7 +99,7 @@ function reported(
97
99
  }
98
100
 
99
101
  /**
100
- * The findings of the intra-function family, `DS1800` to `DS1899`, each about a part of
102
+ * The findings of the inside-functions family, `DS1401` to `DS1406`, each about a part of
101
103
  * the declaration its reference names, at the part's own position, whatever the sweep
102
104
  * decided about a production declaration. A part of test code is reported only where the
103
105
  * run that counts test references reaches its declaration and that is no test of dead
@@ -125,7 +127,7 @@ export const intraFunction: Emitter = (input) => {
125
127
  }),
126
128
  );
127
129
  const { declared, loaded } = input.boundary.consumers;
128
- const closed = input.config.consumersComplete && declared.every((id) => loaded.includes(id));
130
+ const closed = input.config.consumers.complete && declared.every((id) => loaded.includes(id));
129
131
  const published = (id: string): boolean => {
130
132
  const symbol = byId.get(id);
131
133
  return (
@@ -144,12 +146,12 @@ export const intraFunction: Emitter = (input) => {
144
146
  const found: Finding[] = [];
145
147
  for (const part of input.intraFunction.parts) {
146
148
  const declaration = byId.get(part.declaration);
147
- const overlap = KINDS.get(part.code)?.overlap ?? [];
149
+ const overlap = KINDS.get(part.code)?.overlap?.ts ?? [];
148
150
  if (declaration === undefined || !judged(declaration.id) || !reported(input, part, unknown)) {
149
151
  continue;
150
152
  }
151
153
  const verdict =
152
- part.code === UNUSED_PARAMETER
154
+ part.code === CODE.unusedParameter
153
155
  ? parameterVerdict(part, input.intraFunction.free, input.intraFunction.freeButValued)
154
156
  : undefined;
155
157
  const message =
@@ -160,7 +162,7 @@ export const intraFunction: Emitter = (input) => {
160
162
  code: part.code,
161
163
  position: part.position,
162
164
  symbol: {
163
- ...(part.code === UNUSED_PARAMETER
165
+ ...(part.code === CODE.unusedParameter
164
166
  ? { ref: parameterRef(declaration.ref, part.name), holder: declaration.ref }
165
167
  : { ref: declaration.ref }),
166
168
  kind: part.kind,
@@ -1,10 +1,8 @@
1
- import type { Config } from "../config.ts";
1
+ import { CODE } from "../contract/contract.generated.ts";
2
+ import type { ResolvedConfig } from "../config.ts";
2
3
  import type { Finding } from "../finding.ts";
3
4
  import type { Emitter, EmitterInput } from "./emitter.ts";
4
5
 
5
- const FILE_NEVER_BUILT = "DS1501";
6
- const FILE_NEVER_IMPORTED = "DS1502";
7
-
8
6
  /** The subject kind of a finding about a source file, from the finding schema's vocabulary. */
9
7
  const FILE_SUBJECT = "file";
10
8
 
@@ -17,10 +15,10 @@ const FILE_START = 1;
17
15
  * completeness and listing no project declares it of a matrix the run derived, and a
18
16
  * derived matrix is never complete.
19
17
  */
20
- function completeMatrix(config: Config): boolean {
18
+ function completeMatrix(config: ResolvedConfig): boolean {
21
19
  return (
22
- config.analysis.matrixComplete &&
23
- config.analysis.configurations.some((entry) => entry.shape === "project")
20
+ config.analysis.matrix.complete &&
21
+ config.analysis.configurations.some((entry) => "project" in entry)
24
22
  );
25
23
  }
26
24
 
@@ -57,7 +55,7 @@ function fileNeverBuilt({ config, swept, files }: EmitterInput): readonly Findin
57
55
  const message = `no project of the build matrix includes this file (${swept.matrix.configurations.join(", ")})`;
58
56
  return files.tree
59
57
  .filter((file) => !built.has(file.path))
60
- .map((file) => fileFinding(FILE_NEVER_BUILT, file, message));
58
+ .map((file) => fileFinding(CODE.fileNeverBuilt, file, message));
61
59
  }
62
60
 
63
61
  /** The files of the run, each with whether a reference written in another file reaches it. */
@@ -152,21 +150,21 @@ function fileNeverImported(input: EmitterInput): readonly Finding[] {
152
150
  return referenced.has(symbol.position.path)
153
151
  ? {
154
152
  ...fileFinding(
155
- FILE_NEVER_IMPORTED,
153
+ CODE.fileNeverImported,
156
154
  file,
157
155
  "only code that is itself dead imports this file, and no root names it or a declaration in it",
158
156
  ),
159
157
  unreachableOnly: true as const,
160
158
  }
161
159
  : fileFinding(
162
- FILE_NEVER_IMPORTED,
160
+ CODE.fileNeverImported,
163
161
  file,
164
162
  "no import reaches this file and no root names it or a declaration in it",
165
163
  );
166
164
  });
167
165
  }
168
166
 
169
- /** The findings of the non-code-artifacts family, `DS1500` to `DS1599`. */
167
+ /** The findings of the files family, `DS1600` to `DS1699`. */
170
168
  export const nonCodeArtifacts: Emitter = (input) => [
171
169
  ...fileNeverBuilt(input),
172
170
  ...fileNeverImported(input),
@@ -1,17 +1,20 @@
1
+ import { CODE } from "../contract/contract.generated.ts";
1
2
  import type { Finding, FindingDetails, FindingPosition } from "../finding.ts";
2
3
  import type { InventorySymbol } from "../inventory.ts";
3
4
  import type { MatrixCandidate } from "../matrix.ts";
4
5
  import { positionKey } from "../position.ts";
5
6
  import { declarationKey } from "../ref.ts";
6
7
  import type { Emitter, EmitterInput } from "./emitter.ts";
8
+ import { bytewise } from "../text/compare.ts";
7
9
 
8
- /** The codes of this family. */
9
- type ReadsAndWritesCode = "DS1301" | "DS1302" | "DS1303";
10
+ /** The codes this emitter reports. */
11
+ type ReadsAndWritesCode =
12
+ typeof CODE.writeOnlySymbol | typeof CODE.unusedEnumMember | typeof CODE.unusedTypeParameter;
10
13
 
11
- /** The containers whose type parameters `DS1303` reports: a function and a class method. */
12
- const SIGNATURES: ReadonlySet<string> = new Set(["function", "method"]);
14
+ /** The containers whose type parameters `DS1006` reports: a function, a class method and a type alias. */
15
+ const SIGNATURES: ReadonlySet<string> = new Set(["function", "method", "type"]);
13
16
 
14
- /** What the family reads of one run, indexed by declaration. */
17
+ /** What this emitter reads of one run, indexed by declaration. */
15
18
  interface Run {
16
19
  readonly input: EmitterInput;
17
20
  readonly symbols: ReadonlyMap<string, InventorySymbol>;
@@ -121,7 +124,7 @@ function writeOnlyMessage(
121
124
  : "never read";
122
125
  const cascade = [
123
126
  ...parametersOnlyNamedBy(run, namedBy, symbol).map((name) => `type parameter ${name}`),
124
- ...[...held.alone].sort().map((name) => `import ${name}`),
127
+ ...[...held.alone].sort(bytewise).map((name) => `import ${name}`),
125
128
  ];
126
129
  const word = SUBJECT_WORDS[symbol.kind] ?? "member";
127
130
  const message = `${word} ${symbol.name} is written ${writes} and ${read}`;
@@ -185,7 +188,7 @@ function writeOnlySymbols(run: Run): readonly Finding[] {
185
188
  continue;
186
189
  }
187
190
  found.push(
188
- findingAbout(symbol, "DS1301", writeOnlyMessage(run, namedBy, symbol, held), {
191
+ findingAbout(symbol, CODE.writeOnlySymbol, writeOnlyMessage(run, namedBy, symbol, held), {
189
192
  writePositions: held.writes,
190
193
  }),
191
194
  );
@@ -214,21 +217,22 @@ function unnamed(run: Run, kind: InventorySymbol["kind"]): readonly InventorySym
214
217
  }
215
218
 
216
219
  /**
217
- * `DS1302`: a member of an enum declaration that nothing names. A member an enum-group
220
+ * `DS1005`: a member of an enum declaration that nothing names. A member an enum-group
218
221
  * record holds back is no candidate, so a member a conversion can produce never reaches
219
222
  * this kind.
220
223
  */
221
224
  function unusedEnumMembers(run: Run): readonly Finding[] {
222
225
  return unnamed(run, "enum-member").map((symbol) =>
223
- findingAbout(symbol, "DS1302", `enum member ${symbol.name} is named nowhere`),
226
+ findingAbout(symbol, CODE.unusedEnumMember, `enum member ${symbol.name} is named nowhere`),
224
227
  );
225
228
  }
226
229
 
227
230
  /**
228
- * `DS1303`: a type parameter of a function or a class method that neither the
229
- * declaration's signature nor its body names. A type parameter of a class, an interface,
230
- * a type alias or a method signature belongs to a type declaration and is never
231
- * reported, because a phantom parameter makes two instantiations distinct types.
231
+ * `DS1006`: a type parameter of a function, a class method or a type alias that neither
232
+ * the declaration's signature nor its body names. An alias names no type of its own, so
233
+ * a parameter its type never names makes no two instantiations distinct. One of a class,
234
+ * an interface or a method signature is never reported: a class or an interface merges
235
+ * only with declarations of the same parameters.
232
236
  */
233
237
  function unusedTypeParameters(run: Run): readonly Finding[] {
234
238
  return unnamed(run, "type-parameter")
@@ -236,7 +240,7 @@ function unusedTypeParameters(run: Run): readonly Finding[] {
236
240
  .map((symbol) =>
237
241
  findingAbout(
238
242
  symbol,
239
- "DS1303",
243
+ CODE.unusedTypeParameter,
240
244
  `type parameter ${symbol.name} is named in neither its signature nor its body`,
241
245
  ),
242
246
  );
@@ -256,8 +260,8 @@ export function writeOnlyDeclarations(input: EmitterInput): ReadonlySet<string>
256
260
  }
257
261
 
258
262
  /**
259
- * The findings of the reads-and-writes family, `DS1300` to `DS1399`, in code order and
260
- * each code's in site order.
263
+ * The findings of the reads-and-writes kinds, `DS1301`, `DS1005` and `DS1006`, in that
264
+ * order and each code's in site order.
261
265
  */
262
266
  export const readsAndWrites: Emitter = (input) => {
263
267
  const run = indexed(input);
@@ -1,3 +1,4 @@
1
+ import { CODE } from "../contract/contract.generated.ts";
1
2
  import { REPOSITORY_DOCUMENT } from "../config.ts";
2
3
  import type { Finding, FindingDetails, SuppressionEntry } from "../finding.ts";
3
4
  import type { InventorySymbol } from "../inventory.ts";
@@ -6,19 +7,12 @@ import type { Position } from "../position.ts";
6
7
  import {
7
8
  isDependencyCode,
8
9
  isUnsuppressibleCode,
9
- STALE_SUPPRESSION,
10
- SUPPRESSION_WITHOUT_REASON,
11
10
  type Mechanism,
12
11
  type Refusal,
13
12
  type SuppressionRecord,
14
13
  } from "../suppress.ts";
15
14
  import type { Emitter } from "./emitter.ts";
16
-
17
- /** The code a configured root that matches nothing is reported under. */
18
- const UNMATCHED_ROOT = "DS1704";
19
-
20
- /** The code a configured declaration that names nothing is reported under. */
21
- const UNMATCHED_DECLARATION = "DS1706";
15
+ import { bytewise } from "../text/compare.ts";
22
16
 
23
17
  /** The subject kind of a finding about a configured declaration. */
24
18
  const DECLARATION_SUBJECT = "configured-declaration";
@@ -39,7 +33,7 @@ export interface StaleRecord {
39
33
  readonly reports: readonly string[];
40
34
  }
41
35
 
42
- /** What the self-check family reads: the run's refused suppressions and its configured roots. */
36
+ /** What the configuration family reads: the run's refused suppressions and its configured roots. */
43
37
  export interface SelfCheckFacts {
44
38
  /** The suppressions the grammar refused with a finding, in reading order. */
45
39
  readonly refusals: readonly Refusal[];
@@ -135,7 +129,7 @@ function refusedSuppressions(refusals: readonly Refusal[], files: FileRefs): rea
135
129
  suppressionRef(refused.symbol, refused.path, files),
136
130
  refused.site,
137
131
  `${WRITTEN[refused.mechanism]} for ${refused.code} ${
138
- refused.reported === SUPPRESSION_WITHOUT_REASON
132
+ refused.reported === CODE.suppressionWithoutReason
139
133
  ? "carries no reason"
140
134
  : "names a symbol and no path"
141
135
  }`,
@@ -146,7 +140,7 @@ function refusedSuppressions(refusals: readonly Refusal[], files: FileRefs): rea
146
140
 
147
141
  /** One stale suppression as the report's stale-suppression record carries it. */
148
142
  export interface StaleSuppression {
149
- readonly code: typeof STALE_SUPPRESSION;
143
+ readonly code: typeof CODE.staleSuppression;
150
144
  readonly mechanism: Mechanism;
151
145
  readonly entry: {
152
146
  readonly code: string;
@@ -178,10 +172,10 @@ export function staleSuppressions(
178
172
  bySite.set(key, held);
179
173
  }
180
174
  return [...bySite.values()].map(({ first, records }) => {
181
- const codes = [...new Set(records.map((one) => one.record.code))].sort();
175
+ const codes = [...new Set(records.map((one) => one.record.code))].sort(bytewise);
182
176
  const reports = [...new Set(records.flatMap((one) => one.reports))]
183
177
  .filter((code) => !codes.includes(code))
184
- .sort();
178
+ .sort(bytewise);
185
179
  const rows = codes.filter(isUnsuppressibleCode);
186
180
  const dependencies = first.mechanism === "inline" ? codes.filter(isDependencyCode) : [];
187
181
  const settable = rows.filter((code) => !FIXED_SEVERITY_CODES.includes(code));
@@ -209,7 +203,7 @@ export function staleSuppressions(
209
203
  ? ""
210
204
  : `, and ${declared}`;
211
205
  return {
212
- code: STALE_SUPPRESSION,
206
+ code: CODE.staleSuppression,
213
207
  mechanism: first.mechanism,
214
208
  entry: {
215
209
  code: first.code,
@@ -242,7 +236,7 @@ function unmatchedDeclarationFindings(
242
236
  unmatched: readonly UnmatchedDeclaration[],
243
237
  ): readonly Finding[] {
244
238
  return unmatched.map((one) => ({
245
- code: UNMATCHED_DECLARATION,
239
+ code: CODE.unmatchedConfiguredDeclaration,
246
240
  position: documentPosition(one.document),
247
241
  symbol: { ref: one.ref, kind: DECLARATION_SUBJECT, name: one.ref, sizeLines: 1 },
248
242
  message: `${one.key} entry names no declaration in any project`,
@@ -262,7 +256,7 @@ export function unmatchedRootFindings(
262
256
  ): readonly Finding[] {
263
257
  const position = documentPosition(document);
264
258
  return sources.map((source) => ({
265
- code: UNMATCHED_ROOT,
259
+ code: CODE.unmatchedRoot,
266
260
  position,
267
261
  symbol: { ref: source, kind: ROOT_SUBJECT, name: source, sizeLines: 1 },
268
262
  message:
@@ -273,7 +267,7 @@ export function unmatchedRootFindings(
273
267
  }
274
268
 
275
269
  /**
276
- * The findings of the self-check family, `DS1700` to `DS1799`: a suppression refused for
270
+ * The findings of the configuration family, `DS9000` to `DS9099`: a suppression refused for
277
271
  * carrying no reason or naming no path, and a configured root or declaration that named
278
272
  * nothing. A
279
273
  * suppression that matched nothing is a record of the report's stale suppressions, which
@@ -1,7 +1,9 @@
1
+ import { CODE } from "../contract/contract.generated.ts";
1
2
  import type { Finding } from "../finding.ts";
2
3
  import type { InventorySymbol, SymbolKind } from "../inventory.ts";
3
4
  import type { MatrixCandidate } from "../matrix.ts";
4
5
  import type { Emitter, EmitterInput } from "./emitter.ts";
6
+ import { testsUnseenAPI } from "./completion.ts";
5
7
  import { unreachableExports } from "./visibility-narrowing.ts";
6
8
 
7
9
  /** The kinds of declaration that are members of a class, an interface, a type or an enum. */
@@ -13,18 +15,18 @@ const MEMBERS: ReadonlySet<SymbolKind> = new Set([
13
15
  ]);
14
16
 
15
17
  /**
16
- * The kinds of declaration no code of this family reports: an interface and a method an
18
+ * The kinds of declaration no code of this emitter reports: an interface and a method an
17
19
  * interface declares are the interface kinds' subjects, and a type parameter is the
18
20
  * subject of the unused-type-parameter kind or of none.
19
21
  */
20
- const NOT_THIS_FAMILY: ReadonlySet<SymbolKind> = new Set([
22
+ const NOT_REPORTED_HERE: ReadonlySet<SymbolKind> = new Set([
21
23
  "file",
22
24
  "interface",
23
25
  "interface-method",
24
26
  "type-parameter",
25
27
  ]);
26
28
 
27
- /** The reader's word for each kind of declaration a finding of the family names. */
29
+ /** The reader's word for each kind of declaration a finding of this emitter names. */
28
30
  const WORDS: Readonly<Record<SymbolKind, string>> = {
29
31
  file: "file",
30
32
  function: "function",
@@ -55,21 +57,24 @@ interface Judged {
55
57
  readonly deprecated: boolean;
56
58
  /** Whether the unreachable-export kind reports it. */
57
59
  readonly unreachable: boolean;
60
+ /** Whether it is a test with a target that is published API no declared consumer judges. */
61
+ readonly testsUnseenAPI: boolean;
58
62
  }
59
63
 
60
64
  /**
61
65
  * The code one candidate is reported under, or none, each symbol once under the most
62
66
  * specific code: a test of dead code first; no other test-file declaration or enum
63
67
  * member nothing names; a test-support declaration test code references as test-only
64
- * use; then deprecation, a test reference, and the unreferenced codes, an unimportable
65
- * unused export being the unreachable kind's.
68
+ * use; then deprecation, a test reference, or only dead production references beside a
69
+ * test that stays, and the unreferenced codes, an unimportable unused export being the
70
+ * unreachable kind's.
66
71
  */
67
72
  function codeOf(judged: Judged): string | undefined {
68
73
  const { candidate, symbol } = judged;
69
74
  if (candidate.testOfDeadCode) {
70
- return "DS1005";
75
+ return judged.testsUnseenAPI ? undefined : CODE.testOfDeadCode;
71
76
  }
72
- if ((judged.test && !candidate.unreferencedTest) || NOT_THIS_FAMILY.has(symbol.kind)) {
77
+ if ((judged.test && !candidate.unreferencedTest) || NOT_REPORTED_HERE.has(symbol.kind)) {
73
78
  return undefined;
74
79
  }
75
80
  const referenced = candidate.productionRefs + candidate.testRefs > 0;
@@ -80,29 +85,33 @@ function codeOf(judged: Judged): string | undefined {
80
85
  return unreferencedCode(symbol);
81
86
  }
82
87
  if (candidate.heldByTests === candidate.id) {
83
- return "DS1004";
88
+ return CODE.testOnlyUse;
84
89
  }
85
90
  if (candidate.productionRefs === 0 && judged.deprecated) {
86
- return "DS1006";
91
+ return CODE.deprecatedUnused;
87
92
  }
88
- if (candidate.productionRefs === 0 && candidate.testRefs > 0) {
89
- return "DS1004";
93
+ if (
94
+ candidate.testRefs > 0 &&
95
+ (candidate.productionRefs === 0 ||
96
+ (candidate.relation === "reachability" && candidate.keptByTests))
97
+ ) {
98
+ return CODE.testOnlyUse;
90
99
  }
91
100
  if (MEMBERS.has(symbol.kind)) {
92
- return "DS1003";
101
+ return CODE.unusedMember;
93
102
  }
94
103
  if (!symbol.exported) {
95
- return "DS1002";
104
+ return CODE.unusedUnexported;
96
105
  }
97
- return judged.unreachable ? undefined : "DS1001";
106
+ return judged.unreachable ? undefined : CODE.unusedExported;
98
107
  }
99
108
 
100
109
  /** The code a declaration nothing references carries, by its shape and its visibility. */
101
110
  function unreferencedCode(symbol: InventorySymbol): string {
102
111
  if (MEMBERS.has(symbol.kind)) {
103
- return "DS1003";
112
+ return CODE.unusedMember;
104
113
  }
105
- return symbol.exported ? "DS1001" : "DS1002";
114
+ return symbol.exported ? CODE.unusedExported : CODE.unusedUnexported;
106
115
  }
107
116
 
108
117
  /** The visibility a member's message names, where it narrows the member's reach. */
@@ -127,15 +136,17 @@ function messageOf(code: string, judged: Judged): string {
127
136
  const { candidate, symbol } = judged;
128
137
  const word = WORDS[symbol.kind];
129
138
  switch (code) {
130
- case "DS1005":
139
+ case CODE.testOfDeadCode:
131
140
  return TEST_OF_DEAD_CODE;
132
- case "DS1006":
141
+ case CODE.deprecatedUnused:
133
142
  return `deprecated ${word} has no production reference`;
134
- case "DS1004":
135
- return `${word} is referenced only from test files and never from production code`;
143
+ case CODE.testOnlyUse:
144
+ return candidate.productionRefs === 0
145
+ ? `${word} is referenced only from test files and never from production code`
146
+ : `${word} is referenced only from test files and from declarations that are themselves dead`;
136
147
  }
137
148
  const subject =
138
- code === "DS1003"
149
+ code === CODE.unusedMember
139
150
  ? `${visibilityWord(symbol)}${word}`
140
151
  : symbol.kind === "export-alias"
141
152
  ? word
@@ -143,7 +154,7 @@ function messageOf(code: string, judged: Judged): string {
143
154
  if (candidate.relation === "reachability") {
144
155
  return `${subject} is referenced only from declarations that are themselves dead`;
145
156
  }
146
- if (code === "DS1001") {
157
+ if (code === CODE.unusedExported) {
147
158
  return `${subject} has no reference in the target and none from any loaded consumer`;
148
159
  }
149
160
  return `${subject} has no reference in the target`;
@@ -195,25 +206,25 @@ function brandMembers(input: EmitterInput): ReadonlySet<string> {
195
206
  /** The kinds of member a brand is: a data member of a type or of a class. */
196
207
  const BRANDS: ReadonlySet<SymbolKind> = new Set(["type-member", "class-member"]);
197
208
 
198
- /** The findings of the unused-declarations family, `DS1000` to `DS1099`. */
209
+ /** The findings of the unused-declaration kinds, `DS1001` to `DS1004` and `DS1102` to `DS1104`. */
199
210
  export const unusedDeclarations: Emitter = (input) => [
200
- ...familyFindings(input, false),
211
+ ...emitterFindings(input, false),
201
212
  ...unusedImports(input),
202
213
  ];
203
214
 
204
215
  /**
205
- * The import bindings their file never reads, under the unexported code. A generated
206
- * file's are the generator's to remove unless the run includes generated files.
216
+ * The import bindings their file never reads. A generated file's are the generator's to
217
+ * remove unless the run includes generated files.
207
218
  */
208
219
  function unusedImports(input: EmitterInput): Finding[] {
209
220
  const generated =
210
- input.config.analysis.generatedFiles === "include" ? undefined : input.files.generated;
221
+ input.config.analysis.generated_files === "include" ? undefined : input.files.generated;
211
222
  return input.intraFunction.imports.flatMap((binding) =>
212
223
  binding.used || generated?.has(binding.position.path) === true
213
224
  ? []
214
225
  : [
215
226
  {
216
- code: "DS1002",
227
+ code: CODE.unusedImport,
217
228
  position: binding.position,
218
229
  symbol: { ref: binding.ref, kind: "import", name: binding.name, sizeLines: 1 },
219
230
  message: `import binding ${binding.name} is never read in its file`,
@@ -227,13 +238,14 @@ function unusedImports(input: EmitterInput): Finding[] {
227
238
  * a record on such a member is matched against, since the report carries the container's
228
239
  * finding rather than one of the member's own.
229
240
  */
230
- export const fallenMembers: Emitter = (input) => familyFindings(input, true);
241
+ export const fallenMembers: Emitter = (input) => emitterFindings(input, true);
231
242
 
232
- /** The family's findings, or, where `fallen` is set, its dead containers' members' alone. */
233
- function familyFindings(input: EmitterInput, fallen: boolean): Finding[] {
243
+ /** This emitter's findings, or, where `fallen` is set, its dead containers' members' alone. */
244
+ function emitterFindings(input: EmitterInput, fallen: boolean): Finding[] {
234
245
  const union = input.swept.matrix.union;
235
246
  const dead = new Set(input.swept.sweep.candidates.map((candidate) => candidate.id));
236
247
  const unreachable = unreachableExports(input);
248
+ const unseenAPI = testsUnseenAPI(input);
237
249
  let brands: ReadonlySet<string> | undefined;
238
250
 
239
251
  const found: Finding[] = [];
@@ -253,11 +265,12 @@ function familyFindings(input: EmitterInput, fallen: boolean): Finding[] {
253
265
  test: union.test[at] === true,
254
266
  deprecated: input.deprecated.has(symbol.id),
255
267
  unreachable: unreachable.has(symbol.id),
268
+ testsUnseenAPI: candidate.testOfDeadCode && unseenAPI(candidate.id),
256
269
  };
257
270
  const code = codeOf(judged);
258
271
  if (
259
272
  code === undefined ||
260
- (code === "DS1003" && (brands ??= brandMembers(input)).has(symbol.id))
273
+ (code === CODE.unusedMember && (brands ??= brandMembers(input)).has(symbol.id))
261
274
  ) {
262
275
  continue;
263
276
  }
@@ -1,3 +1,4 @@
1
+ import { CODE } from "../contract/contract.generated.ts";
1
2
  import type { Finding } from "../finding.ts";
2
3
  import { OUTSIDE, type Graph } from "../graph.ts";
3
4
  import type { InventorySymbol, SymbolKind } from "../inventory.ts";
@@ -8,10 +9,6 @@ import { runnerCalls } from "../sweep.ts";
8
9
  import type { Emitter, EmitterInput } from "./emitter.ts";
9
10
  import { writeOnlyDeclarations } from "./reads-and-writes.ts";
10
11
 
11
- const UNNECESSARY_EXPORT = "DS1101";
12
- const UNREACHABLE_EXPORT = "DS1103";
13
- const REDUNDANT_EXPORT_KEYWORD = "DS1104";
14
-
15
12
  /** How far the references to one declaration reach, from the narrowest. */
16
13
  type Reach = "file" | "package" | "outside";
17
14
 
@@ -22,7 +19,7 @@ type Reach = "file" | "package" | "outside";
22
19
  */
23
20
  const PUBLISHING: ReadonlySet<RootKind> = new Set<RootKind>(["manifest-entry", "published-api"]);
24
21
 
25
- /** The reader's word for each kind of declaration this family reports. */
22
+ /** The reader's word for each kind of declaration this emitter reports. */
26
23
  const WORDS: Partial<Readonly<Record<SymbolKind, string>>> = {
27
24
  function: "function",
28
25
  class: "class",
@@ -63,6 +60,12 @@ function entersByName(kinds: ReadonlySet<RootKind> | undefined): boolean {
63
60
  return [...(kinds ?? [])].some((kind) => !PUBLISHING.has(kind) && !RUN_ONLY.has(kind));
64
61
  }
65
62
 
63
+ /**
64
+ * The root kinds whose root of a file enters no export by name: a document's import roots
65
+ * each export it imports, so an export it does not import is judged as in any file.
66
+ */
67
+ const PER_NAME: ReadonlySet<RootKind> = new Set<RootKind>(["document-import"]);
68
+
66
69
  /**
67
70
  * Whether the roots of a declaration's file enter it by name: a test runner's root
68
71
  * enters only an export the runner calls, so another export of a test file is judged.
@@ -72,7 +75,7 @@ function fileEntersByName(
72
75
  symbol: InventorySymbol,
73
76
  ): boolean {
74
77
  const entering = [...(kinds ?? [])].filter(
75
- (kind) => !PUBLISHING.has(kind) && !RUN_ONLY.has(kind),
78
+ (kind) => !PUBLISHING.has(kind) && !RUN_ONLY.has(kind) && !PER_NAME.has(kind),
76
79
  );
77
80
  return (
78
81
  entering.some((kind) => kind !== "test-runner") || (entering.length > 0 && runnerCalls(symbol))
@@ -145,8 +148,8 @@ function wordOf(symbol: InventorySymbol): string {
145
148
 
146
149
  /** The visibility each narrowing code names, which only the narrowing codes carry. */
147
150
  const NARROWER: Readonly<Record<string, "file" | "package">> = {
148
- [REDUNDANT_EXPORT_KEYWORD]: "file",
149
- [UNNECESSARY_EXPORT]: "package",
151
+ [CODE.redundantExportKeyword]: "file",
152
+ [CODE.unnecessaryExport]: "package",
150
153
  };
151
154
 
152
155
  function findingOf(symbol: InventorySymbol, code: string, message: string): Finding {
@@ -200,7 +203,7 @@ function narrowing(
200
203
  }
201
204
  return findingOf(
202
205
  symbol,
203
- REDUNDANT_EXPORT_KEYWORD,
206
+ CODE.redundantExportKeyword,
204
207
  `exported ${word} is referenced only inside the file that declares it`,
205
208
  );
206
209
  case "package":
@@ -209,7 +212,7 @@ function narrowing(
209
212
  }
210
213
  return findingOf(
211
214
  symbol,
212
- UNNECESSARY_EXPORT,
215
+ CODE.unnecessaryExport,
213
216
  `exported ${word} is referenced only inside the package that declares it`,
214
217
  );
215
218
  default:
@@ -222,7 +225,7 @@ function narrowing(
222
225
  * export no code outside the target can import, because the manifest declares
223
226
  * `exports` and no root reaches it. Each arm yields to a more specific kind, so one
224
227
  * declaration is reported once: a test whose every subject is dead, an interface, a
225
- * declaration only a test file references, and a deprecated one.
228
+ * declaration only a test file references or a test that stays keeps, and a deprecated one.
226
229
  */
227
230
  function unreachable(
228
231
  facts: Facts,
@@ -237,7 +240,7 @@ function unreachable(
237
240
  (facts.rootedBy[at]?.size ?? 0) > 0 ||
238
241
  candidate.testOfDeadCode ||
239
242
  symbol.kind === "interface" ||
240
- (candidate.productionRefs === 0 && candidate.testRefs > 0) ||
243
+ (candidate.testRefs > 0 && (candidate.productionRefs === 0 || candidate.keptByTests)) ||
241
244
  (candidate.productionRefs === 0 && input.deprecated.has(symbol.id))
242
245
  ) {
243
246
  return undefined;
@@ -248,13 +251,13 @@ function unreachable(
248
251
  : "has no reference in the target";
249
252
  return findingOf(
250
253
  symbol,
251
- UNREACHABLE_EXPORT,
254
+ CODE.unreachableExport,
252
255
  `exported ${wordOf(symbol)} ${found}, and nothing outside can import the file that declares it`,
253
256
  );
254
257
  }
255
258
 
256
259
  /**
257
- * The visibility-narrowing family over one run: `DS1101`, `DS1103` and `DS1104`. A finding
260
+ * The visibility-narrowing kinds over one run: `DS1501`, `DS1101` and `DS1503`. A finding
258
261
  * about a symbol a declared cross-language edge names is reported here like any other, and
259
262
  * the edge's evaluation then holds it pending, because the edge stands for a reference from
260
263
  * outside the file and the package whose use is decided in the other language. A
@@ -263,13 +266,13 @@ function unreachable(
263
266
  export function narrowings(input: EmitterInput): readonly Finding[] {
264
267
  const facts = factsOf(input.swept.matrix.union);
265
268
  const { declared, loaded } = input.boundary.consumers;
266
- const closed = input.config.consumersComplete && declared.every((id) => loaded.includes(id));
269
+ const closed = input.config.consumers.complete && declared.every((id) => loaded.includes(id));
267
270
  const world = { closed, writeOnly: writeOnlyDeclarations(input) };
268
271
  const candidates = new Map(
269
272
  input.swept.sweep.candidates.map((candidate) => [candidate.id, candidate]),
270
273
  );
271
274
  const generated =
272
- input.config.analysis.generatedFiles === "include" ? undefined : input.files.generated;
275
+ input.config.analysis.generated_files === "include" ? undefined : input.files.generated;
273
276
 
274
277
  const findings: Finding[] = [];
275
278
  facts.graph.symbols.forEach((symbol, at) => {
@@ -310,5 +313,5 @@ export function unreachableExports(input: EmitterInput): ReadonlySet<string> {
310
313
  return found;
311
314
  }
312
315
 
313
- /** The findings of the visibility-narrowing family, `DS1100` to `DS1199`. */
316
+ /** The findings of the visibility-narrowing kinds, `DS1501`, `DS1101` and `DS1503`. */
314
317
  export const visibilityNarrowing: Emitter = narrowings;