@nielspeter/eess-ts 0.2.1 → 0.5.0
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 +61 -35
- package/dist/builders/call-rule-builder.d.ts +66 -26
- package/dist/builders/call-rule-builder.d.ts.map +1 -1
- package/dist/builders/call-rule-builder.js +75 -32
- package/dist/builders/call-rule-builder.js.map +1 -1
- package/dist/builders/class-rule-builder.d.ts +125 -26
- package/dist/builders/class-rule-builder.d.ts.map +1 -1
- package/dist/builders/class-rule-builder.js +141 -55
- package/dist/builders/class-rule-builder.js.map +1 -1
- package/dist/builders/correspondence-builder.d.ts +287 -0
- package/dist/builders/correspondence-builder.d.ts.map +1 -0
- package/dist/builders/correspondence-builder.js +385 -0
- package/dist/builders/correspondence-builder.js.map +1 -0
- package/dist/builders/correspondence-findings.d.ts +104 -0
- package/dist/builders/correspondence-findings.d.ts.map +1 -0
- package/dist/builders/correspondence-findings.js +301 -0
- package/dist/builders/correspondence-findings.js.map +1 -0
- package/dist/builders/cross-layer-builder.d.ts +99 -16
- package/dist/builders/cross-layer-builder.d.ts.map +1 -1
- package/dist/builders/cross-layer-builder.js +182 -35
- package/dist/builders/cross-layer-builder.js.map +1 -1
- package/dist/builders/function-rule-builder.d.ts +144 -25
- package/dist/builders/function-rule-builder.d.ts.map +1 -1
- package/dist/builders/function-rule-builder.js +177 -39
- package/dist/builders/function-rule-builder.js.map +1 -1
- package/dist/builders/jsx-rule-builder.d.ts +70 -14
- package/dist/builders/jsx-rule-builder.d.ts.map +1 -1
- package/dist/builders/jsx-rule-builder.js +73 -14
- package/dist/builders/jsx-rule-builder.js.map +1 -1
- package/dist/builders/module-rule-builder.d.ts +2 -2
- package/dist/builders/module-rule-builder.d.ts.map +1 -1
- package/dist/builders/module-rule-builder.js +16 -19
- package/dist/builders/module-rule-builder.js.map +1 -1
- package/dist/builders/scoped-function-rule-builder.d.ts +11 -0
- package/dist/builders/scoped-function-rule-builder.d.ts.map +1 -1
- package/dist/builders/scoped-function-rule-builder.js +12 -0
- package/dist/builders/scoped-function-rule-builder.js.map +1 -1
- package/dist/builders/slice-discovery-message.d.ts +36 -0
- package/dist/builders/slice-discovery-message.d.ts.map +1 -0
- package/dist/builders/slice-discovery-message.js +181 -0
- package/dist/builders/slice-discovery-message.js.map +1 -0
- package/dist/builders/slice-rule-builder.d.ts +151 -12
- package/dist/builders/slice-rule-builder.d.ts.map +1 -1
- package/dist/builders/slice-rule-builder.js +243 -35
- package/dist/builders/slice-rule-builder.js.map +1 -1
- package/dist/builders/type-rule-builder.d.ts +95 -24
- package/dist/builders/type-rule-builder.d.ts.map +1 -1
- package/dist/builders/type-rule-builder.js +109 -42
- package/dist/builders/type-rule-builder.js.map +1 -1
- package/dist/{helpers → builders}/within.d.ts +2 -2
- package/dist/builders/within.d.ts.map +1 -0
- package/dist/{helpers → builders}/within.js +1 -1
- package/dist/builders/within.js.map +1 -0
- package/dist/cli/commands/baseline.d.ts +8 -3
- package/dist/cli/commands/baseline.d.ts.map +1 -1
- package/dist/cli/commands/baseline.js +111 -7
- package/dist/cli/commands/baseline.js.map +1 -1
- package/dist/cli/commands/check.d.ts +7 -2
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +385 -47
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +29 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +224 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/explain.d.ts +2 -1
- package/dist/cli/commands/explain.d.ts.map +1 -1
- package/dist/cli/commands/explain.js +19 -10
- package/dist/cli/commands/explain.js.map +1 -1
- package/dist/cli/commands/init.d.ts +9 -3
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +162 -137
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/import-rule-module.d.ts +29 -0
- package/dist/cli/import-rule-module.d.ts.map +1 -0
- package/dist/cli/import-rule-module.js +47 -0
- package/dist/cli/import-rule-module.js.map +1 -0
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +101 -43
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/load-rules.d.ts +6 -11
- package/dist/cli/load-rules.d.ts.map +1 -1
- package/dist/cli/load-rules.js +25 -32
- package/dist/cli/load-rules.js.map +1 -1
- package/dist/cli/resolve-config.d.ts +0 -8
- package/dist/cli/resolve-config.d.ts.map +1 -1
- package/dist/cli/resolve-config.js +25 -55
- package/dist/cli/resolve-config.js.map +1 -1
- package/dist/cli/rule-file-findings.d.ts +178 -0
- package/dist/cli/rule-file-findings.d.ts.map +1 -0
- package/dist/cli/rule-file-findings.js +351 -0
- package/dist/cli/rule-file-findings.js.map +1 -0
- package/dist/cli/watch.d.ts +17 -34
- package/dist/cli/watch.d.ts.map +1 -1
- package/dist/cli/watch.js +14 -129
- package/dist/cli/watch.js.map +1 -1
- package/dist/conditions/body-analysis-function.d.ts.map +1 -1
- package/dist/conditions/body-analysis-function.js +16 -7
- package/dist/conditions/body-analysis-function.js.map +1 -1
- package/dist/conditions/body-analysis-module.d.ts.map +1 -1
- package/dist/conditions/body-analysis-module.js +14 -9
- package/dist/conditions/body-analysis-module.js.map +1 -1
- package/dist/conditions/body-analysis.d.ts.map +1 -1
- package/dist/conditions/body-analysis.js +16 -7
- package/dist/conditions/body-analysis.js.map +1 -1
- package/dist/conditions/call.d.ts.map +1 -1
- package/dist/conditions/call.js +41 -19
- package/dist/conditions/call.js.map +1 -1
- package/dist/conditions/catch-analysis.d.ts +2 -1
- package/dist/conditions/catch-analysis.d.ts.map +1 -1
- package/dist/conditions/catch-analysis.js.map +1 -1
- package/dist/conditions/cross-layer.d.ts +2 -10
- package/dist/conditions/cross-layer.d.ts.map +1 -1
- package/dist/conditions/cross-layer.js +227 -23
- package/dist/conditions/cross-layer.js.map +1 -1
- package/dist/conditions/dependency.d.ts +35 -6
- package/dist/conditions/dependency.d.ts.map +1 -1
- package/dist/conditions/dependency.js +299 -45
- package/dist/conditions/dependency.js.map +1 -1
- package/dist/conditions/exports.d.ts.map +1 -1
- package/dist/conditions/exports.js +41 -37
- package/dist/conditions/exports.js.map +1 -1
- package/dist/conditions/function.d.ts.map +1 -1
- package/dist/conditions/function.js +19 -5
- package/dist/conditions/function.js.map +1 -1
- package/dist/conditions/helpers.d.ts +2 -1
- package/dist/conditions/helpers.d.ts.map +1 -1
- package/dist/conditions/helpers.js +4 -1
- package/dist/conditions/helpers.js.map +1 -1
- package/dist/conditions/jsx.d.ts.map +1 -1
- package/dist/conditions/jsx.js +7 -2
- package/dist/conditions/jsx.js.map +1 -1
- package/dist/conditions/match-identity.d.ts +43 -0
- package/dist/conditions/match-identity.d.ts.map +1 -0
- package/dist/conditions/match-identity.js +43 -0
- package/dist/conditions/match-identity.js.map +1 -0
- package/dist/conditions/members.d.ts.map +1 -1
- package/dist/conditions/members.js +20 -6
- package/dist/conditions/members.js.map +1 -1
- package/dist/conditions/reverse-dependency.d.ts +18 -5
- package/dist/conditions/reverse-dependency.d.ts.map +1 -1
- package/dist/conditions/reverse-dependency.js +155 -93
- package/dist/conditions/reverse-dependency.js.map +1 -1
- package/dist/conditions/slice.d.ts +86 -2
- package/dist/conditions/slice.d.ts.map +1 -1
- package/dist/conditions/slice.js +234 -53
- package/dist/conditions/slice.js.map +1 -1
- package/dist/conditions/structural.d.ts.map +1 -1
- package/dist/conditions/structural.js +16 -4
- package/dist/conditions/structural.js.map +1 -1
- package/dist/core/check-all.d.ts +19 -0
- package/dist/core/check-all.d.ts.map +1 -0
- package/dist/core/check-all.js +150 -0
- package/dist/core/check-all.js.map +1 -0
- package/dist/core/combinators.d.ts +48 -0
- package/dist/core/combinators.d.ts.map +1 -0
- package/dist/core/combinators.js +49 -0
- package/dist/core/combinators.js.map +1 -0
- package/dist/core/descendant-cache.d.ts +36 -0
- package/dist/core/descendant-cache.d.ts.map +1 -0
- package/dist/core/descendant-cache.js +117 -0
- package/dist/core/descendant-cache.js.map +1 -0
- package/dist/core/diagnose.d.ts +234 -0
- package/dist/core/diagnose.d.ts.map +1 -0
- package/dist/core/diagnose.js +390 -0
- package/dist/core/diagnose.js.map +1 -0
- package/dist/core/disk-set.d.ts +48 -0
- package/dist/core/disk-set.d.ts.map +1 -0
- package/dist/core/disk-set.js +218 -0
- package/dist/core/disk-set.js.map +1 -0
- package/dist/core/element-cache.d.ts +75 -0
- package/dist/core/element-cache.d.ts.map +1 -0
- package/dist/core/element-cache.js +32 -0
- package/dist/core/element-cache.js.map +1 -0
- package/dist/core/empty-project-advice.d.ts +75 -0
- package/dist/core/empty-project-advice.d.ts.map +1 -0
- package/dist/core/empty-project-advice.js +61 -0
- package/dist/core/empty-project-advice.js.map +1 -0
- package/dist/core/exclusion-comments.d.ts +19 -0
- package/dist/core/exclusion-comments.d.ts.map +1 -0
- package/dist/core/exclusion-comments.js +7 -0
- package/dist/core/exclusion-comments.js.map +1 -0
- package/dist/core/execute-rule.d.ts +158 -0
- package/dist/core/execute-rule.d.ts.map +1 -0
- package/dist/core/execute-rule.js +666 -0
- package/dist/core/execute-rule.js.map +1 -0
- package/dist/core/glob-diagnosis.d.ts +78 -0
- package/dist/core/glob-diagnosis.d.ts.map +1 -0
- package/dist/core/glob-diagnosis.js +134 -0
- package/dist/core/glob-diagnosis.js.map +1 -0
- package/dist/core/glob-evaluator.d.ts +48 -0
- package/dist/core/glob-evaluator.d.ts.map +1 -0
- package/dist/core/glob-evaluator.js +89 -0
- package/dist/core/glob-evaluator.js.map +1 -0
- package/dist/core/import-candidates.d.ts +60 -0
- package/dist/core/import-candidates.d.ts.map +1 -0
- package/dist/core/import-candidates.js +93 -0
- package/dist/core/import-candidates.js.map +1 -0
- package/dist/core/import-options.d.ts +55 -2
- package/dist/core/import-options.d.ts.map +1 -1
- package/dist/core/import-options.js +64 -0
- package/dist/core/import-options.js.map +1 -1
- package/dist/core/invalidate-on-modify.d.ts +20 -0
- package/dist/core/invalidate-on-modify.d.ts.map +1 -0
- package/dist/core/invalidate-on-modify.js +26 -0
- package/dist/core/invalidate-on-modify.js.map +1 -0
- package/dist/core/line-index.d.ts +3 -0
- package/dist/core/line-index.d.ts.map +1 -0
- package/dist/core/line-index.js +227 -0
- package/dist/core/line-index.js.map +1 -0
- package/dist/core/metric-violation.d.ts +86 -0
- package/dist/core/metric-violation.d.ts.map +1 -0
- package/dist/core/metric-violation.js +132 -0
- package/dist/core/metric-violation.js.map +1 -0
- package/dist/core/module-edges.d.ts +361 -0
- package/dist/core/module-edges.d.ts.map +1 -0
- package/dist/core/module-edges.js +593 -0
- package/dist/core/module-edges.js.map +1 -0
- package/dist/core/object-literal-functions.d.ts +42 -0
- package/dist/core/object-literal-functions.d.ts.map +1 -0
- package/dist/core/object-literal-functions.js +75 -0
- package/dist/core/object-literal-functions.js.map +1 -0
- package/dist/core/orphan-exclusions.d.ts +44 -0
- package/dist/core/orphan-exclusions.d.ts.map +1 -0
- package/dist/core/orphan-exclusions.js +224 -0
- package/dist/core/orphan-exclusions.js.map +1 -0
- package/dist/core/pair-condition.d.ts +32 -3
- package/dist/core/pair-condition.d.ts.map +1 -1
- package/dist/core/path-universe.d.ts +22 -0
- package/dist/core/path-universe.d.ts.map +1 -0
- package/dist/core/path-universe.js +45 -0
- package/dist/core/path-universe.js.map +1 -0
- package/dist/core/per-root-compiler-options.d.ts +20 -0
- package/dist/core/per-root-compiler-options.d.ts.map +1 -0
- package/dist/core/per-root-compiler-options.js +57 -0
- package/dist/core/per-root-compiler-options.js.map +1 -0
- package/dist/core/project-relative.d.ts +98 -0
- package/dist/core/project-relative.d.ts.map +1 -0
- package/dist/core/project-relative.js +185 -0
- package/dist/core/project-relative.js.map +1 -0
- package/dist/core/project.d.ts +7 -1
- package/dist/core/project.d.ts.map +1 -1
- package/dist/core/project.js +29 -4
- package/dist/core/project.js.map +1 -1
- package/dist/core/rule-builder.d.ts +303 -0
- package/dist/core/rule-builder.d.ts.map +1 -0
- package/dist/core/rule-builder.js +463 -0
- package/dist/core/rule-builder.js.map +1 -0
- package/dist/core/rule-declaration.d.ts +32 -0
- package/dist/core/rule-declaration.d.ts.map +1 -0
- package/dist/core/rule-declaration.js +88 -0
- package/dist/core/rule-declaration.js.map +1 -0
- package/dist/core/terminal-builder.d.ts +629 -0
- package/dist/core/terminal-builder.d.ts.map +1 -0
- package/dist/core/terminal-builder.js +807 -0
- package/dist/core/terminal-builder.js.map +1 -0
- package/dist/core/terminal-execution.d.ts +39 -0
- package/dist/core/terminal-execution.d.ts.map +1 -0
- package/dist/core/terminal-execution.js +103 -0
- package/dist/core/terminal-execution.js.map +1 -0
- package/dist/core/ts-comment-mask.d.ts +2 -0
- package/dist/core/ts-comment-mask.d.ts.map +1 -0
- package/dist/core/ts-comment-mask.js +102 -0
- package/dist/core/ts-comment-mask.js.map +1 -0
- package/dist/core/vacuity-diagnosis.d.ts +103 -0
- package/dist/core/vacuity-diagnosis.d.ts.map +1 -0
- package/dist/core/vacuity-diagnosis.js +415 -0
- package/dist/core/vacuity-diagnosis.js.map +1 -0
- package/dist/core/violation.d.ts +16 -11
- package/dist/core/violation.d.ts.map +1 -1
- package/dist/core/violation.js +33 -13
- package/dist/core/violation.js.map +1 -1
- package/dist/graphql/graphql-rule-builder.d.ts +95 -0
- package/dist/graphql/graphql-rule-builder.d.ts.map +1 -0
- package/dist/graphql/graphql-rule-builder.js +127 -0
- package/dist/graphql/graphql-rule-builder.js.map +1 -0
- package/dist/graphql/index.d.ts +1 -0
- package/dist/graphql/index.d.ts.map +1 -1
- package/dist/graphql/index.js +2 -1
- package/dist/graphql/index.js.map +1 -1
- package/dist/graphql/resolver-rule-builder.d.ts +44 -23
- package/dist/graphql/resolver-rule-builder.d.ts.map +1 -1
- package/dist/graphql/resolver-rule-builder.js +80 -72
- package/dist/graphql/resolver-rule-builder.js.map +1 -1
- package/dist/graphql/schema-loader.d.ts +21 -0
- package/dist/graphql/schema-loader.d.ts.map +1 -1
- package/dist/graphql/schema-loader.js +82 -12
- package/dist/graphql/schema-loader.js.map +1 -1
- package/dist/graphql/schema-predicates.d.ts.map +1 -1
- package/dist/graphql/schema-predicates.js +17 -12
- package/dist/graphql/schema-predicates.js.map +1 -1
- package/dist/graphql/schema-rule-builder.d.ts +15 -24
- package/dist/graphql/schema-rule-builder.d.ts.map +1 -1
- package/dist/graphql/schema-rule-builder.js +39 -77
- package/dist/graphql/schema-rule-builder.js.map +1 -1
- package/dist/helpers/baseline-diagnostics.d.ts +45 -0
- package/dist/helpers/baseline-diagnostics.d.ts.map +1 -0
- package/dist/helpers/baseline-diagnostics.js +168 -0
- package/dist/helpers/baseline-diagnostics.js.map +1 -0
- package/dist/helpers/baseline-generator.d.ts +28 -0
- package/dist/helpers/baseline-generator.d.ts.map +1 -0
- package/dist/helpers/baseline-generator.js +27 -0
- package/dist/helpers/baseline-generator.js.map +1 -0
- package/dist/helpers/baseline.d.ts +336 -0
- package/dist/helpers/baseline.d.ts.map +1 -0
- package/dist/helpers/baseline.js +664 -0
- package/dist/helpers/baseline.js.map +1 -0
- package/dist/helpers/body-traversal.d.ts +27 -2
- package/dist/helpers/body-traversal.d.ts.map +1 -1
- package/dist/helpers/body-traversal.js +135 -16
- package/dist/helpers/body-traversal.js.map +1 -1
- package/dist/helpers/callback-extractor.d.ts.map +1 -1
- package/dist/helpers/callback-extractor.js +53 -84
- package/dist/helpers/callback-extractor.js.map +1 -1
- package/dist/helpers/complexity.d.ts +13 -5
- package/dist/helpers/complexity.d.ts.map +1 -1
- package/dist/helpers/complexity.js +15 -6
- package/dist/helpers/complexity.js.map +1 -1
- package/dist/helpers/diff-aware.d.ts +16 -0
- package/dist/helpers/diff-aware.d.ts.map +1 -0
- package/dist/helpers/diff-aware.js +16 -0
- package/dist/helpers/diff-aware.js.map +1 -0
- package/dist/helpers/matchers.d.ts +68 -7
- package/dist/helpers/matchers.d.ts.map +1 -1
- package/dist/helpers/matchers.js +164 -86
- package/dist/helpers/matchers.js.map +1 -1
- package/dist/helpers/slice-graph.d.ts +100 -8
- package/dist/helpers/slice-graph.d.ts.map +1 -1
- package/dist/helpers/slice-graph.js +126 -34
- package/dist/helpers/slice-graph.js.map +1 -1
- package/dist/helpers/tarjan.d.ts +0 -14
- package/dist/helpers/tarjan.d.ts.map +1 -1
- package/dist/helpers/tarjan.js +29 -16
- package/dist/helpers/tarjan.js.map +1 -1
- package/dist/index.d.ts +55 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +67 -15
- package/dist/index.js.map +1 -1
- package/dist/models/arch-call.d.ts +3 -2
- package/dist/models/arch-call.d.ts.map +1 -1
- package/dist/models/arch-call.js.map +1 -1
- package/dist/models/arch-function.d.ts +54 -8
- package/dist/models/arch-function.d.ts.map +1 -1
- package/dist/models/arch-function.js +145 -8
- package/dist/models/arch-function.js.map +1 -1
- package/dist/models/arch-jsx-element.d.ts.map +1 -1
- package/dist/models/arch-jsx-element.js +18 -19
- package/dist/models/arch-jsx-element.js.map +1 -1
- package/dist/models/slice.d.ts +33 -9
- package/dist/models/slice.d.ts.map +1 -1
- package/dist/models/slice.js +129 -19
- package/dist/models/slice.js.map +1 -1
- package/dist/predicates/call.d.ts.map +1 -1
- package/dist/predicates/call.js +5 -0
- package/dist/predicates/call.js.map +1 -1
- package/dist/predicates/identity.d.ts +21 -0
- package/dist/predicates/identity.d.ts.map +1 -1
- package/dist/predicates/identity.js +75 -3
- package/dist/predicates/identity.js.map +1 -1
- package/dist/predicates/index.d.ts +1 -1
- package/dist/predicates/index.d.ts.map +1 -1
- package/dist/predicates/index.js +1 -1
- package/dist/predicates/index.js.map +1 -1
- package/dist/predicates/jsx.d.ts.map +1 -1
- package/dist/predicates/jsx.js +2 -1
- package/dist/predicates/jsx.js.map +1 -1
- package/dist/predicates/metrics.d.ts +4 -2
- package/dist/predicates/metrics.d.ts.map +1 -1
- package/dist/predicates/metrics.js +4 -2
- package/dist/predicates/metrics.js.map +1 -1
- package/dist/predicates/module.d.ts +4 -12
- package/dist/predicates/module.d.ts.map +1 -1
- package/dist/predicates/module.js +57 -37
- package/dist/predicates/module.js.map +1 -1
- package/dist/presets/agent-guardrails.d.ts +49 -16
- package/dist/presets/agent-guardrails.d.ts.map +1 -1
- package/dist/presets/agent-guardrails.js +308 -19
- package/dist/presets/agent-guardrails.js.map +1 -1
- package/dist/presets/boundaries.d.ts +46 -3
- package/dist/presets/boundaries.d.ts.map +1 -1
- package/dist/presets/boundaries.js +132 -23
- package/dist/presets/boundaries.js.map +1 -1
- package/dist/presets/data-layer.d.ts +23 -3
- package/dist/presets/data-layer.d.ts.map +1 -1
- package/dist/presets/data-layer.js +58 -16
- package/dist/presets/data-layer.js.map +1 -1
- package/dist/presets/index.d.ts +10 -5
- package/dist/presets/index.d.ts.map +1 -1
- package/dist/presets/index.js +19 -3
- package/dist/presets/index.js.map +1 -1
- package/dist/presets/layered.d.ts +47 -3
- package/dist/presets/layered.d.ts.map +1 -1
- package/dist/presets/layered.js +66 -29
- package/dist/presets/layered.js.map +1 -1
- package/dist/presets/recommended.d.ts +81 -10
- package/dist/presets/recommended.d.ts.map +1 -1
- package/dist/presets/recommended.js +25 -23
- package/dist/presets/recommended.js.map +1 -1
- package/dist/presets/shared.d.ts +267 -2
- package/dist/presets/shared.d.ts.map +1 -1
- package/dist/presets/shared.js +367 -4
- package/dist/presets/shared.js.map +1 -1
- package/dist/rules/code-quality.d.ts.map +1 -1
- package/dist/rules/code-quality.js +15 -6
- package/dist/rules/code-quality.js.map +1 -1
- package/dist/rules/hygiene.d.ts +1 -1
- package/dist/rules/hygiene.js +1 -1
- package/dist/rules/metrics-function.d.ts +2 -1
- package/dist/rules/metrics-function.d.ts.map +1 -1
- package/dist/rules/metrics-function.js +63 -39
- package/dist/rules/metrics-function.js.map +1 -1
- package/dist/rules/metrics.d.ts +2 -1
- package/dist/rules/metrics.d.ts.map +1 -1
- package/dist/rules/metrics.js +80 -47
- package/dist/rules/metrics.js.map +1 -1
- package/dist/smells/clusters.d.ts +78 -0
- package/dist/smells/clusters.d.ts.map +1 -0
- package/dist/smells/clusters.js +124 -0
- package/dist/smells/clusters.js.map +1 -0
- package/dist/smells/duplicate-bodies.d.ts +92 -5
- package/dist/smells/duplicate-bodies.d.ts.map +1 -1
- package/dist/smells/duplicate-bodies.js +203 -73
- package/dist/smells/duplicate-bodies.js.map +1 -1
- package/dist/smells/duplicate-report.d.ts +90 -0
- package/dist/smells/duplicate-report.d.ts.map +1 -0
- package/dist/smells/duplicate-report.js +344 -0
- package/dist/smells/duplicate-report.js.map +1 -0
- package/dist/smells/fingerprint.d.ts +20 -1
- package/dist/smells/fingerprint.d.ts.map +1 -1
- package/dist/smells/fingerprint.js +27 -3
- package/dist/smells/fingerprint.js.map +1 -1
- package/dist/smells/inconsistent-siblings.d.ts +128 -7
- package/dist/smells/inconsistent-siblings.d.ts.map +1 -1
- package/dist/smells/inconsistent-siblings.js +288 -86
- package/dist/smells/inconsistent-siblings.js.map +1 -1
- package/dist/smells/sibling-files.d.ts +47 -0
- package/dist/smells/sibling-files.d.ts.map +1 -0
- package/dist/smells/sibling-files.js +104 -0
- package/dist/smells/sibling-files.js.map +1 -0
- package/dist/smells/similar-pairs.d.ts +28 -0
- package/dist/smells/similar-pairs.d.ts.map +1 -0
- package/dist/smells/similar-pairs.js +134 -0
- package/dist/smells/similar-pairs.js.map +1 -0
- package/dist/smells/smell-builder.d.ts +57 -12
- package/dist/smells/smell-builder.d.ts.map +1 -1
- package/dist/smells/smell-builder.js +112 -14
- package/dist/smells/smell-builder.js.map +1 -1
- package/dist/smells/variation.d.ts +47 -0
- package/dist/smells/variation.d.ts.map +1 -0
- package/dist/smells/variation.js +90 -0
- package/dist/smells/variation.js.map +1 -0
- package/dist/tsconfig/index.d.ts +19 -0
- package/dist/tsconfig/index.d.ts.map +1 -0
- package/dist/tsconfig/index.js +20 -0
- package/dist/tsconfig/index.js.map +1 -0
- package/dist/tsconfig/tsconfig-builder.d.ts +42 -9
- package/dist/tsconfig/tsconfig-builder.d.ts.map +1 -1
- package/dist/tsconfig/tsconfig-builder.js +65 -16
- package/dist/tsconfig/tsconfig-builder.js.map +1 -1
- package/package.json +4 -2
- package/dist/core/module-dependencies.d.ts +0 -28
- package/dist/core/module-dependencies.d.ts.map +0 -1
- package/dist/core/module-dependencies.js +0 -35
- package/dist/core/module-dependencies.js.map +0 -1
- package/dist/helpers/within.d.ts.map +0 -1
- package/dist/helpers/within.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ImportDeclaration } from 'ts-morph';
|
|
1
|
+
import type { ExportDeclaration, ImportDeclaration } from 'ts-morph';
|
|
2
2
|
/**
|
|
3
3
|
* Options for import-related conditions and predicates.
|
|
4
4
|
*/
|
|
@@ -10,7 +10,11 @@ export interface ImportOptions {
|
|
|
10
10
|
* Type-only imports are erased at compile time and create no runtime dependency.
|
|
11
11
|
* Useful for layer isolation rules where type-sharing is acceptable.
|
|
12
12
|
*
|
|
13
|
-
* Default: false
|
|
13
|
+
* Default: **per condition.** `false` — count every import — for `dependOn`,
|
|
14
|
+
* `importFrom`, `notImportFrom`, `onlyImportFrom`, `notDependOn` and
|
|
15
|
+
* `respectLayerOrder`, which ask whether the code is *coupled*. `true` for
|
|
16
|
+
* `beFreeOfCycles`, which asks whether the module is *evaluated*: an erased import
|
|
17
|
+
* cannot contribute to an initialization cycle. See `docs/slices.md`.
|
|
14
18
|
*/
|
|
15
19
|
ignoreTypeImports?: boolean;
|
|
16
20
|
}
|
|
@@ -29,4 +33,53 @@ export interface ImportOptions {
|
|
|
29
33
|
* - `import * as Foo from '...'` (namespace import is runtime)
|
|
30
34
|
*/
|
|
31
35
|
export declare function isTypeOnlyImport(decl: ImportDeclaration): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Check whether a re-export is purely type-only (no runtime dependency).
|
|
38
|
+
*
|
|
39
|
+
* The `export … from` analogue of {@link isTypeOnlyImport}, and **both halves of
|
|
40
|
+
* the disjunction are needed** — measured, the two spellings put the flag in
|
|
41
|
+
* different places:
|
|
42
|
+
*
|
|
43
|
+
* | form | `decl.isTypeOnly()` | specifiers |
|
|
44
|
+
* | ------------------------------- | ------------------- | ---------- |
|
|
45
|
+
* | `export type { X } from 's'` | **true** | false |
|
|
46
|
+
* | `export { type X } from 's'` | false | **true** |
|
|
47
|
+
* | `export type * from 's'` | **true** | (none) |
|
|
48
|
+
* | `export { X } from 's'` | false | false |
|
|
49
|
+
*
|
|
50
|
+
* No default or namespace analogue exists, verified: there is no way to write a
|
|
51
|
+
* re-export that binds a runtime value while every named specifier is
|
|
52
|
+
* type-only, so this needs none of {@link isTypeOnlyImport}'s guards. A bare
|
|
53
|
+
* `export * from 's'` has no named specifiers and is runtime, which is why the
|
|
54
|
+
* second half requires a non-empty list.
|
|
55
|
+
*/
|
|
56
|
+
export declare function isTypeOnlyReExport(decl: ExportDeclaration): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Split a variadic glob API's arguments, without a type assertion.
|
|
59
|
+
*
|
|
60
|
+
* Five entry points take `...args: [string[], ImportOptions] | string[]` —
|
|
61
|
+
* `onlyImportFrom`, `notImportFrom`, `dependOn`, `importFrom`, `importFromAny` —
|
|
62
|
+
* so a caller can write either `f('a', 'b')` or `f(['a', 'b'], { … })`. TypeScript
|
|
63
|
+
* cannot narrow a tuple-union rest parameter from `Array.isArray(args[0])`, which
|
|
64
|
+
* is true and was the stated reason for **ten** `as` casts across three files:
|
|
65
|
+
*
|
|
66
|
+
* ```ts
|
|
67
|
+
* const globs: string[] = Array.isArray(args[0]) ? args[0] : (args as string[])
|
|
68
|
+
* const options = Array.isArray(args[0]) && args.length > 1 ? (args[1] as ImportOptions) : undefined
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* [ADR-005](../../../../adr/005-no-any-no-type-assertions.md) prescribes a type guard,
|
|
72
|
+
* and a guard does narrow it: `.filter((a): a is string => …)` produces `string[]`
|
|
73
|
+
* with no assertion, and `typeof second === 'object'` narrows the options. The
|
|
74
|
+
* casts were avoidable; only the direct narrowing was not.
|
|
75
|
+
*
|
|
76
|
+
* One owner rather than five copies, which is the other half. The dispatch was
|
|
77
|
+
* duplicated five times, and a duplicated predicate in this repo has already
|
|
78
|
+
* caused a measurement error once —
|
|
79
|
+
* [ts-archunit bug 0044](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0044-an-inline-exclusion-comment-has-no-feedback-channel.md).
|
|
80
|
+
*/
|
|
81
|
+
export declare function splitGlobArgs(args: readonly (string[] | ImportOptions | string)[]): {
|
|
82
|
+
globs: string[];
|
|
83
|
+
options: ImportOptions | undefined;
|
|
84
|
+
};
|
|
32
85
|
//# sourceMappingURL=import-options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-options.d.ts","sourceRoot":"","sources":["../../src/core/import-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"import-options.d.ts","sourceRoot":"","sources":["../../src/core/import-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAEpE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAUjE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAInE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,aAAa,GAAG,MAAM,CAAC,EAAE,GAAG;IACnF,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,aAAa,GAAG,SAAS,CAAA;CACnC,CAcA"}
|
|
@@ -26,4 +26,68 @@ export function isTypeOnlyImport(decl) {
|
|
|
26
26
|
const specifiers = decl.getNamedImports();
|
|
27
27
|
return specifiers.length > 0 && specifiers.every((s) => s.isTypeOnly());
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Check whether a re-export is purely type-only (no runtime dependency).
|
|
31
|
+
*
|
|
32
|
+
* The `export … from` analogue of {@link isTypeOnlyImport}, and **both halves of
|
|
33
|
+
* the disjunction are needed** — measured, the two spellings put the flag in
|
|
34
|
+
* different places:
|
|
35
|
+
*
|
|
36
|
+
* | form | `decl.isTypeOnly()` | specifiers |
|
|
37
|
+
* | ------------------------------- | ------------------- | ---------- |
|
|
38
|
+
* | `export type { X } from 's'` | **true** | false |
|
|
39
|
+
* | `export { type X } from 's'` | false | **true** |
|
|
40
|
+
* | `export type * from 's'` | **true** | (none) |
|
|
41
|
+
* | `export { X } from 's'` | false | false |
|
|
42
|
+
*
|
|
43
|
+
* No default or namespace analogue exists, verified: there is no way to write a
|
|
44
|
+
* re-export that binds a runtime value while every named specifier is
|
|
45
|
+
* type-only, so this needs none of {@link isTypeOnlyImport}'s guards. A bare
|
|
46
|
+
* `export * from 's'` has no named specifiers and is runtime, which is why the
|
|
47
|
+
* second half requires a non-empty list.
|
|
48
|
+
*/
|
|
49
|
+
export function isTypeOnlyReExport(decl) {
|
|
50
|
+
if (decl.isTypeOnly())
|
|
51
|
+
return true;
|
|
52
|
+
const specifiers = decl.getNamedExports();
|
|
53
|
+
return specifiers.length > 0 && specifiers.every((s) => s.isTypeOnly());
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Split a variadic glob API's arguments, without a type assertion.
|
|
57
|
+
*
|
|
58
|
+
* Five entry points take `...args: [string[], ImportOptions] | string[]` —
|
|
59
|
+
* `onlyImportFrom`, `notImportFrom`, `dependOn`, `importFrom`, `importFromAny` —
|
|
60
|
+
* so a caller can write either `f('a', 'b')` or `f(['a', 'b'], { … })`. TypeScript
|
|
61
|
+
* cannot narrow a tuple-union rest parameter from `Array.isArray(args[0])`, which
|
|
62
|
+
* is true and was the stated reason for **ten** `as` casts across three files:
|
|
63
|
+
*
|
|
64
|
+
* ```ts
|
|
65
|
+
* const globs: string[] = Array.isArray(args[0]) ? args[0] : (args as string[])
|
|
66
|
+
* const options = Array.isArray(args[0]) && args.length > 1 ? (args[1] as ImportOptions) : undefined
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* [ADR-005](../../../../adr/005-no-any-no-type-assertions.md) prescribes a type guard,
|
|
70
|
+
* and a guard does narrow it: `.filter((a): a is string => …)` produces `string[]`
|
|
71
|
+
* with no assertion, and `typeof second === 'object'` narrows the options. The
|
|
72
|
+
* casts were avoidable; only the direct narrowing was not.
|
|
73
|
+
*
|
|
74
|
+
* One owner rather than five copies, which is the other half. The dispatch was
|
|
75
|
+
* duplicated five times, and a duplicated predicate in this repo has already
|
|
76
|
+
* caused a measurement error once —
|
|
77
|
+
* [ts-archunit bug 0044](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0044-an-inline-exclusion-comment-has-no-feedback-channel.md).
|
|
78
|
+
*/
|
|
79
|
+
export function splitGlobArgs(args) {
|
|
80
|
+
const [first, second] = args;
|
|
81
|
+
if (Array.isArray(first)) {
|
|
82
|
+
return {
|
|
83
|
+
globs: first,
|
|
84
|
+
options: typeof second === 'object' && second !== null && !Array.isArray(second)
|
|
85
|
+
? second
|
|
86
|
+
: undefined,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// The variadic form: every argument is a glob string. The predicate is what
|
|
90
|
+
// makes this cast-free — `filter` alone would leave the union in place.
|
|
91
|
+
return { globs: args.filter((a) => typeof a === 'string'), options: undefined };
|
|
92
|
+
}
|
|
29
93
|
//# sourceMappingURL=import-options.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-options.js","sourceRoot":"","sources":["../../src/core/import-options.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"import-options.js","sourceRoot":"","sources":["../../src/core/import-options.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAuB;IACtD,0DAA0D;IAC1D,IAAI,IAAI,CAAC,UAAU,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,2CAA2C;IAC3C,IAAI,IAAI,CAAC,gBAAgB,EAAE;QAAE,OAAO,KAAK,CAAA;IACzC,6CAA6C;IAC7C,IAAI,IAAI,CAAC,kBAAkB,EAAE;QAAE,OAAO,KAAK,CAAA;IAC3C,sDAAsD;IACtD,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;IACzC,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAA;AACzE,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAuB;IACxD,IAAI,IAAI,CAAC,UAAU,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;IACzC,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAA;AACzE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,aAAa,CAAC,IAAoD;IAIhF,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;IAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,OAAO,EACL,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBACrE,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,SAAS;SAChB,CAAA;IACH,CAAC;IACD,4EAA4E;IAC5E,wEAAwE;IACxE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA;AAC9F,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SourceFile } from 'ts-morph';
|
|
2
|
+
/**
|
|
3
|
+
* Drop a file's cached derivations the first time it is modified, registering
|
|
4
|
+
* the listener exactly once.
|
|
5
|
+
*
|
|
6
|
+
* `descendant-cache.ts` and `line-index.ts` each carried this. They are the two
|
|
7
|
+
* per-file memo caches in this package, so they need the same invalidation and
|
|
8
|
+
* had the same code for it — `no-copy-paste` reported it at 100%.
|
|
9
|
+
*
|
|
10
|
+
* **`invalidate` is a callback rather than the caches themselves, and that is
|
|
11
|
+
* not a style choice.** Both modules RESET by reassigning their `WeakMap`s
|
|
12
|
+
* (`byFile = new WeakMap(...)`), so a listener holding the map objects would go
|
|
13
|
+
* on deleting from the map that was replaced, leaving the live one stale. A
|
|
14
|
+
* callback reads the module's current bindings at the moment it fires.
|
|
15
|
+
*
|
|
16
|
+
* `watched` stays the caller's, because it is reset alongside the caches it
|
|
17
|
+
* guards.
|
|
18
|
+
*/
|
|
19
|
+
export declare function invalidateOnModify(sourceFile: SourceFile, watched: WeakSet<SourceFile>, invalidate: (file: SourceFile) => void): void;
|
|
20
|
+
//# sourceMappingURL=invalidate-on-modify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalidate-on-modify.d.ts","sourceRoot":"","sources":["../../src/core/invalidate-on-modify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,EAC5B,UAAU,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,GACrC,IAAI,CAMN"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drop a file's cached derivations the first time it is modified, registering
|
|
3
|
+
* the listener exactly once.
|
|
4
|
+
*
|
|
5
|
+
* `descendant-cache.ts` and `line-index.ts` each carried this. They are the two
|
|
6
|
+
* per-file memo caches in this package, so they need the same invalidation and
|
|
7
|
+
* had the same code for it — `no-copy-paste` reported it at 100%.
|
|
8
|
+
*
|
|
9
|
+
* **`invalidate` is a callback rather than the caches themselves, and that is
|
|
10
|
+
* not a style choice.** Both modules RESET by reassigning their `WeakMap`s
|
|
11
|
+
* (`byFile = new WeakMap(...)`), so a listener holding the map objects would go
|
|
12
|
+
* on deleting from the map that was replaced, leaving the live one stale. A
|
|
13
|
+
* callback reads the module's current bindings at the moment it fires.
|
|
14
|
+
*
|
|
15
|
+
* `watched` stays the caller's, because it is reset alongside the caches it
|
|
16
|
+
* guards.
|
|
17
|
+
*/
|
|
18
|
+
export function invalidateOnModify(sourceFile, watched, invalidate) {
|
|
19
|
+
if (watched.has(sourceFile))
|
|
20
|
+
return;
|
|
21
|
+
watched.add(sourceFile);
|
|
22
|
+
sourceFile.onModified(() => {
|
|
23
|
+
invalidate(sourceFile);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=invalidate-on-modify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalidate-on-modify.js","sourceRoot":"","sources":["../../src/core/invalidate-on-modify.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAsB,EACtB,OAA4B,EAC5B,UAAsC;IAEtC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAM;IACnC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACvB,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE;QACzB,UAAU,CAAC,UAAU,CAAC,CAAA;IACxB,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-index.d.ts","sourceRoot":"","sources":["../../src/core/line-index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,UAAU,CAAA;AA6NhD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAYjD"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { SyntaxKind } from 'ts-morph';
|
|
2
|
+
import { registerCacheReset } from '@nielspeter/eess/internal';
|
|
3
|
+
import { invalidateOnModify } from './invalidate-on-modify.js';
|
|
4
|
+
/**
|
|
5
|
+
* The per-file line index behind `linesOfCode`.
|
|
6
|
+
*
|
|
7
|
+
* **Why this is in `core/` and not beside `linesOfCode` in `helpers/`.** It is a
|
|
8
|
+
* cache over ts-morph state, and this package already has three of those —
|
|
9
|
+
* `element-cache.ts`, `descendant-cache.ts`, `module-edges.ts` — each of which
|
|
10
|
+
* registers a reset and drops per-file entries on `onModified`. The first cut of
|
|
11
|
+
* this index lived in `helpers/`, followed neither convention, and reintroduced
|
|
12
|
+
* the exact defect the other three exist to document. Caches live here, next to
|
|
13
|
+
* their siblings, where the convention is visible.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Comment kinds ts-morph surfaces as ordinary leaves in `getChildren()`.
|
|
17
|
+
*
|
|
18
|
+
* The compiler treats these as trivia and omits them; ts-morph deliberately does
|
|
19
|
+
* not, which is useful everywhere else and is exactly what `linesOfCode` must
|
|
20
|
+
* undo. Measured: without this set a body of 4 code lines and 3 comment lines
|
|
21
|
+
* counted 7.
|
|
22
|
+
*/
|
|
23
|
+
const NON_CODE_KINDS = new Set([
|
|
24
|
+
SyntaxKind.SingleLineCommentTrivia,
|
|
25
|
+
SyntaxKind.MultiLineCommentTrivia,
|
|
26
|
+
]);
|
|
27
|
+
/**
|
|
28
|
+
* Count the lines of a node that actually carry code.
|
|
29
|
+
*
|
|
30
|
+
* Physical source lines, excluding comments and blank lines. A line holding only
|
|
31
|
+
* `}` still counts — it is a source line; this is not a statement count.
|
|
32
|
+
*
|
|
33
|
+
* **Why not the span.**
|
|
34
|
+
* [Bug 0170](../../../../work/bugs/fixed/0170-linesofcode-counts-comments-so-documentation-reads-as-size.md):
|
|
35
|
+
* this was `end - start + 1`, which measures documentation as size. In this repo
|
|
36
|
+
* that put two rules in direct conflict — `eess/jsdoc-on-public-methods` requires
|
|
37
|
+
* a doc block on every public method, and `eess/max-class-lines` then counted
|
|
38
|
+
* those blocks, so satisfying the first rule broke the second. Measured across
|
|
39
|
+
* this source, six of nine class findings and two of four method findings were
|
|
40
|
+
* comment lines alone.
|
|
41
|
+
*
|
|
42
|
+
* The old docstring justified the span by saying it "avoids the fragility of
|
|
43
|
+
* text-based comment stripping". That reason is sound and it is why this counts
|
|
44
|
+
* TOKENS rather than matching comment syntax in text: comments are trivia, so
|
|
45
|
+
* they are never tokens, and they drop out structurally. Nothing is stripped.
|
|
46
|
+
*
|
|
47
|
+
* Comments have to be skipped by hand even so: ts-morph does not hide them the
|
|
48
|
+
* way the compiler's own tree does — `getChildren()` hands back
|
|
49
|
+
* `SingleLineCommentTrivia` and `MultiLineCommentTrivia` as ordinary leaves, and
|
|
50
|
+
* JSDoc as a child node. JSDoc is the sharpest of the three, because
|
|
51
|
+
* `getStartLineNumber()` excludes it while `getChildren()` returns it, so
|
|
52
|
+
* counting it made an element measure LARGER than its own span —
|
|
53
|
+
* `complexity.test.ts` pins against that as a corpus-wide invariant.
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Character offset of the first character of each line, ascending.
|
|
57
|
+
*
|
|
58
|
+
* Measured, this is the whole performance story. Walking every token in this
|
|
59
|
+
* repo's source costs 99ms and reading their POSITIONS costs 21ms — but asking
|
|
60
|
+
* ts-morph for their line NUMBERS costs 523ms, five times the walk. `getStart()`
|
|
61
|
+
* returns a number the AST already holds; `getStartLineNumber()` resolves it
|
|
62
|
+
* against the file's text on every call.
|
|
63
|
+
*
|
|
64
|
+
* So positions come from the AST and the offset-to-line mapping is done here,
|
|
65
|
+
* against a table built once per file. That mapping is pure arithmetic over
|
|
66
|
+
* newline offsets — it is not text-based comment detection, which would be
|
|
67
|
+
* genuinely fragile (a regex literal containing `//` cannot be told from a
|
|
68
|
+
* comment without parsing). Deciding what is a comment stays the AST's job.
|
|
69
|
+
*/
|
|
70
|
+
let lineStartsByFile = new WeakMap();
|
|
71
|
+
function lineStartsOf(sourceFile) {
|
|
72
|
+
const cached = lineStartsByFile.get(sourceFile);
|
|
73
|
+
if (cached !== undefined)
|
|
74
|
+
return cached;
|
|
75
|
+
const text = sourceFile.getFullText();
|
|
76
|
+
const starts = [0];
|
|
77
|
+
for (let i = 0; i < text.length; i++) {
|
|
78
|
+
if (text.charCodeAt(i) === NEWLINE)
|
|
79
|
+
starts.push(i + 1);
|
|
80
|
+
}
|
|
81
|
+
lineStartsByFile.set(sourceFile, starts);
|
|
82
|
+
return starts;
|
|
83
|
+
}
|
|
84
|
+
const NEWLINE = 10;
|
|
85
|
+
/**
|
|
86
|
+
* The 1-based line holding a character offset.
|
|
87
|
+
*
|
|
88
|
+
* The count of line starts at or before the offset IS the line number, because
|
|
89
|
+
* the table begins with 0 for line 1.
|
|
90
|
+
*/
|
|
91
|
+
function lineAt(lineStarts, pos) {
|
|
92
|
+
return countUpTo(lineStarts, pos);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Every line of a source file that carries at least one token, ascending.
|
|
96
|
+
*
|
|
97
|
+
* Computed once per file and cached. Per-subject walking re-visited a method's
|
|
98
|
+
* tokens for every enclosing rule — `maxClassLines` walks the class, then
|
|
99
|
+
* `maxMethodLines` walks each method inside it.
|
|
100
|
+
*
|
|
101
|
+
* Dropped when the file is modified, via the listener in {@link watchOnce}.
|
|
102
|
+
* **Object identity is not enough here and never was.** A `SourceFile`'s
|
|
103
|
+
* identity SURVIVES an edit — `module-edges.ts` measured it, `descendant-cache.ts`
|
|
104
|
+
* records the same trap one level down, and the first cut of this index asserted
|
|
105
|
+
* the opposite and shipped the third instance of it.
|
|
106
|
+
*
|
|
107
|
+
* The failure is not "returns the previous number". Positions come from the AST
|
|
108
|
+
* and stay fresh while the table goes stale, so the two are read against each
|
|
109
|
+
* other and the answer corresponds to nothing: measured, a class that grew from
|
|
110
|
+
* 5 code lines to 8 reported 6.
|
|
111
|
+
*/
|
|
112
|
+
let codeLinesByFile = new WeakMap();
|
|
113
|
+
const watched = new WeakSet();
|
|
114
|
+
/**
|
|
115
|
+
* Join `resetProjectCache()`, the documented consumer escape hatch.
|
|
116
|
+
*
|
|
117
|
+
* **This registration is UNPROVEN, and saying so is the point.** Measured:
|
|
118
|
+
* emptying this callback leaves all 3,523 `packages/ts` tests green. That is not
|
|
119
|
+
* an oversight to fix with a cleverer test — it follows from what the
|
|
120
|
+
* registration is FOR. Correctness is already carried by the per-file
|
|
121
|
+
* `onModified` listener in {@link watchOnce}, which fires on every mutation path
|
|
122
|
+
* (and which IS proven — removing it reddens two rows in `complexity.test.ts`).
|
|
123
|
+
* What this adds is **memory reclamation on an explicit reset**: a consumer done
|
|
124
|
+
* with a large project can drop the tables without waiting for the `WeakMap` keys
|
|
125
|
+
* to become unreachable.
|
|
126
|
+
*
|
|
127
|
+
* A property with no observable correctness signature cannot have a break class,
|
|
128
|
+
* and this file's own rule two functions down — "a redundant guard is an
|
|
129
|
+
* unprovable one" — is why that is recorded here rather than left to look
|
|
130
|
+
* tested. Do not add a test that calls `resetProjectCache()` and asserts the next
|
|
131
|
+
* measurement is correct: it is correct either way, and such a row would pass
|
|
132
|
+
* over a deleted callback, which is worse than no row at all.
|
|
133
|
+
*/
|
|
134
|
+
registerCacheReset(() => {
|
|
135
|
+
lineStartsByFile = new WeakMap();
|
|
136
|
+
codeLinesByFile = new WeakMap();
|
|
137
|
+
});
|
|
138
|
+
/**
|
|
139
|
+
* Register the per-file invalidation listener, once.
|
|
140
|
+
*
|
|
141
|
+
* Not once per cache miss: a watch session re-evaluating rules would otherwise
|
|
142
|
+
* accumulate a listener per rule execution. Both maps drop together, because the
|
|
143
|
+
* same edit invalidates both.
|
|
144
|
+
*
|
|
145
|
+
* The closure reads `lineStartsByFile` / `codeLinesByFile` as **live bindings**
|
|
146
|
+
* rather than capturing them, which is what keeps invalidation working after
|
|
147
|
+
* `registerCacheReset` replaces the maps — `descendant-cache.ts` records that
|
|
148
|
+
* capturing by value made a post-reset edit invisible and passed the suite.
|
|
149
|
+
*
|
|
150
|
+
* `onModified` fires on every mutation path that matters here — measured:
|
|
151
|
+
* `addMethod`, `replaceWithText`, and `createSourceFile(path, text,
|
|
152
|
+
* { overwrite: true })`, which is the fixture shape this repo's own guidance
|
|
153
|
+
* prescribes and the one that returned a wrong number for every case after the
|
|
154
|
+
* first.
|
|
155
|
+
*/
|
|
156
|
+
function watchOnce(sourceFile) {
|
|
157
|
+
invalidateOnModify(sourceFile, watched, (file) => {
|
|
158
|
+
lineStartsByFile.delete(file);
|
|
159
|
+
codeLinesByFile.delete(file);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function codeLinesOf(sourceFile) {
|
|
163
|
+
const cached = codeLinesByFile.get(sourceFile);
|
|
164
|
+
if (cached !== undefined)
|
|
165
|
+
return cached;
|
|
166
|
+
const lineStarts = lineStartsOf(sourceFile);
|
|
167
|
+
const lines = new Set();
|
|
168
|
+
const visit = (current) => {
|
|
169
|
+
if (NON_CODE_KINDS.has(current.getKind()))
|
|
170
|
+
return;
|
|
171
|
+
// JSDoc spans many kinds; the prefix is what they share.
|
|
172
|
+
if (current.getKindName().startsWith('JSDoc'))
|
|
173
|
+
return;
|
|
174
|
+
const children = current.getChildren();
|
|
175
|
+
if (children.length === 0) {
|
|
176
|
+
addTokenLines(lines, lineStarts, current);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
for (const child of children)
|
|
180
|
+
visit(child);
|
|
181
|
+
};
|
|
182
|
+
visit(sourceFile);
|
|
183
|
+
const sorted = [...lines].sort((a, b) => a - b);
|
|
184
|
+
codeLinesByFile.set(sourceFile, sorted);
|
|
185
|
+
return sorted;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Mark every line a leaf token occupies. Multi-line tokens exist — a template
|
|
189
|
+
* literal, a long string — and every line they cover is code.
|
|
190
|
+
*/
|
|
191
|
+
function addTokenLines(lines, lineStarts, token) {
|
|
192
|
+
const first = lineAt(lineStarts, token.getStart());
|
|
193
|
+
// `getEnd()` is exclusive, so the last character is one before it. Clamped,
|
|
194
|
+
// because a zero-width node has `getEnd() === getStart()`.
|
|
195
|
+
const last = lineAt(lineStarts, Math.max(token.getStart(), token.getEnd() - 1));
|
|
196
|
+
for (let line = first; line <= last; line++)
|
|
197
|
+
lines.add(line);
|
|
198
|
+
}
|
|
199
|
+
/** How many entries of an ascending array are `<= value`. */
|
|
200
|
+
function countUpTo(sorted, value) {
|
|
201
|
+
let low = 0;
|
|
202
|
+
let high = sorted.length;
|
|
203
|
+
while (low < high) {
|
|
204
|
+
const mid = (low + high) >>> 1;
|
|
205
|
+
// `?? -Infinity` satisfies noUncheckedIndexedAccess without a non-null
|
|
206
|
+
// assertion (ADR-005); `mid` is always in range, so it never applies.
|
|
207
|
+
if ((sorted[mid] ?? -Infinity) <= value)
|
|
208
|
+
low = mid + 1;
|
|
209
|
+
else
|
|
210
|
+
high = mid;
|
|
211
|
+
}
|
|
212
|
+
return low;
|
|
213
|
+
}
|
|
214
|
+
export function countCodeLines(node) {
|
|
215
|
+
const sourceFile = node.getSourceFile();
|
|
216
|
+
// ONE registration, here rather than in each accessor. Both maps drop on the
|
|
217
|
+
// same event, so a call in either accessor made the other's redundant — and a
|
|
218
|
+
// redundant guard is an unprovable one: removing either alone left the suite
|
|
219
|
+
// green. At the single entry, removing it reddens the invalidation tests.
|
|
220
|
+
watchOnce(sourceFile);
|
|
221
|
+
const lineStarts = lineStartsOf(sourceFile);
|
|
222
|
+
const lines = codeLinesOf(sourceFile);
|
|
223
|
+
const first = lineAt(lineStarts, node.getStart());
|
|
224
|
+
const last = lineAt(lineStarts, Math.max(node.getStart(), node.getEnd() - 1));
|
|
225
|
+
return countUpTo(lines, last) - countUpTo(lines, first - 1);
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=line-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-index.js","sourceRoot":"","sources":["../../src/core/line-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { Node } from 'ts-morph';
|
|
2
|
+
import type { ArchViolation } from '@nielspeter/eess';
|
|
3
|
+
/**
|
|
4
|
+
* A finding whose message states a **measurement** — bug 0012.
|
|
5
|
+
*
|
|
6
|
+
* Metric conditions write the measured value into the message:
|
|
7
|
+
*
|
|
8
|
+
* Big has 10 methods (max: 5) — consider splitting into focused classes
|
|
9
|
+
*
|
|
10
|
+
* `hashViolation` identifies a violation by its message, so the identity moved
|
|
11
|
+
* whenever the measurement moved — **in either direction**. Baseline a class at
|
|
12
|
+
* 10 methods, delete two, and the finding was reported as new:
|
|
13
|
+
*
|
|
14
|
+
* 10 → 10 green ✓
|
|
15
|
+
* 10 → 12 red ✓ (worse)
|
|
16
|
+
* 10 → 8 RED ✗ (better — the defect)
|
|
17
|
+
* 10 → 5 green ✓ (under the threshold)
|
|
18
|
+
*
|
|
19
|
+
* Paying down the debt failed CI, and kept failing on every incremental step
|
|
20
|
+
* until the class dropped under the threshold entirely. A team that split four
|
|
21
|
+
* methods out of an 87-method service got a red build for its trouble. The
|
|
22
|
+
* external audit that motivated this recommends adopting these rules "behind a
|
|
23
|
+
* ratchet (accept today's god objects, block new regressions)" and records them
|
|
24
|
+
* at **zero uses** — the ratchet they were told to use did not work.
|
|
25
|
+
*
|
|
26
|
+
* ## Why identity alone cannot fix it
|
|
27
|
+
*
|
|
28
|
+
* Bug 0010 added `identity` for messages that state a derived population, and
|
|
29
|
+
* applying it naively here trades one failure for a worse one:
|
|
30
|
+
*
|
|
31
|
+
* | identity contains | improving to 8 | regressing to 12 |
|
|
32
|
+
* | ----------------- | -------------- | ---------------- |
|
|
33
|
+
* | the count | **red** ✗ | red ✓ |
|
|
34
|
+
* | no count | green ✓ | **green** ✗ |
|
|
35
|
+
*
|
|
36
|
+
* Dropping the count turns the baseline into a mute button. Identity answers
|
|
37
|
+
* "is this the same finding?", and a metric needs "is it **worse** than what we
|
|
38
|
+
* accepted?" — a comparison, not an equality. So this carries both: a stable
|
|
39
|
+
* identity that finds the entry, and `measured`, which the baseline stores and
|
|
40
|
+
* compares. See `Baseline.isKnown`.
|
|
41
|
+
*
|
|
42
|
+
* **Ten sites produce these, not the eight the bug enumerated.** That table was
|
|
43
|
+
* built by grepping the `has N <noun>` message shape, which misses the two
|
|
44
|
+
* complexity conditions — `has cyclomatic complexity N` puts the number last.
|
|
45
|
+
* Both were left on `createViolation` in the first cut of this fix while the
|
|
46
|
+
* docs already claimed complexity was ratcheted, so a reader would have removed
|
|
47
|
+
* their CI escape hatch for a gate that still fired on every improvement. Found
|
|
48
|
+
* by review; a mechanical enumeration by *shape* is not one by *behaviour*.
|
|
49
|
+
*/
|
|
50
|
+
export declare function metricViolation(node: Node, options: {
|
|
51
|
+
/**
|
|
52
|
+
* What is being measured — `methods`, `lines`, `parameters`, `properties`,
|
|
53
|
+
* `named-exports`. Part of the identity, so one element can carry several
|
|
54
|
+
* metric findings without them colliding.
|
|
55
|
+
*/
|
|
56
|
+
metric: string;
|
|
57
|
+
/** The measurement now. Compared against the baselined value, not equated. */
|
|
58
|
+
measured: number;
|
|
59
|
+
/**
|
|
60
|
+
* What `measured` COUNTS, when that is not simply the metric's name.
|
|
61
|
+
*
|
|
62
|
+
* The baseline persists this and refuses to compare across a change of unit
|
|
63
|
+
* ([bug 0171](../../../../work/bugs/fixed/0171-a-metric-unit-change-silently-loosens-every-baselined-ratchet.md)).
|
|
64
|
+
* `lines` is why it exists: the metric kept its name while `linesOfCode`
|
|
65
|
+
* changed from counting a span to counting code, so identity still matched
|
|
66
|
+
* and every baselined ceiling silently tripled. A metric whose name already
|
|
67
|
+
* says what it counts — `methods`, `parameters` — needs nothing here.
|
|
68
|
+
*/
|
|
69
|
+
unit?: string;
|
|
70
|
+
message: string;
|
|
71
|
+
/**
|
|
72
|
+
* The element's qualified name, when `getElementName` would under-qualify it.
|
|
73
|
+
*
|
|
74
|
+
* Members need this: `getElementName(member)` returns the bare `save`, while
|
|
75
|
+
* the message already says `UserRepo.save`. Two classes with a `save` method
|
|
76
|
+
* would otherwise be one entry.
|
|
77
|
+
*/
|
|
78
|
+
qualifiedName?: string;
|
|
79
|
+
}, context: {
|
|
80
|
+
rule: string;
|
|
81
|
+
because?: string;
|
|
82
|
+
suggestion?: string;
|
|
83
|
+
ruleId?: string;
|
|
84
|
+
docs?: string;
|
|
85
|
+
}): ArchViolation;
|
|
86
|
+
//# sourceMappingURL=metric-violation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metric-violation.d.ts","sourceRoot":"","sources":["../../src/core/metric-violation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAGrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE;IACP;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,EACD,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,GACA,aAAa,CAkCf"}
|