@cplieger/deadset-ts 8.0.0-dev.2 → 8.0.0-dev.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/THIRD_PARTY_NOTICES.md +27 -0
- package/dist/bin/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/alias-chain.js +35 -9
- package/dist/src/amd.js +81 -0
- package/dist/src/analysis.js +274 -496
- package/dist/src/augmentations.js +64 -3
- package/dist/src/automatic-types.js +10 -29
- package/dist/src/bindings.js +382 -0
- package/dist/src/commands/held.js +499 -0
- package/dist/src/commands/read.js +161 -0
- package/dist/src/commands/shell.js +169 -0
- package/dist/src/commands/tools.js +1847 -0
- package/dist/src/component-files.js +3 -2
- package/dist/src/component-layer.js +4 -2
- package/dist/src/config.js +6 -82
- package/dist/src/conformance-record.js +2 -2
- package/dist/src/consumers.js +10 -38
- package/dist/src/contextual-uses.js +57 -26
- package/dist/src/contract/config.generated.js +561 -0
- package/dist/src/contract/contract.generated.js +1370 -0
- package/dist/src/contract/report.generated.js +866 -0
- package/dist/src/dependencies.js +165 -122
- package/dist/src/destructuring.js +1 -19
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +181 -168
- package/dist/src/entries/build-scripts.js +222 -0
- package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
- package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
- package/dist/src/entries/conventions.js +740 -0
- package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
- package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
- package/dist/src/entries/run-directories.js +77 -0
- package/dist/src/entries/sources.js +144 -0
- package/dist/src/entries/static-module.js +670 -0
- package/dist/src/entries/test-runners.js +650 -0
- package/dist/src/entries/workflow-steps.js +345 -0
- package/dist/src/exemptions/argument-places.js +131 -0
- package/dist/src/exemptions/calls.js +338 -0
- package/dist/src/exemptions/classes.js +13 -0
- package/dist/src/{decorator.js → exemptions/decorator.js} +19 -30
- package/dist/src/exemptions/detectors.js +48 -0
- package/dist/src/{enum-group.js → exemptions/enum-group.js} +9 -16
- package/dist/src/{erased-stores.js → exemptions/erased-stores.js} +7 -11
- package/dist/src/{framework-lifecycle.js → exemptions/framework-lifecycle.js} +76 -54
- package/dist/src/exemptions/generated-file.js +241 -0
- package/dist/src/{injection-container.js → exemptions/injection-container.js} +20 -26
- package/dist/src/exemptions/installed-globals.js +173 -0
- package/dist/src/{interface-satisfaction.js → exemptions/interface-satisfaction.js} +52 -121
- package/dist/src/exemptions/lifecycle.js +150 -0
- package/dist/src/{reflective-lookup.js → exemptions/reflective-lookup.js} +3 -3
- package/dist/src/exemptions/serialization-contract.js +1276 -0
- package/dist/src/exemptions/sites.js +182 -0
- package/dist/src/{template-field.js → exemptions/template-field.js} +13 -23
- package/dist/src/{value-reach.js → exemptions/value-reach.js} +14 -7
- package/dist/src/exposure.js +400 -0
- package/dist/src/extensions.js +37 -0
- package/dist/src/facts.js +38 -0
- package/dist/src/failure.js +36 -0
- package/dist/src/file-facts.js +3 -26
- package/dist/src/findings/completion.js +109 -56
- package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
- package/dist/src/findings/emitters.js +27 -41
- package/dist/src/{implementations.js → findings/implementations.js} +3 -3
- package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +16 -13
- package/dist/src/findings/non-code-artifacts.js +17 -12
- package/dist/src/findings/reads-and-writes.js +86 -27
- package/dist/src/findings/self-check.js +44 -30
- package/dist/src/findings/unused-declarations.js +29 -45
- package/dist/src/findings/visibility-narrowing.js +23 -31
- package/dist/src/findings-pass.js +13 -21
- package/dist/src/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +67 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/git-ignore.js +39 -26
- package/dist/src/import-bindings.js +73 -28
- package/dist/src/index/sites.js +557 -0
- package/dist/src/index/values.js +124 -0
- package/dist/src/index.js +2 -2
- package/dist/src/indexed-access.js +523 -478
- package/dist/src/intra-function-parts.js +63 -43
- package/dist/src/inventory/commonjs.js +507 -0
- package/dist/src/inventory/enumerate.js +167 -0
- package/dist/src/inventory/syntax.js +236 -0
- package/dist/src/inventory.js +323 -724
- package/dist/src/javascript-file.js +48 -0
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +126 -107
- package/dist/src/kinds.js +3 -366
- package/dist/src/{components.js → liveness/components.js} +2 -3
- package/dist/src/{graph.js → liveness/graph.js} +52 -28
- package/dist/src/liveness/matrix.js +99 -0
- package/dist/src/liveness/sweep.js +558 -0
- package/dist/src/load/classify.js +289 -0
- package/dist/src/load/diagnostics.js +87 -0
- package/dist/src/load/discover.js +285 -0
- package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
- package/dist/src/load/expected-module.js +136 -0
- package/dist/src/load/load.js +27 -0
- package/dist/src/load/module-lookup.js +37 -0
- package/dist/src/load/package-scope.js +56 -0
- package/dist/src/load/plan.js +313 -0
- package/dist/src/load/specifiers.js +113 -0
- package/dist/src/load/synthesize.js +152 -0
- package/dist/src/load/test-globals.js +207 -0
- package/dist/src/load/test-joins.js +82 -0
- package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
- package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
- package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
- package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
- package/dist/src/{workspace.js → load/workspace.js} +62 -124
- package/dist/src/module-declarations.js +70 -85
- package/dist/src/overrides.js +134 -112
- package/dist/src/partial.js +2 -1
- package/dist/src/paths.js +82 -16
- package/dist/src/platform-calls.js +78 -0
- package/dist/src/platform-symbols.js +134 -0
- package/dist/src/position.js +43 -1
- package/dist/src/print.js +11 -79
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +95 -0
- package/dist/src/ref.js +12 -20
- package/dist/src/references/read-rule.js +1 -0
- package/dist/src/references/read-rules.js +48 -0
- package/dist/src/references/sink.js +237 -0
- package/dist/src/references/sources.js +450 -0
- package/dist/src/references.js +117 -1074
- package/dist/src/report-schema.js +51 -0
- package/dist/src/report.js +57 -41
- package/dist/src/reporters/annotations.js +15 -8
- package/dist/src/reporters/sarif.js +16 -10
- package/dist/src/reporters/template.js +4 -19
- package/dist/src/resolve.js +246 -730
- package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
- package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
- package/dist/src/roots/manifest.js +216 -0
- package/dist/src/roots/published-reach.js +412 -0
- package/dist/src/roots/root-set.js +487 -0
- package/dist/src/roots/unseen-loads.js +236 -0
- package/dist/src/run.js +66 -77
- package/dist/src/schema.js +320 -343
- package/dist/src/scope.js +38 -115
- package/dist/src/session.js +37 -29
- package/dist/src/source-files.js +6 -10
- package/dist/src/stores.js +4 -2
- package/dist/src/suppress-file.js +25 -28
- package/dist/src/suppress-inline.js +36 -83
- package/dist/src/suppress.js +50 -71
- package/dist/src/symbol-keys.js +92 -88
- package/dist/src/tests/file-class.js +76 -0
- package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
- package/dist/src/{test-support.js → tests/support.js} +5 -12
- package/dist/src/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/named-files.js +298 -0
- package/dist/src/text/yaml.js +684 -0
- package/dist/src/type-errors.js +11 -232
- package/dist/src/type-parameter-reads.js +178 -139
- package/dist/src/unimplemented-callees.js +262 -242
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/vendor/unbash/ansi-c.js +132 -0
- package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
- package/dist/src/vendor/unbash/arithmetic.js +591 -0
- package/dist/src/vendor/unbash/assignment.js +131 -0
- package/dist/src/vendor/unbash/chars.js +48 -0
- package/dist/src/vendor/unbash/command.js +41 -0
- package/dist/src/vendor/unbash/expansion.js +80 -0
- package/dist/src/vendor/unbash/glob.js +268 -0
- package/dist/src/vendor/unbash/heredoc.js +27 -0
- package/dist/src/vendor/unbash/internal-types.js +1 -0
- package/dist/src/vendor/unbash/lexer.js +4274 -0
- package/dist/src/vendor/unbash/limits.js +3 -0
- package/dist/src/vendor/unbash/parser.js +1366 -0
- package/dist/src/vendor/unbash/parts.js +57 -0
- package/dist/src/vendor/unbash/substitution-context.js +8 -0
- package/dist/src/vendor/unbash/traversal.js +212 -0
- package/dist/src/vendor/unbash/types.js +1 -0
- package/dist/src/vendor/unbash/word-value.js +61 -0
- package/dist/src/vendor/unbash/word.js +40 -0
- package/dist/src/verbs/analyze.js +194 -127
- package/dist/src/verbs/describe.js +13 -18
- package/dist/src/verbs/explain.js +85 -139
- package/dist/src/verbs/print-config.js +2 -1
- package/dist/src/verbs/print-projects.js +6 -4
- package/dist/src/verbs/print-retained.js +30 -6
- package/dist/src/verbs/print-roots.js +4 -2
- package/dist/src/verbs/verb.js +1 -5
- package/dist/src/verbs/version.js +14 -3
- package/jsr.json +2 -1
- package/package.json +14 -8
- package/src/alias-chain.ts +40 -11
- package/src/amd.ts +130 -0
- package/src/analysis.ts +426 -733
- package/src/augmentations.ts +93 -4
- package/src/automatic-types.ts +12 -30
- package/src/bindings.ts +460 -0
- package/src/commands/held.ts +632 -0
- package/src/commands/read.ts +242 -0
- package/src/commands/shell.ts +228 -0
- package/src/commands/tools.ts +2382 -0
- package/src/component-files.ts +4 -2
- package/src/component-layer.ts +4 -2
- package/src/config.ts +31 -302
- package/src/conformance-record.ts +2 -2
- package/src/consumers.ts +16 -66
- package/src/contextual-uses.ts +66 -34
- package/src/contract/config.generated.ts +821 -0
- package/src/contract/contract.generated.ts +1453 -0
- package/src/contract/report.generated.ts +1241 -0
- package/src/dependencies.ts +223 -128
- package/src/destructuring.ts +1 -31
- package/src/edges.ts +41 -140
- package/src/element-access.ts +190 -187
- package/src/entries/build-scripts.ts +292 -0
- package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
- package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
- package/src/{conventions.ts → entries/conventions.ts} +367 -583
- package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
- package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
- package/src/entries/run-directories.ts +108 -0
- package/src/entries/sources.ts +266 -0
- package/src/entries/static-module.ts +858 -0
- package/src/entries/test-runners.ts +835 -0
- package/src/entries/workflow-steps.ts +432 -0
- package/src/exemptions/argument-places.ts +198 -0
- package/src/exemptions/calls.ts +483 -0
- package/src/exemptions/classes.ts +49 -0
- package/src/exemptions/decorator.ts +56 -0
- package/src/exemptions/detectors.ts +75 -0
- package/src/{enum-group.ts → exemptions/enum-group.ts} +10 -19
- package/src/{erased-stores.ts → exemptions/erased-stores.ts} +7 -14
- package/src/{framework-lifecycle.ts → exemptions/framework-lifecycle.ts} +85 -66
- package/src/exemptions/generated-file.ts +318 -0
- package/src/{injection-container.ts → exemptions/injection-container.ts} +29 -34
- package/src/exemptions/installed-globals.ts +255 -0
- package/src/{interface-satisfaction.ts → exemptions/interface-satisfaction.ts} +69 -160
- package/src/exemptions/lifecycle.ts +286 -0
- package/src/{reflective-lookup.ts → exemptions/reflective-lookup.ts} +5 -5
- package/src/exemptions/serialization-contract.ts +1729 -0
- package/src/exemptions/sites.ts +293 -0
- package/src/{template-field.ts → exemptions/template-field.ts} +22 -32
- package/src/{value-reach.ts → exemptions/value-reach.ts} +16 -8
- package/src/exposure.ts +492 -0
- package/src/extensions.ts +45 -0
- package/src/facts.ts +46 -0
- package/src/failure.ts +63 -0
- package/src/file-facts.ts +15 -25
- package/src/finding.ts +10 -10
- package/src/findings/boundary.ts +11 -0
- package/src/findings/completion.ts +133 -64
- package/src/findings/dependencies-and-module-machinery.ts +4 -7
- package/src/findings/emitter.ts +9 -10
- package/src/findings/emitters.ts +38 -52
- package/src/{implementations.ts → findings/implementations.ts} +4 -4
- package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
- package/src/findings/interfaces.ts +7 -9
- package/src/findings/intra-function.ts +16 -14
- package/src/findings/non-code-artifacts.ts +24 -15
- package/src/findings/reads-and-writes.ts +118 -41
- package/src/findings/self-check.ts +51 -38
- package/src/findings/unused-declarations.ts +31 -49
- package/src/findings/visibility-narrowing.ts +36 -40
- package/src/findings-pass.ts +15 -31
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +96 -0
- package/src/fs/tree.ts +110 -0
- package/src/git-ignore.ts +50 -26
- package/src/host.ts +12 -5
- package/src/import-bindings.ts +98 -29
- package/src/index/sites.ts +781 -0
- package/src/index/values.ts +170 -0
- package/src/index.ts +2 -2
- package/src/indexed-access.ts +570 -527
- package/src/intra-function-parts.ts +73 -44
- package/src/inventory/commonjs.ts +696 -0
- package/src/inventory/enumerate.ts +203 -0
- package/src/inventory/syntax.ts +311 -0
- package/src/inventory.ts +442 -895
- package/src/javascript-file.ts +54 -0
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +133 -122
- package/src/kinds.ts +5 -413
- package/src/{components.ts → liveness/components.ts} +4 -6
- package/src/{graph.ts → liveness/graph.ts} +100 -35
- package/src/liveness/matrix.ts +162 -0
- package/src/liveness/sweep.ts +855 -0
- package/src/load/classify.ts +433 -0
- package/src/load/diagnostics.ts +154 -0
- package/src/load/discover.ts +471 -0
- package/src/{emit-map.ts → load/emit-map.ts} +1 -1
- package/src/load/expected-module.ts +194 -0
- package/src/load/load.ts +73 -0
- package/src/load/module-lookup.ts +50 -0
- package/src/load/package-scope.ts +74 -0
- package/src/load/plan.ts +513 -0
- package/src/load/specifiers.ts +171 -0
- package/src/load/synthesize.ts +230 -0
- package/src/load/test-globals.ts +251 -0
- package/src/load/test-joins.ts +98 -0
- package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
- package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
- package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
- package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
- package/src/{workspace.ts → load/workspace.ts} +90 -134
- package/src/module-declarations.ts +74 -98
- package/src/overrides.ts +162 -134
- package/src/partial.ts +3 -2
- package/src/paths.ts +92 -16
- package/src/platform-calls.ts +119 -0
- package/src/platform-symbols.ts +189 -0
- package/src/position.ts +44 -1
- package/src/print.ts +12 -92
- package/src/product.ts +18 -0
- package/src/query.ts +201 -10
- package/src/ref.ts +12 -20
- package/src/references/read-rule.ts +60 -0
- package/src/references/read-rules.ts +55 -0
- package/src/references/sink.ts +314 -0
- package/src/references/sources.ts +632 -0
- package/src/references.ts +187 -1450
- package/src/report-schema.ts +68 -0
- package/src/report.ts +103 -226
- package/src/reporters/annotations.ts +22 -11
- package/src/reporters/json.ts +1 -1
- package/src/reporters/reporter.ts +2 -4
- package/src/reporters/reporters.ts +1 -1
- package/src/reporters/sarif.ts +29 -16
- package/src/reporters/template.ts +4 -20
- package/src/reporters/text.ts +3 -3
- package/src/resolve.ts +284 -1115
- package/src/{configured-declarations.ts → roots/configured-declarations.ts} +26 -29
- package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
- package/src/roots/manifest.ts +303 -0
- package/src/roots/published-reach.ts +486 -0
- package/src/{roots.ts → roots/root-set.ts} +286 -469
- package/src/roots/unseen-loads.ts +345 -0
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -388
- package/src/scope.ts +46 -138
- package/src/session.ts +87 -55
- package/src/source-files.ts +6 -11
- package/src/stores.ts +15 -3
- package/src/suppress-file.ts +24 -33
- package/src/suppress-inline.ts +55 -91
- package/src/suppress.ts +78 -79
- package/src/symbol-keys.ts +104 -107
- package/src/tests/file-class.ts +135 -0
- package/src/{outside-tests.ts → tests/outside.ts} +16 -10
- package/src/{test-support.ts → tests/support.ts} +15 -21
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/named-files.ts +388 -0
- package/src/text/yaml.ts +747 -0
- package/src/type-errors.ts +18 -288
- package/src/type-parameter-reads.ts +187 -158
- package/src/unimplemented-callees.ts +297 -280
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/vendor/unbash/LICENSE +15 -0
- package/src/vendor/unbash/VENDORED.md +16 -0
- package/src/vendor/unbash/ansi-c.ts +132 -0
- package/src/vendor/unbash/arithmetic-parts.ts +53 -0
- package/src/vendor/unbash/arithmetic.ts +641 -0
- package/src/vendor/unbash/assignment.ts +163 -0
- package/src/vendor/unbash/chars.ts +48 -0
- package/src/vendor/unbash/command.ts +47 -0
- package/src/vendor/unbash/expansion.ts +144 -0
- package/src/vendor/unbash/glob.ts +284 -0
- package/src/vendor/unbash/heredoc.ts +34 -0
- package/src/vendor/unbash/internal-types.ts +94 -0
- package/src/vendor/unbash/lexer.ts +4352 -0
- package/src/vendor/unbash/limits.ts +3 -0
- package/src/vendor/unbash/parser.ts +1612 -0
- package/src/vendor/unbash/parts.ts +96 -0
- package/src/vendor/unbash/substitution-context.ts +20 -0
- package/src/vendor/unbash/traversal.ts +182 -0
- package/src/vendor/unbash/types.ts +660 -0
- package/src/vendor/unbash/word-value.ts +64 -0
- package/src/vendor/unbash/word.ts +50 -0
- package/src/verbs/analyze.ts +255 -164
- package/src/verbs/describe.ts +19 -17
- package/src/verbs/explain.ts +93 -169
- package/src/verbs/print-config.ts +2 -1
- package/src/verbs/print-projects.ts +6 -4
- package/src/verbs/print-retained.ts +36 -6
- package/src/verbs/print-roots.ts +4 -2
- package/src/verbs/verb.ts +2 -8
- package/src/verbs/version.ts +15 -3
- package/dist/src/base-url.js +0 -18
- package/dist/src/calls.js +0 -155
- package/dist/src/conventions.js +0 -937
- package/dist/src/discover.js +0 -468
- package/dist/src/entry-points.js +0 -529
- package/dist/src/exempt-classes.js +0 -75
- package/dist/src/exempt.js +0 -209
- package/dist/src/generated-file.js +0 -95
- package/dist/src/glob.js +0 -65
- package/dist/src/manifest.js +0 -165
- package/dist/src/matrix.js +0 -246
- package/dist/src/pnpm-workspace.js +0 -120
- package/dist/src/roots.js +0 -672
- package/dist/src/serialization-contract.js +0 -611
- package/dist/src/setup-failure.js +0 -23
- package/dist/src/sweep.js +0 -224
- package/dist/src/test-joins.js +0 -101
- package/dist/src/value-flow.js +0 -74
- package/dist/src/version.js +0 -7
- package/dist/src/workflow-steps.js +0 -185
- package/src/base-url.ts +0 -24
- package/src/calls.ts +0 -225
- package/src/decorator.ts +0 -78
- package/src/discover.ts +0 -653
- package/src/entry-points.ts +0 -687
- package/src/exempt-classes.ts +0 -123
- package/src/exempt.ts +0 -323
- package/src/generated-file.ts +0 -111
- package/src/glob.ts +0 -67
- package/src/manifest.ts +0 -234
- package/src/matrix.ts +0 -423
- package/src/pnpm-workspace.ts +0 -135
- package/src/serialization-contract.ts +0 -849
- package/src/setup-failure.ts +0 -39
- package/src/sweep.ts +0 -347
- package/src/test-joins.ts +0 -120
- package/src/value-flow.ts +0 -104
- package/src/version.ts +0 -7
- package/src/workflow-steps.ts +0 -216
package/src/exempt-classes.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The exemption classes of the Contract's vocabulary, in its order: each class's name, its
|
|
3
|
-
* languages and, for a TypeScript class, which private members it may retain. The rows are
|
|
4
|
-
* written out, as the fixed severity codes are, and a test holds them equal to the Contract.
|
|
5
|
-
* A class name is a type, so a table or a record naming a class outside the vocabulary, or
|
|
6
|
-
* one of another language only, does not compile.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { Language } from "./config.ts";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Whether a class may retain a member declared with the `private` modifier, and one
|
|
13
|
-
* declared with a `#private` name. The modifier is a compile-time constraint only, so
|
|
14
|
-
* such a member stays reachable by its name at run time; a private name cannot be
|
|
15
|
-
* named from outside its class body at all.
|
|
16
|
-
*/
|
|
17
|
-
export interface TypeScriptVisibility {
|
|
18
|
-
readonly private: boolean;
|
|
19
|
-
readonly privateName: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** One class of the vocabulary. */
|
|
23
|
-
interface ExemptionClassRow {
|
|
24
|
-
readonly class: string;
|
|
25
|
-
readonly languages: readonly Language[];
|
|
26
|
-
/** Present exactly on a class that runs on TypeScript. */
|
|
27
|
-
readonly typescriptVisibility?: TypeScriptVisibility;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Every class of the vocabulary, in the order the Contract lists them. */
|
|
31
|
-
export const EXEMPTION_CLASSES = [
|
|
32
|
-
{
|
|
33
|
-
class: "interface-satisfaction",
|
|
34
|
-
languages: ["go", "ts"],
|
|
35
|
-
typescriptVisibility: { private: false, privateName: false },
|
|
36
|
-
},
|
|
37
|
-
{ class: "encoding-reflection", languages: ["go"] },
|
|
38
|
-
{ class: "format-verb-contract", languages: ["go"] },
|
|
39
|
-
{ class: "errors-duck-typing", languages: ["go"] },
|
|
40
|
-
{
|
|
41
|
-
class: "enum-group",
|
|
42
|
-
languages: ["go", "ts"],
|
|
43
|
-
typescriptVisibility: { private: false, privateName: false },
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
class: "generated-file",
|
|
47
|
-
languages: ["go", "ts"],
|
|
48
|
-
typescriptVisibility: { private: true, privateName: false },
|
|
49
|
-
},
|
|
50
|
-
{ class: "linkname-cgo-asm-plugin", languages: ["go"] },
|
|
51
|
-
{
|
|
52
|
-
class: "template-field",
|
|
53
|
-
languages: ["go", "ts"],
|
|
54
|
-
typescriptVisibility: { private: true, privateName: false },
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
class: "reflective-lookup",
|
|
58
|
-
languages: ["go", "ts"],
|
|
59
|
-
typescriptVisibility: { private: true, privateName: false },
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
class: "decorator",
|
|
63
|
-
languages: ["ts"],
|
|
64
|
-
typescriptVisibility: { private: true, privateName: false },
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
class: "injection-container",
|
|
68
|
-
languages: ["ts"],
|
|
69
|
-
typescriptVisibility: { private: true, privateName: false },
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
class: "framework-lifecycle",
|
|
73
|
-
languages: ["ts"],
|
|
74
|
-
typescriptVisibility: { private: true, privateName: false },
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
class: "serialization-contract",
|
|
78
|
-
languages: ["ts"],
|
|
79
|
-
typescriptVisibility: { private: true, privateName: false },
|
|
80
|
-
},
|
|
81
|
-
] as const satisfies readonly ExemptionClassRow[];
|
|
82
|
-
|
|
83
|
-
type Row = (typeof EXEMPTION_CLASSES)[number];
|
|
84
|
-
|
|
85
|
-
/** The name of a class of the vocabulary. */
|
|
86
|
-
export type ExemptionClass = Row["class"];
|
|
87
|
-
|
|
88
|
-
/** The classes of the rows that list one language. */
|
|
89
|
-
type ClassesOf<R, L extends Language> = R extends {
|
|
90
|
-
readonly class: infer C;
|
|
91
|
-
readonly languages: readonly (infer Listed)[];
|
|
92
|
-
}
|
|
93
|
-
? L extends Listed
|
|
94
|
-
? C
|
|
95
|
-
: never
|
|
96
|
-
: never;
|
|
97
|
-
|
|
98
|
-
/** The name of a class that runs on TypeScript, the only classes this analyzer records. */
|
|
99
|
-
export type TSExemptionClass = ClassesOf<Row, "ts">;
|
|
100
|
-
|
|
101
|
-
function runsOnTS(row: Row): row is Extract<Row, { readonly class: TSExemptionClass }> {
|
|
102
|
-
const languages: readonly Language[] = row.languages;
|
|
103
|
-
return languages.includes("ts");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const TS_ROWS = EXEMPTION_CLASSES.filter(runsOnTS);
|
|
107
|
-
|
|
108
|
-
/** The classes that run on TypeScript, in the vocabulary's order. */
|
|
109
|
-
export const TS_EXEMPTION_CLASSES: readonly TSExemptionClass[] = TS_ROWS.map((row) => row.class);
|
|
110
|
-
|
|
111
|
-
const VISIBILITY: ReadonlyMap<TSExemptionClass, TypeScriptVisibility> = new Map(
|
|
112
|
-
TS_ROWS.map((row) => [row.class, row.typescriptVisibility]),
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
/** Which private members one class that runs on TypeScript may retain. */
|
|
116
|
-
export function typescriptVisibilityOf(exemptionClass: TSExemptionClass): TypeScriptVisibility {
|
|
117
|
-
return VISIBILITY.get(exemptionClass) ?? { private: false, privateName: false };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** Whether one name is a class of the vocabulary, whichever language it runs on. */
|
|
121
|
-
export function isExemptionClass(name: string): name is ExemptionClass {
|
|
122
|
-
return EXEMPTION_CLASSES.some((row) => row.class === name);
|
|
123
|
-
}
|
package/src/exempt.ts
DELETED
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The exemption framework: the classes of reason for which a declaration the reference
|
|
3
|
-
* graph alone would report is live all the same. A class is policy over what one
|
|
4
|
-
* project's checker answers, and its detector names the declarations it holds back;
|
|
5
|
-
* this module runs the detectors, decides which of their records stand, and answers
|
|
6
|
-
* which records held something back. It names no class's detector: the composition
|
|
7
|
-
* hands it the table of the classes it has.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type { Config, TSSection } from "./config.ts";
|
|
11
|
-
import { ConfigError } from "./config.ts";
|
|
12
|
-
import {
|
|
13
|
-
EXEMPTION_CLASSES,
|
|
14
|
-
isExemptionClass,
|
|
15
|
-
TS_EXEMPTION_CLASSES,
|
|
16
|
-
typescriptVisibilityOf,
|
|
17
|
-
type ExemptionClass,
|
|
18
|
-
type TSExemptionClass,
|
|
19
|
-
type TypeScriptVisibility,
|
|
20
|
-
} from "./exempt-classes.ts";
|
|
21
|
-
import type { Inventory, InventorySymbol, SymbolKind, Visibility } from "./inventory.ts";
|
|
22
|
-
import type { Matrix } from "./matrix.ts";
|
|
23
|
-
import { byPosition, positionKey, type Position } from "./position.ts";
|
|
24
|
-
import { Unanswerable } from "./query.ts";
|
|
25
|
-
import type { ProjectView } from "./session.ts";
|
|
26
|
-
import type { Templates } from "./template-field.ts";
|
|
27
|
-
import { sweep, type Exemption, type Implementing, type Mode, type SweepInput } from "./sweep.ts";
|
|
28
|
-
|
|
29
|
-
/** One declaration a detector holds back, and where and why. */
|
|
30
|
-
export interface Evidence {
|
|
31
|
-
/** The identifier of the declaration held back. */
|
|
32
|
-
readonly id: string;
|
|
33
|
-
/** One clause naming the relation, then the thing it relates to. */
|
|
34
|
-
readonly detail: string;
|
|
35
|
-
readonly site: Position;
|
|
36
|
-
/** The component file, below the target root, whose markup holds the evidence. */
|
|
37
|
-
readonly whileLive?: string;
|
|
38
|
-
/** Where the evidence is an implementation of interface methods, which and how. */
|
|
39
|
-
readonly implementing?: Implementing;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** What a detector reads of one project, while the project's view is open. */
|
|
43
|
-
export interface DetectorInput<Brand> {
|
|
44
|
-
readonly project: ProjectView<Brand>;
|
|
45
|
-
readonly held: Inventory;
|
|
46
|
-
readonly targetRoot: string;
|
|
47
|
-
/** The configured templates, read once for the run. */
|
|
48
|
-
readonly templates: Templates;
|
|
49
|
-
/** The `ts` section, whose declarations the configured classes read. */
|
|
50
|
-
readonly ts: TSSection;
|
|
51
|
-
/** The absolute path of each declared consumer, whose modules are part of the analysis. */
|
|
52
|
-
readonly consumers: readonly string[];
|
|
53
|
-
/** The project's generated files, by path below the target root, each with the detail its retentions name. */
|
|
54
|
-
readonly generated?: ReadonlyMap<string, string>;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* One class's detection over one project. The framework records each piece of evidence
|
|
59
|
-
* under the class the table names the detector by, so a detector names no class.
|
|
60
|
-
*/
|
|
61
|
-
export type Detector = <Brand>(input: DetectorInput<Brand>) => readonly Evidence[];
|
|
62
|
-
|
|
63
|
-
/** The detector of each class one composition implements. */
|
|
64
|
-
export type Detectors = ReadonlyMap<TSExemptionClass, Detector>;
|
|
65
|
-
|
|
66
|
-
/** What decides which records of one project stand. */
|
|
67
|
-
interface Holding {
|
|
68
|
-
readonly mode: Mode;
|
|
69
|
-
/** The paths the reference pass classified as test files. */
|
|
70
|
-
readonly testFiles: ReadonlySet<string>;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* The classes `exemptions.disabled` switches off. A name is refused unless the
|
|
75
|
-
* vocabulary holds it; a class that runs on another language only is admitted and
|
|
76
|
-
* switches nothing off here, so one configuration serves every analyzer.
|
|
77
|
-
*/
|
|
78
|
-
export function disabledClasses(config: Config): ReadonlySet<ExemptionClass> {
|
|
79
|
-
const disabled = new Set<ExemptionClass>();
|
|
80
|
-
for (const name of config.exemptionsDisabled) {
|
|
81
|
-
if (!isExemptionClass(name)) {
|
|
82
|
-
const known = EXEMPTION_CLASSES.map((row) => row.class).join(", ");
|
|
83
|
-
throw new ConfigError(
|
|
84
|
-
"malformed",
|
|
85
|
-
"exemptions.disabled",
|
|
86
|
-
`exemptions.disabled: ${JSON.stringify(name)} is not an exemption class: the classes are ${known}`,
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
disabled.add(name);
|
|
90
|
-
}
|
|
91
|
-
return disabled;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Whether a class whose row states `allowed` may retain a member of one visibility. A
|
|
96
|
-
* declaration the inventory does not hold has no visibility to refuse it by.
|
|
97
|
-
*/
|
|
98
|
-
function retainable(allowed: TypeScriptVisibility, visibility: Visibility | undefined): boolean {
|
|
99
|
-
if (visibility === "private") {
|
|
100
|
-
return allowed.private;
|
|
101
|
-
}
|
|
102
|
-
if (visibility === "private-name") {
|
|
103
|
-
return allowed.privateName;
|
|
104
|
-
}
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* The kinds of declaration each class can hold back, which a detector that stops holds
|
|
110
|
-
* back whole. A class with no row here holds back every declaration but a file.
|
|
111
|
-
*/
|
|
112
|
-
const RETAINABLE: ReadonlyMap<TSExemptionClass, ReadonlySet<SymbolKind>> = new Map([
|
|
113
|
-
["interface-satisfaction", new Set<SymbolKind>(["method", "class-member"])],
|
|
114
|
-
["enum-group", new Set<SymbolKind>(["enum-member"])],
|
|
115
|
-
["injection-container", new Set<SymbolKind>(["method", "class-member"])],
|
|
116
|
-
["framework-lifecycle", new Set<SymbolKind>(["method", "class-member"])],
|
|
117
|
-
[
|
|
118
|
-
"serialization-contract",
|
|
119
|
-
new Set<SymbolKind>(["method", "class-member", "interface-method", "type-member"]),
|
|
120
|
-
],
|
|
121
|
-
]);
|
|
122
|
-
|
|
123
|
-
/** The detail of a record a detector that could not finish holds. */
|
|
124
|
-
const UNANSWERED_DETAIL = "kept live by a question the checker did not answer";
|
|
125
|
-
|
|
126
|
-
/** Whether one record is held by a detector that could not finish. */
|
|
127
|
-
export function isUnansweredRecord(record: Exemption): boolean {
|
|
128
|
-
return record.detail === UNANSWERED_DETAIL;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* What one detector holds back over one project. A detector that stops because the
|
|
133
|
-
* checker left a question it needs unanswered holds back every declaration of the
|
|
134
|
-
* project its class could hold back, each recorded at its own position, so the gap
|
|
135
|
-
* never yields a finding.
|
|
136
|
-
*/
|
|
137
|
-
function detected<Brand>(
|
|
138
|
-
exemptionClass: TSExemptionClass,
|
|
139
|
-
detect: Detector,
|
|
140
|
-
input: DetectorInput<Brand>,
|
|
141
|
-
): readonly Evidence[] {
|
|
142
|
-
try {
|
|
143
|
-
return detect(input);
|
|
144
|
-
} catch (error: unknown) {
|
|
145
|
-
if (!(error instanceof Unanswerable)) {
|
|
146
|
-
throw error;
|
|
147
|
-
}
|
|
148
|
-
const kinds = RETAINABLE.get(exemptionClass);
|
|
149
|
-
return input.held.symbols
|
|
150
|
-
.filter((symbol) => (kinds === undefined ? symbol.kind !== "file" : kinds.has(symbol.kind)))
|
|
151
|
-
.map((symbol) => ({ id: symbol.id, detail: UNANSWERED_DETAIL, site: symbol.position }));
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/** One project's records, and the evidence a production mode found in a test file. */
|
|
156
|
-
interface Detected {
|
|
157
|
-
readonly records: readonly Exemption[];
|
|
158
|
-
/**
|
|
159
|
-
* Under a production mode, each record whose evidence is written in a test file. It
|
|
160
|
-
* holds nothing, and it is a test reference to its declaration, as a reference the
|
|
161
|
-
* test file wrote would be.
|
|
162
|
-
*/
|
|
163
|
-
readonly inTestFiles: readonly Exemption[];
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Every record one project's detectors found, one per piece of evidence, before the
|
|
168
|
-
* mode decides which of them hold: what {@link heldRecords} reads. Classes run in the
|
|
169
|
-
* vocabulary's order and a switched-off class runs not at all; evidence on a private
|
|
170
|
-
* member the class's row says it cannot retain is dropped, whatever the detector found.
|
|
171
|
-
*/
|
|
172
|
-
export function evidenceRecords<Brand>(
|
|
173
|
-
input: DetectorInput<Brand>,
|
|
174
|
-
detectors: Detectors,
|
|
175
|
-
disabled: ReadonlySet<ExemptionClass>,
|
|
176
|
-
): readonly Exemption[] {
|
|
177
|
-
const visibility = new Map(input.held.symbols.map((symbol) => [symbol.id, symbol.visibility]));
|
|
178
|
-
const found: Exemption[] = [];
|
|
179
|
-
for (const exemptionClass of TS_EXEMPTION_CLASSES) {
|
|
180
|
-
const detect = detectors.get(exemptionClass);
|
|
181
|
-
if (detect === undefined || disabled.has(exemptionClass)) {
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
const allowed = typescriptVisibilityOf(exemptionClass);
|
|
185
|
-
for (const evidence of detected(exemptionClass, detect, input)) {
|
|
186
|
-
if (!retainable(allowed, visibility.get(evidence.id))) {
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
found.push({
|
|
190
|
-
id: evidence.id,
|
|
191
|
-
class: exemptionClass,
|
|
192
|
-
detail: evidence.detail,
|
|
193
|
-
site: evidence.site,
|
|
194
|
-
...(evidence.whileLive === undefined ? {} : { whileLive: evidence.whileLive }),
|
|
195
|
-
...(evidence.implementing === undefined ? {} : { implementing: evidence.implementing }),
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return found;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/** The records that hold under one mode, beside the evidence a production mode found in a test file. */
|
|
203
|
-
export function heldRecords(records: readonly Exemption[], holding: Holding): Detected {
|
|
204
|
-
const found: Exemption[] = [];
|
|
205
|
-
const inTestFiles: Exemption[] = [];
|
|
206
|
-
for (const record of records) {
|
|
207
|
-
if (holding.mode.production && holding.testFiles.has(record.site.path)) {
|
|
208
|
-
inTestFiles.push(record);
|
|
209
|
-
} else {
|
|
210
|
-
found.push(record);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return { records: exemptionsOf(found), inTestFiles };
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/** Two strings ordered bytewise. */
|
|
217
|
-
function compare(a: string, b: string): number {
|
|
218
|
-
if (a === b) {
|
|
219
|
-
return 0;
|
|
220
|
-
}
|
|
221
|
-
return a < b ? -1 : 1;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Records as a run holds them: ordered by site, then class, then declaration, and one
|
|
226
|
-
* per declaration, class, detail and file it holds while live, the one at the first
|
|
227
|
-
* site. A fact found at many sites, or by several projects, is one record.
|
|
228
|
-
*/
|
|
229
|
-
export function exemptionsOf(found: readonly Exemption[]): readonly Exemption[] {
|
|
230
|
-
const ordered = [...found].sort(
|
|
231
|
-
(a, b) => byPosition(a.site, b.site) || compare(a.class, b.class) || compare(a.id, b.id),
|
|
232
|
-
);
|
|
233
|
-
const seen = new Set<string>();
|
|
234
|
-
return ordered.filter((record) => {
|
|
235
|
-
const fact = [record.id, record.class, record.detail, record.whileLive ?? ""].join("\u0000");
|
|
236
|
-
if (seen.has(fact)) {
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
seen.add(fact);
|
|
240
|
-
return true;
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* The records that hold while the component files at `live` are live: every record that
|
|
246
|
-
* holds whatever is live, and each one a live file's markup holds, as a record of the run.
|
|
247
|
-
*/
|
|
248
|
-
export function holdingWhile(
|
|
249
|
-
records: readonly Exemption[],
|
|
250
|
-
live: ReadonlySet<string>,
|
|
251
|
-
): readonly Exemption[] {
|
|
252
|
-
return exemptionsOf(
|
|
253
|
-
records.flatMap(({ whileLive, ...record }) =>
|
|
254
|
-
whileLive === undefined || live.has(whileLive) ? [record] : [],
|
|
255
|
-
),
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/** The records per declaration, each declaration's in the order given. */
|
|
260
|
-
function byDeclaration(records: readonly Exemption[]): ReadonlyMap<string, readonly Exemption[]> {
|
|
261
|
-
const grouped = new Map<string, Exemption[]>();
|
|
262
|
-
for (const record of records) {
|
|
263
|
-
const held = grouped.get(record.id);
|
|
264
|
-
if (held === undefined) {
|
|
265
|
-
grouped.set(record.id, [record]);
|
|
266
|
-
} else {
|
|
267
|
-
held.push(record);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
return grouped;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* The records that held back a declaration: one some configuration's graph, swept
|
|
275
|
-
* again with no exemption and its marks, judges a candidate, whatever another
|
|
276
|
-
* configuration answers, or one in `writeOnly`, which the run would report as written
|
|
277
|
-
* and never read without the record's read. A declaration a relation or a mark holds
|
|
278
|
-
* live in every configuration is held back by no record. The order is the
|
|
279
|
-
* declarations' site order, and for one declaration the input's.
|
|
280
|
-
*/
|
|
281
|
-
export function retainedIn(
|
|
282
|
-
matrix: Matrix,
|
|
283
|
-
input: SweepInput,
|
|
284
|
-
writeOnly: ReadonlySet<string> = new Set(),
|
|
285
|
-
): readonly Exemption[] {
|
|
286
|
-
const exempt = input.exempt ?? [];
|
|
287
|
-
if (exempt.length === 0) {
|
|
288
|
-
return [];
|
|
289
|
-
}
|
|
290
|
-
const bare: SweepInput = { marked: input.marked, mode: input.mode };
|
|
291
|
-
const dead = new Set(
|
|
292
|
-
matrix.graphs.flatMap((graph) =>
|
|
293
|
-
sweep(graph, bare).candidates.map((candidate) => candidate.id),
|
|
294
|
-
),
|
|
295
|
-
);
|
|
296
|
-
const held = byDeclaration(
|
|
297
|
-
exempt.filter((record) => dead.has(record.id) || writeOnly.has(record.id)),
|
|
298
|
-
);
|
|
299
|
-
return matrix.union.symbols.flatMap((symbol) => held.get(symbol.id) ?? []);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* One line per held-back declaration, in site order: its reference, then each record's
|
|
304
|
-
* class, site and detail, all separated by tabs.
|
|
305
|
-
*/
|
|
306
|
-
export function retainedLines(
|
|
307
|
-
symbols: readonly InventorySymbol[],
|
|
308
|
-
retained: readonly Exemption[],
|
|
309
|
-
): readonly string[] {
|
|
310
|
-
const held = byDeclaration(retained);
|
|
311
|
-
return symbols.flatMap((symbol) => {
|
|
312
|
-
const records = held.get(symbol.id);
|
|
313
|
-
if (records === undefined) {
|
|
314
|
-
return [];
|
|
315
|
-
}
|
|
316
|
-
const fields = records.flatMap((record) => [
|
|
317
|
-
record.class,
|
|
318
|
-
positionKey(record.site),
|
|
319
|
-
record.detail,
|
|
320
|
-
]);
|
|
321
|
-
return [[symbol.ref, ...fields].join("\t")];
|
|
322
|
-
});
|
|
323
|
-
}
|
package/src/generated-file.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The generated-file class on TypeScript: every declaration in a file that marks itself
|
|
3
|
-
* generated, or below a directory an applied convention row names as generated, is
|
|
4
|
-
* retained, because a generator owns the file and a deletion there is undone at the next
|
|
5
|
-
* generation.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { DetectorInput, Evidence } from "./exempt.ts";
|
|
9
|
-
import type { SourceFiles } from "./source-files.ts";
|
|
10
|
-
|
|
11
|
-
/** The generated-code header, matched against each line of a leading comment. */
|
|
12
|
-
const HEADER_LINE = /^\/\/ Code generated .* DO NOT EDIT\.$/u;
|
|
13
|
-
|
|
14
|
-
/** The documentation tag `@generated` as a word of a comment. */
|
|
15
|
-
const GENERATED_TAG = /(?<![\w@$])@generated(?![\w$-])/u;
|
|
16
|
-
|
|
17
|
-
/** A first comment naming the tool that wrote the file. */
|
|
18
|
-
const GENERATED_BY = /^\/\/ Generated by \S/u;
|
|
19
|
-
|
|
20
|
-
/** The word a generator's notice holds, beside one of {@link KEEP_OUT}. */
|
|
21
|
-
const GENERATED_WORD = /\bgenerated\b/iu;
|
|
22
|
-
|
|
23
|
-
/** The phrases a generator's notice asks a reader not to edit the file by. */
|
|
24
|
-
const KEEP_OUT = /\b(?:do not edit|will be overwritten|should not make any changes)\b/iu;
|
|
25
|
-
|
|
26
|
-
/** The comments before a text's first token, a leading hashbang line skipped. */
|
|
27
|
-
function leadingComments(text: string): readonly string[] {
|
|
28
|
-
const comments: string[] = [];
|
|
29
|
-
let at = text.startsWith("\uFEFF") ? 1 : 0;
|
|
30
|
-
if (text.startsWith("#!", at)) {
|
|
31
|
-
const end = text.indexOf("\n", at);
|
|
32
|
-
at = end === -1 ? text.length : end + 1;
|
|
33
|
-
}
|
|
34
|
-
for (;;) {
|
|
35
|
-
while (at < text.length && /\s/u.test(text.charAt(at))) {
|
|
36
|
-
at++;
|
|
37
|
-
}
|
|
38
|
-
if (text.startsWith("//", at)) {
|
|
39
|
-
const end = text.slice(at).search(/[\r\n\u2028\u2029]/u);
|
|
40
|
-
const stop = end === -1 ? text.length : at + end;
|
|
41
|
-
comments.push(text.slice(at, stop));
|
|
42
|
-
at = stop;
|
|
43
|
-
} else if (text.startsWith("/*", at)) {
|
|
44
|
-
const end = text.indexOf("*/", at + 2);
|
|
45
|
-
if (end === -1) {
|
|
46
|
-
return comments;
|
|
47
|
-
}
|
|
48
|
-
comments.push(text.slice(at, end + 2));
|
|
49
|
-
at = end + 2;
|
|
50
|
-
} else {
|
|
51
|
-
return comments;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** The detail a file's leading comments mark it generated by, or undefined where they mark nothing. */
|
|
57
|
-
export function generatedByComment(text: string): string | undefined {
|
|
58
|
-
const comments = leadingComments(text);
|
|
59
|
-
if (comments.some((one) => one.split(/\r?\n/u).some((line) => HEADER_LINE.test(line)))) {
|
|
60
|
-
return "generated by the header line its leading comments hold";
|
|
61
|
-
}
|
|
62
|
-
if (comments.some((one) => GENERATED_TAG.test(one))) {
|
|
63
|
-
return "generated by the @generated tag its leading comments hold";
|
|
64
|
-
}
|
|
65
|
-
const notice = comments.join("\n");
|
|
66
|
-
if (
|
|
67
|
-
GENERATED_BY.test(comments[0] ?? "") ||
|
|
68
|
-
(GENERATED_WORD.test(notice) && KEEP_OUT.test(notice))
|
|
69
|
-
) {
|
|
70
|
-
return "generated by the notice its leading comments hold";
|
|
71
|
-
}
|
|
72
|
-
return undefined;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Every own file of one project that is generated, by its path below the target root,
|
|
77
|
-
* with the detail a retention in it names: its leading comments' mark, else the row
|
|
78
|
-
* naming its directory as generated.
|
|
79
|
-
*/
|
|
80
|
-
export function generatedFilesOf(
|
|
81
|
-
files: SourceFiles,
|
|
82
|
-
byRow: ReadonlyMap<string, string>,
|
|
83
|
-
): ReadonlyMap<string, string> {
|
|
84
|
-
const found = new Map<string, string>();
|
|
85
|
-
for (const [path, file] of files.byPath) {
|
|
86
|
-
const row = byRow.get(path);
|
|
87
|
-
const detail =
|
|
88
|
-
generatedByComment(file.text) ??
|
|
89
|
-
(row === undefined
|
|
90
|
-
? undefined
|
|
91
|
-
: `generated below a directory the convention row ${row} names`);
|
|
92
|
-
if (detail !== undefined) {
|
|
93
|
-
found.set(path, detail);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return found;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** The generated-file detector, recording each file's first line. */
|
|
100
|
-
export function generatedFile<Brand>(input: DetectorInput<Brand>): readonly Evidence[] {
|
|
101
|
-
const generated = input.generated;
|
|
102
|
-
if (generated === undefined || generated.size === 0) {
|
|
103
|
-
return [];
|
|
104
|
-
}
|
|
105
|
-
return input.held.symbols.flatMap((symbol): Evidence[] => {
|
|
106
|
-
const detail = generated.get(symbol.position.path);
|
|
107
|
-
return symbol.kind === "file" || detail === undefined
|
|
108
|
-
? []
|
|
109
|
-
: [{ id: symbol.id, detail, site: { path: symbol.position.path, line: 1, column: 1 } }];
|
|
110
|
-
});
|
|
111
|
-
}
|
package/src/glob.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Glob patterns over the paths of the target's own files, as the configuration
|
|
3
|
-
* writes them. Both `ts.test_files` and `ts.entry_files` name files this way, and
|
|
4
|
-
* one grammar answers for both.
|
|
5
|
-
*
|
|
6
|
-
* A configured root is not written in this grammar. It names a symbol reference
|
|
7
|
-
* rather than a path, `*` there spans the solidus and a brace list means nothing,
|
|
8
|
-
* so that rule is written where it is read.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* One literal run of a pattern, with every character the expression syntax claims
|
|
13
|
-
* escaped.
|
|
14
|
-
*
|
|
15
|
-
* The set is the syntax characters and the solidus, and it is closed: an escape of any
|
|
16
|
-
* other character is refused outright by the expression syntax under the unicode flag,
|
|
17
|
-
* so escaping a hyphen, which needs none outside a character class, would refuse every
|
|
18
|
-
* pattern that names a hyphenated path.
|
|
19
|
-
*/
|
|
20
|
-
function quoted(text: string): string {
|
|
21
|
-
return text.replaceAll(/[.*+?^${}()|[\]\\/]/gu, (character) => `\\${character}`);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* The expression one glob pattern denotes. `**` spans path separators while `*` and `?`
|
|
26
|
-
* do not, a brace list is an alternation of its members, and every other character
|
|
27
|
-
* stands for itself.
|
|
28
|
-
*/
|
|
29
|
-
export function globExpression(pattern: string): RegExp {
|
|
30
|
-
let source = "^";
|
|
31
|
-
let at = 0;
|
|
32
|
-
while (at < pattern.length) {
|
|
33
|
-
const rest = pattern.slice(at);
|
|
34
|
-
if (rest.startsWith("**/")) {
|
|
35
|
-
source += "(?:[^/]*/)*";
|
|
36
|
-
at += 3;
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if (rest.startsWith("**")) {
|
|
40
|
-
source += ".*";
|
|
41
|
-
at += 2;
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
const character = pattern[at] ?? "";
|
|
45
|
-
at += 1;
|
|
46
|
-
if (character === "*") {
|
|
47
|
-
source += "[^/]*";
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
if (character === "?") {
|
|
51
|
-
source += "[^/]";
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
if (character === "{") {
|
|
55
|
-
const close = pattern.indexOf("}", at);
|
|
56
|
-
if (close < 0) {
|
|
57
|
-
source += "\\{";
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
source += `(?:${pattern.slice(at, close).split(",").map(quoted).join("|")})`;
|
|
61
|
-
at = close + 1;
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
source += quoted(character);
|
|
65
|
-
}
|
|
66
|
-
return new RegExp(`${source}$`, "u");
|
|
67
|
-
}
|