@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/dist/src/suppress.js
CHANGED
|
@@ -4,25 +4,20 @@
|
|
|
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
|
-
import {
|
|
9
|
+
import { KIND_ROWS, REMEDIES, SYMBOL_SUBJECTS, } from "./contract/contract.generated.js";
|
|
10
|
+
import { UsageError } from "./usage.js";
|
|
10
11
|
import { positionKey } from "./position.js";
|
|
11
12
|
import { isRef } from "./ref.js";
|
|
12
|
-
/** The code a suppression that carries no reason is reported under. */
|
|
13
|
-
export const SUPPRESSION_WITHOUT_REASON = "DS1701";
|
|
14
|
-
/** The code an ignore entry or a baseline row that names no path is reported under. */
|
|
15
|
-
export const UNSCOPED_ENTRY = "DS1702";
|
|
16
|
-
/** The code a suppression that withholds nothing is reported under. */
|
|
17
|
-
export const STALE_SUPPRESSION = "DS1703";
|
|
18
13
|
/**
|
|
19
14
|
* A directive, an entry or a document the grammar refuses before any finding exists: an
|
|
20
15
|
* instruction the analysis cannot carry out. It is a malformed input, so the command line
|
|
21
16
|
* answers it with the usage code.
|
|
22
17
|
*/
|
|
23
|
-
export class SuppressionError extends
|
|
18
|
+
export class SuppressionError extends UsageError {
|
|
24
19
|
constructor(mechanism, at, text, want) {
|
|
25
|
-
super(
|
|
20
|
+
super(`${mechanism} ${at}: ${text}: want ${want}`);
|
|
26
21
|
this.name = "SuppressionError";
|
|
27
22
|
}
|
|
28
23
|
}
|
|
@@ -71,73 +66,54 @@ export function isSymbolRef(value) {
|
|
|
71
66
|
export function blankReason(reason) {
|
|
72
67
|
return reason === undefined || /^[ \t\r\n]*$/u.test(reason);
|
|
73
68
|
}
|
|
74
|
-
/**
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
*/
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const ROW_SUBJECTS = new Map([
|
|
89
|
-
["file", ["DS1501", "DS1502"]],
|
|
90
|
-
...DEPENDENCY_SUBJECTS,
|
|
91
|
-
["root", ["DS1704"]],
|
|
92
|
-
["configured-declaration", ["DS1706"]],
|
|
93
|
-
["suppression", ["DS1701", "DS1702", "DS1703"]],
|
|
94
|
-
["edge", ["DS1705"]],
|
|
95
|
-
]);
|
|
69
|
+
/** No hold. */
|
|
70
|
+
const NO_HOLDS = { withholds: () => false, holdsRecord: () => false };
|
|
71
|
+
/** The subject of the kind each live code names. */
|
|
72
|
+
const SUBJECT_OF_CODE = new Map(KIND_ROWS.map((row) => [row.code, row.subject]));
|
|
73
|
+
/** The subject a finding about one symbol kind is about. */
|
|
74
|
+
function subjectOf(kind) {
|
|
75
|
+
return Object.hasOwn(SYMBOL_SUBJECTS, kind)
|
|
76
|
+
? SYMBOL_SUBJECTS[kind]
|
|
77
|
+
: undefined;
|
|
78
|
+
}
|
|
79
|
+
/** Whether a subject is a row of a document rather than a declaration of the program. */
|
|
80
|
+
function rowOf(subject) {
|
|
81
|
+
return subject === "file" || subject === "dependency" || subject === "record";
|
|
82
|
+
}
|
|
96
83
|
/** Whether a finding's subject is a row of a document rather than a declaration. */
|
|
97
84
|
export function isRowSubject(kind) {
|
|
98
|
-
return
|
|
85
|
+
return rowOf(subjectOf(kind));
|
|
99
86
|
}
|
|
100
|
-
/**
|
|
101
|
-
export function
|
|
102
|
-
return
|
|
87
|
+
/** The subject a code reports, which kinds.json's remedies table answers for. */
|
|
88
|
+
export function subjectOfCode(code) {
|
|
89
|
+
return SUBJECT_OF_CODE.get(code);
|
|
103
90
|
}
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
export function
|
|
110
|
-
return [
|
|
91
|
+
/**
|
|
92
|
+
* Whether a record of `mechanism` can name a finding about `subject`, as kinds.json's
|
|
93
|
+
* remedies table lists the suppressions of each subject. A subject the table does not
|
|
94
|
+
* know is a declaration's.
|
|
95
|
+
*/
|
|
96
|
+
export function names(subject, mechanism) {
|
|
97
|
+
return REMEDIES[subject ?? "declaration"].suppressions.includes(mechanism);
|
|
111
98
|
}
|
|
112
|
-
/** Whether a
|
|
113
|
-
export function
|
|
114
|
-
return
|
|
99
|
+
/** Whether a finding about a symbol of `kind` is one a record of `mechanism` can name. */
|
|
100
|
+
export function namesKind(kind, mechanism) {
|
|
101
|
+
return names(subjectOf(kind), mechanism);
|
|
115
102
|
}
|
|
116
103
|
/**
|
|
117
|
-
*
|
|
104
|
+
* Whether a finding's subject is a part of the declaration its reference names: a part
|
|
118
105
|
* has no reference of its own, so a finding about one names the declaration that holds
|
|
119
106
|
* it, and the part is decided inside that declaration whatever uses it.
|
|
120
107
|
*/
|
|
121
|
-
const PART_SUBJECTS = new Set([
|
|
122
|
-
"parameter",
|
|
123
|
-
"receiver",
|
|
124
|
-
"result",
|
|
125
|
-
"statement",
|
|
126
|
-
"case",
|
|
127
|
-
"store",
|
|
128
|
-
]);
|
|
129
|
-
/** Whether a finding's subject is a part of the declaration its reference names. */
|
|
130
108
|
export function isPartSubject(kind) {
|
|
131
|
-
return
|
|
109
|
+
return subjectOf(kind) === "part";
|
|
132
110
|
}
|
|
133
|
-
/** The prefix of the codes of the part kinds, the intra-function range. */
|
|
134
|
-
const PART_KIND_PREFIX = "DS18";
|
|
135
111
|
/**
|
|
136
112
|
* Whether a code is a part kind, whose record withholds its finding and marks nothing:
|
|
137
113
|
* the record says the part is wanted, not that the declaration holding it is.
|
|
138
114
|
*/
|
|
139
115
|
export function isPartKind(code) {
|
|
140
|
-
return
|
|
116
|
+
return SUBJECT_OF_CODE.get(code) === "part";
|
|
141
117
|
}
|
|
142
118
|
/** One finding's identity: its code and the position of the thing it names. */
|
|
143
119
|
function claimKey(finding) {
|
|
@@ -155,14 +131,13 @@ export function pairs(record, finding) {
|
|
|
155
131
|
if (record.code !== finding.code) {
|
|
156
132
|
return false;
|
|
157
133
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
record.symbol === finding.symbol.ref &&
|
|
161
|
-
record.path === finding.position.path);
|
|
162
|
-
}
|
|
163
|
-
if (ROW_SUBJECTS.has(finding.symbol.kind)) {
|
|
134
|
+
const subject = subjectOf(finding.symbol.kind);
|
|
135
|
+
if (!names(subject, record.mechanism)) {
|
|
164
136
|
return false;
|
|
165
137
|
}
|
|
138
|
+
if (subject === "dependency") {
|
|
139
|
+
return record.symbol === finding.symbol.ref && record.path === finding.position.path;
|
|
140
|
+
}
|
|
166
141
|
if (record.bound !== "" && record.bound === positionKey(finding.position)) {
|
|
167
142
|
return true;
|
|
168
143
|
}
|
|
@@ -174,10 +149,10 @@ export function pairs(record, finding) {
|
|
|
174
149
|
* there: swept with no mark for a liveness kind, and as swept otherwise. The first record
|
|
175
150
|
* in reading order claims a finding, so a second naming it is stale; a part-kind record
|
|
176
151
|
* claims every finding of its code about a part of its declaration. A record is dormant
|
|
177
|
-
* when the dials withhold every finding it claims,
|
|
178
|
-
*
|
|
152
|
+
* when the dials or `holds` withhold every finding it claims, or when it claims none and
|
|
153
|
+
* its code is at `allow` or a hold keeps its declaration live.
|
|
179
154
|
*/
|
|
180
|
-
export function ledgerOf(records, would, dials) {
|
|
155
|
+
export function ledgerOf(records, would, dials, holds = NO_HOLDS) {
|
|
181
156
|
const taken = new Set();
|
|
182
157
|
const verdicts = [];
|
|
183
158
|
for (const record of records) {
|
|
@@ -185,13 +160,17 @@ export function ledgerOf(records, would, dials) {
|
|
|
185
160
|
const first = would.find(open);
|
|
186
161
|
const claimed = first === undefined ? [] : isPartKind(record.code) ? would.filter(open) : [first];
|
|
187
162
|
if (claimed.length === 0) {
|
|
188
|
-
verdicts.push(record.bound !== "" && dials.allows(record.code)
|
|
163
|
+
verdicts.push(record.bound !== "" && (dials.allows(record.code) || holds.holdsRecord(record))
|
|
164
|
+
? "dormant"
|
|
165
|
+
: "stale");
|
|
189
166
|
continue;
|
|
190
167
|
}
|
|
191
168
|
for (const finding of claimed) {
|
|
192
169
|
taken.add(claimKey(finding));
|
|
193
170
|
}
|
|
194
|
-
verdicts.push(claimed.every((finding) => dials.withholds(finding)
|
|
171
|
+
verdicts.push(claimed.every((finding) => dials.withholds(finding) || holds.withholds(finding))
|
|
172
|
+
? "dormant"
|
|
173
|
+
: "in-effect");
|
|
195
174
|
}
|
|
196
175
|
return {
|
|
197
176
|
verdicts,
|
package/dist/src/symbol-keys.js
CHANGED
|
@@ -5,16 +5,12 @@
|
|
|
5
5
|
* No name node resolves to such a member: the key's name resolves to the constant. An
|
|
6
6
|
* iteration reads the member its well-known iteration symbol keys.
|
|
7
7
|
*/
|
|
8
|
-
import { isComputedPropertyName, isForOfStatement, isIdentifier, isNoSubstitutionTemplateLiteral, isNumericLiteral,
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { isAnswered } from "./query.js";
|
|
8
|
+
import { isComputedPropertyName, isForOfStatement, isIdentifier, isNoSubstitutionTemplateLiteral, isNumericLiteral, isPropertyAccessExpression, isSpreadElement, isStringLiteral, } from "@typescript/native/ast";
|
|
9
|
+
import { parenthesesRemoved } from "./unwrap.js";
|
|
10
|
+
import { isAnswered, UNANSWERED } from "./query.js";
|
|
12
11
|
/** The identifier an element access's argument names its key by, where it is a name. */
|
|
13
12
|
export function keyNameOf(argument) {
|
|
14
|
-
|
|
15
|
-
while (isParenthesizedExpression(at)) {
|
|
16
|
-
at = at.expression;
|
|
17
|
-
}
|
|
13
|
+
const at = parenthesesRemoved(argument);
|
|
18
14
|
if (isIdentifier(at)) {
|
|
19
15
|
return at;
|
|
20
16
|
}
|
|
@@ -129,87 +125,95 @@ function wellKnownName(name) {
|
|
|
129
125
|
: undefined;
|
|
130
126
|
}
|
|
131
127
|
/**
|
|
132
|
-
* The
|
|
133
|
-
*
|
|
134
|
-
* `
|
|
135
|
-
*
|
|
128
|
+
* The reads the iterations of a side's files make of the iteration members of the values they
|
|
129
|
+
* iterate: a `for…of` statement and a spread element read `[Symbol.iterator]`, and a
|
|
130
|
+
* `for await…of` statement reads `[Symbol.asyncIterator]` and, which it falls back to,
|
|
131
|
+
* `[Symbol.iterator]`. Each is made by the declaration holding it. A value whose type or
|
|
132
|
+
* members the checker leaves unanswered holds the members those names could spell.
|
|
136
133
|
*/
|
|
137
|
-
export
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
const visit = (node, from) => {
|
|
147
|
-
const holder = held.declarations.get(nodeKey(file, node)) ?? from;
|
|
148
|
-
if (isForOfStatement(node)) {
|
|
149
|
-
const protocols = node.awaitModifier === undefined ? ["iterator"] : ["asyncIterator", "iterator"];
|
|
150
|
-
iterated.push({ file, from: holder, operand: node.expression, protocols });
|
|
151
|
-
}
|
|
152
|
-
else if (isSpreadElement(node)) {
|
|
153
|
-
iterated.push({ file, from: holder, operand: node.expression, protocols: ["iterator"] });
|
|
154
|
-
}
|
|
155
|
-
node.forEachChild((child) => {
|
|
156
|
-
visit(child, holder);
|
|
157
|
-
});
|
|
158
|
-
};
|
|
159
|
-
file.forEachChild((child) => {
|
|
160
|
-
visit(child, fileId);
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
if (iterated.length === 0) {
|
|
164
|
-
return [];
|
|
165
|
-
}
|
|
166
|
-
const types = queries.typesAt(iterated.map((one) => one.operand));
|
|
167
|
-
const members = new Map();
|
|
168
|
-
const membersOf = (type) => {
|
|
169
|
-
const known = members.get(type.id);
|
|
170
|
-
if (known !== undefined) {
|
|
171
|
-
return known;
|
|
172
|
-
}
|
|
173
|
-
const keyed = [];
|
|
174
|
-
const properties = queries.propertiesOf(type);
|
|
175
|
-
for (const property of isAnswered(properties) ? properties : []) {
|
|
176
|
-
for (const handle of property.declarations) {
|
|
177
|
-
const node = ownPaths.has(handle.path) ? project.declarationAt(handle)?.node : undefined;
|
|
178
|
-
const name = wellKnownName(node?.name);
|
|
179
|
-
if (name !== undefined) {
|
|
180
|
-
keyed.push({ name, ids: chains.declarationsOf(property) });
|
|
181
|
-
break;
|
|
134
|
+
export const iteration = {
|
|
135
|
+
start() {
|
|
136
|
+
const iterated = [];
|
|
137
|
+
return {
|
|
138
|
+
visit(node, { file, from }) {
|
|
139
|
+
if (isForOfStatement(node)) {
|
|
140
|
+
const protocols = node.awaitModifier === undefined ? ["iterator"] : ["asyncIterator", "iterator"];
|
|
141
|
+
iterated.push({ file, from, operand: node.expression, protocols });
|
|
182
142
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
members.set(type.id, keyed);
|
|
186
|
-
return keyed;
|
|
187
|
-
};
|
|
188
|
-
const found = [];
|
|
189
|
-
iterated.forEach((one, index) => {
|
|
190
|
-
const type = types[index];
|
|
191
|
-
if (type === undefined || !isAnswered(type)) {
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
const parts = type.isUnionType() || type.isIntersectionType() ? queries.constituents(type) : [type];
|
|
195
|
-
const position = renderPosition(one.file, root, one.operand.getStart());
|
|
196
|
-
for (const part of isAnswered(parts) ? parts : []) {
|
|
197
|
-
for (const member of membersOf(part)) {
|
|
198
|
-
if (!one.protocols.includes(member.name)) {
|
|
199
|
-
continue;
|
|
143
|
+
else if (isSpreadElement(node)) {
|
|
144
|
+
iterated.push({ file, from, operand: node.expression, protocols: ["iterator"] });
|
|
200
145
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
use: "read",
|
|
207
|
-
resolution: "keyed",
|
|
208
|
-
test: testFiles.has(position.path),
|
|
209
|
-
});
|
|
146
|
+
},
|
|
147
|
+
reads({ project, chains }) {
|
|
148
|
+
const found = [];
|
|
149
|
+
if (iterated.length === 0) {
|
|
150
|
+
return found;
|
|
210
151
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
152
|
+
const queries = project.queries;
|
|
153
|
+
const ownPaths = project.ownPaths();
|
|
154
|
+
const types = queries.typesAt(iterated.map((one) => one.operand));
|
|
155
|
+
const members = new Map();
|
|
156
|
+
const membersOf = (type) => {
|
|
157
|
+
const known = members.get(type.id);
|
|
158
|
+
if (known !== undefined) {
|
|
159
|
+
return known;
|
|
160
|
+
}
|
|
161
|
+
const properties = queries.propertiesOf(type);
|
|
162
|
+
const keyed = [];
|
|
163
|
+
for (const property of isAnswered(properties) ? properties : []) {
|
|
164
|
+
for (const handle of property.declarations) {
|
|
165
|
+
const node = ownPaths.has(handle.path)
|
|
166
|
+
? project.declarationAt(handle)?.node
|
|
167
|
+
: undefined;
|
|
168
|
+
const name = wellKnownName(node?.name);
|
|
169
|
+
if (name !== undefined) {
|
|
170
|
+
keyed.push({ name, ids: chains.declarationsOf(property) });
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const result = isAnswered(properties) ? keyed : UNANSWERED;
|
|
176
|
+
members.set(type.id, result);
|
|
177
|
+
return result;
|
|
178
|
+
};
|
|
179
|
+
// A member a well-known symbol keys is named by the symbol's computed name.
|
|
180
|
+
const spelled = (protocols) => protocols.map((protocol) => `Symbol.${protocol}`);
|
|
181
|
+
iterated.forEach((one, index) => {
|
|
182
|
+
const type = types[index];
|
|
183
|
+
if (type === UNANSWERED) {
|
|
184
|
+
found.push({ kind: "held", from: one.from, names: spelled(one.protocols) });
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (type === undefined) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const parts = type.isUnionType() || type.isIntersectionType() ? queries.constituents(type) : [type];
|
|
191
|
+
for (const part of isAnswered(parts) ? parts : [type]) {
|
|
192
|
+
const keyed = membersOf(part);
|
|
193
|
+
if (keyed === UNANSWERED) {
|
|
194
|
+
found.push({ kind: "held", from: one.from, names: spelled(one.protocols) });
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
for (const member of keyed) {
|
|
198
|
+
if (!one.protocols.includes(member.name)) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
for (const to of member.ids) {
|
|
202
|
+
found.push({
|
|
203
|
+
kind: "named",
|
|
204
|
+
from: one.from,
|
|
205
|
+
to,
|
|
206
|
+
file: one.file,
|
|
207
|
+
at: one.operand,
|
|
208
|
+
use: "read",
|
|
209
|
+
via: "keyed",
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
return found;
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
};
|
|
@@ -12,10 +12,12 @@
|
|
|
12
12
|
* type, because nothing ties the name to a type.
|
|
13
13
|
*/
|
|
14
14
|
import { readComponent } from "./component-files.js";
|
|
15
|
-
import { ConfigError } from "./config.js";
|
|
16
15
|
import { memberNames } from "./member-names.js";
|
|
17
16
|
import { extensionOf, isAbsolutePath, joinPath, normalizePath, relativePath } from "./paths.js";
|
|
18
17
|
import { isComponentFile } from "./position.js";
|
|
18
|
+
import { bytewise } from "./text/compare.js";
|
|
19
|
+
import { filesBelow } from "./fs/tree.js";
|
|
20
|
+
import { UsageError } from "./usage.js";
|
|
19
21
|
/** The kinds of declaration an action can name. */
|
|
20
22
|
const READ_BY_A_TEMPLATE = new Set([
|
|
21
23
|
"method",
|
|
@@ -30,13 +32,6 @@ const READ_BY_A_TEMPLATE = new Set([
|
|
|
30
32
|
const READ_BY_MARKUP = new Set([...READ_BY_A_TEMPLATE, "enum-member"]);
|
|
31
33
|
/** One identifier, as the grammar of the analyzed language spells one. */
|
|
32
34
|
const IDENTIFIER = /[\p{ID_Start}$_][\p{ID_Continue}$\u200C\u200D]*/uy;
|
|
33
|
-
/** Two strings ordered bytewise. */
|
|
34
|
-
function compare(a, b) {
|
|
35
|
-
if (a === b) {
|
|
36
|
-
return 0;
|
|
37
|
-
}
|
|
38
|
-
return a < b ? -1 : 1;
|
|
39
|
-
}
|
|
40
35
|
/**
|
|
41
36
|
* Every template under the configured directories, read once for the run, in path
|
|
42
37
|
* order and each file once. A directory is named relative to the target root, and
|
|
@@ -48,34 +43,29 @@ function compare(a, b) {
|
|
|
48
43
|
export function readTemplates(host, targetRoot, analysis) {
|
|
49
44
|
const files = new Map();
|
|
50
45
|
const read = (dir) => {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const path = joinPath(dir, entry.name);
|
|
54
|
-
if (entry.directory) {
|
|
55
|
-
read(path);
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
46
|
+
for (const below of filesBelow(host, joinPath(targetRoot, dir), () => true)) {
|
|
47
|
+
const path = joinPath(dir, below);
|
|
58
48
|
const absolute = joinPath(targetRoot, path);
|
|
59
49
|
if (!files.has(path) && host.kindOf(absolute) === "file") {
|
|
60
50
|
files.set(path, host.readFile(absolute));
|
|
61
51
|
}
|
|
62
52
|
}
|
|
63
53
|
};
|
|
64
|
-
for (const configured of analysis.
|
|
54
|
+
for (const configured of analysis.template_dirs) {
|
|
65
55
|
const dir = normalizePath(configured);
|
|
66
56
|
if (isAbsolutePath(dir) ||
|
|
67
57
|
dir === ".." ||
|
|
68
58
|
dir.startsWith("../") ||
|
|
69
59
|
host.kindOf(joinPath(targetRoot, dir)) !== "directory") {
|
|
70
|
-
throw new
|
|
60
|
+
throw new UsageError(`analysis.template_dirs: ${JSON.stringify(configured)} is not a directory below the target root`);
|
|
71
61
|
}
|
|
72
62
|
read(dir);
|
|
73
63
|
}
|
|
74
64
|
return {
|
|
75
|
-
delimiters: analysis.
|
|
65
|
+
delimiters: analysis.template_delimiters,
|
|
76
66
|
files: [...files]
|
|
77
67
|
.map(([path, text]) => ({ path, text }))
|
|
78
|
-
.sort((a, b) =>
|
|
68
|
+
.sort((a, b) => bytewise(a.path, b.path)),
|
|
79
69
|
};
|
|
80
70
|
}
|
|
81
71
|
/** The end of the quoted string that opens at `from`, past its closing quote. */
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The file classes the run counts references by. A test file is one a `ts.test_files`
|
|
3
|
+
* pattern or a test runner's row names (the test-runner entry source decides which), a test
|
|
4
|
+
* file no project holds, or a consumer's file a pattern names below the consumer's root.
|
|
5
|
+
* A test-support file is test code as well, decided once the references are known
|
|
6
|
+
* (`support.ts`), so a reference carries only whether a test file made it and the counters
|
|
7
|
+
* read the support class beside it.
|
|
8
|
+
*/
|
|
9
|
+
import { renderPosition } from "../position.js";
|
|
10
|
+
import { bytewise } from "../text/compare.js";
|
|
11
|
+
import { globExpression } from "../text/glob.js";
|
|
12
|
+
/** The test files of the target: each file the test-runner source names, by its file name. */
|
|
13
|
+
export function targetTestFile(named) {
|
|
14
|
+
return (file) => named.has(file.fileName);
|
|
15
|
+
}
|
|
16
|
+
/** The test files a pattern names, each by its path below `root`: a consumer's, below the consumer's root. */
|
|
17
|
+
export function patternTestFile(patterns, root) {
|
|
18
|
+
const expressions = patterns.map(globExpression);
|
|
19
|
+
return (file) => {
|
|
20
|
+
const path = renderPosition(file, root, 0).path;
|
|
21
|
+
return expressions.some((expression) => expression.test(path));
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** The own files of a project that are test files, by their path below `root`, ascending. */
|
|
25
|
+
export function testFilePaths(project, root, testFile) {
|
|
26
|
+
return project
|
|
27
|
+
.ownSourceFiles()
|
|
28
|
+
.filter(testFile)
|
|
29
|
+
.map((file) => renderPosition(file, root, 0).path)
|
|
30
|
+
.sort(bytewise);
|
|
31
|
+
}
|
|
32
|
+
/** Whether test code made one reference: a test file, or a test-support file of the target. */
|
|
33
|
+
export function madeByTestCode(reference, support) {
|
|
34
|
+
return (reference.test || (reference.consumer === undefined && support.has(reference.position.path)));
|
|
35
|
+
}
|
|
36
|
+
/** Whether the mode classes a reference test code made as a test one: any but a loaded consumer's it classes as production. */
|
|
37
|
+
export function classedAsTest(test, consumer, mode) {
|
|
38
|
+
return test && !(consumer && mode.consumerTestsProduction === true);
|
|
39
|
+
}
|
|
40
|
+
/** Whether a production mode counts no reference of this one: test code made it, as the mode classes it. */
|
|
41
|
+
export function withheldBy(mode, reference, support) {
|
|
42
|
+
return (mode.production &&
|
|
43
|
+
classedAsTest(madeByTestCode(reference, support), reference.consumer !== undefined, mode));
|
|
44
|
+
}
|
|
45
|
+
/** Whether a production mode follows no edge like this one: {@link withheldBy} for a graph edge. */
|
|
46
|
+
export function edgeWithheldBy(mode, edge) {
|
|
47
|
+
return mode.production && classedAsTest(edge.test, edge.consumer, mode);
|
|
48
|
+
}
|
|
49
|
+
/** The rule a file the analysis classified as test-support code is counted under. */
|
|
50
|
+
const TEST_SUPPORT_RULE = "test-support";
|
|
51
|
+
/**
|
|
52
|
+
* The name one test-file rule takes. A rule's name is a word list the report's own
|
|
53
|
+
* vocabulary spells, which cannot carry a pattern, so a rule is named by the place of
|
|
54
|
+
* its pattern in the configured list.
|
|
55
|
+
*/
|
|
56
|
+
function patternRule(index) {
|
|
57
|
+
return `test-file-pattern-${String(index + 1)}`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The rules over the test files of several projects at once, ordered by rule: a file two
|
|
61
|
+
* projects hold is one file, so each rule counts the distinct paths it matches.
|
|
62
|
+
*/
|
|
63
|
+
export function testFileRulesOf(testFiles, paths, supportFiles = []) {
|
|
64
|
+
const distinct = [...new Set(paths)];
|
|
65
|
+
const support = new Set(supportFiles).size;
|
|
66
|
+
return [
|
|
67
|
+
...testFiles.map((pattern, index) => {
|
|
68
|
+
const expression = globExpression(pattern);
|
|
69
|
+
return {
|
|
70
|
+
rule: patternRule(index),
|
|
71
|
+
matched: distinct.filter((path) => expression.test(path)).length,
|
|
72
|
+
};
|
|
73
|
+
}),
|
|
74
|
+
...(support === 0 ? [] : [{ rule: TEST_SUPPORT_RULE, matched: support }]),
|
|
75
|
+
].sort((a, b) => bytewise(a.rule, b.rule));
|
|
76
|
+
}
|
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
* it names is not known.
|
|
8
8
|
*/
|
|
9
9
|
import { isCallExpression, isExportDeclaration, isImportDeclaration, isNamespaceExport, isNamespaceImport, isNoSubstitutionTemplateLiteral, isStringLiteral, SyntaxKind, } from "@typescript/native/ast";
|
|
10
|
-
import { RESOLVED_EXTENSIONS } from "
|
|
11
|
-
import { emittedFrom } from "
|
|
12
|
-
import { namesImported } from "
|
|
13
|
-
import { dirnamePath, joinPath, normalizePath, queriedModulePath } from "
|
|
14
|
-
import { renderPosition } from "
|
|
15
|
-
import { nameComponent } from "
|
|
10
|
+
import { RESOLVED_EXTENSIONS } from "../entries/configuration-files.js";
|
|
11
|
+
import { emittedFrom } from "../load/emit-map.js";
|
|
12
|
+
import { namesImported } from "../import-bindings.js";
|
|
13
|
+
import { dirnamePath, joinPath, normalizePath, queriedModulePath, startsRelativePath, } from "../paths.js";
|
|
14
|
+
import { renderPosition } from "../position.js";
|
|
15
|
+
import { nameComponent } from "../ref.js";
|
|
16
16
|
/** The paths below the target root one relative specifier may name, written path first. */
|
|
17
17
|
function candidates(dir, specifier) {
|
|
18
|
-
if (!
|
|
18
|
+
if (!startsRelativePath(specifier)) {
|
|
19
19
|
return [];
|
|
20
20
|
}
|
|
21
21
|
const path = normalizePath(dir === "" ? specifier : `${dir}/${specifier}`);
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* another such file, so it is judged with the tests: what it references is referenced by
|
|
6
6
|
* test code.
|
|
7
7
|
*/
|
|
8
|
-
import { CONVENTION_ROWS, TEST_LIBRARIES, TEST_LIBRARY_SCOPES } from "
|
|
9
|
-
import { packageOfSpecifier } from "
|
|
8
|
+
import { CONVENTION_ROWS, TEST_LIBRARIES, TEST_LIBRARY_SCOPES, } from "../entries/convention-rows.js";
|
|
9
|
+
import { packageOfSpecifier } from "../dependencies.js";
|
|
10
10
|
/** The root kind that never takes a file out of test-support code: the skip only withholds. */
|
|
11
11
|
const SKIP_ROOT = "type-error";
|
|
12
12
|
/**
|
|
@@ -14,7 +14,9 @@ const SKIP_ROOT = "type-error";
|
|
|
14
14
|
* convention row reads test files for, and the convention table's test libraries.
|
|
15
15
|
*/
|
|
16
16
|
const TEST_PACKAGES = new Set([
|
|
17
|
-
...CONVENTION_ROWS.filter((row) => row.testFiles !== undefined
|
|
17
|
+
...CONVENTION_ROWS.filter((row) => row.testFiles !== undefined ||
|
|
18
|
+
row.testDirectories !== undefined ||
|
|
19
|
+
row.testRunner !== undefined).map((row) => row.package),
|
|
18
20
|
...TEST_LIBRARIES,
|
|
19
21
|
]);
|
|
20
22
|
/**
|
|
@@ -161,12 +163,3 @@ export function testSupportFiles(symbols, references, roots, testFiles, evidence
|
|
|
161
163
|
const support = withoutOutsideUsers(new Set([...onlyTests].filter((path) => carries(onlyTests, path))));
|
|
162
164
|
return { support, testUsed: new Set([...onlyTests].filter((path) => !support.has(path))) };
|
|
163
165
|
}
|
|
164
|
-
/** The references with every one a test-support file makes counted as a test reference. */
|
|
165
|
-
export function supportReferences(references, support) {
|
|
166
|
-
if (support.size === 0) {
|
|
167
|
-
return references;
|
|
168
|
-
}
|
|
169
|
-
return references.map((reference) => !reference.test && support.has(reference.position.path)
|
|
170
|
-
? { ...reference, test: true }
|
|
171
|
-
: reference);
|
|
172
|
-
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two strings in the order of their UTF-8 bytes, the order every set of a run is read in.
|
|
3
|
+
* That is code point order, which UTF-16 code unit order (`<` on strings) breaks above
|
|
4
|
+
* U+FFFF: a surrogate unit is below U+E000 while the code point it encodes is above U+FFFF.
|
|
5
|
+
*/
|
|
6
|
+
export function bytewise(a, b) {
|
|
7
|
+
if (a === b) {
|
|
8
|
+
return 0;
|
|
9
|
+
}
|
|
10
|
+
const length = Math.min(a.length, b.length);
|
|
11
|
+
for (let at = 0; at < length; at += 1) {
|
|
12
|
+
const x = a.charCodeAt(at);
|
|
13
|
+
const y = b.charCodeAt(at);
|
|
14
|
+
if (x !== y) {
|
|
15
|
+
return ranked(x) < ranked(y) ? -1 : 1;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return a.length < b.length ? -1 : 1;
|
|
19
|
+
}
|
|
20
|
+
/** One UTF-16 unit moved so that a surrogate ranks above every unit of U+E000 to U+FFFF. */
|
|
21
|
+
function ranked(unit) {
|
|
22
|
+
if (unit >= 0xe000) {
|
|
23
|
+
return unit - 0x800;
|
|
24
|
+
}
|
|
25
|
+
return unit >= 0xd800 ? unit + 0x2000 : unit;
|
|
26
|
+
}
|