@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/symbol-keys.ts
CHANGED
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
isIdentifier,
|
|
13
13
|
isNoSubstitutionTemplateLiteral,
|
|
14
14
|
isNumericLiteral,
|
|
15
|
-
isParenthesizedExpression,
|
|
16
15
|
isPropertyAccessExpression,
|
|
17
16
|
isSpreadElement,
|
|
18
17
|
isStringLiteral,
|
|
@@ -21,12 +20,12 @@ import {
|
|
|
21
20
|
type Node,
|
|
22
21
|
type SourceFile,
|
|
23
22
|
} from "@typescript/native/ast";
|
|
23
|
+
import { parenthesesRemoved } from "./unwrap.ts";
|
|
24
24
|
import type { Symbol as TSSymbol, Type } from "@typescript/native/sync";
|
|
25
25
|
import type { AliasChains } from "./alias-chain.ts";
|
|
26
|
-
import
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import type { Reference } from "./references.ts";
|
|
26
|
+
import type { InventorySymbol } from "./inventory.ts";
|
|
27
|
+
import { isAnswered, UNANSWERED, type PropertyTables } from "./query.ts";
|
|
28
|
+
import type { Read, ReadRule } from "./references/read-rule.ts";
|
|
30
29
|
import type { ProjectView } from "./session.ts";
|
|
31
30
|
|
|
32
31
|
/** One element access whose key is a name, and how the access uses the member it selects. */
|
|
@@ -52,10 +51,7 @@ interface KeyedUse {
|
|
|
52
51
|
|
|
53
52
|
/** The identifier an element access's argument names its key by, where it is a name. */
|
|
54
53
|
export function keyNameOf(argument: Node): Node | undefined {
|
|
55
|
-
|
|
56
|
-
while (isParenthesizedExpression(at)) {
|
|
57
|
-
at = at.expression;
|
|
58
|
-
}
|
|
54
|
+
const at = parenthesesRemoved(argument);
|
|
59
55
|
if (isIdentifier(at)) {
|
|
60
56
|
return at;
|
|
61
57
|
}
|
|
@@ -196,104 +192,105 @@ function wellKnownName(name: Node | undefined): string | undefined {
|
|
|
196
192
|
}
|
|
197
193
|
|
|
198
194
|
/**
|
|
199
|
-
* The
|
|
200
|
-
*
|
|
201
|
-
* `
|
|
202
|
-
*
|
|
195
|
+
* The reads the iterations of a side's files make of the iteration members of the values they
|
|
196
|
+
* iterate: a `for…of` statement and a spread element read `[Symbol.iterator]`, and a
|
|
197
|
+
* `for await…of` statement reads `[Symbol.asyncIterator]` and, which it falls back to,
|
|
198
|
+
* `[Symbol.iterator]`. Each is made by the declaration holding it. A value whose type or
|
|
199
|
+
* members the checker leaves unanswered holds the members those names could spell.
|
|
203
200
|
*/
|
|
204
|
-
export
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const fileId = held.declarations.get(nodeKey(file, file));
|
|
221
|
-
if (fileId === undefined) {
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
const visit = (node: Node, from: string): void => {
|
|
225
|
-
const holder = held.declarations.get(nodeKey(file, node)) ?? from;
|
|
226
|
-
if (isForOfStatement(node)) {
|
|
227
|
-
const protocols: readonly Protocol[] =
|
|
228
|
-
node.awaitModifier === undefined ? ["iterator"] : ["asyncIterator", "iterator"];
|
|
229
|
-
iterated.push({ file, from: holder, operand: node.expression, protocols });
|
|
230
|
-
} else if (isSpreadElement(node)) {
|
|
231
|
-
iterated.push({ file, from: holder, operand: node.expression, protocols: ["iterator"] });
|
|
232
|
-
}
|
|
233
|
-
node.forEachChild((child) => {
|
|
234
|
-
visit(child, holder);
|
|
235
|
-
});
|
|
236
|
-
};
|
|
237
|
-
file.forEachChild((child) => {
|
|
238
|
-
visit(child, fileId);
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
if (iterated.length === 0) {
|
|
242
|
-
return [];
|
|
243
|
-
}
|
|
244
|
-
const types = queries.typesAt(iterated.map((one) => one.operand));
|
|
245
|
-
const members = new Map<
|
|
246
|
-
number,
|
|
247
|
-
readonly { readonly name: string; readonly ids: readonly string[] }[]
|
|
248
|
-
>();
|
|
249
|
-
const membersOf = (
|
|
250
|
-
type: Type,
|
|
251
|
-
): readonly { readonly name: string; readonly ids: readonly string[] }[] => {
|
|
252
|
-
const known = members.get(type.id);
|
|
253
|
-
if (known !== undefined) {
|
|
254
|
-
return known;
|
|
255
|
-
}
|
|
256
|
-
const keyed: { name: string; ids: readonly string[] }[] = [];
|
|
257
|
-
const properties = queries.propertiesOf(type);
|
|
258
|
-
for (const property of isAnswered(properties) ? properties : []) {
|
|
259
|
-
for (const handle of property.declarations) {
|
|
260
|
-
const node = ownPaths.has(handle.path) ? project.declarationAt(handle)?.node : undefined;
|
|
261
|
-
const name = wellKnownName((node as { readonly name?: Node } | undefined)?.name);
|
|
262
|
-
if (name !== undefined) {
|
|
263
|
-
keyed.push({ name, ids: chains.declarationsOf(property) });
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
members.set(type.id, keyed);
|
|
269
|
-
return keyed;
|
|
270
|
-
};
|
|
271
|
-
const found: Reference[] = [];
|
|
272
|
-
iterated.forEach((one, index) => {
|
|
273
|
-
const type = types[index];
|
|
274
|
-
if (type === undefined || !isAnswered(type)) {
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
const parts =
|
|
278
|
-
type.isUnionType() || type.isIntersectionType() ? queries.constituents(type) : [type];
|
|
279
|
-
const position = renderPosition(one.file, root, one.operand.getStart());
|
|
280
|
-
for (const part of isAnswered(parts) ? parts : []) {
|
|
281
|
-
for (const member of membersOf(part)) {
|
|
282
|
-
if (!(one.protocols as readonly string[]).includes(member.name)) {
|
|
283
|
-
continue;
|
|
201
|
+
export const iteration: ReadRule = {
|
|
202
|
+
start() {
|
|
203
|
+
const iterated: {
|
|
204
|
+
readonly file: SourceFile;
|
|
205
|
+
readonly from: string;
|
|
206
|
+
readonly operand: Expression;
|
|
207
|
+
readonly protocols: readonly Protocol[];
|
|
208
|
+
}[] = [];
|
|
209
|
+
return {
|
|
210
|
+
visit(node, { file, from }) {
|
|
211
|
+
if (isForOfStatement(node)) {
|
|
212
|
+
const protocols: readonly Protocol[] =
|
|
213
|
+
node.awaitModifier === undefined ? ["iterator"] : ["asyncIterator", "iterator"];
|
|
214
|
+
iterated.push({ file, from, operand: node.expression, protocols });
|
|
215
|
+
} else if (isSpreadElement(node)) {
|
|
216
|
+
iterated.push({ file, from, operand: node.expression, protocols: ["iterator"] });
|
|
284
217
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
use: "read",
|
|
291
|
-
resolution: "keyed",
|
|
292
|
-
test: testFiles.has(position.path),
|
|
293
|
-
});
|
|
218
|
+
},
|
|
219
|
+
reads({ project, chains }) {
|
|
220
|
+
const found: Read[] = [];
|
|
221
|
+
if (iterated.length === 0) {
|
|
222
|
+
return found;
|
|
294
223
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
224
|
+
const queries = project.queries;
|
|
225
|
+
const ownPaths = project.ownPaths();
|
|
226
|
+
const types = queries.typesAt(iterated.map((one) => one.operand));
|
|
227
|
+
const members = new Map<
|
|
228
|
+
number,
|
|
229
|
+
readonly { readonly name: string; readonly ids: readonly string[] }[] | typeof UNANSWERED
|
|
230
|
+
>();
|
|
231
|
+
const membersOf = (type: Type) => {
|
|
232
|
+
const known = members.get(type.id);
|
|
233
|
+
if (known !== undefined) {
|
|
234
|
+
return known;
|
|
235
|
+
}
|
|
236
|
+
const properties = queries.propertiesOf(type);
|
|
237
|
+
const keyed: { name: string; ids: readonly string[] }[] = [];
|
|
238
|
+
for (const property of isAnswered(properties) ? properties : []) {
|
|
239
|
+
for (const handle of property.declarations) {
|
|
240
|
+
const node = ownPaths.has(handle.path)
|
|
241
|
+
? project.declarationAt(handle)?.node
|
|
242
|
+
: undefined;
|
|
243
|
+
const name = wellKnownName((node as { readonly name?: Node } | undefined)?.name);
|
|
244
|
+
if (name !== undefined) {
|
|
245
|
+
keyed.push({ name, ids: chains.declarationsOf(property) });
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const result = isAnswered(properties) ? keyed : UNANSWERED;
|
|
251
|
+
members.set(type.id, result);
|
|
252
|
+
return result;
|
|
253
|
+
};
|
|
254
|
+
// A member a well-known symbol keys is named by the symbol's computed name.
|
|
255
|
+
const spelled = (protocols: readonly Protocol[]): readonly string[] =>
|
|
256
|
+
protocols.map((protocol) => `Symbol.${protocol}`);
|
|
257
|
+
iterated.forEach((one, index) => {
|
|
258
|
+
const type = types[index];
|
|
259
|
+
if (type === UNANSWERED) {
|
|
260
|
+
found.push({ kind: "held", from: one.from, names: spelled(one.protocols) });
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (type === undefined) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const parts =
|
|
267
|
+
type.isUnionType() || type.isIntersectionType() ? queries.constituents(type) : [type];
|
|
268
|
+
for (const part of isAnswered(parts) ? parts : [type]) {
|
|
269
|
+
const keyed = membersOf(part);
|
|
270
|
+
if (keyed === UNANSWERED) {
|
|
271
|
+
found.push({ kind: "held", from: one.from, names: spelled(one.protocols) });
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
for (const member of keyed) {
|
|
275
|
+
if (!(one.protocols as readonly string[]).includes(member.name)) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
for (const to of member.ids) {
|
|
279
|
+
found.push({
|
|
280
|
+
kind: "named",
|
|
281
|
+
from: one.from,
|
|
282
|
+
to,
|
|
283
|
+
file: one.file,
|
|
284
|
+
at: one.operand,
|
|
285
|
+
use: "read",
|
|
286
|
+
via: "keyed",
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
return found;
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
},
|
|
296
|
+
};
|
package/src/template-field.ts
CHANGED
|
@@ -13,13 +13,16 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { readComponent } from "./component-files.ts";
|
|
16
|
-
import {
|
|
16
|
+
import type { ResolvedConfig, TemplateDelimiters } from "./config.ts";
|
|
17
17
|
import type { DetectorInput, Evidence } from "./exempt.ts";
|
|
18
18
|
import type { Host } from "./host.ts";
|
|
19
19
|
import type { SymbolKind } from "./inventory.ts";
|
|
20
20
|
import { memberNames } from "./member-names.ts";
|
|
21
21
|
import { extensionOf, isAbsolutePath, joinPath, normalizePath, relativePath } from "./paths.ts";
|
|
22
22
|
import { isComponentFile, type Position } from "./position.ts";
|
|
23
|
+
import { bytewise } from "./text/compare.ts";
|
|
24
|
+
import { filesBelow } from "./fs/tree.ts";
|
|
25
|
+
import { UsageError } from "./usage.ts";
|
|
23
26
|
|
|
24
27
|
/** One template, by its path below the target root. */
|
|
25
28
|
interface TemplateFile {
|
|
@@ -50,14 +53,6 @@ const READ_BY_MARKUP: ReadonlySet<SymbolKind> = new Set([...READ_BY_A_TEMPLATE,
|
|
|
50
53
|
/** One identifier, as the grammar of the analyzed language spells one. */
|
|
51
54
|
const IDENTIFIER = /[\p{ID_Start}$_][\p{ID_Continue}$\u200C\u200D]*/uy;
|
|
52
55
|
|
|
53
|
-
/** Two strings ordered bytewise. */
|
|
54
|
-
function compare(a: string, b: string): number {
|
|
55
|
-
if (a === b) {
|
|
56
|
-
return 0;
|
|
57
|
-
}
|
|
58
|
-
return a < b ? -1 : 1;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
56
|
/**
|
|
62
57
|
* Every template under the configured directories, read once for the run, in path
|
|
63
58
|
* order and each file once. A directory is named relative to the target root, and
|
|
@@ -66,25 +61,22 @@ function compare(a: string, b: string): number {
|
|
|
66
61
|
* exemption it was configured for off. A symbolic link to a directory is not
|
|
67
62
|
* followed.
|
|
68
63
|
*/
|
|
69
|
-
export function readTemplates(
|
|
64
|
+
export function readTemplates(
|
|
65
|
+
host: Host,
|
|
66
|
+
targetRoot: string,
|
|
67
|
+
analysis: ResolvedConfig["analysis"],
|
|
68
|
+
): Templates {
|
|
70
69
|
const files = new Map<string, string>();
|
|
71
70
|
const read = (dir: string): void => {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
);
|
|
75
|
-
for (const entry of entries) {
|
|
76
|
-
const path = joinPath(dir, entry.name);
|
|
77
|
-
if (entry.directory) {
|
|
78
|
-
read(path);
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
71
|
+
for (const below of filesBelow(host, joinPath(targetRoot, dir), () => true)) {
|
|
72
|
+
const path = joinPath(dir, below);
|
|
81
73
|
const absolute = joinPath(targetRoot, path);
|
|
82
74
|
if (!files.has(path) && host.kindOf(absolute) === "file") {
|
|
83
75
|
files.set(path, host.readFile(absolute));
|
|
84
76
|
}
|
|
85
77
|
}
|
|
86
78
|
};
|
|
87
|
-
for (const configured of analysis.
|
|
79
|
+
for (const configured of analysis.template_dirs) {
|
|
88
80
|
const dir = normalizePath(configured);
|
|
89
81
|
if (
|
|
90
82
|
isAbsolutePath(dir) ||
|
|
@@ -92,19 +84,17 @@ export function readTemplates(host: Host, targetRoot: string, analysis: Analysis
|
|
|
92
84
|
dir.startsWith("../") ||
|
|
93
85
|
host.kindOf(joinPath(targetRoot, dir)) !== "directory"
|
|
94
86
|
) {
|
|
95
|
-
throw new
|
|
96
|
-
"malformed",
|
|
97
|
-
"analysis.template_dirs",
|
|
87
|
+
throw new UsageError(
|
|
98
88
|
`analysis.template_dirs: ${JSON.stringify(configured)} is not a directory below the target root`,
|
|
99
89
|
);
|
|
100
90
|
}
|
|
101
91
|
read(dir);
|
|
102
92
|
}
|
|
103
93
|
return {
|
|
104
|
-
delimiters: analysis.
|
|
94
|
+
delimiters: analysis.template_delimiters,
|
|
105
95
|
files: [...files]
|
|
106
96
|
.map(([path, text]) => ({ path, text }))
|
|
107
|
-
.sort((a, b) =>
|
|
97
|
+
.sort((a, b) => bytewise(a.path, b.path)),
|
|
108
98
|
};
|
|
109
99
|
}
|
|
110
100
|
|
|
@@ -0,0 +1,135 @@
|
|
|
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
|
+
|
|
10
|
+
import type { SourceFile } from "@typescript/native/ast";
|
|
11
|
+
import type { Edge } from "../liveness/graph.ts";
|
|
12
|
+
import { renderPosition } from "../position.ts";
|
|
13
|
+
import type { Reference } from "../references.ts";
|
|
14
|
+
import type { ProjectView } from "../session.ts";
|
|
15
|
+
import { bytewise } from "../text/compare.ts";
|
|
16
|
+
import { globExpression } from "../text/glob.ts";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The run's reference mode, decided once by the composition and read by every stage
|
|
20
|
+
* that counts references.
|
|
21
|
+
*/
|
|
22
|
+
export interface Mode {
|
|
23
|
+
/**
|
|
24
|
+
* Counts no reference a test file made, under either relation. Every reference a root
|
|
25
|
+
* in a test file makes is such a reference, so nothing only a test reaches is live.
|
|
26
|
+
*/
|
|
27
|
+
readonly production: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Classes a reference a loaded consumer's test file made as a production one rather than a
|
|
30
|
+
* test one, `analysis.consumer_tests` at `production`: a classification, not a filter, so it
|
|
31
|
+
* decides the split a candidate reports as well as what a production sweep counts.
|
|
32
|
+
*/
|
|
33
|
+
readonly consumerTestsProduction?: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** One rule that classified files as test files, and how many files it matched. */
|
|
37
|
+
export interface TestFileRule {
|
|
38
|
+
/** The rule's name, as a report's own rule list spells one. */
|
|
39
|
+
readonly rule: string;
|
|
40
|
+
readonly matched: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Whether one file of a side is a test file. */
|
|
44
|
+
export type TestFile = (file: SourceFile) => boolean;
|
|
45
|
+
|
|
46
|
+
/** The test files of the target: each file the test-runner source names, by its file name. */
|
|
47
|
+
export function targetTestFile(named: ReadonlySet<string>): TestFile {
|
|
48
|
+
return (file) => named.has(file.fileName);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** The test files a pattern names, each by its path below `root`: a consumer's, below the consumer's root. */
|
|
52
|
+
export function patternTestFile(patterns: readonly string[], root: string): TestFile {
|
|
53
|
+
const expressions = patterns.map(globExpression);
|
|
54
|
+
return (file) => {
|
|
55
|
+
const path = renderPosition(file, root, 0).path;
|
|
56
|
+
return expressions.some((expression) => expression.test(path));
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The own files of a project that are test files, by their path below `root`, ascending. */
|
|
61
|
+
export function testFilePaths<Brand>(
|
|
62
|
+
project: ProjectView<Brand>,
|
|
63
|
+
root: string,
|
|
64
|
+
testFile: TestFile,
|
|
65
|
+
): readonly string[] {
|
|
66
|
+
return project
|
|
67
|
+
.ownSourceFiles()
|
|
68
|
+
.filter(testFile)
|
|
69
|
+
.map((file) => renderPosition(file, root, 0).path)
|
|
70
|
+
.sort(bytewise);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Whether test code made one reference: a test file, or a test-support file of the target. */
|
|
74
|
+
export function madeByTestCode(reference: Reference, support: ReadonlySet<string>): boolean {
|
|
75
|
+
return (
|
|
76
|
+
reference.test || (reference.consumer === undefined && support.has(reference.position.path))
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Whether the mode classes a reference test code made as a test one: any but a loaded consumer's it classes as production. */
|
|
81
|
+
export function classedAsTest(test: boolean, consumer: boolean, mode: Mode): boolean {
|
|
82
|
+
return test && !(consumer && mode.consumerTestsProduction === true);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Whether a production mode counts no reference of this one: test code made it, as the mode classes it. */
|
|
86
|
+
export function withheldBy(
|
|
87
|
+
mode: Mode,
|
|
88
|
+
reference: Reference,
|
|
89
|
+
support: ReadonlySet<string>,
|
|
90
|
+
): boolean {
|
|
91
|
+
return (
|
|
92
|
+
mode.production &&
|
|
93
|
+
classedAsTest(madeByTestCode(reference, support), reference.consumer !== undefined, mode)
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Whether a production mode follows no edge like this one: {@link withheldBy} for a graph edge. */
|
|
98
|
+
export function edgeWithheldBy(mode: Mode, edge: Edge): boolean {
|
|
99
|
+
return mode.production && classedAsTest(edge.test, edge.consumer, mode);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** The rule a file the analysis classified as test-support code is counted under. */
|
|
103
|
+
const TEST_SUPPORT_RULE = "test-support";
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The name one test-file rule takes. A rule's name is a word list the report's own
|
|
107
|
+
* vocabulary spells, which cannot carry a pattern, so a rule is named by the place of
|
|
108
|
+
* its pattern in the configured list.
|
|
109
|
+
*/
|
|
110
|
+
function patternRule(index: number): string {
|
|
111
|
+
return `test-file-pattern-${String(index + 1)}`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* The rules over the test files of several projects at once, ordered by rule: a file two
|
|
116
|
+
* projects hold is one file, so each rule counts the distinct paths it matches.
|
|
117
|
+
*/
|
|
118
|
+
export function testFileRulesOf(
|
|
119
|
+
testFiles: readonly string[],
|
|
120
|
+
paths: readonly string[],
|
|
121
|
+
supportFiles: readonly string[] = [],
|
|
122
|
+
): readonly TestFileRule[] {
|
|
123
|
+
const distinct = [...new Set(paths)];
|
|
124
|
+
const support = new Set(supportFiles).size;
|
|
125
|
+
return [
|
|
126
|
+
...testFiles.map((pattern, index) => {
|
|
127
|
+
const expression = globExpression(pattern);
|
|
128
|
+
return {
|
|
129
|
+
rule: patternRule(index),
|
|
130
|
+
matched: distinct.filter((path) => expression.test(path)).length,
|
|
131
|
+
};
|
|
132
|
+
}),
|
|
133
|
+
...(support === 0 ? [] : [{ rule: TEST_SUPPORT_RULE, matched: support }]),
|
|
134
|
+
].sort((a, b) => bytewise(a.rule, b.rule));
|
|
135
|
+
}
|
|
@@ -19,19 +19,25 @@ import {
|
|
|
19
19
|
type Node,
|
|
20
20
|
type SourceFile,
|
|
21
21
|
} from "@typescript/native/ast";
|
|
22
|
-
import { RESOLVED_EXTENSIONS, type ParseFile } from "
|
|
23
|
-
import { emittedFrom } from "
|
|
24
|
-
import type { Host } from "
|
|
25
|
-
import type { Inventory } from "
|
|
26
|
-
import { namesImported } from "
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
import { RESOLVED_EXTENSIONS, type ParseFile } from "../entries/configuration-files.ts";
|
|
23
|
+
import { emittedFrom } from "../load/emit-map.ts";
|
|
24
|
+
import type { Host } from "../host.ts";
|
|
25
|
+
import type { Inventory } from "../inventory.ts";
|
|
26
|
+
import { namesImported } from "../import-bindings.ts";
|
|
27
|
+
import {
|
|
28
|
+
dirnamePath,
|
|
29
|
+
joinPath,
|
|
30
|
+
normalizePath,
|
|
31
|
+
queriedModulePath,
|
|
32
|
+
startsRelativePath,
|
|
33
|
+
} from "../paths.ts";
|
|
34
|
+
import { renderPosition } from "../position.ts";
|
|
35
|
+
import { nameComponent } from "../ref.ts";
|
|
36
|
+
import type { Reference } from "../references.ts";
|
|
31
37
|
|
|
32
38
|
/** The paths below the target root one relative specifier may name, written path first. */
|
|
33
39
|
function candidates(dir: string, specifier: string): readonly string[] {
|
|
34
|
-
if (!
|
|
40
|
+
if (!startsRelativePath(specifier)) {
|
|
35
41
|
return [];
|
|
36
42
|
}
|
|
37
43
|
const path = normalizePath(dir === "" ? specifier : `${dir}/${specifier}`);
|
|
@@ -6,11 +6,15 @@
|
|
|
6
6
|
* test code.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
import {
|
|
10
|
+
CONVENTION_ROWS,
|
|
11
|
+
TEST_LIBRARIES,
|
|
12
|
+
TEST_LIBRARY_SCOPES,
|
|
13
|
+
} from "../entries/convention-rows.ts";
|
|
14
|
+
import { packageOfSpecifier } from "../dependencies.ts";
|
|
15
|
+
import type { InventorySymbol } from "../inventory.ts";
|
|
16
|
+
import type { Reference } from "../references.ts";
|
|
17
|
+
import type { Root } from "../roots/root-set.ts";
|
|
14
18
|
|
|
15
19
|
/** The root kind that never takes a file out of test-support code: the skip only withholds. */
|
|
16
20
|
const SKIP_ROOT = "type-error";
|
|
@@ -20,7 +24,12 @@ const SKIP_ROOT = "type-error";
|
|
|
20
24
|
* convention row reads test files for, and the convention table's test libraries.
|
|
21
25
|
*/
|
|
22
26
|
const TEST_PACKAGES: ReadonlySet<string> = new Set([
|
|
23
|
-
...CONVENTION_ROWS.filter(
|
|
27
|
+
...CONVENTION_ROWS.filter(
|
|
28
|
+
(row) =>
|
|
29
|
+
row.testFiles !== undefined ||
|
|
30
|
+
row.testDirectories !== undefined ||
|
|
31
|
+
row.testRunner !== undefined,
|
|
32
|
+
).map((row) => row.package),
|
|
24
33
|
...TEST_LIBRARIES,
|
|
25
34
|
]);
|
|
26
35
|
|
|
@@ -209,18 +218,3 @@ export function testSupportFiles(
|
|
|
209
218
|
);
|
|
210
219
|
return { support, testUsed: new Set([...onlyTests].filter((path) => !support.has(path))) };
|
|
211
220
|
}
|
|
212
|
-
|
|
213
|
-
/** The references with every one a test-support file makes counted as a test reference. */
|
|
214
|
-
export function supportReferences(
|
|
215
|
-
references: readonly Reference[],
|
|
216
|
-
support: ReadonlySet<string>,
|
|
217
|
-
): readonly Reference[] {
|
|
218
|
-
if (support.size === 0) {
|
|
219
|
-
return references;
|
|
220
|
-
}
|
|
221
|
-
return references.map((reference) =>
|
|
222
|
-
!reference.test && support.has(reference.position.path)
|
|
223
|
-
? { ...reference, test: true }
|
|
224
|
-
: reference,
|
|
225
|
-
);
|
|
226
|
-
}
|
|
@@ -0,0 +1,27 @@
|
|
|
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: string, b: string): number {
|
|
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
|
+
|
|
21
|
+
/** One UTF-16 unit moved so that a surrogate ranks above every unit of U+E000 to U+FFFF. */
|
|
22
|
+
function ranked(unit: number): number {
|
|
23
|
+
if (unit >= 0xe000) {
|
|
24
|
+
return unit - 0x800;
|
|
25
|
+
}
|
|
26
|
+
return unit >= 0xd800 ? unit + 0x2000 : unit;
|
|
27
|
+
}
|