@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
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The platform's names read through a program's checker: its `require` and `URL`, as
|
|
3
|
+
* `platform-calls.ts` decides them, its worker constructors and `navigator`, and Node's
|
|
4
|
+
* `Worker`.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
isArrowFunction,
|
|
9
|
+
isClassDeclaration,
|
|
10
|
+
isClassExpression,
|
|
11
|
+
isFunctionDeclaration,
|
|
12
|
+
isFunctionExpression,
|
|
13
|
+
isMethodDeclaration,
|
|
14
|
+
isModuleDeclaration,
|
|
15
|
+
isPropertyAssignment,
|
|
16
|
+
isPropertyDeclaration,
|
|
17
|
+
isSourceFile,
|
|
18
|
+
isStringLiteralLikeNode,
|
|
19
|
+
isVariableDeclaration,
|
|
20
|
+
type Identifier,
|
|
21
|
+
type Node,
|
|
22
|
+
} from "@typescript/native/ast";
|
|
23
|
+
import { SymbolFlags, type Symbol as TSSymbol } from "@typescript/native/sync";
|
|
24
|
+
import { UNANSWERED, type Answer } from "./query.ts";
|
|
25
|
+
import type { ProjectView } from "./session.ts";
|
|
26
|
+
import { boundExports, NAMESPACE } from "./entries/static-module.ts";
|
|
27
|
+
import { isAmbient } from "./inventory.ts";
|
|
28
|
+
import { callsPlatformBy, carriedNames, type BindingOf, type Bound } from "./platform-calls.ts";
|
|
29
|
+
import { unwrapped } from "./unwrap.ts";
|
|
30
|
+
|
|
31
|
+
/** The symbol one symbol names through its aliases, or the symbol itself where it is none. */
|
|
32
|
+
function dealiased<Brand>(project: ProjectView<Brand>, symbol: TSSymbol): Answer<TSSymbol> {
|
|
33
|
+
if ((symbol.flags & SymbolFlags.Alias) === 0) {
|
|
34
|
+
return symbol;
|
|
35
|
+
}
|
|
36
|
+
return project.queries.aliased(symbol);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Each declaration of `symbol` in a file of the target, read in this project's program. */
|
|
40
|
+
function ownDeclarations<Brand>(project: ProjectView<Brand>, symbol: TSSymbol): readonly Node[] {
|
|
41
|
+
const own = project.ownPaths();
|
|
42
|
+
return symbol.declarations.flatMap((handle) => {
|
|
43
|
+
const node = own.has(handle.path) ? project.declarationAt(handle)?.node : undefined;
|
|
44
|
+
return node === undefined ? [] : [node];
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Whether one declaration writes a function or a class with a body (roots.23): a function
|
|
50
|
+
* or method declaration with a body, a class declaration, or a variable, a property or a
|
|
51
|
+
* class field whose initializer is a function, an arrow function or a class expression,
|
|
52
|
+
* under no `declare` modifier and in no declaration file.
|
|
53
|
+
*/
|
|
54
|
+
function writesBody(node: Node): boolean {
|
|
55
|
+
const value =
|
|
56
|
+
(isVariableDeclaration(node) || isPropertyAssignment(node) || isPropertyDeclaration(node)) &&
|
|
57
|
+
node.initializer !== undefined
|
|
58
|
+
? unwrapped(node.initializer)
|
|
59
|
+
: node;
|
|
60
|
+
return (
|
|
61
|
+
(isFunctionDeclaration(value) || isMethodDeclaration(value)
|
|
62
|
+
? value.body !== undefined
|
|
63
|
+
: isFunctionExpression(value) ||
|
|
64
|
+
isArrowFunction(value) ||
|
|
65
|
+
isClassDeclaration(value) ||
|
|
66
|
+
isClassExpression(value)) && !isAmbient(value.getSourceFile(), value)
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* What the checker binds `symbol` to, one alias step at a time: every name a step of the
|
|
72
|
+
* chain carries it by, and the declarations of the target its last step reaches, which
|
|
73
|
+
* prove it the target's own where one {@link writesBody}. A chain that ends at no
|
|
74
|
+
* declaration, or that the checker leaves unanswered, reaches none.
|
|
75
|
+
*/
|
|
76
|
+
function boundBy<Brand>(
|
|
77
|
+
project: ProjectView<Brand>,
|
|
78
|
+
symbol: Answer<TSSymbol> | undefined,
|
|
79
|
+
): Bound | undefined {
|
|
80
|
+
if (typeof symbol !== "object") {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
const names = new Set<string>();
|
|
84
|
+
const stepped = new Set<number>();
|
|
85
|
+
for (let at: TSSymbol | undefined = symbol; at !== undefined && !stepped.has(at.id);) {
|
|
86
|
+
stepped.add(at.id);
|
|
87
|
+
names.add(at.name);
|
|
88
|
+
const own = ownDeclarations(project, at);
|
|
89
|
+
for (const node of own) {
|
|
90
|
+
carriedNames(node).forEach((one) => names.add(one));
|
|
91
|
+
}
|
|
92
|
+
if ((at.flags & SymbolFlags.Alias) === 0) {
|
|
93
|
+
return { names, own, provenOwn: own.some(writesBody) };
|
|
94
|
+
}
|
|
95
|
+
const next = project.aliasStepOf(at);
|
|
96
|
+
at = typeof next === "object" ? next : undefined;
|
|
97
|
+
}
|
|
98
|
+
return { names, own: [], provenOwn: false };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Each written name's binding, as this project's checker answers it. */
|
|
102
|
+
function checkerBinding<Brand>(project: ProjectView<Brand>): BindingOf {
|
|
103
|
+
return (written) => boundBy(project, project.symbolsAt([project.handle(written)])[0]);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Whether a call or construction through `callee`, the batch's answer for which is `symbol`,
|
|
108
|
+
* is one of the platform's `require`, AMD's `define` or `URL` (roots.23, references-ts.37,
|
|
109
|
+
* references-ts.1), as {@link callsPlatformBy} decides it over this project's checker.
|
|
110
|
+
*/
|
|
111
|
+
export function callsPlatform<Brand>(
|
|
112
|
+
project: ProjectView<Brand>,
|
|
113
|
+
name: "require" | "define" | "URL",
|
|
114
|
+
callee: Identifier,
|
|
115
|
+
symbol: Answer<TSSymbol> | undefined,
|
|
116
|
+
): boolean {
|
|
117
|
+
const others = checkerBinding(project);
|
|
118
|
+
return callsPlatformBy(name, callee, (written) =>
|
|
119
|
+
written === callee ? boundBy(project, symbol) : others(written),
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Whether a worker's constructor or `navigator`, the batch's answer for which is `symbol`, is
|
|
125
|
+
* the platform's (references-ts.2): a name the checker leaves unanswered, or one whose symbol
|
|
126
|
+
* is no alias and has a declaration outside the target's files.
|
|
127
|
+
*/
|
|
128
|
+
export function isPlatformGlobal<Brand>(
|
|
129
|
+
project: ProjectView<Brand>,
|
|
130
|
+
symbol: Answer<TSSymbol> | undefined,
|
|
131
|
+
): boolean {
|
|
132
|
+
if (symbol === UNANSWERED) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
const own = project.ownPaths();
|
|
136
|
+
return (
|
|
137
|
+
symbol !== undefined &&
|
|
138
|
+
(symbol.flags & SymbolFlags.Alias) === 0 &&
|
|
139
|
+
symbol.declarations.some((handle) => !own.has(handle.path))
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** The module names Node's worker threads are imported by. */
|
|
144
|
+
const THREADS: ReadonlySet<string> = new Set(["worker_threads", "node:worker_threads"]);
|
|
145
|
+
|
|
146
|
+
function namesThreads(node: Node | undefined): boolean {
|
|
147
|
+
return node !== undefined && isStringLiteralLikeNode(node) && THREADS.has(node.text);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Whether one declaration is written in the body of `declare module "worker_threads"`. */
|
|
151
|
+
function inThreadsModule(node: Node): boolean {
|
|
152
|
+
for (let at = node; !isSourceFile(at); at = at.parent) {
|
|
153
|
+
if (isModuleDeclaration(at) && namesThreads(at.name)) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Whether a `Worker` constructor, the batch's answer for which is `symbol`, is Node's
|
|
162
|
+
* (references-ts.2): its symbol resolves to a declaration of `worker_threads`, or one of its
|
|
163
|
+
* own declarations binds the module's `Worker`, or `holder`, the namespace it is read
|
|
164
|
+
* through, binds the module, each binding read as {@link boundExports} reads one, which
|
|
165
|
+
* decides where the module has no declaration.
|
|
166
|
+
*/
|
|
167
|
+
export function startsThread<Brand>(
|
|
168
|
+
project: ProjectView<Brand>,
|
|
169
|
+
symbol: Answer<TSSymbol> | undefined,
|
|
170
|
+
holder: Answer<TSSymbol> | undefined,
|
|
171
|
+
): boolean {
|
|
172
|
+
const bindingOf = checkerBinding(project);
|
|
173
|
+
const declared = (one: Answer<TSSymbol> | undefined, member: string): boolean =>
|
|
174
|
+
typeof one === "object" &&
|
|
175
|
+
ownDeclarations(project, one).some((node) =>
|
|
176
|
+
boundExports(node, (specifier) => THREADS.has(specifier), bindingOf).includes(member),
|
|
177
|
+
);
|
|
178
|
+
if (declared(symbol, "Worker") || declared(holder, NAMESPACE)) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
const named = typeof symbol === "object" ? dealiased(project, symbol) : undefined;
|
|
182
|
+
return (
|
|
183
|
+
typeof named === "object" &&
|
|
184
|
+
named.declarations.some((handle) => {
|
|
185
|
+
const node = project.declarationAt(handle)?.node;
|
|
186
|
+
return node !== undefined && inThreadsModule(node);
|
|
187
|
+
})
|
|
188
|
+
);
|
|
189
|
+
}
|
package/src/position.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SourceFile } from "@typescript/native/ast";
|
|
2
2
|
import { relativePath } from "./paths.ts";
|
|
3
|
+
import { bytewise } from "./text/compare.ts";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Where one declaration is written, as every report renders it.
|
|
@@ -47,6 +48,48 @@ export function writtenLength(file: SourceFile): number {
|
|
|
47
48
|
return isComponentFile(file) ? file.originalText.length : file.text.length;
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
/** Whether one character ends a line, under the language's line terminators. */
|
|
52
|
+
function endsLine(char: string | undefined): boolean {
|
|
53
|
+
return char === "\n" || char === "\r" || char === "\u2028" || char === "\u2029";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The offset where the line holding `from` ends. */
|
|
57
|
+
export function lineEnd(text: string, from: number): number {
|
|
58
|
+
let at = from;
|
|
59
|
+
while (at < text.length && !endsLine(text[at])) {
|
|
60
|
+
at += 1;
|
|
61
|
+
}
|
|
62
|
+
return at;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The offset of the first token at or after `from`: whitespace, comments and a leading
|
|
67
|
+
* hashbang are trivia.
|
|
68
|
+
*/
|
|
69
|
+
export function tokenStart(text: string, from: number): number {
|
|
70
|
+
let at = from;
|
|
71
|
+
if (at === 0 && text.startsWith("#!")) {
|
|
72
|
+
at = lineEnd(text, 0);
|
|
73
|
+
}
|
|
74
|
+
for (;;) {
|
|
75
|
+
if (/\s/u.test(text[at] ?? "")) {
|
|
76
|
+
at += 1;
|
|
77
|
+
} else if (text.startsWith("//", at)) {
|
|
78
|
+
at = lineEnd(text, at);
|
|
79
|
+
} else if (text.startsWith("/*", at)) {
|
|
80
|
+
const close = text.indexOf("*/", at + 2);
|
|
81
|
+
at = close < 0 ? text.length : close + 2;
|
|
82
|
+
} else {
|
|
83
|
+
return at;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** The line, counted from one, of the first token at or after one offset of one file. */
|
|
89
|
+
export function startLine(file: SourceFile, offset: number): number {
|
|
90
|
+
return file.getLineAndCharacterOfPosition(tokenStart(file.text, offset)).line + 1;
|
|
91
|
+
}
|
|
92
|
+
|
|
50
93
|
/**
|
|
51
94
|
* The position of one offset of one file, rendered against the target root.
|
|
52
95
|
*
|
|
@@ -87,7 +130,7 @@ export function positionKey(position: Position): string {
|
|
|
87
130
|
*/
|
|
88
131
|
export function byPosition(a: Position, b: Position): number {
|
|
89
132
|
if (a.path !== b.path) {
|
|
90
|
-
return a.path
|
|
133
|
+
return bytewise(a.path, b.path);
|
|
91
134
|
}
|
|
92
135
|
if (a.line !== b.line) {
|
|
93
136
|
return a.line - b.line;
|
package/src/print.ts
CHANGED
|
@@ -1,96 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type Config,
|
|
4
|
-
type DeclarationEntry,
|
|
5
|
-
type Provenance,
|
|
6
|
-
type Provider,
|
|
7
|
-
} from "./config.ts";
|
|
8
|
-
|
|
9
|
-
/** One declaration entry as a document writes it: the members of its shape alone. */
|
|
10
|
-
function declarationOf(entry: DeclarationEntry): Record<string, string> {
|
|
11
|
-
switch (entry.shape) {
|
|
12
|
-
case "symbol":
|
|
13
|
-
return { symbol: entry.symbol };
|
|
14
|
-
case "module":
|
|
15
|
-
return { module: entry.module, name: entry.name };
|
|
16
|
-
case "global":
|
|
17
|
-
return { global: entry.global };
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** One provider entry as a document writes it: the members of its shape alone. */
|
|
22
|
-
function providerOf(entry: Provider): Record<string, unknown> {
|
|
23
|
-
const installed = { name: entry.name, languages: entry.languages, command: entry.command };
|
|
24
|
-
if (entry.shape === "installed") {
|
|
25
|
-
return installed;
|
|
26
|
-
}
|
|
27
|
-
return { ...installed, source: entry.source, version: entry.version, digest: entry.digest };
|
|
28
|
-
}
|
|
1
|
+
import { renderOrigin, type Provenance, type ResolvedConfig } from "./config.ts";
|
|
2
|
+
import { bytewise } from "./text/compare.ts";
|
|
29
3
|
|
|
30
4
|
/**
|
|
31
|
-
* The resolved configuration and its provenance as one JSON object, indented,
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* object is a declared key resolution ignores. Keys are written in the schema's
|
|
37
|
-
* order and the severity and provenance objects in ascending key order, so one
|
|
38
|
-
* configuration renders to one string whatever order a source named its settings
|
|
39
|
-
* in.
|
|
5
|
+
* The resolved configuration and its provenance as one JSON object, indented, ending
|
|
6
|
+
* in a newline: the configuration in the order resolution gives it, then the provenance
|
|
7
|
+
* object in ascending key order. Read back as a repository configuration it resolves to
|
|
8
|
+
* the same configuration, because resolution checks the provenance object and then
|
|
9
|
+
* ignores it.
|
|
40
10
|
*/
|
|
41
|
-
export function printConfig(config:
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
languages: config.analysis.languages,
|
|
47
|
-
min_confidence: config.analysis.minConfidence,
|
|
48
|
-
generated_files: config.analysis.generatedFiles,
|
|
49
|
-
consumer_tests: config.analysis.consumerTests,
|
|
50
|
-
configurations: config.analysis.configurations.map((entry) =>
|
|
51
|
-
entry.shape === "project"
|
|
52
|
-
? { id: entry.id, project: entry.project }
|
|
53
|
-
: { id: entry.id, os: entry.os, arch: entry.arch, tags: entry.tags },
|
|
54
|
-
),
|
|
55
|
-
matrix: { complete: config.analysis.matrixComplete },
|
|
56
|
-
template_dirs: config.analysis.templateDirs,
|
|
57
|
-
template_delimiters: {
|
|
58
|
-
left: config.analysis.templateDelimiters.left,
|
|
59
|
-
right: config.analysis.templateDelimiters.right,
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
consumers: { complete: config.consumersComplete },
|
|
63
|
-
roots: { patterns: config.rootPatterns },
|
|
64
|
-
severity: Object.fromEntries([...config.severity].sort(([a], [b]) => (a < b ? -1 : 1))),
|
|
65
|
-
exemptions: { disabled: config.exemptionsDisabled },
|
|
66
|
-
reporters: {
|
|
67
|
-
formats: config.reporters.formats,
|
|
68
|
-
sort: config.reporters.sort,
|
|
69
|
-
cascade: config.reporters.cascade,
|
|
70
|
-
max_findings: config.reporters.maxFindings,
|
|
71
|
-
fail_on: config.reporters.failOn,
|
|
72
|
-
},
|
|
73
|
-
providers: { analyzers: config.providers.analyzers.map(providerOf) },
|
|
74
|
-
go: {},
|
|
75
|
-
ts: {
|
|
76
|
-
test_files: config.ts.testFiles,
|
|
77
|
-
entry_files: config.ts.entryFiles,
|
|
78
|
-
component_extensions: config.ts.componentExtensions,
|
|
79
|
-
disabled_conventions: config.ts.disabledConventions,
|
|
80
|
-
injection_registrations: config.ts.injectionRegistrations.map(declarationOf),
|
|
81
|
-
lifecycle_contracts: config.ts.lifecycleContracts.map((entry) => ({
|
|
82
|
-
components: entry.components.map(declarationOf),
|
|
83
|
-
bases: entry.bases.map(declarationOf),
|
|
84
|
-
members: entry.members,
|
|
85
|
-
})),
|
|
86
|
-
serializers: config.ts.serializers.map(declarationOf),
|
|
87
|
-
roots_complete: config.ts.rootsComplete,
|
|
88
|
-
},
|
|
89
|
-
provenance: Object.fromEntries(
|
|
90
|
-
[...provenance]
|
|
91
|
-
.sort(([a], [b]) => (a < b ? -1 : 1))
|
|
92
|
-
.map(([path, origin]) => [path, renderOrigin(origin)]),
|
|
93
|
-
),
|
|
94
|
-
};
|
|
95
|
-
return `${JSON.stringify(document, undefined, 2)}\n`;
|
|
11
|
+
export function printConfig(config: ResolvedConfig, provenance: Provenance): string {
|
|
12
|
+
const origins = [...provenance]
|
|
13
|
+
.sort(([a], [b]) => bytewise(a, b))
|
|
14
|
+
.map(([path, origin]): [string, string] => [path, renderOrigin(origin)]);
|
|
15
|
+
return `${JSON.stringify({ ...config, provenance: Object.fromEntries(origins) }, undefined, 2)}\n`;
|
|
96
16
|
}
|
package/src/product.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { LANGUAGE_ROWS } from "./contract/contract.generated.ts";
|
|
2
|
+
import type { Writer } from "./run.ts";
|
|
3
|
+
|
|
4
|
+
/** The language this analyzer reads. */
|
|
5
|
+
export const LANGUAGE = "ts";
|
|
6
|
+
|
|
7
|
+
/** The analyzer's name: the one its language's row names, which every output spells it with. */
|
|
8
|
+
export const PRODUCT = LANGUAGE_ROWS[LANGUAGE].analyzer;
|
|
9
|
+
|
|
10
|
+
/** Writes one diagnostic line to the error stream, named for the analyzer. */
|
|
11
|
+
export function diagnose(err: Writer, text: string): void {
|
|
12
|
+
err.write(`${PRODUCT}: ${text}\n`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** The text one thrown value carries. */
|
|
16
|
+
export function message(error: unknown): string {
|
|
17
|
+
return error instanceof Error ? error.message : String(error);
|
|
18
|
+
}
|
package/src/query.ts
CHANGED
|
@@ -207,10 +207,26 @@ export interface Queries {
|
|
|
207
207
|
constraintOf(type: Type): Answer<Type | undefined>;
|
|
208
208
|
/** The object and the index of an indexed-access type; none for another type. */
|
|
209
209
|
indexedAccessOf(type: Type): Answer<{ readonly object: Type; readonly index: Type } | undefined>;
|
|
210
|
+
/**
|
|
211
|
+
* The types one type is spelled from besides its constituents, type arguments and members:
|
|
212
|
+
* a type parameter's constraint and default, a conditional's check, extends, true
|
|
213
|
+
* and false types, a mapped type's constraint, name and template, an indexed access's
|
|
214
|
+
* object and index, the operand of `keyof` or of a string mapping, a template literal's
|
|
215
|
+
* spans and a substitution's base and constraint. None for another type.
|
|
216
|
+
*/
|
|
217
|
+
partsOf(type: Type): Answer<readonly Type[]>;
|
|
218
|
+
/** The type parameters of a signature, its `this` parameter's type and its predicate's type. */
|
|
219
|
+
signaturePartsOf(signature: Signature): Answer<readonly Type[]>;
|
|
210
220
|
/** The symbol a type is declared by. */
|
|
211
221
|
symbolOfType(type: Type): Answer<TSSymbol | undefined>;
|
|
222
|
+
/** The type alias a type was instantiated from, where it was. */
|
|
223
|
+
aliasSymbolOf(type: Type): Answer<TSSymbol | undefined>;
|
|
224
|
+
/** The type arguments the alias a type was instantiated from was given. */
|
|
225
|
+
aliasArgumentsOf(type: Type): Answer<readonly Type[]>;
|
|
212
226
|
signaturesOf(type: Type, kind: SignatureKind): Answer<readonly Signature[]>;
|
|
213
227
|
resolvedSignature(node: Node): Answer<Signature | undefined>;
|
|
228
|
+
/** The signature each call-like node resolves to. */
|
|
229
|
+
resolvedSignatures(nodes: readonly Node[], cap?: number): Answer<Signature | undefined>[];
|
|
214
230
|
parameterType(signature: Signature, index: number): Answer<Type | undefined>;
|
|
215
231
|
/** The generic signature an instantiated one instantiates; none for another signature. */
|
|
216
232
|
genericOf(signature: Signature): Answer<Signature | undefined>;
|
|
@@ -221,6 +237,37 @@ export interface Queries {
|
|
|
221
237
|
typeToString(type: Type): Answer<string>;
|
|
222
238
|
}
|
|
223
239
|
|
|
240
|
+
/** How to read the types one type is spelled from, as {@link Queries.partsOf} names them. */
|
|
241
|
+
function partQuestion(type: Type): (() => readonly (Type | undefined)[]) | undefined {
|
|
242
|
+
if (type.isTypeParameter()) {
|
|
243
|
+
return () => [type.getConstraint(), type.getDefault()];
|
|
244
|
+
}
|
|
245
|
+
if (type.isConditionalType()) {
|
|
246
|
+
return () => [
|
|
247
|
+
type.getCheckType(),
|
|
248
|
+
type.getExtendsType(),
|
|
249
|
+
type.getTrueType(),
|
|
250
|
+
type.getFalseType(),
|
|
251
|
+
];
|
|
252
|
+
}
|
|
253
|
+
if (type.isMappedType()) {
|
|
254
|
+
return () => [type.getConstraintType(), type.getNameType(), type.getTemplateType()];
|
|
255
|
+
}
|
|
256
|
+
if (type.isIndexedAccessType()) {
|
|
257
|
+
return () => [type.getObjectType(), type.getIndexType()];
|
|
258
|
+
}
|
|
259
|
+
if (type.isIndexType() || type.isStringMappingType()) {
|
|
260
|
+
return () => [type.getTarget()];
|
|
261
|
+
}
|
|
262
|
+
if (type.isTemplateLiteralType()) {
|
|
263
|
+
return () => type.getTypes();
|
|
264
|
+
}
|
|
265
|
+
if (type.isSubstitutionType()) {
|
|
266
|
+
return () => [type.getBaseType(), type.getConstraint()];
|
|
267
|
+
}
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
|
|
224
271
|
/**
|
|
225
272
|
* The guarded questions over one project's checker. `configFile` names the project
|
|
226
273
|
* in the log, `batch` sends many questions in one round trip, `log` is the run's,
|
|
@@ -526,12 +573,48 @@ export function queriesOf(
|
|
|
526
573
|
() => ({ object: type.getObjectType(), index: type.getIndexType() }),
|
|
527
574
|
)
|
|
528
575
|
: undefined,
|
|
576
|
+
partsOf: (type) => {
|
|
577
|
+
const parts = partQuestion(type);
|
|
578
|
+
return parts === undefined
|
|
579
|
+
? []
|
|
580
|
+
: one(
|
|
581
|
+
"getParts",
|
|
582
|
+
() => typeLocation(type),
|
|
583
|
+
() => parts().filter((part) => part !== undefined),
|
|
584
|
+
);
|
|
585
|
+
},
|
|
586
|
+
signaturePartsOf: (signature) =>
|
|
587
|
+
one(
|
|
588
|
+
"getSignatureParts",
|
|
589
|
+
() => `signature ${String(signature.id)}`,
|
|
590
|
+
() => {
|
|
591
|
+
const self =
|
|
592
|
+
signature.thisParameter === undefined ? undefined : signature.getThisParameter();
|
|
593
|
+
return [
|
|
594
|
+
...((signature.typeParameters ?? []).length === 0 ? [] : signature.getTypeParameters()),
|
|
595
|
+
self === undefined ? undefined : checker.getTypeOfSymbol(self),
|
|
596
|
+
checker.getTypePredicateOfSignature(signature)?.type,
|
|
597
|
+
].filter((part) => part !== undefined);
|
|
598
|
+
},
|
|
599
|
+
),
|
|
529
600
|
symbolOfType: (type) =>
|
|
530
601
|
one(
|
|
531
602
|
"getSymbol",
|
|
532
603
|
() => typeLocation(type),
|
|
533
604
|
() => type.getSymbol(),
|
|
534
605
|
),
|
|
606
|
+
aliasSymbolOf: (type) =>
|
|
607
|
+
one(
|
|
608
|
+
"getAliasSymbol",
|
|
609
|
+
() => typeLocation(type),
|
|
610
|
+
() => type.getAliasSymbol(),
|
|
611
|
+
),
|
|
612
|
+
aliasArgumentsOf: (type) =>
|
|
613
|
+
one(
|
|
614
|
+
"getAliasTypeArguments",
|
|
615
|
+
() => typeLocation(type),
|
|
616
|
+
() => type.getAliasTypeArguments(),
|
|
617
|
+
),
|
|
535
618
|
signaturesOf: (type, kind) =>
|
|
536
619
|
one(
|
|
537
620
|
"getSignaturesOfType",
|
|
@@ -544,6 +627,15 @@ export function queriesOf(
|
|
|
544
627
|
() => nodeLocation(node),
|
|
545
628
|
() => checker.getResolvedSignature(node),
|
|
546
629
|
),
|
|
630
|
+
resolvedSignatures: (nodes, cap = DEFAULT_BATCH_CAP) =>
|
|
631
|
+
each(
|
|
632
|
+
"getResolvedSignature",
|
|
633
|
+
nodes,
|
|
634
|
+
cap,
|
|
635
|
+
nodeLocation,
|
|
636
|
+
(node) => checker.getResolvedSignature.gen(node),
|
|
637
|
+
(node) => checker.getResolvedSignature(node),
|
|
638
|
+
),
|
|
547
639
|
parameterType: (signature, index) =>
|
|
548
640
|
one(
|
|
549
641
|
"getParameterType",
|
package/src/ref.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The stable symbol reference: the identifier that names one declaration across
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* written.
|
|
8
|
-
*
|
|
9
|
-
* The position key of {@link ./position.ts} is the other identifier and has the
|
|
10
|
-
* other job: it locates a finding inside one run, and the two never mix.
|
|
2
|
+
* The stable symbol reference: the identifier that names one declaration across runs,
|
|
3
|
+
* reports, ignore entries, configured roots and cross-language edges. It is built from
|
|
4
|
+
* names and containers only, so an edit above a declaration leaves it unchanged, and it
|
|
5
|
+
* is compared as bytes, so this module writes the one canonical spelling. The position
|
|
6
|
+
* key of {@link ./position.ts} locates a finding inside one run; the two never mix.
|
|
11
7
|
*/
|
|
12
8
|
|
|
13
9
|
/** The language prefix, which namespaces every reference this analyzer emits. */
|
|
@@ -34,16 +30,10 @@ const SCOPE = `${PREFIX}${TS_PACKAGE}/${TS_FILE}`;
|
|
|
34
30
|
const MANIFEST_SCOPE = `${PREFIX}${TS_PACKAGE}/${TS_DIRS}package\\.json`;
|
|
35
31
|
|
|
36
32
|
/**
|
|
37
|
-
* One expression per
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* They are written here rather than read from the Contract at run time: the Contract
|
|
43
|
-
* is data a reader outside this program consults, and a product that read it while
|
|
44
|
-
* running would need it installed beside itself. A test compares this list against
|
|
45
|
-
* the release this analyzer is written against, so a grammar that grows a form
|
|
46
|
-
* arrives here as a failing test.
|
|
33
|
+
* One anchored expression per spelling the grammar defines; a reference is valid when it
|
|
34
|
+
* matches one. They are written here rather than read from the Contract at run time, so
|
|
35
|
+
* the product needs no Contract installed beside it; a test compares this list against
|
|
36
|
+
* the release this analyzer implements, so a grammar that grows a form fails it.
|
|
47
37
|
*/
|
|
48
38
|
export const REF_EXPRESSIONS: readonly string[] = [
|
|
49
39
|
`^${SCOPE}#$`,
|
|
@@ -52,6 +42,7 @@ export const REF_EXPRESSIONS: readonly string[] = [
|
|
|
52
42
|
`^${SCOPE}#${TS_HEAD}:import$`,
|
|
53
43
|
`^${SCOPE}#${TS_HEAD}(?:\\.${TS_MEMBER})+$`,
|
|
54
44
|
`^${SCOPE}#${TS_HEAD}(?:\\.${TS_MEMBER})+:static$`,
|
|
45
|
+
`^${SCOPE}#${TS_HEAD}(?:\\.${TS_MEMBER})+\\.${TS_QUOTED}:case$`,
|
|
55
46
|
`^${SCOPE}#${TS_HEAD}(?:\\.${TS_MEMBER})*(?::static)?<${TS_IDENT}>$`,
|
|
56
47
|
`^${SCOPE}#(?:${TS_HEAD}(?:\\.${TS_MEMBER})*(?::static)?)?\\(${TS_IDENT}\\)$`,
|
|
57
48
|
`^${MANIFEST_SCOPE}#${TS_PACKAGE}:(?:dependency|dev-dependency|peer-dependency)$`,
|
|
@@ -169,7 +160,8 @@ export function aliasFragment(name: string, block?: string): string {
|
|
|
169
160
|
return `${head}${nameComponent(name)}:alias`;
|
|
170
161
|
}
|
|
171
162
|
|
|
172
|
-
|
|
163
|
+
/** The canonical spelling of one component: a name, or a computed key. */
|
|
164
|
+
export function spell(component: Component): string {
|
|
173
165
|
return component.computed ? computedComponent(component.text) : nameComponent(component.text);
|
|
174
166
|
}
|
|
175
167
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Node, SourceFile } from "@typescript/native/ast";
|
|
2
|
+
import type { Type } from "@typescript/native/sync";
|
|
3
|
+
import type { AliasChains } from "../alias-chain.ts";
|
|
4
|
+
import type { Inventory } from "../inventory.ts";
|
|
5
|
+
import type { Position } from "../position.ts";
|
|
6
|
+
import type { Resolution } from "../references.ts";
|
|
7
|
+
import type { ProjectView } from "../session.ts";
|
|
8
|
+
|
|
9
|
+
/** Where the walk offered a read rule one node: the file, and the declaration enclosing the node. */
|
|
10
|
+
interface ReadSite {
|
|
11
|
+
readonly file: SourceFile;
|
|
12
|
+
readonly from: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** What a read rule reads its answers through, after the walk of every file of the side. */
|
|
16
|
+
export interface ReadContext<Brand> {
|
|
17
|
+
readonly project: ProjectView<Brand>;
|
|
18
|
+
readonly held: Inventory;
|
|
19
|
+
readonly chains: AliasChains;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* One read a rule makes: a use of the declaration `to` by `from` at a node of a walked file,
|
|
24
|
+
* or, where a question the read needed went unanswered, a hold. A hold names what the answer
|
|
25
|
+
* could have made live (program.33): the declarations `ids`, each declaration bearing one of
|
|
26
|
+
* `names`, each member of one of `types`, or with `members` every member the inventory holds;
|
|
27
|
+
* the declaration making the read is held as well. A named read sits at a node of `file`, or
|
|
28
|
+
* at a declaration's own position in it.
|
|
29
|
+
*/
|
|
30
|
+
export type Read =
|
|
31
|
+
| {
|
|
32
|
+
readonly kind: "named";
|
|
33
|
+
readonly from: string;
|
|
34
|
+
readonly to: string;
|
|
35
|
+
readonly file: SourceFile;
|
|
36
|
+
readonly at: Node | Position;
|
|
37
|
+
readonly use: "read" | "write";
|
|
38
|
+
readonly via: Resolution;
|
|
39
|
+
/** A read a rule counts as production code's whoever writes it. */
|
|
40
|
+
readonly production?: true;
|
|
41
|
+
}
|
|
42
|
+
| {
|
|
43
|
+
readonly kind: "held";
|
|
44
|
+
readonly from: string;
|
|
45
|
+
readonly ids?: readonly string[];
|
|
46
|
+
readonly names?: readonly string[];
|
|
47
|
+
readonly types?: readonly Type[];
|
|
48
|
+
readonly members?: true;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** One pass of one read rule over the files of one side: it collects while the walk offers nodes, then reads. */
|
|
52
|
+
interface ReadRuleRun {
|
|
53
|
+
visit(node: Node, site: ReadSite): void;
|
|
54
|
+
reads<Brand>(context: ReadContext<Brand>): readonly Read[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** One rule of the references pages that reads declarations no name node names. */
|
|
58
|
+
export interface ReadRule {
|
|
59
|
+
start(): ReadRuleRun;
|
|
60
|
+
}
|