@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.
- package/README.md +1 -1
- package/dist/bin/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/analysis.js +245 -309
- package/dist/src/augmentations.js +124 -18
- package/dist/src/automatic-types.js +170 -0
- package/dist/src/build-scripts.js +425 -0
- package/dist/src/component-layer.js +4 -2
- package/dist/src/components.js +9 -9
- package/dist/src/config.js +6 -81
- package/dist/src/configuration-files.js +78 -188
- package/dist/src/configured-declarations.js +15 -20
- package/dist/src/conformance-record.js +2 -2
- package/dist/src/consumers.js +3 -30
- package/dist/src/contextual-uses.js +56 -9
- package/dist/src/contract/config.generated.js +558 -0
- package/dist/src/contract/contract.generated.js +1244 -0
- package/dist/src/contract/report.generated.js +862 -0
- package/dist/src/convention-rows.js +146 -1
- package/dist/src/conventions.js +136 -70
- package/dist/src/decorator.js +21 -18
- package/dist/src/dependencies.js +280 -62
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +4 -6
- package/dist/src/entry-point-gaps.js +9 -18
- package/dist/src/entry-points.js +106 -21
- package/dist/src/enum-group.js +3 -10
- package/dist/src/erased-stores.js +4 -6
- package/dist/src/exempt-classes.js +1 -63
- package/dist/src/exempt.js +21 -40
- package/dist/src/failure.js +36 -0
- package/dist/src/file-facts.js +2 -25
- package/dist/src/findings/completion.js +225 -63
- package/dist/src/findings/dependencies-and-module-machinery.js +72 -27
- package/dist/src/findings/emitters.js +6 -6
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +53 -19
- package/dist/src/findings/non-code-artifacts.js +71 -39
- package/dist/src/findings/reads-and-writes.js +16 -13
- package/dist/src/findings/self-check.js +10 -12
- package/dist/src/findings/unused-declarations.js +57 -28
- package/dist/src/findings/visibility-narrowing.js +40 -18
- package/dist/src/findings-pass.js +8 -15
- package/dist/src/framework-lifecycle.js +7 -7
- package/dist/src/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +72 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/generated-file.js +18 -4
- package/dist/src/git-ignore.js +99 -0
- package/dist/src/graph.js +9 -4
- package/dist/src/html-entries.js +6 -33
- package/dist/src/import-bindings.js +97 -0
- package/dist/src/in-operands.js +2 -1
- package/dist/src/index.js +1 -1
- package/dist/src/indexed-access.js +130 -28
- package/dist/src/injection-container.js +1 -1
- package/dist/src/interface-satisfaction.js +30 -12
- package/dist/src/intra-function-parts.js +341 -69
- package/dist/src/inventory.js +54 -29
- package/dist/src/javascript-file.js +33 -0
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +4 -6
- package/dist/src/kinds.js +3 -366
- package/dist/src/load/classify.js +270 -0
- package/dist/src/load/diagnostics.js +80 -0
- package/dist/src/load/discover.js +277 -0
- package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
- package/dist/src/load/expected-module.js +136 -0
- package/dist/src/load/load.js +27 -0
- package/dist/src/load/module-lookup.js +37 -0
- package/dist/src/load/plan.js +313 -0
- package/dist/src/load/specifiers.js +115 -0
- package/dist/src/load/synthesize.js +140 -0
- package/dist/src/load/test-globals.js +207 -0
- package/dist/src/load/test-joins.js +82 -0
- package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
- package/dist/src/{workspace-programs.js → load/workspace-programs.js} +88 -61
- package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +60 -59
- package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
- package/dist/src/{workspace.js → load/workspace.js} +62 -124
- package/dist/src/manifest.js +49 -54
- package/dist/src/matrix.js +94 -13
- package/dist/src/mdx-entries.js +174 -0
- package/dist/src/module-declarations.js +9 -13
- package/dist/src/outside-tests.js +1 -1
- package/dist/src/overrides.js +41 -10
- package/dist/src/partial.js +2 -1
- package/dist/src/paths.js +26 -15
- package/dist/src/position.js +2 -1
- package/dist/src/print.js +11 -78
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +1 -0
- package/dist/src/ref.js +11 -0
- package/dist/src/references.js +52 -31
- package/dist/src/report-schema.js +51 -0
- package/dist/src/report.js +59 -41
- package/dist/src/reporters/annotations.js +15 -8
- package/dist/src/reporters/sarif.js +16 -10
- package/dist/src/reporters/template.js +4 -19
- package/dist/src/resolve.js +245 -727
- package/dist/src/roots.js +374 -116
- package/dist/src/run.js +66 -77
- package/dist/src/schema.js +320 -342
- package/dist/src/scope.js +38 -115
- package/dist/src/serialization-contract.js +649 -29
- package/dist/src/session.js +41 -29
- package/dist/src/source-files.js +40 -15
- package/dist/src/suppress-file.js +34 -29
- package/dist/src/suppress-inline.js +21 -4
- package/dist/src/suppress.js +40 -56
- package/dist/src/sweep.js +32 -17
- package/dist/src/symbol-keys.js +105 -6
- package/dist/src/template-field.js +9 -19
- package/dist/src/test-support.js +119 -18
- package/dist/src/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/named-files.js +54 -0
- package/dist/src/text/shell.js +159 -0
- package/dist/src/text/yaml.js +393 -0
- package/dist/src/type-errors.js +27 -221
- package/dist/src/type-parameter-reads.js +172 -0
- package/dist/src/unseen-loads.js +100 -0
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/verbs/analyze.js +181 -125
- package/dist/src/verbs/describe.js +9 -16
- package/dist/src/verbs/explain.js +14 -9
- package/dist/src/verbs/print-config.js +2 -1
- package/dist/src/verbs/print-projects.js +6 -4
- package/dist/src/verbs/print-retained.js +4 -2
- package/dist/src/verbs/print-roots.js +4 -2
- package/dist/src/verbs/verb.js +1 -5
- package/dist/src/verbs/version.js +14 -3
- package/dist/src/workflow-steps.js +128 -33
- package/jsr.json +1 -1
- package/package.json +5 -4
- package/src/analysis.ts +333 -457
- package/src/augmentations.ts +152 -23
- package/src/automatic-types.ts +228 -0
- package/src/build-scripts.ts +543 -0
- package/src/component-layer.ts +4 -2
- package/src/components.ts +9 -10
- package/src/config.ts +31 -299
- package/src/configuration-files.ts +100 -191
- package/src/configured-declarations.ts +18 -23
- package/src/conformance-record.ts +2 -2
- package/src/consumers.ts +6 -57
- package/src/contextual-uses.ts +64 -12
- package/src/contract/config.generated.ts +818 -0
- package/src/contract/contract.generated.ts +1308 -0
- package/src/contract/report.generated.ts +1237 -0
- package/src/convention-rows.ts +186 -1
- package/src/conventions.ts +166 -90
- package/src/decorator.ts +28 -18
- package/src/dependencies.ts +356 -78
- package/src/edges.ts +41 -140
- package/src/element-access.ts +4 -7
- package/src/entry-point-gaps.ts +11 -20
- package/src/entry-points.ts +124 -28
- package/src/enum-group.ts +2 -11
- package/src/erased-stores.ts +3 -7
- package/src/exempt-classes.ts +1 -75
- package/src/exempt.ts +36 -50
- package/src/failure.ts +63 -0
- package/src/file-facts.ts +9 -24
- package/src/finding.ts +24 -9
- package/src/findings/boundary.ts +2 -0
- package/src/findings/completion.ts +297 -77
- package/src/findings/dependencies-and-module-machinery.ts +90 -31
- package/src/findings/emitter.ts +8 -9
- package/src/findings/emitters.ts +8 -8
- package/src/findings/interfaces.ts +4 -6
- package/src/findings/intra-function.ts +64 -20
- package/src/findings/non-code-artifacts.ts +88 -50
- package/src/findings/reads-and-writes.ts +20 -16
- package/src/findings/self-check.ts +11 -17
- package/src/findings/unused-declarations.ts +65 -28
- package/src/findings/visibility-narrowing.ts +51 -19
- package/src/findings-pass.ts +10 -19
- package/src/framework-lifecycle.ts +7 -7
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +92 -0
- package/src/fs/tree.ts +110 -0
- package/src/generated-file.ts +23 -4
- package/src/git-ignore.ts +122 -0
- package/src/graph.ts +11 -3
- package/src/host.ts +17 -14
- package/src/html-entries.ts +6 -33
- package/src/import-bindings.ts +128 -0
- package/src/in-operands.ts +2 -1
- package/src/index.ts +1 -1
- package/src/indexed-access.ts +152 -30
- package/src/injection-container.ts +1 -1
- package/src/interface-satisfaction.ts +33 -13
- package/src/intra-function-parts.ts +449 -85
- package/src/inventory.ts +73 -27
- package/src/javascript-file.ts +37 -0
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +3 -7
- package/src/kinds.ts +5 -413
- package/src/load/classify.ts +397 -0
- package/src/load/diagnostics.ts +144 -0
- package/src/load/discover.ts +455 -0
- package/src/{emit-map.ts → load/emit-map.ts} +1 -1
- package/src/load/expected-module.ts +188 -0
- package/src/load/load.ts +73 -0
- package/src/load/module-lookup.ts +50 -0
- package/src/load/plan.ts +504 -0
- package/src/load/specifiers.ts +168 -0
- package/src/load/synthesize.ts +211 -0
- package/src/load/test-globals.ts +251 -0
- package/src/load/test-joins.ts +98 -0
- package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
- package/src/{workspace-programs.ts → load/workspace-programs.ts} +127 -80
- package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +73 -64
- package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
- package/src/{workspace.ts → load/workspace.ts} +90 -134
- package/src/manifest.ts +81 -75
- package/src/matrix.ts +154 -18
- package/src/mdx-entries.ts +218 -0
- package/src/module-declarations.ts +11 -13
- package/src/outside-tests.ts +1 -1
- package/src/overrides.ts +51 -12
- package/src/partial.ts +3 -2
- package/src/paths.ts +27 -15
- package/src/position.ts +2 -1
- package/src/print.ts +12 -91
- package/src/product.ts +18 -0
- package/src/query.ts +11 -0
- package/src/ref.ts +13 -0
- package/src/references.ts +62 -32
- package/src/report-schema.ts +68 -0
- package/src/report.ts +105 -215
- package/src/reporters/annotations.ts +22 -11
- package/src/reporters/json.ts +1 -1
- package/src/reporters/reporter.ts +2 -4
- package/src/reporters/reporters.ts +1 -1
- package/src/reporters/sarif.ts +29 -16
- package/src/reporters/template.ts +4 -20
- package/src/reporters/text.ts +3 -3
- package/src/resolve.ts +283 -1111
- package/src/roots.ts +490 -137
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -387
- package/src/scope.ts +46 -138
- package/src/serialization-contract.ts +818 -26
- package/src/session.ts +77 -54
- package/src/source-files.ts +67 -17
- package/src/suppress-file.ts +36 -34
- package/src/suppress-inline.ts +20 -3
- package/src/suppress.ts +52 -63
- package/src/sweep.ts +53 -18
- package/src/symbol-keys.ts +131 -7
- package/src/template-field.ts +15 -25
- package/src/test-support.ts +155 -18
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/named-files.inputs.json +1522 -0
- package/src/text/named-files.ts +68 -0
- package/src/text/shell.ts +161 -0
- package/src/text/yaml.ts +423 -0
- package/src/type-errors.ts +35 -273
- package/src/type-parameter-reads.ts +227 -0
- package/src/unseen-loads.ts +134 -0
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/verbs/analyze.ts +245 -161
- package/src/verbs/describe.ts +14 -15
- package/src/verbs/explain.ts +15 -13
- package/src/verbs/print-config.ts +2 -1
- package/src/verbs/print-projects.ts +6 -4
- package/src/verbs/print-retained.ts +4 -2
- package/src/verbs/print-roots.ts +4 -2
- package/src/verbs/verb.ts +2 -8
- package/src/verbs/version.ts +15 -3
- package/src/workflow-steps.ts +149 -34
- package/dist/src/discover.js +0 -347
- package/dist/src/glob.js +0 -65
- package/dist/src/pnpm-workspace.js +0 -120
- package/dist/src/setup-failure.js +0 -23
- package/dist/src/test-joins.js +0 -101
- package/dist/src/version.js +0 -7
- package/src/discover.ts +0 -510
- package/src/glob.ts +0 -67
- package/src/pnpm-workspace.ts +0 -135
- package/src/setup-failure.ts +0 -39
- package/src/test-joins.ts +0 -120
- package/src/version.ts +0 -7
package/src/report.ts
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* renders this document, so no two renderings disagree about which findings exist.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import { SCHEMA_VERSION, SCHEMA_VERSIONS } from "./contract/contract.generated.ts";
|
|
8
|
+
import type * as wire from "./contract/report.generated.ts";
|
|
9
|
+
import type { Sort, TargetKind } from "./config.ts";
|
|
8
10
|
import type { Conformance, DeclaredGap } from "./conformance.ts";
|
|
9
11
|
import type { EdgeEvaluation } from "./edges.ts";
|
|
10
12
|
import type {
|
|
@@ -17,129 +19,8 @@ import type { AppliedConvention } from "./conventions.ts";
|
|
|
17
19
|
import type { PassResult } from "./findings-pass.ts";
|
|
18
20
|
import type { StaleSuppression } from "./findings/self-check.ts";
|
|
19
21
|
import type { TestFileRule } from "./references.ts";
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const SCHEMA_VERSION = "8.2.0";
|
|
23
|
-
|
|
24
|
-
/** Every report schema version this analyzer reads: the one the Contract it implements admits. */
|
|
25
|
-
export const SCHEMA_VERSIONS_ACCEPTED: readonly string[] = [SCHEMA_VERSION];
|
|
26
|
-
|
|
27
|
-
/** The name this analyzer writes every document under and mints every identifier with. */
|
|
28
|
-
export const ANALYZER_NAME = "deadset-ts";
|
|
29
|
-
|
|
30
|
-
/** The language this analyzer claims. */
|
|
31
|
-
export const LANGUAGE = "ts";
|
|
32
|
-
|
|
33
|
-
interface WirePosition {
|
|
34
|
-
readonly path: string;
|
|
35
|
-
readonly line: number;
|
|
36
|
-
readonly column: number;
|
|
37
|
-
readonly end_line: number;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface WireDetails {
|
|
41
|
-
readonly narrower_visibility?: string;
|
|
42
|
-
readonly implementations?: readonly {
|
|
43
|
-
readonly ref: string;
|
|
44
|
-
readonly name: string;
|
|
45
|
-
readonly position: WirePosition;
|
|
46
|
-
}[];
|
|
47
|
-
readonly write_positions?: readonly WirePosition[];
|
|
48
|
-
/** Set under the name-literal rule, which no finding of this analyzer meets; SARIF still maps it. */
|
|
49
|
-
readonly name_literal?: WirePosition;
|
|
50
|
-
readonly dependency_class?: string;
|
|
51
|
-
readonly mechanism?: string;
|
|
52
|
-
readonly entry?: {
|
|
53
|
-
readonly code: string;
|
|
54
|
-
readonly symbol?: string;
|
|
55
|
-
readonly path?: string;
|
|
56
|
-
readonly reason?: string;
|
|
57
|
-
};
|
|
58
|
-
readonly overlap?: readonly string[];
|
|
59
|
-
readonly removes_last_use_of?: readonly string[];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** One finding as the finding schema spells it. */
|
|
63
|
-
export interface WireFinding {
|
|
64
|
-
readonly code: string;
|
|
65
|
-
readonly kind: string;
|
|
66
|
-
readonly language: string;
|
|
67
|
-
readonly position: WirePosition;
|
|
68
|
-
readonly symbol: {
|
|
69
|
-
readonly ref: string;
|
|
70
|
-
readonly kind: string;
|
|
71
|
-
readonly name: string;
|
|
72
|
-
readonly size_lines: number;
|
|
73
|
-
};
|
|
74
|
-
readonly reachability_class: string;
|
|
75
|
-
readonly confidence: string;
|
|
76
|
-
readonly liveness_relation?: string;
|
|
77
|
-
readonly test_only: boolean;
|
|
78
|
-
readonly generated: boolean;
|
|
79
|
-
readonly component: {
|
|
80
|
-
readonly id: string;
|
|
81
|
-
readonly root: boolean;
|
|
82
|
-
readonly symbol_count: number;
|
|
83
|
-
readonly deletable_lines: number;
|
|
84
|
-
readonly members?: readonly {
|
|
85
|
-
readonly ref: string;
|
|
86
|
-
readonly name: string;
|
|
87
|
-
readonly position: WirePosition;
|
|
88
|
-
}[];
|
|
89
|
-
};
|
|
90
|
-
readonly retained_by: readonly string[];
|
|
91
|
-
readonly configurations: readonly string[];
|
|
92
|
-
readonly consumers_loaded: readonly string[];
|
|
93
|
-
readonly fixability: string;
|
|
94
|
-
readonly severity: Severity;
|
|
95
|
-
readonly message: string;
|
|
96
|
-
readonly details: WireDetails;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
interface WireEdgeEvaluation {
|
|
100
|
-
readonly edge: string;
|
|
101
|
-
readonly side: string;
|
|
102
|
-
readonly symbol: string;
|
|
103
|
-
readonly state: string;
|
|
104
|
-
readonly finding?: WireFinding;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export interface WireStaleSuppression {
|
|
108
|
-
readonly code: string;
|
|
109
|
-
readonly mechanism: string;
|
|
110
|
-
readonly entry: {
|
|
111
|
-
readonly code: string;
|
|
112
|
-
readonly symbol?: string;
|
|
113
|
-
readonly path: string;
|
|
114
|
-
readonly reason: string;
|
|
115
|
-
};
|
|
116
|
-
readonly position: { readonly path: string; readonly line: number; readonly column: number };
|
|
117
|
-
readonly symbol: string;
|
|
118
|
-
readonly message: string;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
interface WireDeclaredGap {
|
|
122
|
-
readonly fixture: string;
|
|
123
|
-
readonly symbol?: string;
|
|
124
|
-
readonly capability: string;
|
|
125
|
-
readonly reason: string;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export interface WireTotals {
|
|
129
|
-
readonly findings: number;
|
|
130
|
-
readonly by_severity: { readonly allow: number; readonly warn: number; readonly deny: number };
|
|
131
|
-
readonly deletable_lines: number;
|
|
132
|
-
readonly suppressions_in_effect: number;
|
|
133
|
-
readonly reasons_recorded: number;
|
|
134
|
-
readonly stale_suppressions: number;
|
|
135
|
-
readonly pending: number;
|
|
136
|
-
readonly omitted: number;
|
|
137
|
-
readonly withheld: {
|
|
138
|
-
readonly certain: number;
|
|
139
|
-
readonly probable: number;
|
|
140
|
-
readonly possible: number;
|
|
141
|
-
};
|
|
142
|
-
}
|
|
22
|
+
import { bytewise } from "./text/compare.ts";
|
|
23
|
+
import { LANGUAGE, PRODUCT } from "./product.ts";
|
|
143
24
|
|
|
144
25
|
/** One project configuration of the matrix a run analyzed. */
|
|
145
26
|
export interface ReportConfiguration {
|
|
@@ -186,49 +67,21 @@ interface UnavailableConsumer {
|
|
|
186
67
|
readonly reason: string;
|
|
187
68
|
}
|
|
188
69
|
|
|
189
|
-
/**
|
|
190
|
-
export
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
readonly name: string;
|
|
195
|
-
readonly version: string;
|
|
196
|
-
readonly languages: readonly string[];
|
|
197
|
-
readonly schema_versions_accepted: readonly string[];
|
|
198
|
-
readonly conformance: {
|
|
199
|
-
readonly corpus_version: string;
|
|
200
|
-
readonly result: string;
|
|
201
|
-
readonly digest: string;
|
|
202
|
-
};
|
|
203
|
-
};
|
|
204
|
-
readonly target: { readonly kind: TargetKind; readonly root: string; readonly identity: string };
|
|
205
|
-
readonly configurations: readonly ReportConfiguration[];
|
|
206
|
-
readonly configurations_not_built: readonly ReportNotBuilt[];
|
|
207
|
-
readonly consumers: {
|
|
208
|
-
readonly declared: number;
|
|
209
|
-
readonly loaded: readonly {
|
|
210
|
-
readonly id: string;
|
|
211
|
-
readonly role: "consumer";
|
|
70
|
+
/** One hint about the run's setup, as the report schema's `notes` spells it. */
|
|
71
|
+
export type ReportNote =
|
|
72
|
+
| {
|
|
73
|
+
readonly kind: "unmapped-entry";
|
|
74
|
+
/** The directory of the manifest the note is about, below the target root. */
|
|
212
75
|
readonly path: string;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
readonly
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
readonly stale_suppressions: readonly WireStaleSuppression[];
|
|
223
|
-
readonly declared_gaps: readonly WireDeclaredGap[];
|
|
224
|
-
readonly excluded_by_cgo: readonly never[];
|
|
225
|
-
readonly test_file_rules: readonly TestFileRule[];
|
|
226
|
-
readonly type_error_skips: readonly TypeErrorSkip[];
|
|
227
|
-
readonly notes: readonly never[];
|
|
228
|
-
readonly unanswered_questions: readonly UnansweredCount[];
|
|
229
|
-
readonly conventions_applied: readonly AppliedConvention[];
|
|
230
|
-
readonly totals: WireTotals;
|
|
231
|
-
}
|
|
76
|
+
readonly key: "ts.entry_files";
|
|
77
|
+
readonly message: string;
|
|
78
|
+
}
|
|
79
|
+
| {
|
|
80
|
+
readonly kind: "computed-load" | "unread-command" | "unresolved-specifier";
|
|
81
|
+
/** The directory of the file that writes the load or the specifier, or of the manifest, below the target root. */
|
|
82
|
+
readonly path: string;
|
|
83
|
+
readonly message: string;
|
|
84
|
+
};
|
|
232
85
|
|
|
233
86
|
/** What one run answered, from which its report is built. */
|
|
234
87
|
export interface ReportInput {
|
|
@@ -247,17 +100,34 @@ export interface ReportInput {
|
|
|
247
100
|
readonly unanswered: readonly UnansweredCount[];
|
|
248
101
|
/** The convention rows the run applied, in the report's order. */
|
|
249
102
|
readonly conventionsApplied: readonly AppliedConvention[];
|
|
103
|
+
/** The notes the run states, in any order. */
|
|
104
|
+
readonly notes?: readonly ReportNote[];
|
|
105
|
+
/** Whether the run lists each component in full, which `reporters.cascade: full` asks for. */
|
|
106
|
+
readonly listsComponents?: boolean;
|
|
250
107
|
}
|
|
251
108
|
|
|
252
|
-
/**
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Each component the findings name, once, with the members the first finding naming it
|
|
111
|
+
* carries, in the order the findings are: `findings` paired with their wire forms and
|
|
112
|
+
* sorted, then the edge evaluations' findings.
|
|
113
|
+
*/
|
|
114
|
+
function componentsOf(
|
|
115
|
+
findings: readonly (readonly [wire.Finding, CompletedFinding])[],
|
|
116
|
+
): readonly wire.ComponentsEntry[] {
|
|
117
|
+
const listed = new Map<string, wire.ComponentsEntry>();
|
|
118
|
+
for (const [written, finding] of findings) {
|
|
119
|
+
const { members } = finding.component;
|
|
120
|
+
if (members !== undefined && !listed.has(written.component.id)) {
|
|
121
|
+
listed.set(written.component.id, {
|
|
122
|
+
id: written.component.id,
|
|
123
|
+
members: members.map(wireSymbol),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
256
126
|
}
|
|
257
|
-
return
|
|
127
|
+
return [...listed.values()];
|
|
258
128
|
}
|
|
259
129
|
|
|
260
|
-
function wirePosition(position: FindingPosition):
|
|
130
|
+
function wirePosition(position: FindingPosition): wire.Position {
|
|
261
131
|
return {
|
|
262
132
|
path: position.path,
|
|
263
133
|
line: position.line,
|
|
@@ -269,13 +139,13 @@ function wirePosition(position: FindingPosition): WirePosition {
|
|
|
269
139
|
function wireSymbol(symbol: PositionedSymbol): {
|
|
270
140
|
ref: string;
|
|
271
141
|
name: string;
|
|
272
|
-
position:
|
|
142
|
+
position: wire.Position;
|
|
273
143
|
} {
|
|
274
144
|
return { ref: symbol.ref, name: symbol.name, position: wirePosition(symbol.position) };
|
|
275
145
|
}
|
|
276
146
|
|
|
277
147
|
/** The details one code carries, in the order the finding schema lists them. */
|
|
278
|
-
function wireDetails(details: FindingDetails):
|
|
148
|
+
function wireDetails(details: FindingDetails): wire.Details {
|
|
279
149
|
const { entry } = details;
|
|
280
150
|
return {
|
|
281
151
|
...(details.narrowerVisibility === undefined
|
|
@@ -307,7 +177,7 @@ function wireDetails(details: FindingDetails): WireDetails {
|
|
|
307
177
|
}
|
|
308
178
|
|
|
309
179
|
/** One finding as the finding schema spells it, member for member in its order. */
|
|
310
|
-
export function wireFinding(finding: CompletedFinding):
|
|
180
|
+
export function wireFinding(finding: CompletedFinding): wire.Finding {
|
|
311
181
|
return {
|
|
312
182
|
code: finding.code,
|
|
313
183
|
kind: finding.kind,
|
|
@@ -331,9 +201,6 @@ export function wireFinding(finding: CompletedFinding): WireFinding {
|
|
|
331
201
|
root: finding.component.root,
|
|
332
202
|
symbol_count: finding.component.symbolCount,
|
|
333
203
|
deletable_lines: finding.component.deletableLines,
|
|
334
|
-
...(finding.component.members === undefined
|
|
335
|
-
? {}
|
|
336
|
-
: { members: finding.component.members.map(wireSymbol) }),
|
|
337
204
|
},
|
|
338
205
|
retained_by: finding.retainedBy,
|
|
339
206
|
configurations: finding.configurations,
|
|
@@ -345,7 +212,7 @@ export function wireFinding(finding: CompletedFinding): WireFinding {
|
|
|
345
212
|
};
|
|
346
213
|
}
|
|
347
214
|
|
|
348
|
-
function wireEvaluation(evaluation: EdgeEvaluation<CompletedFinding>):
|
|
215
|
+
function wireEvaluation(evaluation: EdgeEvaluation<CompletedFinding>): wire.EdgeEvaluationsEntry {
|
|
349
216
|
return {
|
|
350
217
|
edge: evaluation.edge,
|
|
351
218
|
side: evaluation.side,
|
|
@@ -355,7 +222,7 @@ function wireEvaluation(evaluation: EdgeEvaluation<CompletedFinding>): WireEdgeE
|
|
|
355
222
|
};
|
|
356
223
|
}
|
|
357
224
|
|
|
358
|
-
function wireStale(stale: StaleSuppression):
|
|
225
|
+
function wireStale(stale: StaleSuppression): wire.StaleSuppressionsEntry {
|
|
359
226
|
return {
|
|
360
227
|
code: stale.code,
|
|
361
228
|
mechanism: stale.mechanism,
|
|
@@ -376,29 +243,29 @@ function wireStale(stale: StaleSuppression): WireStaleSuppression {
|
|
|
376
243
|
}
|
|
377
244
|
|
|
378
245
|
/** The canonical key over two findings: path, line, column, code, then the symbol reference. */
|
|
379
|
-
function canonical(a:
|
|
246
|
+
function canonical(a: wire.Finding, b: wire.Finding): number {
|
|
380
247
|
return (
|
|
381
|
-
|
|
248
|
+
bytewise(a.position.path, b.position.path) ||
|
|
382
249
|
a.position.line - b.position.line ||
|
|
383
250
|
a.position.column - b.position.column ||
|
|
384
|
-
|
|
385
|
-
|
|
251
|
+
bytewise(a.code, b.code) ||
|
|
252
|
+
bytewise(a.symbol.ref, b.symbol.ref)
|
|
386
253
|
);
|
|
387
254
|
}
|
|
388
255
|
|
|
389
256
|
/** The canonical key over two stale suppressions, each component from the record's own member. */
|
|
390
|
-
function canonicalStale(a:
|
|
257
|
+
function canonicalStale(a: wire.StaleSuppressionsEntry, b: wire.StaleSuppressionsEntry): number {
|
|
391
258
|
return (
|
|
392
|
-
|
|
259
|
+
bytewise(a.position.path, b.position.path) ||
|
|
393
260
|
a.position.line - b.position.line ||
|
|
394
261
|
a.position.column - b.position.column ||
|
|
395
|
-
|
|
396
|
-
|
|
262
|
+
bytewise(a.code, b.code) ||
|
|
263
|
+
bytewise(a.symbol, b.symbol)
|
|
397
264
|
);
|
|
398
265
|
}
|
|
399
266
|
|
|
400
267
|
/** One declared gap as a report carries it, its members in the schema's order. */
|
|
401
|
-
function wireGap(gap: DeclaredGap):
|
|
268
|
+
function wireGap(gap: DeclaredGap): wire.DeclaredGapsEntry {
|
|
402
269
|
return {
|
|
403
270
|
fixture: gap.fixture,
|
|
404
271
|
...(gap.symbol === undefined ? {} : { symbol: gap.symbol }),
|
|
@@ -408,11 +275,11 @@ function wireGap(gap: DeclaredGap): WireDeclaredGap {
|
|
|
408
275
|
}
|
|
409
276
|
|
|
410
277
|
/** Edge evaluations by edge, then side, then their compact encodings. */
|
|
411
|
-
function byEdge(a:
|
|
278
|
+
function byEdge(a: wire.EdgeEvaluationsEntry, b: wire.EdgeEvaluationsEntry): number {
|
|
412
279
|
return (
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
280
|
+
bytewise(a.edge, b.edge) ||
|
|
281
|
+
bytewise(a.side, b.side) ||
|
|
282
|
+
bytewise(JSON.stringify(a), JSON.stringify(b))
|
|
416
283
|
);
|
|
417
284
|
}
|
|
418
285
|
|
|
@@ -420,7 +287,7 @@ function byEdge(a: WireEdgeEvaluation, b: WireEdgeEvaluation): number {
|
|
|
420
287
|
* The lines a reader deletes by acting on every finding: each distinct component a root
|
|
421
288
|
* finding names, counted once however many of its roots the findings hold.
|
|
422
289
|
*/
|
|
423
|
-
function deletableLines(findings: readonly
|
|
290
|
+
function deletableLines(findings: readonly wire.Finding[]): number {
|
|
424
291
|
const counted = new Map<string, number>();
|
|
425
292
|
for (const finding of findings) {
|
|
426
293
|
if (finding.component.root) {
|
|
@@ -435,7 +302,7 @@ function deletableLines(findings: readonly WireFinding[]): number {
|
|
|
435
302
|
}
|
|
436
303
|
|
|
437
304
|
/** The totals of one finding set, counted over the whole set. */
|
|
438
|
-
function totalsOf(findings: readonly
|
|
305
|
+
function totalsOf(findings: readonly wire.Finding[], result: PassResult): wire.Totals {
|
|
439
306
|
const bySeverity = { allow: 0, warn: 0, deny: 0 };
|
|
440
307
|
for (const finding of findings) {
|
|
441
308
|
bySeverity[finding.severity] += 1;
|
|
@@ -458,22 +325,28 @@ function totalsOf(findings: readonly WireFinding[], result: PassResult): WireTot
|
|
|
458
325
|
}
|
|
459
326
|
|
|
460
327
|
/** Builds the report of one run, every array in the order the Contract fixes for it. */
|
|
461
|
-
export function buildReport(input: ReportInput): Report {
|
|
462
|
-
const
|
|
328
|
+
export function buildReport(input: ReportInput): wire.Report {
|
|
329
|
+
const paired = input.result.findings
|
|
330
|
+
.map((finding) => [wireFinding(finding), finding] as const)
|
|
331
|
+
.sort(([a], [b]) => canonical(a, b));
|
|
332
|
+
const findings = paired.map(([wire]) => wire);
|
|
333
|
+
const evaluated = input.result.edgeEvaluations.flatMap((one) =>
|
|
334
|
+
one.finding === undefined ? [] : [[wireFinding(one.finding), one.finding] as const],
|
|
335
|
+
);
|
|
463
336
|
const unavailable = [...new Map(input.unavailable.map((one) => [one.id, one])).values()]
|
|
464
|
-
.sort((a, b) =>
|
|
337
|
+
.sort((a, b) => bytewise(a.id, b.id))
|
|
465
338
|
.map((one) => ({ id: one.id, role: "consumer" as const, reason: one.reason }));
|
|
466
339
|
const loaded = [...input.loaded]
|
|
467
|
-
.sort((a, b) =>
|
|
340
|
+
.sort((a, b) => bytewise(a.id, b.id) || bytewise(a.path, b.path))
|
|
468
341
|
.map((one) => ({ id: one.id, role: "consumer" as const, path: one.path }));
|
|
469
342
|
return {
|
|
470
343
|
schema_version: SCHEMA_VERSION,
|
|
471
344
|
contract_version: input.contractVersion,
|
|
472
345
|
analyzer: {
|
|
473
|
-
name:
|
|
346
|
+
name: PRODUCT,
|
|
474
347
|
version: input.version,
|
|
475
348
|
languages: [LANGUAGE],
|
|
476
|
-
schema_versions_accepted:
|
|
349
|
+
schema_versions_accepted: SCHEMA_VERSIONS,
|
|
477
350
|
conformance: {
|
|
478
351
|
corpus_version: input.conformance.corpusVersion,
|
|
479
352
|
result: input.conformance.result,
|
|
@@ -482,23 +355,26 @@ export function buildReport(input: ReportInput): Report {
|
|
|
482
355
|
},
|
|
483
356
|
target: { kind: input.target.kind, root: input.target.root, identity: input.target.identity },
|
|
484
357
|
configurations: [...input.configurations]
|
|
485
|
-
.sort((a, b) =>
|
|
358
|
+
.sort((a, b) => bytewise(a.id, b.id))
|
|
486
359
|
.map((one) => ({ id: one.id, project: one.project })),
|
|
487
360
|
configurations_not_built: [...input.notBuilt]
|
|
488
|
-
.sort((a, b) =>
|
|
361
|
+
.sort((a, b) => bytewise(a.id, b.id))
|
|
489
362
|
.map((one) => ({ id: one.id, project: one.project, error: one.error })),
|
|
490
363
|
consumers: { declared: loaded.length + unavailable.length, loaded, unavailable },
|
|
491
364
|
findings,
|
|
365
|
+
...(input.listsComponents === true
|
|
366
|
+
? { components: componentsOf([...paired, ...evaluated]) }
|
|
367
|
+
: {}),
|
|
492
368
|
edge_evaluations: input.result.edgeEvaluations.map(wireEvaluation).sort(byEdge),
|
|
493
369
|
stale_suppressions: input.result.staleSuppressions.map(wireStale).sort(canonicalStale),
|
|
494
370
|
// Every gap shares the one component of the canonical key a gap supplies, the analyzer's
|
|
495
371
|
// name, so the compact encodings alone order them.
|
|
496
372
|
declared_gaps: input.declaredGaps
|
|
497
373
|
.map(wireGap)
|
|
498
|
-
.sort((a, b) =>
|
|
374
|
+
.sort((a, b) => bytewise(JSON.stringify(a), JSON.stringify(b))),
|
|
499
375
|
excluded_by_cgo: [],
|
|
500
376
|
test_file_rules: [...input.testFileRules]
|
|
501
|
-
.sort((a, b) =>
|
|
377
|
+
.sort((a, b) => bytewise(a.rule, b.rule) || a.matched - b.matched)
|
|
502
378
|
.map((one) => ({ rule: one.rule, matched: one.matched })),
|
|
503
379
|
type_error_skips: [
|
|
504
380
|
...new Map(
|
|
@@ -508,14 +384,18 @@ export function buildReport(input: ReportInput): Report {
|
|
|
508
384
|
}),
|
|
509
385
|
),
|
|
510
386
|
]
|
|
511
|
-
.sort(([a, x], [b, y]) =>
|
|
387
|
+
.sort(([a, x], [b, y]) => bytewise(x.path, y.path) || x.line - y.line || bytewise(a, b))
|
|
512
388
|
.map(([, skip]) => skip),
|
|
513
|
-
notes: [],
|
|
389
|
+
notes: [...new Map((input.notes ?? []).map((one) => [JSON.stringify(one), one])).entries()]
|
|
390
|
+
.sort(
|
|
391
|
+
([a, x], [b, y]) => bytewise(x.kind, y.kind) || bytewise(x.path, y.path) || bytewise(a, b),
|
|
392
|
+
)
|
|
393
|
+
.map(([, note]) => note),
|
|
514
394
|
unanswered_questions: [...input.unanswered]
|
|
515
395
|
.sort(
|
|
516
396
|
(a, b) =>
|
|
517
|
-
|
|
518
|
-
|
|
397
|
+
bytewise(a.configuration, b.configuration) ||
|
|
398
|
+
bytewise(JSON.stringify(a), JSON.stringify(b)),
|
|
519
399
|
)
|
|
520
400
|
.map((one) => ({
|
|
521
401
|
configuration: one.configuration,
|
|
@@ -537,8 +417,8 @@ export function buildReport(input: ReportInput): Report {
|
|
|
537
417
|
* whose component a deletion shrinks more comes first, then one whose subject is larger,
|
|
538
418
|
* then the canonical key, so the order stays total; by position it is the canonical key.
|
|
539
419
|
*/
|
|
540
|
-
export function sortFindings(report: Report, by: Sort): Report {
|
|
541
|
-
const bySize = (a:
|
|
420
|
+
export function sortFindings(report: wire.Report, by: Sort): wire.Report {
|
|
421
|
+
const bySize = (a: wire.Finding, b: wire.Finding): number =>
|
|
542
422
|
b.component.deletable_lines - a.component.deletable_lines ||
|
|
543
423
|
b.symbol.size_lines - a.symbol.size_lines ||
|
|
544
424
|
canonical(a, b);
|
|
@@ -546,16 +426,26 @@ export function sortFindings(report: Report, by: Sort): Report {
|
|
|
546
426
|
}
|
|
547
427
|
|
|
548
428
|
/**
|
|
549
|
-
* The report holding the first `most` findings of its order, the rest counted as omitted
|
|
550
|
-
*
|
|
429
|
+
* The report holding the first `most` findings of its order, the rest counted as omitted,
|
|
430
|
+
* and listing only the components those findings name. Every other total keeps describing
|
|
431
|
+
* the whole set. Zero keeps every finding.
|
|
551
432
|
*/
|
|
552
|
-
export function capFindings(report: Report, most: number): Report {
|
|
433
|
+
export function capFindings(report: wire.Report, most: number): wire.Report {
|
|
553
434
|
if (most <= 0 || report.findings.length <= most) {
|
|
554
435
|
return report;
|
|
555
436
|
}
|
|
437
|
+
const findings = report.findings.slice(0, most);
|
|
438
|
+
const named = new Set(
|
|
439
|
+
[...findings, ...report.edge_evaluations.flatMap((one) => one.finding ?? [])].map(
|
|
440
|
+
(finding) => finding.component.id,
|
|
441
|
+
),
|
|
442
|
+
);
|
|
556
443
|
return {
|
|
557
444
|
...report,
|
|
558
|
-
findings
|
|
445
|
+
findings,
|
|
446
|
+
...(report.components === undefined
|
|
447
|
+
? {}
|
|
448
|
+
: { components: report.components.filter((listed) => named.has(listed.id)) }),
|
|
559
449
|
totals: { ...report.totals, omitted: report.findings.length - most },
|
|
560
450
|
};
|
|
561
451
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Severity } from "../contract/contract.generated.ts";
|
|
2
2
|
import { coalesced } from "../json-chunks.ts";
|
|
3
3
|
import { KINDS } from "../kinds.ts";
|
|
4
|
-
import type { Report } from "../report.ts";
|
|
5
|
-
import type { RenderOptions } from "./reporter.ts";
|
|
4
|
+
import type { Report } from "../contract/report.generated.ts";
|
|
6
5
|
|
|
7
6
|
/** The escapes a workflow command's message needs, so a line break does not end the command. */
|
|
8
7
|
const DATA_ESCAPES: Readonly<Record<string, string>> = { "%": "%25", "\r": "%0D", "\n": "%0A" };
|
|
@@ -27,8 +26,18 @@ function kindName(code: string): string {
|
|
|
27
26
|
return KINDS.get(code)?.name ?? code;
|
|
28
27
|
}
|
|
29
28
|
|
|
29
|
+
/** The workflow command a record is written as. */
|
|
30
|
+
type Level = "error" | "warning" | "notice";
|
|
31
|
+
|
|
32
|
+
/** The command each finding severity is annotated with, whatever the failing severity. */
|
|
33
|
+
const LEVELS: Readonly<Record<Severity, Level>> = {
|
|
34
|
+
deny: "error",
|
|
35
|
+
warn: "warning",
|
|
36
|
+
allow: "notice",
|
|
37
|
+
};
|
|
38
|
+
|
|
30
39
|
function command(
|
|
31
|
-
level:
|
|
40
|
+
level: Level,
|
|
32
41
|
at: { readonly path: string; readonly line: number; readonly column: number },
|
|
33
42
|
endLine: number,
|
|
34
43
|
title: string,
|
|
@@ -43,18 +52,17 @@ const SKIP_MESSAGE =
|
|
|
43
52
|
"the analysis did not evaluate the function or statement holding this type error: ";
|
|
44
53
|
|
|
45
54
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* is fixed on at the failing severity.
|
|
55
|
+
* The annotations `contract/grammar/annotations.md` states: one per finding, at the
|
|
56
|
+
* command its severity names, and one error per stale suppression, each naming its file,
|
|
57
|
+
* line, column and last line and titled by its code and kind; then one warning per
|
|
58
|
+
* type-error skip naming its file and line, and one per note naming its directory.
|
|
51
59
|
*/
|
|
52
|
-
export function annotations(report: Report
|
|
60
|
+
export function annotations(report: Report): Iterable<string> {
|
|
53
61
|
return coalesced(
|
|
54
62
|
(function* lines(): Generator<string, void, undefined> {
|
|
55
63
|
for (const found of report.findings) {
|
|
56
64
|
yield `${command(
|
|
57
|
-
|
|
65
|
+
LEVELS[found.severity],
|
|
58
66
|
found.position,
|
|
59
67
|
found.position.end_line,
|
|
60
68
|
`${found.code} ${found.kind}`,
|
|
@@ -73,6 +81,9 @@ export function annotations(report: Report, options: RenderOptions): Iterable<st
|
|
|
73
81
|
for (const skip of report.type_error_skips) {
|
|
74
82
|
yield `::warning file=${escapeProperty(skip.path)},line=${String(skip.line)},title=${escapeProperty(SKIP_TITLE)}::${escapeData(SKIP_MESSAGE + skip.message)}\n`;
|
|
75
83
|
}
|
|
84
|
+
for (const note of report.notes) {
|
|
85
|
+
yield `::warning file=${escapeProperty(note.path)},title=${escapeProperty(note.kind)}::${escapeData(note.message)}\n`;
|
|
86
|
+
}
|
|
76
87
|
})(),
|
|
77
88
|
);
|
|
78
89
|
}
|
package/src/reporters/json.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsonChunks } from "../json-chunks.ts";
|
|
2
|
-
import type { Report } from "../report.ts";
|
|
2
|
+
import type { Report } from "../contract/report.generated.ts";
|
|
3
3
|
|
|
4
4
|
/** The indentation of the report document, which with the schema's member order fixes its bytes. */
|
|
5
5
|
const INDENT = 2;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import type { Format
|
|
2
|
-
import type { Report } from "../report.ts";
|
|
1
|
+
import type { Format } from "../contract/contract.generated.ts";
|
|
2
|
+
import type { Report } from "../contract/report.generated.ts";
|
|
3
3
|
import type { Template } from "./template.ts";
|
|
4
4
|
|
|
5
5
|
/** What a rendering reads beside the report. */
|
|
6
6
|
export interface RenderOptions {
|
|
7
|
-
/** The lowest severity at which a finding fails the run. */
|
|
8
|
-
readonly failOn: Severity;
|
|
9
7
|
/** The text of the file at one path below the target root, or a throw naming why not. */
|
|
10
8
|
readonly readSource: (path: string) => string;
|
|
11
9
|
/** The template the template rendering renders, where one was named. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Format } from "../
|
|
1
|
+
import type { Format } from "../contract/contract.generated.ts";
|
|
2
2
|
import { annotations } from "./annotations.ts";
|
|
3
3
|
import { json } from "./json.ts";
|
|
4
4
|
import { RenderError, type Rendering, type Renderings } from "./reporter.ts";
|