@cplieger/deadset-ts 8.0.0-dev.2 → 8.0.0-dev.21
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 +3 -1
- package/THIRD_PARTY_NOTICES.md +27 -0
- package/dist/bin/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/alias-chain.js +35 -9
- package/dist/src/amd.js +81 -0
- package/dist/src/analysis.js +274 -496
- package/dist/src/augmentations.js +64 -3
- package/dist/src/automatic-types.js +10 -29
- package/dist/src/bindings.js +382 -0
- package/dist/src/commands/held.js +499 -0
- package/dist/src/commands/read.js +161 -0
- package/dist/src/commands/shell.js +169 -0
- package/dist/src/commands/tools.js +1847 -0
- package/dist/src/component-files.js +3 -2
- package/dist/src/component-layer.js +4 -2
- package/dist/src/config.js +6 -82
- package/dist/src/conformance-record.js +2 -2
- package/dist/src/consumers.js +10 -38
- package/dist/src/contextual-uses.js +57 -26
- package/dist/src/contract/config.generated.js +561 -0
- package/dist/src/contract/contract.generated.js +1370 -0
- package/dist/src/contract/report.generated.js +866 -0
- package/dist/src/dependencies.js +165 -122
- package/dist/src/destructuring.js +1 -19
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +181 -168
- package/dist/src/entries/build-scripts.js +222 -0
- package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
- package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
- package/dist/src/entries/conventions.js +740 -0
- package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
- package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
- package/dist/src/entries/run-directories.js +77 -0
- package/dist/src/entries/sources.js +144 -0
- package/dist/src/entries/static-module.js +670 -0
- package/dist/src/entries/test-runners.js +650 -0
- package/dist/src/entries/workflow-steps.js +345 -0
- package/dist/src/exemptions/argument-places.js +131 -0
- package/dist/src/exemptions/calls.js +338 -0
- package/dist/src/exemptions/classes.js +13 -0
- package/dist/src/{decorator.js → exemptions/decorator.js} +19 -30
- package/dist/src/exemptions/detectors.js +48 -0
- package/dist/src/{enum-group.js → exemptions/enum-group.js} +9 -16
- package/dist/src/{erased-stores.js → exemptions/erased-stores.js} +7 -11
- package/dist/src/{framework-lifecycle.js → exemptions/framework-lifecycle.js} +76 -54
- package/dist/src/exemptions/generated-file.js +241 -0
- package/dist/src/{injection-container.js → exemptions/injection-container.js} +20 -26
- package/dist/src/exemptions/installed-globals.js +173 -0
- package/dist/src/{interface-satisfaction.js → exemptions/interface-satisfaction.js} +52 -121
- package/dist/src/exemptions/lifecycle.js +150 -0
- package/dist/src/{reflective-lookup.js → exemptions/reflective-lookup.js} +3 -3
- package/dist/src/exemptions/serialization-contract.js +1276 -0
- package/dist/src/exemptions/sites.js +182 -0
- package/dist/src/{template-field.js → exemptions/template-field.js} +13 -23
- package/dist/src/{value-reach.js → exemptions/value-reach.js} +14 -7
- package/dist/src/exposure.js +400 -0
- package/dist/src/extensions.js +37 -0
- package/dist/src/facts.js +38 -0
- package/dist/src/failure.js +36 -0
- package/dist/src/file-facts.js +3 -26
- package/dist/src/findings/completion.js +109 -56
- package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
- package/dist/src/findings/emitters.js +27 -41
- package/dist/src/{implementations.js → findings/implementations.js} +3 -3
- package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +16 -13
- package/dist/src/findings/non-code-artifacts.js +17 -12
- package/dist/src/findings/reads-and-writes.js +86 -27
- package/dist/src/findings/self-check.js +44 -30
- package/dist/src/findings/unused-declarations.js +29 -45
- package/dist/src/findings/visibility-narrowing.js +23 -31
- package/dist/src/findings-pass.js +13 -21
- package/dist/src/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +67 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/git-ignore.js +39 -26
- package/dist/src/import-bindings.js +73 -28
- package/dist/src/index/sites.js +557 -0
- package/dist/src/index/values.js +124 -0
- package/dist/src/index.js +2 -2
- package/dist/src/indexed-access.js +523 -478
- package/dist/src/intra-function-parts.js +63 -43
- package/dist/src/inventory/commonjs.js +507 -0
- package/dist/src/inventory/enumerate.js +167 -0
- package/dist/src/inventory/syntax.js +236 -0
- package/dist/src/inventory.js +323 -724
- package/dist/src/javascript-file.js +48 -0
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +126 -107
- package/dist/src/kinds.js +3 -366
- package/dist/src/{components.js → liveness/components.js} +2 -3
- package/dist/src/{graph.js → liveness/graph.js} +52 -28
- package/dist/src/liveness/matrix.js +99 -0
- package/dist/src/liveness/sweep.js +558 -0
- package/dist/src/load/classify.js +289 -0
- package/dist/src/load/diagnostics.js +87 -0
- package/dist/src/load/discover.js +285 -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/package-scope.js +56 -0
- package/dist/src/load/plan.js +313 -0
- package/dist/src/load/specifiers.js +113 -0
- package/dist/src/load/synthesize.js +152 -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} +89 -66
- package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
- 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/module-declarations.js +70 -85
- package/dist/src/overrides.js +134 -112
- package/dist/src/partial.js +2 -1
- package/dist/src/paths.js +82 -16
- package/dist/src/platform-calls.js +78 -0
- package/dist/src/platform-symbols.js +134 -0
- package/dist/src/position.js +43 -1
- package/dist/src/print.js +11 -79
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +95 -0
- package/dist/src/ref.js +12 -20
- package/dist/src/references/read-rule.js +1 -0
- package/dist/src/references/read-rules.js +48 -0
- package/dist/src/references/sink.js +237 -0
- package/dist/src/references/sources.js +450 -0
- package/dist/src/references.js +117 -1074
- package/dist/src/report-schema.js +51 -0
- package/dist/src/report.js +57 -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 +246 -730
- package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
- package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
- package/dist/src/roots/manifest.js +216 -0
- package/dist/src/roots/published-reach.js +412 -0
- package/dist/src/roots/root-set.js +487 -0
- package/dist/src/roots/unseen-loads.js +236 -0
- package/dist/src/run.js +66 -77
- package/dist/src/schema.js +320 -343
- package/dist/src/scope.js +38 -115
- package/dist/src/session.js +37 -29
- package/dist/src/source-files.js +6 -10
- package/dist/src/stores.js +4 -2
- package/dist/src/suppress-file.js +25 -28
- package/dist/src/suppress-inline.js +36 -83
- package/dist/src/suppress.js +50 -71
- package/dist/src/symbol-keys.js +92 -88
- package/dist/src/tests/file-class.js +76 -0
- package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
- package/dist/src/{test-support.js → tests/support.js} +5 -12
- package/dist/src/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/named-files.js +298 -0
- package/dist/src/text/yaml.js +684 -0
- package/dist/src/type-errors.js +11 -232
- package/dist/src/type-parameter-reads.js +178 -139
- package/dist/src/unimplemented-callees.js +262 -242
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/vendor/unbash/ansi-c.js +132 -0
- package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
- package/dist/src/vendor/unbash/arithmetic.js +591 -0
- package/dist/src/vendor/unbash/assignment.js +131 -0
- package/dist/src/vendor/unbash/chars.js +48 -0
- package/dist/src/vendor/unbash/command.js +41 -0
- package/dist/src/vendor/unbash/expansion.js +80 -0
- package/dist/src/vendor/unbash/glob.js +268 -0
- package/dist/src/vendor/unbash/heredoc.js +27 -0
- package/dist/src/vendor/unbash/internal-types.js +1 -0
- package/dist/src/vendor/unbash/lexer.js +4274 -0
- package/dist/src/vendor/unbash/limits.js +3 -0
- package/dist/src/vendor/unbash/parser.js +1366 -0
- package/dist/src/vendor/unbash/parts.js +57 -0
- package/dist/src/vendor/unbash/substitution-context.js +8 -0
- package/dist/src/vendor/unbash/traversal.js +212 -0
- package/dist/src/vendor/unbash/types.js +1 -0
- package/dist/src/vendor/unbash/word-value.js +61 -0
- package/dist/src/vendor/unbash/word.js +40 -0
- package/dist/src/verbs/analyze.js +194 -127
- package/dist/src/verbs/describe.js +13 -18
- package/dist/src/verbs/explain.js +85 -139
- 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 +30 -6
- 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/jsr.json +2 -1
- package/package.json +14 -8
- package/src/alias-chain.ts +40 -11
- package/src/amd.ts +130 -0
- package/src/analysis.ts +426 -733
- package/src/augmentations.ts +93 -4
- package/src/automatic-types.ts +12 -30
- package/src/bindings.ts +460 -0
- package/src/commands/held.ts +632 -0
- package/src/commands/read.ts +242 -0
- package/src/commands/shell.ts +228 -0
- package/src/commands/tools.ts +2382 -0
- package/src/component-files.ts +4 -2
- package/src/component-layer.ts +4 -2
- package/src/config.ts +31 -302
- package/src/conformance-record.ts +2 -2
- package/src/consumers.ts +16 -66
- package/src/contextual-uses.ts +66 -34
- package/src/contract/config.generated.ts +821 -0
- package/src/contract/contract.generated.ts +1453 -0
- package/src/contract/report.generated.ts +1241 -0
- package/src/dependencies.ts +223 -128
- package/src/destructuring.ts +1 -31
- package/src/edges.ts +41 -140
- package/src/element-access.ts +190 -187
- package/src/entries/build-scripts.ts +292 -0
- package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
- package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
- package/src/{conventions.ts → entries/conventions.ts} +367 -583
- package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
- package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
- package/src/entries/run-directories.ts +108 -0
- package/src/entries/sources.ts +266 -0
- package/src/entries/static-module.ts +858 -0
- package/src/entries/test-runners.ts +835 -0
- package/src/entries/workflow-steps.ts +432 -0
- package/src/exemptions/argument-places.ts +198 -0
- package/src/exemptions/calls.ts +483 -0
- package/src/exemptions/classes.ts +49 -0
- package/src/exemptions/decorator.ts +56 -0
- package/src/exemptions/detectors.ts +75 -0
- package/src/{enum-group.ts → exemptions/enum-group.ts} +10 -19
- package/src/{erased-stores.ts → exemptions/erased-stores.ts} +7 -14
- package/src/{framework-lifecycle.ts → exemptions/framework-lifecycle.ts} +85 -66
- package/src/exemptions/generated-file.ts +318 -0
- package/src/{injection-container.ts → exemptions/injection-container.ts} +29 -34
- package/src/exemptions/installed-globals.ts +255 -0
- package/src/{interface-satisfaction.ts → exemptions/interface-satisfaction.ts} +69 -160
- package/src/exemptions/lifecycle.ts +286 -0
- package/src/{reflective-lookup.ts → exemptions/reflective-lookup.ts} +5 -5
- package/src/exemptions/serialization-contract.ts +1729 -0
- package/src/exemptions/sites.ts +293 -0
- package/src/{template-field.ts → exemptions/template-field.ts} +22 -32
- package/src/{value-reach.ts → exemptions/value-reach.ts} +16 -8
- package/src/exposure.ts +492 -0
- package/src/extensions.ts +45 -0
- package/src/facts.ts +46 -0
- package/src/failure.ts +63 -0
- package/src/file-facts.ts +15 -25
- package/src/finding.ts +10 -10
- package/src/findings/boundary.ts +11 -0
- package/src/findings/completion.ts +133 -64
- package/src/findings/dependencies-and-module-machinery.ts +4 -7
- package/src/findings/emitter.ts +9 -10
- package/src/findings/emitters.ts +38 -52
- package/src/{implementations.ts → findings/implementations.ts} +4 -4
- package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
- package/src/findings/interfaces.ts +7 -9
- package/src/findings/intra-function.ts +16 -14
- package/src/findings/non-code-artifacts.ts +24 -15
- package/src/findings/reads-and-writes.ts +118 -41
- package/src/findings/self-check.ts +51 -38
- package/src/findings/unused-declarations.ts +31 -49
- package/src/findings/visibility-narrowing.ts +36 -40
- package/src/findings-pass.ts +15 -31
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +96 -0
- package/src/fs/tree.ts +110 -0
- package/src/git-ignore.ts +50 -26
- package/src/host.ts +12 -5
- package/src/import-bindings.ts +98 -29
- package/src/index/sites.ts +781 -0
- package/src/index/values.ts +170 -0
- package/src/index.ts +2 -2
- package/src/indexed-access.ts +570 -527
- package/src/intra-function-parts.ts +73 -44
- package/src/inventory/commonjs.ts +696 -0
- package/src/inventory/enumerate.ts +203 -0
- package/src/inventory/syntax.ts +311 -0
- package/src/inventory.ts +442 -895
- package/src/javascript-file.ts +54 -0
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +133 -122
- package/src/kinds.ts +5 -413
- package/src/{components.ts → liveness/components.ts} +4 -6
- package/src/{graph.ts → liveness/graph.ts} +100 -35
- package/src/liveness/matrix.ts +162 -0
- package/src/liveness/sweep.ts +855 -0
- package/src/load/classify.ts +433 -0
- package/src/load/diagnostics.ts +154 -0
- package/src/load/discover.ts +471 -0
- package/src/{emit-map.ts → load/emit-map.ts} +1 -1
- package/src/load/expected-module.ts +194 -0
- package/src/load/load.ts +73 -0
- package/src/load/module-lookup.ts +50 -0
- package/src/load/package-scope.ts +74 -0
- package/src/load/plan.ts +513 -0
- package/src/load/specifiers.ts +171 -0
- package/src/load/synthesize.ts +230 -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} +128 -85
- package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
- package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
- package/src/{workspace.ts → load/workspace.ts} +90 -134
- package/src/module-declarations.ts +74 -98
- package/src/overrides.ts +162 -134
- package/src/partial.ts +3 -2
- package/src/paths.ts +92 -16
- package/src/platform-calls.ts +119 -0
- package/src/platform-symbols.ts +189 -0
- package/src/position.ts +44 -1
- package/src/print.ts +12 -92
- package/src/product.ts +18 -0
- package/src/query.ts +201 -10
- package/src/ref.ts +12 -20
- package/src/references/read-rule.ts +60 -0
- package/src/references/read-rules.ts +55 -0
- package/src/references/sink.ts +314 -0
- package/src/references/sources.ts +632 -0
- package/src/references.ts +187 -1450
- package/src/report-schema.ts +68 -0
- package/src/report.ts +103 -226
- 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 +284 -1115
- package/src/{configured-declarations.ts → roots/configured-declarations.ts} +26 -29
- package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
- package/src/roots/manifest.ts +303 -0
- package/src/roots/published-reach.ts +486 -0
- package/src/{roots.ts → roots/root-set.ts} +286 -469
- package/src/roots/unseen-loads.ts +345 -0
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -388
- package/src/scope.ts +46 -138
- package/src/session.ts +87 -55
- package/src/source-files.ts +6 -11
- package/src/stores.ts +15 -3
- package/src/suppress-file.ts +24 -33
- package/src/suppress-inline.ts +55 -91
- package/src/suppress.ts +78 -79
- package/src/symbol-keys.ts +104 -107
- package/src/tests/file-class.ts +135 -0
- package/src/{outside-tests.ts → tests/outside.ts} +16 -10
- package/src/{test-support.ts → tests/support.ts} +15 -21
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/named-files.ts +388 -0
- package/src/text/yaml.ts +747 -0
- package/src/type-errors.ts +18 -288
- package/src/type-parameter-reads.ts +187 -158
- package/src/unimplemented-callees.ts +297 -280
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/vendor/unbash/LICENSE +15 -0
- package/src/vendor/unbash/VENDORED.md +16 -0
- package/src/vendor/unbash/ansi-c.ts +132 -0
- package/src/vendor/unbash/arithmetic-parts.ts +53 -0
- package/src/vendor/unbash/arithmetic.ts +641 -0
- package/src/vendor/unbash/assignment.ts +163 -0
- package/src/vendor/unbash/chars.ts +48 -0
- package/src/vendor/unbash/command.ts +47 -0
- package/src/vendor/unbash/expansion.ts +144 -0
- package/src/vendor/unbash/glob.ts +284 -0
- package/src/vendor/unbash/heredoc.ts +34 -0
- package/src/vendor/unbash/internal-types.ts +94 -0
- package/src/vendor/unbash/lexer.ts +4352 -0
- package/src/vendor/unbash/limits.ts +3 -0
- package/src/vendor/unbash/parser.ts +1612 -0
- package/src/vendor/unbash/parts.ts +96 -0
- package/src/vendor/unbash/substitution-context.ts +20 -0
- package/src/vendor/unbash/traversal.ts +182 -0
- package/src/vendor/unbash/types.ts +660 -0
- package/src/vendor/unbash/word-value.ts +64 -0
- package/src/vendor/unbash/word.ts +50 -0
- package/src/verbs/analyze.ts +255 -164
- package/src/verbs/describe.ts +19 -17
- package/src/verbs/explain.ts +93 -169
- package/src/verbs/print-config.ts +2 -1
- package/src/verbs/print-projects.ts +6 -4
- package/src/verbs/print-retained.ts +36 -6
- package/src/verbs/print-roots.ts +4 -2
- package/src/verbs/verb.ts +2 -8
- package/src/verbs/version.ts +15 -3
- package/dist/src/base-url.js +0 -18
- package/dist/src/calls.js +0 -155
- package/dist/src/conventions.js +0 -937
- package/dist/src/discover.js +0 -468
- package/dist/src/entry-points.js +0 -529
- package/dist/src/exempt-classes.js +0 -75
- package/dist/src/exempt.js +0 -209
- package/dist/src/generated-file.js +0 -95
- package/dist/src/glob.js +0 -65
- package/dist/src/manifest.js +0 -165
- package/dist/src/matrix.js +0 -246
- package/dist/src/pnpm-workspace.js +0 -120
- package/dist/src/roots.js +0 -672
- package/dist/src/serialization-contract.js +0 -611
- package/dist/src/setup-failure.js +0 -23
- package/dist/src/sweep.js +0 -224
- package/dist/src/test-joins.js +0 -101
- package/dist/src/value-flow.js +0 -74
- package/dist/src/version.js +0 -7
- package/dist/src/workflow-steps.js +0 -185
- package/src/base-url.ts +0 -24
- package/src/calls.ts +0 -225
- package/src/decorator.ts +0 -78
- package/src/discover.ts +0 -653
- package/src/entry-points.ts +0 -687
- package/src/exempt-classes.ts +0 -123
- package/src/exempt.ts +0 -323
- package/src/generated-file.ts +0 -111
- package/src/glob.ts +0 -67
- package/src/manifest.ts +0 -234
- package/src/matrix.ts +0 -423
- package/src/pnpm-workspace.ts +0 -135
- package/src/serialization-contract.ts +0 -849
- package/src/setup-failure.ts +0 -39
- package/src/sweep.ts +0 -347
- package/src/test-joins.ts +0 -120
- package/src/value-flow.ts +0 -104
- package/src/version.ts +0 -7
- package/src/workflow-steps.ts +0 -216
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holds a report to `contract/report.schema.json` and `contract/finding.schema.json`
|
|
3
|
+
* before it is written, reading the schemas the generator copies from the Contract, so
|
|
4
|
+
* this analyzer never writes a document a reader refuses.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { REPORT_SCHEMAS, type Report } from "./contract/report.generated.ts";
|
|
8
|
+
import { schemaRefusals, type SchemaRefusal } from "./schema.ts";
|
|
9
|
+
|
|
10
|
+
const reportSchema = schemaRefusals(REPORT_SCHEMAS, "report.schema.json");
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* What the report schema refuses in one report document, none for an instance, and, as
|
|
14
|
+
* no schema keyword can state it, a components listing that is not one entry per
|
|
15
|
+
* component a finding or an edge evaluation's finding names.
|
|
16
|
+
*/
|
|
17
|
+
export function reportRefusals(document: unknown): readonly SchemaRefusal[] {
|
|
18
|
+
const found = reportSchema(document);
|
|
19
|
+
return found.length > 0 ? found : listingRefusals(document as Report);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The components listing held to the components the findings name, once each. */
|
|
23
|
+
function listingRefusals(report: Report): readonly SchemaRefusal[] {
|
|
24
|
+
if (report.components === undefined) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
const refuse = (pointer: string, reason: string): SchemaRefusal[] => [
|
|
28
|
+
{ pointer, keyword: "components", reason, member: "" },
|
|
29
|
+
];
|
|
30
|
+
const listed = new Set<string>();
|
|
31
|
+
for (const [i, entry] of report.components.entries()) {
|
|
32
|
+
if (listed.has(entry.id)) {
|
|
33
|
+
return refuse(
|
|
34
|
+
`/components/${String(i)}`,
|
|
35
|
+
`the entry lists component ${entry.id} a second time`,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
listed.add(entry.id);
|
|
39
|
+
}
|
|
40
|
+
const named = [
|
|
41
|
+
...report.findings.map(
|
|
42
|
+
(finding, i) => [`/findings/${String(i)}`, finding.component.id] as const,
|
|
43
|
+
),
|
|
44
|
+
...report.edge_evaluations.flatMap((one, i) =>
|
|
45
|
+
one.finding === undefined
|
|
46
|
+
? []
|
|
47
|
+
: [[`/edge_evaluations/${String(i)}/finding`, one.finding.component.id] as const],
|
|
48
|
+
),
|
|
49
|
+
];
|
|
50
|
+
for (const [pointer, id] of named) {
|
|
51
|
+
if (!listed.has(id)) {
|
|
52
|
+
return refuse(
|
|
53
|
+
pointer,
|
|
54
|
+
`the finding names component ${id}, which the components listing lacks`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const ids = new Set(named.map(([, id]) => id));
|
|
59
|
+
for (const [i, entry] of report.components.entries()) {
|
|
60
|
+
if (!ids.has(entry.id)) {
|
|
61
|
+
return refuse(
|
|
62
|
+
`/components/${String(i)}`,
|
|
63
|
+
`the entry lists component ${entry.id}, which no finding names`,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return [];
|
|
68
|
+
}
|
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 {
|
|
@@ -13,133 +15,12 @@ import type {
|
|
|
13
15
|
FindingPosition,
|
|
14
16
|
PositionedSymbol,
|
|
15
17
|
} from "./finding.ts";
|
|
16
|
-
import type { AppliedConvention } from "./conventions.ts";
|
|
18
|
+
import type { AppliedConvention } from "./entries/conventions.ts";
|
|
17
19
|
import type { PassResult } from "./findings-pass.ts";
|
|
18
20
|
import type { StaleSuppression } from "./findings/self-check.ts";
|
|
19
|
-
import type { TestFileRule } from "./
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const SCHEMA_VERSION = "9.0.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
|
-
}
|
|
21
|
+
import type { TestFileRule } from "./tests/file-class.ts";
|
|
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,58 +67,21 @@ interface UnavailableConsumer {
|
|
|
186
67
|
readonly reason: string;
|
|
187
68
|
}
|
|
188
69
|
|
|
189
|
-
/** The report document. */
|
|
190
|
-
export interface Report {
|
|
191
|
-
readonly schema_version: string;
|
|
192
|
-
readonly contract_version: string;
|
|
193
|
-
readonly analyzer: {
|
|
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";
|
|
212
|
-
readonly path: string;
|
|
213
|
-
}[];
|
|
214
|
-
readonly unavailable: readonly {
|
|
215
|
-
readonly id: string;
|
|
216
|
-
readonly role: "consumer";
|
|
217
|
-
readonly reason: string;
|
|
218
|
-
}[];
|
|
219
|
-
};
|
|
220
|
-
readonly findings: readonly WireFinding[];
|
|
221
|
-
readonly edge_evaluations: readonly WireEdgeEvaluation[];
|
|
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 ReportNote[];
|
|
228
|
-
readonly unanswered_questions: readonly UnansweredCount[];
|
|
229
|
-
readonly conventions_applied: readonly AppliedConvention[];
|
|
230
|
-
readonly totals: WireTotals;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
70
|
/** One hint about the run's setup, as the report schema's `notes` spells it. */
|
|
234
|
-
export
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
71
|
+
export type ReportNote =
|
|
72
|
+
| {
|
|
73
|
+
readonly kind: "unmapped-entry";
|
|
74
|
+
/** The directory of the manifest the note is about, below the target root. */
|
|
75
|
+
readonly path: string;
|
|
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
|
+
};
|
|
241
85
|
|
|
242
86
|
/** What one run answered, from which its report is built. */
|
|
243
87
|
export interface ReportInput {
|
|
@@ -258,17 +102,32 @@ export interface ReportInput {
|
|
|
258
102
|
readonly conventionsApplied: readonly AppliedConvention[];
|
|
259
103
|
/** The notes the run states, in any order. */
|
|
260
104
|
readonly notes?: readonly ReportNote[];
|
|
105
|
+
/** Whether the run lists each component in full, which `reporters.cascade: full` asks for. */
|
|
106
|
+
readonly listsComponents?: boolean;
|
|
261
107
|
}
|
|
262
108
|
|
|
263
|
-
/**
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
+
}
|
|
267
126
|
}
|
|
268
|
-
return
|
|
127
|
+
return [...listed.values()];
|
|
269
128
|
}
|
|
270
129
|
|
|
271
|
-
function wirePosition(position: FindingPosition):
|
|
130
|
+
function wirePosition(position: FindingPosition): wire.Position {
|
|
272
131
|
return {
|
|
273
132
|
path: position.path,
|
|
274
133
|
line: position.line,
|
|
@@ -280,13 +139,13 @@ function wirePosition(position: FindingPosition): WirePosition {
|
|
|
280
139
|
function wireSymbol(symbol: PositionedSymbol): {
|
|
281
140
|
ref: string;
|
|
282
141
|
name: string;
|
|
283
|
-
position:
|
|
142
|
+
position: wire.Position;
|
|
284
143
|
} {
|
|
285
144
|
return { ref: symbol.ref, name: symbol.name, position: wirePosition(symbol.position) };
|
|
286
145
|
}
|
|
287
146
|
|
|
288
147
|
/** The details one code carries, in the order the finding schema lists them. */
|
|
289
|
-
function wireDetails(details: FindingDetails):
|
|
148
|
+
function wireDetails(details: FindingDetails): wire.Details {
|
|
290
149
|
const { entry } = details;
|
|
291
150
|
return {
|
|
292
151
|
...(details.narrowerVisibility === undefined
|
|
@@ -318,7 +177,7 @@ function wireDetails(details: FindingDetails): WireDetails {
|
|
|
318
177
|
}
|
|
319
178
|
|
|
320
179
|
/** One finding as the finding schema spells it, member for member in its order. */
|
|
321
|
-
export function wireFinding(finding: CompletedFinding):
|
|
180
|
+
export function wireFinding(finding: CompletedFinding): wire.Finding {
|
|
322
181
|
return {
|
|
323
182
|
code: finding.code,
|
|
324
183
|
kind: finding.kind,
|
|
@@ -342,9 +201,6 @@ export function wireFinding(finding: CompletedFinding): WireFinding {
|
|
|
342
201
|
root: finding.component.root,
|
|
343
202
|
symbol_count: finding.component.symbolCount,
|
|
344
203
|
deletable_lines: finding.component.deletableLines,
|
|
345
|
-
...(finding.component.members === undefined
|
|
346
|
-
? {}
|
|
347
|
-
: { members: finding.component.members.map(wireSymbol) }),
|
|
348
204
|
},
|
|
349
205
|
retained_by: finding.retainedBy,
|
|
350
206
|
configurations: finding.configurations,
|
|
@@ -356,7 +212,7 @@ export function wireFinding(finding: CompletedFinding): WireFinding {
|
|
|
356
212
|
};
|
|
357
213
|
}
|
|
358
214
|
|
|
359
|
-
function wireEvaluation(evaluation: EdgeEvaluation<CompletedFinding>):
|
|
215
|
+
function wireEvaluation(evaluation: EdgeEvaluation<CompletedFinding>): wire.EdgeEvaluationsEntry {
|
|
360
216
|
return {
|
|
361
217
|
edge: evaluation.edge,
|
|
362
218
|
side: evaluation.side,
|
|
@@ -366,7 +222,7 @@ function wireEvaluation(evaluation: EdgeEvaluation<CompletedFinding>): WireEdgeE
|
|
|
366
222
|
};
|
|
367
223
|
}
|
|
368
224
|
|
|
369
|
-
function wireStale(stale: StaleSuppression):
|
|
225
|
+
function wireStale(stale: StaleSuppression): wire.StaleSuppressionsEntry {
|
|
370
226
|
return {
|
|
371
227
|
code: stale.code,
|
|
372
228
|
mechanism: stale.mechanism,
|
|
@@ -387,29 +243,29 @@ function wireStale(stale: StaleSuppression): WireStaleSuppression {
|
|
|
387
243
|
}
|
|
388
244
|
|
|
389
245
|
/** The canonical key over two findings: path, line, column, code, then the symbol reference. */
|
|
390
|
-
function canonical(a:
|
|
246
|
+
function canonical(a: wire.Finding, b: wire.Finding): number {
|
|
391
247
|
return (
|
|
392
|
-
|
|
248
|
+
bytewise(a.position.path, b.position.path) ||
|
|
393
249
|
a.position.line - b.position.line ||
|
|
394
250
|
a.position.column - b.position.column ||
|
|
395
|
-
|
|
396
|
-
|
|
251
|
+
bytewise(a.code, b.code) ||
|
|
252
|
+
bytewise(a.symbol.ref, b.symbol.ref)
|
|
397
253
|
);
|
|
398
254
|
}
|
|
399
255
|
|
|
400
256
|
/** The canonical key over two stale suppressions, each component from the record's own member. */
|
|
401
|
-
function canonicalStale(a:
|
|
257
|
+
function canonicalStale(a: wire.StaleSuppressionsEntry, b: wire.StaleSuppressionsEntry): number {
|
|
402
258
|
return (
|
|
403
|
-
|
|
259
|
+
bytewise(a.position.path, b.position.path) ||
|
|
404
260
|
a.position.line - b.position.line ||
|
|
405
261
|
a.position.column - b.position.column ||
|
|
406
|
-
|
|
407
|
-
|
|
262
|
+
bytewise(a.code, b.code) ||
|
|
263
|
+
bytewise(a.symbol, b.symbol)
|
|
408
264
|
);
|
|
409
265
|
}
|
|
410
266
|
|
|
411
267
|
/** One declared gap as a report carries it, its members in the schema's order. */
|
|
412
|
-
function wireGap(gap: DeclaredGap):
|
|
268
|
+
function wireGap(gap: DeclaredGap): wire.DeclaredGapsEntry {
|
|
413
269
|
return {
|
|
414
270
|
fixture: gap.fixture,
|
|
415
271
|
...(gap.symbol === undefined ? {} : { symbol: gap.symbol }),
|
|
@@ -419,11 +275,11 @@ function wireGap(gap: DeclaredGap): WireDeclaredGap {
|
|
|
419
275
|
}
|
|
420
276
|
|
|
421
277
|
/** Edge evaluations by edge, then side, then their compact encodings. */
|
|
422
|
-
function byEdge(a:
|
|
278
|
+
function byEdge(a: wire.EdgeEvaluationsEntry, b: wire.EdgeEvaluationsEntry): number {
|
|
423
279
|
return (
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
280
|
+
bytewise(a.edge, b.edge) ||
|
|
281
|
+
bytewise(a.side, b.side) ||
|
|
282
|
+
bytewise(JSON.stringify(a), JSON.stringify(b))
|
|
427
283
|
);
|
|
428
284
|
}
|
|
429
285
|
|
|
@@ -431,7 +287,7 @@ function byEdge(a: WireEdgeEvaluation, b: WireEdgeEvaluation): number {
|
|
|
431
287
|
* The lines a reader deletes by acting on every finding: each distinct component a root
|
|
432
288
|
* finding names, counted once however many of its roots the findings hold.
|
|
433
289
|
*/
|
|
434
|
-
function deletableLines(findings: readonly
|
|
290
|
+
function deletableLines(findings: readonly wire.Finding[]): number {
|
|
435
291
|
const counted = new Map<string, number>();
|
|
436
292
|
for (const finding of findings) {
|
|
437
293
|
if (finding.component.root) {
|
|
@@ -446,7 +302,7 @@ function deletableLines(findings: readonly WireFinding[]): number {
|
|
|
446
302
|
}
|
|
447
303
|
|
|
448
304
|
/** The totals of one finding set, counted over the whole set. */
|
|
449
|
-
function totalsOf(findings: readonly
|
|
305
|
+
function totalsOf(findings: readonly wire.Finding[], result: PassResult): wire.Totals {
|
|
450
306
|
const bySeverity = { allow: 0, warn: 0, deny: 0 };
|
|
451
307
|
for (const finding of findings) {
|
|
452
308
|
bySeverity[finding.severity] += 1;
|
|
@@ -469,22 +325,28 @@ function totalsOf(findings: readonly WireFinding[], result: PassResult): WireTot
|
|
|
469
325
|
}
|
|
470
326
|
|
|
471
327
|
/** Builds the report of one run, every array in the order the Contract fixes for it. */
|
|
472
|
-
export function buildReport(input: ReportInput): Report {
|
|
473
|
-
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
|
+
);
|
|
474
336
|
const unavailable = [...new Map(input.unavailable.map((one) => [one.id, one])).values()]
|
|
475
|
-
.sort((a, b) =>
|
|
337
|
+
.sort((a, b) => bytewise(a.id, b.id))
|
|
476
338
|
.map((one) => ({ id: one.id, role: "consumer" as const, reason: one.reason }));
|
|
477
339
|
const loaded = [...input.loaded]
|
|
478
|
-
.sort((a, b) =>
|
|
340
|
+
.sort((a, b) => bytewise(a.id, b.id) || bytewise(a.path, b.path))
|
|
479
341
|
.map((one) => ({ id: one.id, role: "consumer" as const, path: one.path }));
|
|
480
342
|
return {
|
|
481
343
|
schema_version: SCHEMA_VERSION,
|
|
482
344
|
contract_version: input.contractVersion,
|
|
483
345
|
analyzer: {
|
|
484
|
-
name:
|
|
346
|
+
name: PRODUCT,
|
|
485
347
|
version: input.version,
|
|
486
348
|
languages: [LANGUAGE],
|
|
487
|
-
schema_versions_accepted:
|
|
349
|
+
schema_versions_accepted: SCHEMA_VERSIONS,
|
|
488
350
|
conformance: {
|
|
489
351
|
corpus_version: input.conformance.corpusVersion,
|
|
490
352
|
result: input.conformance.result,
|
|
@@ -493,23 +355,26 @@ export function buildReport(input: ReportInput): Report {
|
|
|
493
355
|
},
|
|
494
356
|
target: { kind: input.target.kind, root: input.target.root, identity: input.target.identity },
|
|
495
357
|
configurations: [...input.configurations]
|
|
496
|
-
.sort((a, b) =>
|
|
358
|
+
.sort((a, b) => bytewise(a.id, b.id))
|
|
497
359
|
.map((one) => ({ id: one.id, project: one.project })),
|
|
498
360
|
configurations_not_built: [...input.notBuilt]
|
|
499
|
-
.sort((a, b) =>
|
|
361
|
+
.sort((a, b) => bytewise(a.id, b.id))
|
|
500
362
|
.map((one) => ({ id: one.id, project: one.project, error: one.error })),
|
|
501
363
|
consumers: { declared: loaded.length + unavailable.length, loaded, unavailable },
|
|
502
364
|
findings,
|
|
365
|
+
...(input.listsComponents === true
|
|
366
|
+
? { components: componentsOf([...paired, ...evaluated]) }
|
|
367
|
+
: {}),
|
|
503
368
|
edge_evaluations: input.result.edgeEvaluations.map(wireEvaluation).sort(byEdge),
|
|
504
369
|
stale_suppressions: input.result.staleSuppressions.map(wireStale).sort(canonicalStale),
|
|
505
370
|
// Every gap shares the one component of the canonical key a gap supplies, the analyzer's
|
|
506
371
|
// name, so the compact encodings alone order them.
|
|
507
372
|
declared_gaps: input.declaredGaps
|
|
508
373
|
.map(wireGap)
|
|
509
|
-
.sort((a, b) =>
|
|
374
|
+
.sort((a, b) => bytewise(JSON.stringify(a), JSON.stringify(b))),
|
|
510
375
|
excluded_by_cgo: [],
|
|
511
376
|
test_file_rules: [...input.testFileRules]
|
|
512
|
-
.sort((a, b) =>
|
|
377
|
+
.sort((a, b) => bytewise(a.rule, b.rule) || a.matched - b.matched)
|
|
513
378
|
.map((one) => ({ rule: one.rule, matched: one.matched })),
|
|
514
379
|
type_error_skips: [
|
|
515
380
|
...new Map(
|
|
@@ -519,16 +384,18 @@ export function buildReport(input: ReportInput): Report {
|
|
|
519
384
|
}),
|
|
520
385
|
),
|
|
521
386
|
]
|
|
522
|
-
.sort(([a, x], [b, y]) =>
|
|
387
|
+
.sort(([a, x], [b, y]) => bytewise(x.path, y.path) || x.line - y.line || bytewise(a, b))
|
|
523
388
|
.map(([, skip]) => skip),
|
|
524
389
|
notes: [...new Map((input.notes ?? []).map((one) => [JSON.stringify(one), one])).entries()]
|
|
525
|
-
.sort(
|
|
390
|
+
.sort(
|
|
391
|
+
([a, x], [b, y]) => bytewise(x.kind, y.kind) || bytewise(x.path, y.path) || bytewise(a, b),
|
|
392
|
+
)
|
|
526
393
|
.map(([, note]) => note),
|
|
527
394
|
unanswered_questions: [...input.unanswered]
|
|
528
395
|
.sort(
|
|
529
396
|
(a, b) =>
|
|
530
|
-
|
|
531
|
-
|
|
397
|
+
bytewise(a.configuration, b.configuration) ||
|
|
398
|
+
bytewise(JSON.stringify(a), JSON.stringify(b)),
|
|
532
399
|
)
|
|
533
400
|
.map((one) => ({
|
|
534
401
|
configuration: one.configuration,
|
|
@@ -550,8 +417,8 @@ export function buildReport(input: ReportInput): Report {
|
|
|
550
417
|
* whose component a deletion shrinks more comes first, then one whose subject is larger,
|
|
551
418
|
* then the canonical key, so the order stays total; by position it is the canonical key.
|
|
552
419
|
*/
|
|
553
|
-
export function sortFindings(report: Report, by: Sort): Report {
|
|
554
|
-
const bySize = (a:
|
|
420
|
+
export function sortFindings(report: wire.Report, by: Sort): wire.Report {
|
|
421
|
+
const bySize = (a: wire.Finding, b: wire.Finding): number =>
|
|
555
422
|
b.component.deletable_lines - a.component.deletable_lines ||
|
|
556
423
|
b.symbol.size_lines - a.symbol.size_lines ||
|
|
557
424
|
canonical(a, b);
|
|
@@ -559,16 +426,26 @@ export function sortFindings(report: Report, by: Sort): Report {
|
|
|
559
426
|
}
|
|
560
427
|
|
|
561
428
|
/**
|
|
562
|
-
* The report holding the first `most` findings of its order, the rest counted as omitted
|
|
563
|
-
*
|
|
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.
|
|
564
432
|
*/
|
|
565
|
-
export function capFindings(report: Report, most: number): Report {
|
|
433
|
+
export function capFindings(report: wire.Report, most: number): wire.Report {
|
|
566
434
|
if (most <= 0 || report.findings.length <= most) {
|
|
567
435
|
return report;
|
|
568
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
|
+
);
|
|
569
443
|
return {
|
|
570
444
|
...report,
|
|
571
|
-
findings
|
|
445
|
+
findings,
|
|
446
|
+
...(report.components === undefined
|
|
447
|
+
? {}
|
|
448
|
+
: { components: report.components.filter((listed) => named.has(listed.id)) }),
|
|
572
449
|
totals: { ...report.totals, omitted: report.findings.length - most },
|
|
573
450
|
};
|
|
574
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";
|