@cplieger/deadset-ts 8.0.0-dev.2 → 8.0.0-dev.20
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 +2 -7
- package/dist/src/amd.js +81 -0
- package/dist/src/analysis.js +269 -432
- 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/calls.js +279 -43
- 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 +1 -1
- 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 +1369 -0
- package/dist/src/contract/report.generated.js +866 -0
- package/dist/src/dependencies.js +164 -121
- 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/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 -66
- 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/framework-lifecycle.js +46 -19
- 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/generated-file.js +174 -28
- 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.js +2 -2
- package/dist/src/indexed-access.js +523 -478
- package/dist/src/injection-container.js +2 -2
- package/dist/src/interface-satisfaction.js +1 -1
- 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 +47 -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/serialization-contract.js +601 -22
- 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/template-field.js +9 -19
- 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 +7 -5
- 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 +2 -9
- package/src/amd.ts +130 -0
- package/src/analysis.ts +424 -650
- package/src/augmentations.ts +93 -4
- package/src/automatic-types.ts +12 -30
- package/src/bindings.ts +460 -0
- package/src/calls.ts +338 -46
- 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 +1 -1
- 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 +1452 -0
- package/src/contract/report.generated.ts +1241 -0
- package/src/dependencies.ts +222 -127
- 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/enum-group.ts +2 -11
- package/src/erased-stores.ts +3 -7
- package/src/exempt-classes.ts +1 -75
- package/src/exempt.ts +70 -98
- 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/framework-lifecycle.ts +47 -19
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +96 -0
- package/src/fs/tree.ts +110 -0
- package/src/generated-file.ts +242 -35
- 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.ts +2 -2
- package/src/indexed-access.ts +570 -527
- package/src/injection-container.ts +2 -2
- package/src/interface-satisfaction.ts +2 -2
- 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 +92 -0
- 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} +27 -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/serialization-contract.ts +769 -23
- 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/template-field.ts +15 -25
- 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 +7 -5
- 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/conventions.js +0 -937
- package/dist/src/discover.js +0 -468
- package/dist/src/entry-points.js +0 -529
- 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/setup-failure.js +0 -23
- package/dist/src/sweep.js +0 -224
- package/dist/src/test-joins.js +0 -101
- package/dist/src/version.js +0 -7
- package/dist/src/workflow-steps.js +0 -185
- package/src/base-url.ts +0 -24
- package/src/discover.ts +0 -653
- package/src/entry-points.ts +0 -687
- 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/setup-failure.ts +0 -39
- package/src/sweep.ts +0 -347
- package/src/test-joins.ts +0 -120
- package/src/version.ts +0 -7
- package/src/workflow-steps.ts +0 -216
package/src/suppress-inline.ts
CHANGED
|
@@ -4,21 +4,24 @@
|
|
|
4
4
|
* below it, or on its own line where it trails a token there.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
SyntaxKind,
|
|
10
|
-
type Node,
|
|
11
|
-
type SourceFile,
|
|
12
|
-
} from "@typescript/native/ast";
|
|
7
|
+
import { CODE } from "./contract/contract.generated.ts";
|
|
8
|
+
import { SyntaxKind, type Node, type SourceFile } from "@typescript/native/ast";
|
|
13
9
|
import { importBindings } from "./import-bindings.ts";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
10
|
+
import { nodeKey, type Inventory } from "./inventory.ts";
|
|
11
|
+
import { relativePath } from "./paths.ts";
|
|
12
|
+
import {
|
|
13
|
+
byPosition,
|
|
14
|
+
lineEnd,
|
|
15
|
+
positionKey,
|
|
16
|
+
renderPosition,
|
|
17
|
+
startLine,
|
|
18
|
+
tokenStart,
|
|
19
|
+
type Position,
|
|
20
|
+
} from "./position.ts";
|
|
16
21
|
import { importRef } from "./ref.ts";
|
|
17
22
|
import type { ProjectView } from "./session.ts";
|
|
18
|
-
import { signatureOf } from "./signatures.ts";
|
|
19
23
|
import {
|
|
20
24
|
isPartKind,
|
|
21
|
-
SUPPRESSION_WITHOUT_REASON,
|
|
22
25
|
SuppressionError,
|
|
23
26
|
siteText,
|
|
24
27
|
type Refusal,
|
|
@@ -88,43 +91,6 @@ const LITERALS: ReadonlySet<SyntaxKind> = new Set([
|
|
|
88
91
|
SyntaxKind.JsxText,
|
|
89
92
|
]);
|
|
90
93
|
|
|
91
|
-
/** Whether one character ends a line, under the language's line terminators. */
|
|
92
|
-
function endsLine(char: string | undefined): boolean {
|
|
93
|
-
return char === "\n" || char === "\r" || char === "\u2028" || char === "\u2029";
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/** The offset where the line holding `from` ends. */
|
|
97
|
-
function lineEnd(text: string, from: number): number {
|
|
98
|
-
let at = from;
|
|
99
|
-
while (at < text.length && !endsLine(text[at])) {
|
|
100
|
-
at += 1;
|
|
101
|
-
}
|
|
102
|
-
return at;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* The offset of the first token at or after `from`: whitespace, comments and a leading
|
|
107
|
-
* hashbang are trivia.
|
|
108
|
-
*/
|
|
109
|
-
export function tokenStart(text: string, from: number): number {
|
|
110
|
-
let at = from;
|
|
111
|
-
if (at === 0 && text.startsWith("#!")) {
|
|
112
|
-
at = lineEnd(text, 0);
|
|
113
|
-
}
|
|
114
|
-
for (;;) {
|
|
115
|
-
if (/\s/u.test(text[at] ?? "")) {
|
|
116
|
-
at += 1;
|
|
117
|
-
} else if (text.startsWith("//", at)) {
|
|
118
|
-
at = lineEnd(text, at);
|
|
119
|
-
} else if (text.startsWith("/*", at)) {
|
|
120
|
-
const close = text.indexOf("*/", at + 2);
|
|
121
|
-
at = close < 0 ? text.length : close + 2;
|
|
122
|
-
} else {
|
|
123
|
-
return at;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
94
|
/**
|
|
129
95
|
* Every `//` line comment of one file, in file order. The text between tokens is read as
|
|
130
96
|
* the language reads it: a block comment holds no line comment, and the literal tokens the
|
|
@@ -191,63 +157,59 @@ function bindingKey(one: Binding): string {
|
|
|
191
157
|
return `${one.declared?.id ?? ""}\u0000${one.part.id}`;
|
|
192
158
|
}
|
|
193
159
|
|
|
160
|
+
/** One declaration the inventory places, the declaration that holds its parts, and its lines. */
|
|
161
|
+
interface Placed {
|
|
162
|
+
readonly one: Declared;
|
|
163
|
+
readonly holder: Declared;
|
|
164
|
+
readonly startLines: readonly number[];
|
|
165
|
+
readonly partLines: readonly number[];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** The placed declarations of a project by the path of the file each is in. */
|
|
169
|
+
function placedByPath(
|
|
170
|
+
held: Inventory,
|
|
171
|
+
symbols: ReadonlyMap<string, Declared>,
|
|
172
|
+
): ReadonlyMap<string, readonly Placed[]> {
|
|
173
|
+
const byPath = new Map<string, Placed[]>();
|
|
174
|
+
for (const [id, placed] of held.placement) {
|
|
175
|
+
const one = symbols.get(id);
|
|
176
|
+
const holder = symbols.get(placed.holder);
|
|
177
|
+
if (one === undefined || holder === undefined) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const at = byPath.get(one.position.path) ?? [];
|
|
181
|
+
at.push({ one, holder, startLines: placed.startLines, partLines: placed.partLines });
|
|
182
|
+
byPath.set(one.position.path, at);
|
|
183
|
+
}
|
|
184
|
+
return byPath;
|
|
185
|
+
}
|
|
186
|
+
|
|
194
187
|
/**
|
|
195
|
-
* The declarations of one file by the line each
|
|
196
|
-
*
|
|
197
|
-
* keyword, and a variable written on a later line of the statement also begins there. A
|
|
198
|
-
* function also begins, for a directive, on the line of each of its parameters, and a
|
|
199
|
-
* class, for a part kind, on the lines of its constructor and its constructor's parameters.
|
|
188
|
+
* The declarations of one file by the line a directive binds each on, as the inventory
|
|
189
|
+
* places them, and each import binding of the file on its statement's lines.
|
|
200
190
|
*/
|
|
201
191
|
function declarationLines(
|
|
202
192
|
file: SourceFile,
|
|
193
|
+
placed: readonly Placed[],
|
|
203
194
|
held: Inventory,
|
|
204
|
-
symbols: ReadonlyMap<string, Declared>,
|
|
205
195
|
targetRoot: string,
|
|
206
196
|
): ReadonlyMap<number, readonly Binding[]> {
|
|
207
197
|
const below = new Map<number, Binding[]>();
|
|
208
|
-
const add = (
|
|
209
|
-
const line = file.getLineAndCharacterOfPosition(tokenStart(file.text, offset)).line + 1;
|
|
198
|
+
const add = (line: number, one: Binding): void => {
|
|
210
199
|
const at = below.get(line) ?? [];
|
|
211
200
|
if (!at.some((known) => bindingKey(known) === bindingKey(one))) {
|
|
212
201
|
at.push(one);
|
|
213
202
|
}
|
|
214
203
|
below.set(line, at);
|
|
215
204
|
};
|
|
216
|
-
const
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
};
|
|
220
|
-
const visit = (node: Node): void => {
|
|
221
|
-
const one = declaredAt(node);
|
|
222
|
-
const owner = isConstructorDeclaration(node) ? declaredAt(node.parent) : undefined;
|
|
223
|
-
if (owner !== undefined && isConstructorDeclaration(node)) {
|
|
224
|
-
for (const at of [node, ...node.parameters.filter((one) => !isParameterProperty(one))]) {
|
|
225
|
-
add(at.pos, { declared: undefined, part: owner });
|
|
226
|
-
}
|
|
205
|
+
for (const { one, holder, startLines, partLines } of placed) {
|
|
206
|
+
for (const line of startLines) {
|
|
207
|
+
add(line, { declared: one, part: holder });
|
|
227
208
|
}
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
if (one !== undefined && holder !== undefined) {
|
|
231
|
-
add(node.pos, { declared: one, part: holder });
|
|
232
|
-
}
|
|
233
|
-
if (one !== undefined) {
|
|
234
|
-
// A parameter on a later line of a wrapped signature takes its directive on the
|
|
235
|
-
// line above it, inside the parameter list, and the directive binds the function.
|
|
236
|
-
for (const parameter of signatureOf(node)?.parameters ?? []) {
|
|
237
|
-
add(parameter.pos, { declared: one, part: one });
|
|
238
|
-
}
|
|
239
|
-
const list = node.parent;
|
|
240
|
-
if (
|
|
241
|
-
node.kind === SyntaxKind.VariableDeclaration &&
|
|
242
|
-
list.kind === SyntaxKind.VariableDeclarationList &&
|
|
243
|
-
list.parent.kind === SyntaxKind.VariableStatement
|
|
244
|
-
) {
|
|
245
|
-
add(list.parent.pos, { declared: one, part: one });
|
|
246
|
-
}
|
|
209
|
+
for (const line of partLines) {
|
|
210
|
+
add(line, { declared: undefined, part: one });
|
|
247
211
|
}
|
|
248
|
-
|
|
249
|
-
};
|
|
250
|
-
file.forEachChild(visit);
|
|
212
|
+
}
|
|
251
213
|
// An import binding is a subject of its own, bound on its line as a declaration is.
|
|
252
214
|
const fileId = held.declarations.get(nodeKey(file, file));
|
|
253
215
|
const moduleRef = held.symbols.find((symbol) => symbol.id === fileId)?.ref ?? "";
|
|
@@ -259,7 +221,7 @@ function declarationLines(
|
|
|
259
221
|
statement = statement.parent;
|
|
260
222
|
}
|
|
261
223
|
for (const at of [statement.pos, name.getStart()]) {
|
|
262
|
-
add(at, { declared: one, part: one });
|
|
224
|
+
add(startLine(file, at), { declared: one, part: one });
|
|
263
225
|
}
|
|
264
226
|
}
|
|
265
227
|
return below;
|
|
@@ -296,13 +258,15 @@ export function inlineDirectives<Brand>(
|
|
|
296
258
|
.filter((symbol) => symbol.kind !== "file")
|
|
297
259
|
.map((symbol) => [symbol.id, { id: symbol.id, ref: symbol.ref, position: symbol.position }]),
|
|
298
260
|
);
|
|
261
|
+
const placed = placedByPath(held, symbols);
|
|
299
262
|
const found: InlineDirective[] = [];
|
|
300
263
|
for (const file of project.ownSourceFiles()) {
|
|
301
264
|
const comments = lineComments(file).filter((comment) => CANDIDATE.test(comment.text));
|
|
302
265
|
if (comments.length === 0) {
|
|
303
266
|
continue;
|
|
304
267
|
}
|
|
305
|
-
const
|
|
268
|
+
const path = relativePath(targetRoot, file.fileName) ?? "";
|
|
269
|
+
const below = declarationLines(file, placed.get(path) ?? [], held, targetRoot);
|
|
306
270
|
for (const comment of comments) {
|
|
307
271
|
const site = renderPosition(file, targetRoot, comment.offset);
|
|
308
272
|
const target = trails(file, comment.offset) ? site.line : site.line + 1;
|
|
@@ -354,7 +318,7 @@ export function inlineSuppressions(
|
|
|
354
318
|
case "no-reason":
|
|
355
319
|
for (const code of directive.codes) {
|
|
356
320
|
refusals.push({
|
|
357
|
-
reported:
|
|
321
|
+
reported: CODE.suppressionWithoutReason,
|
|
358
322
|
code,
|
|
359
323
|
symbol: "",
|
|
360
324
|
path: site.path,
|
package/src/suppress.ts
CHANGED
|
@@ -4,10 +4,17 @@
|
|
|
4
4
|
* ignore entry or a baseline row. A bound record marks its declaration live before the
|
|
5
5
|
* sweep, unless its code reports a part or a dependency row, and is in effect when it
|
|
6
6
|
* withholds a finding its code would have produced there, dormant when the configuration
|
|
7
|
-
* withholds every such finding anyway, and stale otherwise.
|
|
7
|
+
* or a hold withholds every such finding anyway, and stale otherwise.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type CODE,
|
|
12
|
+
KIND_ROWS,
|
|
13
|
+
REMEDIES,
|
|
14
|
+
SYMBOL_SUBJECTS,
|
|
15
|
+
type Subject,
|
|
16
|
+
} from "./contract/contract.generated.ts";
|
|
17
|
+
import { UsageError } from "./usage.ts";
|
|
11
18
|
import type { Finding } from "./finding.ts";
|
|
12
19
|
import { positionKey, type Position } from "./position.ts";
|
|
13
20
|
import { isRef } from "./ref.ts";
|
|
@@ -15,15 +22,6 @@ import { isRef } from "./ref.ts";
|
|
|
15
22
|
/** Which document a suppression is written in, spelled as a finding carries it. */
|
|
16
23
|
export type Mechanism = "inline" | "ignore" | "baseline";
|
|
17
24
|
|
|
18
|
-
/** The code a suppression that carries no reason is reported under. */
|
|
19
|
-
export const SUPPRESSION_WITHOUT_REASON = "DS1701";
|
|
20
|
-
|
|
21
|
-
/** The code an ignore entry or a baseline row that names no path is reported under. */
|
|
22
|
-
export const UNSCOPED_ENTRY = "DS1702";
|
|
23
|
-
|
|
24
|
-
/** The code a suppression that withholds nothing is reported under. */
|
|
25
|
-
export const STALE_SUPPRESSION = "DS1703";
|
|
26
|
-
|
|
27
25
|
/**
|
|
28
26
|
* One suppression record: one code bound to one site. A directive naming two codes is two
|
|
29
27
|
* records with one reason, and a directive above a line that declares two symbols is one
|
|
@@ -49,7 +47,7 @@ export interface SuppressionRecord {
|
|
|
49
47
|
* nothing, and its finding reports the suppression as written.
|
|
50
48
|
*/
|
|
51
49
|
export interface Refusal {
|
|
52
|
-
readonly reported: typeof
|
|
50
|
+
readonly reported: typeof CODE.suppressionWithoutReason | typeof CODE.unscopedIgnoreEntry;
|
|
53
51
|
readonly code: string;
|
|
54
52
|
/** The reference the entry names, empty for a directive. */
|
|
55
53
|
readonly symbol: string;
|
|
@@ -71,9 +69,9 @@ export interface Suppressions {
|
|
|
71
69
|
* instruction the analysis cannot carry out. It is a malformed input, so the command line
|
|
72
70
|
* answers it with the usage code.
|
|
73
71
|
*/
|
|
74
|
-
export class SuppressionError extends
|
|
72
|
+
export class SuppressionError extends UsageError {
|
|
75
73
|
constructor(mechanism: Mechanism, at: string, text: string, want: string) {
|
|
76
|
-
super(
|
|
74
|
+
super(`${mechanism} ${at}: ${text}: want ${want}`);
|
|
77
75
|
this.name = "SuppressionError";
|
|
78
76
|
}
|
|
79
77
|
}
|
|
@@ -150,6 +148,20 @@ export interface Dials<F extends Finding = Finding> {
|
|
|
150
148
|
readonly withholds: (finding: F) => boolean;
|
|
151
149
|
}
|
|
152
150
|
|
|
151
|
+
/**
|
|
152
|
+
* What the analysis holds because it cannot decide it, as the ledger reads it: a hold is a
|
|
153
|
+
* gap, not evidence that the code changed, so a record it touches is dormant.
|
|
154
|
+
*/
|
|
155
|
+
export interface Holds<F extends Finding = Finding> {
|
|
156
|
+
/** Whether a hold withholds one finding: a type error's skip, or a hold of its declaration. */
|
|
157
|
+
readonly withholds: (finding: F) => boolean;
|
|
158
|
+
/** Whether a hold keeps the declaration one record is bound to live, so no finding about it is computed. */
|
|
159
|
+
readonly holdsRecord: (record: SuppressionRecord) => boolean;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** No hold. */
|
|
163
|
+
const NO_HOLDS: Holds = { withholds: () => false, holdsRecord: () => false };
|
|
164
|
+
|
|
153
165
|
/** What every record did, and the findings the records withhold. */
|
|
154
166
|
export interface Ledger {
|
|
155
167
|
/** One verdict per record, in reading order. */
|
|
@@ -158,83 +170,64 @@ export interface Ledger {
|
|
|
158
170
|
readonly withheld: (finding: Finding) => boolean;
|
|
159
171
|
}
|
|
160
172
|
|
|
161
|
-
/**
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
*/
|
|
166
|
-
const DEPENDENCY_SUBJECTS: ReadonlyMap<string, readonly string[]> = new Map([
|
|
167
|
-
["dependency", ["DS1601"]],
|
|
168
|
-
["module-directive", ["DS1605"]],
|
|
169
|
-
]);
|
|
173
|
+
/** The subject of the kind each live code names. */
|
|
174
|
+
const SUBJECT_OF_CODE: ReadonlyMap<string, Subject> = new Map(
|
|
175
|
+
KIND_ROWS.map((row): [string, Subject] => [row.code, row.subject]),
|
|
176
|
+
);
|
|
170
177
|
|
|
171
|
-
/**
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
["file", ["DS1501", "DS1502"]],
|
|
178
|
-
...DEPENDENCY_SUBJECTS,
|
|
179
|
-
["root", ["DS1704"]],
|
|
180
|
-
["configured-declaration", ["DS1706"]],
|
|
181
|
-
["suppression", ["DS1701", "DS1702", "DS1703"]],
|
|
182
|
-
["edge", ["DS1705"]],
|
|
183
|
-
]);
|
|
178
|
+
/** The subject a finding about one symbol kind is about. */
|
|
179
|
+
function subjectOf(kind: string): Subject | undefined {
|
|
180
|
+
return Object.hasOwn(SYMBOL_SUBJECTS, kind)
|
|
181
|
+
? SYMBOL_SUBJECTS[kind as keyof typeof SYMBOL_SUBJECTS]
|
|
182
|
+
: undefined;
|
|
183
|
+
}
|
|
184
184
|
|
|
185
|
-
/** Whether a
|
|
186
|
-
|
|
187
|
-
return
|
|
185
|
+
/** Whether a subject is a row of a document rather than a declaration of the program. */
|
|
186
|
+
function rowOf(subject: Subject | undefined): boolean {
|
|
187
|
+
return subject === "file" || subject === "dependency" || subject === "record";
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
/** Whether a
|
|
191
|
-
export function
|
|
192
|
-
return
|
|
190
|
+
/** Whether a finding's subject is a row of a document rather than a declaration. */
|
|
191
|
+
export function isRowSubject(kind: string): boolean {
|
|
192
|
+
return rowOf(subjectOf(kind));
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
/**
|
|
196
|
-
export function
|
|
197
|
-
return
|
|
195
|
+
/** The subject a code reports, which kinds.json's remedies table answers for. */
|
|
196
|
+
export function subjectOfCode(code: string): Subject | undefined {
|
|
197
|
+
return SUBJECT_OF_CODE.get(code);
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
/**
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
/**
|
|
201
|
+
* Whether a record of `mechanism` can name a finding about `subject`, as kinds.json's
|
|
202
|
+
* remedies table lists the suppressions of each subject. A subject the table does not
|
|
203
|
+
* know is a declaration's.
|
|
204
|
+
*/
|
|
205
|
+
export function names(subject: Subject | undefined, mechanism: Mechanism): boolean {
|
|
206
|
+
return (REMEDIES[subject ?? "declaration"].suppressions as readonly Mechanism[]).includes(
|
|
207
|
+
mechanism,
|
|
208
|
+
);
|
|
203
209
|
}
|
|
204
210
|
|
|
205
|
-
/** Whether a
|
|
206
|
-
export function
|
|
207
|
-
return
|
|
211
|
+
/** Whether a finding about a symbol of `kind` is one a record of `mechanism` can name. */
|
|
212
|
+
export function namesKind(kind: string, mechanism: Mechanism): boolean {
|
|
213
|
+
return names(subjectOf(kind), mechanism);
|
|
208
214
|
}
|
|
209
215
|
|
|
210
216
|
/**
|
|
211
|
-
*
|
|
217
|
+
* Whether a finding's subject is a part of the declaration its reference names: a part
|
|
212
218
|
* has no reference of its own, so a finding about one names the declaration that holds
|
|
213
219
|
* it, and the part is decided inside that declaration whatever uses it.
|
|
214
220
|
*/
|
|
215
|
-
const PART_SUBJECTS: ReadonlySet<string> = new Set([
|
|
216
|
-
"parameter",
|
|
217
|
-
"receiver",
|
|
218
|
-
"result",
|
|
219
|
-
"statement",
|
|
220
|
-
"case",
|
|
221
|
-
"store",
|
|
222
|
-
]);
|
|
223
|
-
|
|
224
|
-
/** Whether a finding's subject is a part of the declaration its reference names. */
|
|
225
221
|
export function isPartSubject(kind: string): boolean {
|
|
226
|
-
return
|
|
222
|
+
return subjectOf(kind) === "part";
|
|
227
223
|
}
|
|
228
224
|
|
|
229
|
-
/** The prefix of the codes of the part kinds, the intra-function range. */
|
|
230
|
-
const PART_KIND_PREFIX = "DS18";
|
|
231
|
-
|
|
232
225
|
/**
|
|
233
226
|
* Whether a code is a part kind, whose record withholds its finding and marks nothing:
|
|
234
227
|
* the record says the part is wanted, not that the declaration holding it is.
|
|
235
228
|
*/
|
|
236
229
|
export function isPartKind(code: string): boolean {
|
|
237
|
-
return
|
|
230
|
+
return SUBJECT_OF_CODE.get(code) === "part";
|
|
238
231
|
}
|
|
239
232
|
|
|
240
233
|
/** One finding's identity: its code and the position of the thing it names. */
|
|
@@ -254,16 +247,13 @@ export function pairs(record: SuppressionRecord, finding: Finding): boolean {
|
|
|
254
247
|
if (record.code !== finding.code) {
|
|
255
248
|
return false;
|
|
256
249
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
record.mechanism !== "inline" &&
|
|
260
|
-
record.symbol === finding.symbol.ref &&
|
|
261
|
-
record.path === finding.position.path
|
|
262
|
-
);
|
|
263
|
-
}
|
|
264
|
-
if (ROW_SUBJECTS.has(finding.symbol.kind)) {
|
|
250
|
+
const subject = subjectOf(finding.symbol.kind);
|
|
251
|
+
if (!names(subject, record.mechanism)) {
|
|
265
252
|
return false;
|
|
266
253
|
}
|
|
254
|
+
if (subject === "dependency") {
|
|
255
|
+
return record.symbol === finding.symbol.ref && record.path === finding.position.path;
|
|
256
|
+
}
|
|
267
257
|
if (record.bound !== "" && record.bound === positionKey(finding.position)) {
|
|
268
258
|
return true;
|
|
269
259
|
}
|
|
@@ -278,13 +268,14 @@ export function pairs(record: SuppressionRecord, finding: Finding): boolean {
|
|
|
278
268
|
* there: swept with no mark for a liveness kind, and as swept otherwise. The first record
|
|
279
269
|
* in reading order claims a finding, so a second naming it is stale; a part-kind record
|
|
280
270
|
* claims every finding of its code about a part of its declaration. A record is dormant
|
|
281
|
-
* when the dials withhold every finding it claims,
|
|
282
|
-
*
|
|
271
|
+
* when the dials or `holds` withhold every finding it claims, or when it claims none and
|
|
272
|
+
* its code is at `allow` or a hold keeps its declaration live.
|
|
283
273
|
*/
|
|
284
274
|
export function ledgerOf<F extends Finding>(
|
|
285
275
|
records: readonly SuppressionRecord[],
|
|
286
276
|
would: readonly F[],
|
|
287
277
|
dials: Dials<F>,
|
|
278
|
+
holds: Holds<F> = NO_HOLDS,
|
|
288
279
|
): Ledger {
|
|
289
280
|
const taken = new Set<string>();
|
|
290
281
|
const verdicts: Verdict[] = [];
|
|
@@ -294,13 +285,21 @@ export function ledgerOf<F extends Finding>(
|
|
|
294
285
|
const claimed =
|
|
295
286
|
first === undefined ? [] : isPartKind(record.code) ? would.filter(open) : [first];
|
|
296
287
|
if (claimed.length === 0) {
|
|
297
|
-
verdicts.push(
|
|
288
|
+
verdicts.push(
|
|
289
|
+
record.bound !== "" && (dials.allows(record.code) || holds.holdsRecord(record))
|
|
290
|
+
? "dormant"
|
|
291
|
+
: "stale",
|
|
292
|
+
);
|
|
298
293
|
continue;
|
|
299
294
|
}
|
|
300
295
|
for (const finding of claimed) {
|
|
301
296
|
taken.add(claimKey(finding));
|
|
302
297
|
}
|
|
303
|
-
verdicts.push(
|
|
298
|
+
verdicts.push(
|
|
299
|
+
claimed.every((finding) => dials.withholds(finding) || holds.withholds(finding))
|
|
300
|
+
? "dormant"
|
|
301
|
+
: "in-effect",
|
|
302
|
+
);
|
|
304
303
|
}
|
|
305
304
|
return {
|
|
306
305
|
verdicts,
|