@cplieger/deadset-ts 7.0.0-dev.1 → 7.0.0-dev.2

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 (77) hide show
  1. package/dist/src/analysis.js +6 -16
  2. package/dist/src/component-layer.js +1 -1
  3. package/dist/src/configuration-files.js +227 -27
  4. package/dist/src/contextual-uses.js +41 -7
  5. package/dist/src/convention-rows.js +6 -0
  6. package/dist/src/conventions.js +32 -0
  7. package/dist/src/dependencies.js +12 -8
  8. package/dist/src/discover.js +1 -1
  9. package/dist/src/edges.js +1 -1
  10. package/dist/src/exempt-classes.js +9 -22
  11. package/dist/src/exempt.js +3 -15
  12. package/dist/src/findings/completion.js +35 -4
  13. package/dist/src/findings/emitters.js +0 -4
  14. package/dist/src/findings/self-check.js +14 -10
  15. package/dist/src/indexed-access.js +8 -2
  16. package/dist/src/inventory.js +3 -12
  17. package/dist/src/references.js +2 -2
  18. package/dist/src/report.js +3 -0
  19. package/dist/src/roots.js +0 -1
  20. package/dist/src/run.js +0 -2
  21. package/dist/src/schema.js +1 -1
  22. package/dist/src/scope.js +2 -2
  23. package/dist/src/session.js +0 -1
  24. package/dist/src/suppress-inline.js +1 -1
  25. package/dist/src/suppress.js +15 -16
  26. package/dist/src/workspace-programs.js +0 -3
  27. package/dist/src/workspace-resolution.js +0 -2
  28. package/dist/src/workspace.js +0 -3
  29. package/jsr.json +1 -1
  30. package/package.json +2 -1
  31. package/src/analysis.ts +10 -30
  32. package/src/calls.ts +3 -3
  33. package/src/component-files.ts +7 -7
  34. package/src/component-layer.ts +2 -2
  35. package/src/components.ts +1 -1
  36. package/src/config.ts +4 -4
  37. package/src/configuration-files.ts +246 -28
  38. package/src/contextual-uses.ts +63 -9
  39. package/src/convention-rows.ts +19 -0
  40. package/src/conventions.ts +43 -0
  41. package/src/dependencies.ts +14 -10
  42. package/src/discover.ts +3 -3
  43. package/src/edges.ts +3 -3
  44. package/src/entry-points.ts +1 -1
  45. package/src/exempt-classes.ts +10 -24
  46. package/src/exempt.ts +5 -29
  47. package/src/file-facts.ts +1 -1
  48. package/src/finding.ts +3 -1
  49. package/src/findings/completion.ts +46 -4
  50. package/src/findings/emitters.ts +3 -8
  51. package/src/findings/self-check.ts +17 -14
  52. package/src/findings-pass.ts +2 -2
  53. package/src/graph.ts +2 -2
  54. package/src/html-entries.ts +1 -1
  55. package/src/indexed-access.ts +10 -2
  56. package/src/inventory.ts +5 -33
  57. package/src/json-document.ts +1 -1
  58. package/src/manifest.ts +1 -1
  59. package/src/namespace-objects.ts +1 -1
  60. package/src/pnpm-workspace.ts +1 -1
  61. package/src/references.ts +7 -6
  62. package/src/report.ts +8 -4
  63. package/src/roots.ts +0 -3
  64. package/src/run.ts +0 -2
  65. package/src/schema.ts +2 -2
  66. package/src/scope.ts +2 -2
  67. package/src/session.ts +0 -2
  68. package/src/stores.ts +1 -1
  69. package/src/suppress-inline.ts +3 -3
  70. package/src/suppress.ts +21 -24
  71. package/src/template-field.ts +1 -1
  72. package/src/value-reach.ts +1 -1
  73. package/src/verbs/verb.ts +1 -4
  74. package/src/workspace-programs.ts +2 -9
  75. package/src/workspace-resolution.ts +0 -3
  76. package/src/workspace-run.ts +1 -1
  77. package/src/workspace.ts +1 -9
package/src/suppress.ts CHANGED
@@ -65,9 +65,6 @@ export interface Suppressions {
65
65
  readonly refusals: readonly Refusal[];
66
66
  }
67
67
 
68
- /** A target that carries no suppression. */
69
- export const NO_SUPPRESSIONS: Suppressions = { records: [], refusals: [] };
70
-
71
68
  /**
72
69
  * A directive, an entry or a document the grammar refuses before any finding exists: an
73
70
  * instruction the analysis cannot carry out. It is a malformed input, so the command line
@@ -151,27 +148,26 @@ export interface Dials<F extends Finding = Finding> {
151
148
  }
152
149
 
153
150
  /** What every record did, and the findings the records withhold. */
154
- export interface Ledger<F extends Finding = Finding> {
151
+ export interface Ledger {
155
152
  /** One verdict per record, in reading order. */
156
153
  readonly verdicts: readonly Verdict[];
157
- /** Per record, the finding it claimed, where it claimed one. */
158
- readonly claims: readonly (F | undefined)[];
159
154
  /** Whether a record withholds one finding of the run. */
160
155
  readonly withheld: (finding: Finding) => boolean;
161
156
  }
162
157
 
163
158
  /**
164
- * The subject kinds that are a row of a document rather than a declaration of the program.
165
- * A record binds to a declaration, so nothing withholds a finding about one.
159
+ * The subject kinds that are a row of a document rather than a declaration of the program,
160
+ * each with the codes that report one. A record binds to a declaration, so nothing
161
+ * withholds a finding about one.
166
162
  */
167
- const ROW_SUBJECTS: ReadonlySet<string> = new Set([
168
- "file",
169
- "dependency",
170
- "module-directive",
171
- "root",
172
- "configured-declaration",
173
- "suppression",
174
- "edge",
163
+ const ROW_SUBJECTS: ReadonlyMap<string, readonly string[]> = new Map([
164
+ ["file", ["DS1501", "DS1502"]],
165
+ ["dependency", ["DS1601"]],
166
+ ["module-directive", ["DS1605"]],
167
+ ["root", ["DS1704"]],
168
+ ["configured-declaration", ["DS1706"]],
169
+ ["suppression", ["DS1701", "DS1702", "DS1703"]],
170
+ ["edge", ["DS1705"]],
175
171
  ]);
176
172
 
177
173
  /** Whether a finding's subject is a row of a document, which no record can withhold. */
@@ -179,6 +175,11 @@ export function isRowSubject(kind: string): boolean {
179
175
  return ROW_SUBJECTS.has(kind);
180
176
  }
181
177
 
178
+ /** Whether a code reports a row of a document, so no record naming it can match. */
179
+ export function isRowCode(code: string): boolean {
180
+ return [...ROW_SUBJECTS.values()].some((codes) => codes.includes(code));
181
+ }
182
+
182
183
  /**
183
184
  * The subject kinds that are a part of a declaration rather than a declaration: a part
184
185
  * has no reference of its own, so a finding about one names the declaration that holds
@@ -242,20 +243,17 @@ export function ledgerOf<F extends Finding>(
242
243
  records: readonly SuppressionRecord[],
243
244
  would: readonly F[],
244
245
  dials: Dials<F>,
245
- ): Ledger<F> {
246
+ ): Ledger {
246
247
  const taken = new Set<string>();
247
248
  const verdicts: Verdict[] = [];
248
- const claims: (F | undefined)[] = [];
249
249
  for (const record of records) {
250
250
  if (record.bound !== "" && dials.withholdsCode(record.code, record.bound)) {
251
251
  verdicts.push("dormant");
252
- claims.push(undefined);
253
252
  continue;
254
253
  }
255
254
  const claimed = would.find(
256
255
  (finding) => !taken.has(claimKey(finding)) && pairs(record, finding),
257
256
  );
258
- claims.push(claimed);
259
257
  if (claimed === undefined) {
260
258
  verdicts.push("stale");
261
259
  continue;
@@ -265,13 +263,12 @@ export function ledgerOf<F extends Finding>(
265
263
  }
266
264
  return {
267
265
  verdicts,
268
- claims,
269
266
  withheld: (finding) => taken.has(claimKey(finding)) && !ROW_SUBJECTS.has(finding.symbol.kind),
270
267
  };
271
268
  }
272
269
 
273
270
  /** The two suppression counts a report's totals carry. */
274
- export interface SuppressionCounts {
271
+ interface SuppressionCounts {
275
272
  /** The records in effect. */
276
273
  readonly inEffect: number;
277
274
  /** The directives, entries and rows that carry a reason, each once whatever its codes. */
@@ -279,9 +276,9 @@ export interface SuppressionCounts {
279
276
  }
280
277
 
281
278
  /** The suppression counts of one run's records and the ledger over them. */
282
- export function suppressionCounts<F extends Finding>(
279
+ export function suppressionCounts(
283
280
  records: readonly SuppressionRecord[],
284
- ledger: Ledger<F>,
281
+ ledger: Ledger,
285
282
  ): SuppressionCounts {
286
283
  const sites = new Set(
287
284
  records.map((record) => `${record.mechanism}\u0000${positionKey(record.site)}`),
@@ -22,7 +22,7 @@ import { isAbsolutePath, joinPath, normalizePath, relativePath } from "./paths.t
22
22
  import { isComponentFile, type Position } from "./position.ts";
23
23
 
24
24
  /** One template, by its path below the target root. */
25
- export interface TemplateFile {
25
+ interface TemplateFile {
26
26
  readonly path: string;
27
27
  readonly text: string;
28
28
  }
@@ -38,7 +38,7 @@ export interface Reached {
38
38
  }
39
39
 
40
40
  /** What each type's values carry, each type asked of the checker once. */
41
- export interface ValueReach {
41
+ interface ValueReach {
42
42
  reachedFrom(type: Type): Reached;
43
43
  }
44
44
 
package/src/verbs/verb.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import type { Config, Inputs } from "../config.ts";
2
- import type { Emitters } from "../findings/emitter.ts";
3
2
  import type { Host } from "../host.ts";
4
3
  import type { Writer } from "../run.ts";
5
4
  import type { Scope } from "../scope.ts";
@@ -16,7 +15,7 @@ export const EXIT_FAILURE = 3;
16
15
  * options that follow its name, read only when the verb asks for what they name, so
17
16
  * a verb that asks for nothing refuses no option.
18
17
  */
19
- export interface Invocation {
18
+ interface Invocation {
20
19
  readonly out: Writer;
21
20
  readonly err: Writer;
22
21
  readonly host: Host;
@@ -29,8 +28,6 @@ export interface Invocation {
29
28
  * closed if the verb throws.
30
29
  */
31
30
  readonly openClient: (config: Config) => Engine;
32
- /** The emitter of every kind family, which a verb that reports findings runs. */
33
- readonly emitters: Emitters;
34
31
  /** The arguments after the verb's name, as written. */
35
32
  readonly args: readonly string[];
36
33
  /** The last value one of the verb's own options was given, undefined where none was. */
@@ -22,12 +22,10 @@ import type { Engine } from "./session.ts";
22
22
  import type { WorkspaceResolver } from "./workspace-resolution.ts";
23
23
 
24
24
  /** One member import no member source answers for. */
25
- export interface UnresolvedImport {
25
+ interface UnresolvedImport {
26
26
  /** The importing file, absolute. */
27
27
  readonly file: string;
28
28
  readonly specifier: string;
29
- readonly member: string;
30
- readonly subpath: string;
31
29
  readonly reason: string;
32
30
  }
33
31
 
@@ -36,8 +34,6 @@ export interface MemberReading {
36
34
  readonly configFile: string;
37
35
  /** The files the configuration itself compiles, absolute. */
38
36
  readonly fileNames: readonly string[];
39
- /** The static resolutions its program is built with; none for a configuration opened as a project. */
40
- readonly entries: readonly ModuleResolutionEntry[];
41
37
  readonly unresolved: readonly UnresolvedImport[];
42
38
  /**
43
39
  * Why the configuration's component files are not read, where the snapshots read
@@ -53,7 +49,7 @@ export type WorkspaceProgram =
53
49
  | { readonly kind: "configuration"; readonly file: string; readonly text: string };
54
50
 
55
51
  /** The programs one run builds instead of opening projects, with what reading them did. */
56
- export interface WorkspacePrograms {
52
+ interface WorkspacePrograms {
57
53
  /** Per configuration that imports a member, how the snapshot reads it. */
58
54
  readonly programs: ReadonlyMap<string, WorkspaceProgram>;
59
55
  readonly readings: readonly MemberReading[];
@@ -320,8 +316,6 @@ function scan(
320
316
  reading.unresolved.push({
321
317
  file: usage.file,
322
318
  specifier,
323
- member: answer.member,
324
- subpath: answer.subpath,
325
319
  reason: answer.reason,
326
320
  });
327
321
  }
@@ -449,7 +443,6 @@ export function workspacePrograms(
449
443
  readings: readings.map((reading) => ({
450
444
  configFile: reading.configFile,
451
445
  fileNames: reading.parsed.fileNames,
452
- entries: reading.entries,
453
446
  unresolved: reading.unresolved,
454
447
  componentsUnread: unread.get(reading.configFile),
455
448
  })),
@@ -30,7 +30,6 @@ export type MemberResolution =
30
30
  | {
31
31
  readonly kind: "unresolved";
32
32
  readonly member: string;
33
- readonly subpath: string;
34
33
  readonly reason: string;
35
34
  };
36
35
 
@@ -343,7 +342,6 @@ export function workspaceResolver(host: Host, workspace: Workspace): WorkspaceRe
343
342
  return {
344
343
  kind: "unresolved",
345
344
  member: name,
346
- subpath,
347
345
  reason: `${String(linked.dirs.length)} workspace packages are named ${name} (${linked.dirs.join(", ")}) and nothing links the importer to one of them; install the workspace, or declare the dependency with a range only one of them satisfies`,
348
346
  };
349
347
  }
@@ -381,7 +379,6 @@ export function workspaceResolver(host: Host, workspace: Workspace): WorkspaceRe
381
379
  return {
382
380
  kind: "unresolved",
383
381
  member: name,
384
- subpath,
385
382
  reason: built
386
383
  ? `its manifest names ${named}, output no tsconfig*.json of the package maps back to source, and nothing installed links the importer to it; install the workspace, or point an exports condition the importing configuration's customConditions lists at its source`
387
384
  : member.configurations.length === 0
@@ -20,7 +20,7 @@ import {
20
20
  import { workspaceResolver } from "./workspace-resolution.ts";
21
21
 
22
22
  /** One run's workspace. */
23
- export interface WorkspaceRun {
23
+ interface WorkspaceRun {
24
24
  /** Per configuration that imports a member, how the snapshot reads it. */
25
25
  readonly programs: ReadonlyMap<string, WorkspaceProgram>;
26
26
  /**
package/src/workspace.ts CHANGED
@@ -24,8 +24,7 @@ export interface ParsedLayout {
24
24
  }
25
25
 
26
26
  /** One compiler configuration in a member's directory. */
27
- export interface MemberConfiguration {
28
- readonly configFile: string;
27
+ interface MemberConfiguration {
29
28
  /** The files it compiles, absolute. */
30
29
  readonly fileNames: ReadonlySet<string>;
31
30
  /** Where it writes its output, where it writes any. */
@@ -46,10 +45,6 @@ export interface WorkspaceMember {
46
45
 
47
46
  /** The workspace one target sits in. */
48
47
  export interface Workspace {
49
- /** The directory that declares it. */
50
- readonly root: string;
51
- /** The file that declares it. */
52
- readonly declaredIn: string;
53
48
  /** Every member, the root first, then by directory. */
54
49
  readonly members: readonly WorkspaceMember[];
55
50
  /** The members one package name names; two members may share a name. */
@@ -336,7 +331,6 @@ function configurationsOf(
336
331
  ? []
337
332
  : [
338
333
  {
339
- configFile,
340
334
  fileNames: new Set(parsed.fileNames),
341
335
  layout: layoutOf(configFile, parsed),
342
336
  },
@@ -439,8 +433,6 @@ export function findWorkspace(
439
433
  return found;
440
434
  };
441
435
  return {
442
- root: declared.root,
443
- declaredIn: declared.file,
444
436
  members,
445
437
  named,
446
438
  memberOf: (path) => {