@nielspeter/eess-ts 0.2.0 → 0.4.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 +87 -34
- 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 +73 -31
- 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 +134 -30
- 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 +393 -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 +181 -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 +173 -26
- 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 +12 -3
- 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 +242 -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 +105 -29
- 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 +3 -2
- package/dist/cli/commands/baseline.d.ts.map +1 -1
- package/dist/cli/commands/baseline.js +68 -6
- 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 +241 -45
- 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 +60 -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 +98 -33
- 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 +21 -29
- package/dist/cli/load-rules.js.map +1 -1
- package/dist/cli/resolve-config.d.ts.map +1 -1
- package/dist/cli/resolve-config.js +24 -14
- 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 +293 -0
- package/dist/cli/rule-file-findings.js.map +1 -0
- package/dist/cli/watch.d.ts +20 -7
- package/dist/cli/watch.d.ts.map +1 -1
- package/dist/cli/watch.js +39 -14
- 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 +38 -17
- 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 +10 -0
- 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 +17 -4
- 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 +109 -92
- 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 +96 -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 +56 -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 +119 -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 +382 -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 +54 -0
- package/dist/core/exclusion-comments.d.ts.map +1 -0
- package/dist/core/exclusion-comments.js +310 -0
- package/dist/core/exclusion-comments.js.map +1 -0
- package/dist/core/execute-rule.d.ts +150 -0
- package/dist/core/execute-rule.d.ts.map +1 -0
- package/dist/core/execute-rule.js +580 -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/line-index.d.ts +3 -0
- package/dist/core/line-index.d.ts.map +1 -0
- package/dist/core/line-index.js +229 -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 +592 -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 +214 -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 +54 -0
- package/dist/core/path-universe.d.ts.map +1 -0
- package/dist/core/path-universe.js +65 -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 +24 -0
- package/dist/core/project.js.map +1 -1
- package/dist/core/rule-builder.d.ts +282 -0
- package/dist/core/rule-builder.d.ts.map +1 -0
- package/dist/core/rule-builder.js +445 -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 +126 -0
- package/dist/core/rule-declaration.js.map +1 -0
- package/dist/core/terminal-builder.d.ts +625 -0
- package/dist/core/terminal-builder.d.ts.map +1 -0
- package/dist/core/terminal-builder.js +787 -0
- package/dist/core/terminal-builder.js.map +1 -0
- package/dist/core/terminal-execution.d.ts +23 -0
- package/dist/core/terminal-execution.d.ts.map +1 -0
- package/dist/core/terminal-execution.js +71 -0
- package/dist/core/terminal-execution.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/index.js +1 -1
- package/dist/graphql/index.js.map +1 -1
- package/dist/graphql/resolver-rule-builder.d.ts +98 -23
- package/dist/graphql/resolver-rule-builder.d.ts.map +1 -1
- package/dist/graphql/resolver-rule-builder.js +151 -21
- 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 +81 -12
- package/dist/graphql/schema-loader.js.map +1 -1
- package/dist/graphql/schema-rule-builder.d.ts +57 -20
- package/dist/graphql/schema-rule-builder.d.ts.map +1 -1
- package/dist/graphql/schema-rule-builder.js +101 -25
- 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 +19 -0
- package/dist/helpers/baseline-generator.d.ts.map +1 -0
- package/dist/helpers/baseline-generator.js +18 -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 +122 -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 +48 -47
- 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 +44 -0
- package/dist/helpers/diff-aware.d.ts.map +1 -0
- package/dist/helpers/diff-aware.js +84 -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 +114 -20
- 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 +56 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +57 -13
- 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 +28 -6
- package/dist/models/arch-function.d.ts.map +1 -1
- package/dist/models/arch-function.js +106 -3
- package/dist/models/arch-function.js.map +1 -1
- package/dist/models/arch-jsx-element.js +2 -2
- 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/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 +22 -15
- package/dist/presets/agent-guardrails.d.ts.map +1 -1
- package/dist/presets/agent-guardrails.js +124 -19
- package/dist/presets/agent-guardrails.js.map +1 -1
- package/dist/presets/boundaries.d.ts +45 -2
- 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 +22 -2
- 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 +7 -5
- package/dist/presets/index.d.ts.map +1 -1
- package/dist/presets/index.js +9 -3
- package/dist/presets/index.js.map +1 -1
- package/dist/presets/layered.d.ts +46 -2
- 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 +80 -9
- 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 +270 -2
- package/dist/presets/shared.d.ts.map +1 -1
- package/dist/presets/shared.js +338 -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 +33 -6
- 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 +39 -9
- package/dist/rules/metrics.js.map +1 -1
- package/dist/smells/duplicate-bodies.d.ts +58 -5
- package/dist/smells/duplicate-bodies.d.ts.map +1 -1
- package/dist/smells/duplicate-bodies.js +137 -56
- package/dist/smells/duplicate-bodies.js.map +1 -1
- package/dist/smells/fingerprint.d.ts +8 -1
- package/dist/smells/fingerprint.d.ts.map +1 -1
- package/dist/smells/fingerprint.js +21 -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 +27 -0
- package/dist/smells/similar-pairs.d.ts.map +1 -0
- package/dist/smells/similar-pairs.js +52 -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 +111 -14
- package/dist/smells/smell-builder.js.map +1 -1
- 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 +64 -16
- package/dist/tsconfig/tsconfig-builder.js.map +1 -1
- package/package.json +3 -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
|
@@ -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 @@
|
|
|
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;AA8NhD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAYjD"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { SyntaxKind } from 'ts-morph';
|
|
2
|
+
import { registerCacheReset } from '@nielspeter/eess';
|
|
3
|
+
/**
|
|
4
|
+
* The per-file line index behind `linesOfCode`.
|
|
5
|
+
*
|
|
6
|
+
* **Why this is in `core/` and not beside `linesOfCode` in `helpers/`.** It is a
|
|
7
|
+
* cache over ts-morph state, and this package already has three of those —
|
|
8
|
+
* `element-cache.ts`, `descendant-cache.ts`, `module-edges.ts` — each of which
|
|
9
|
+
* registers a reset and drops per-file entries on `onModified`. The first cut of
|
|
10
|
+
* this index lived in `helpers/`, followed neither convention, and reintroduced
|
|
11
|
+
* the exact defect the other three exist to document. Caches live here, next to
|
|
12
|
+
* their siblings, where the convention is visible.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Comment kinds ts-morph surfaces as ordinary leaves in `getChildren()`.
|
|
16
|
+
*
|
|
17
|
+
* The compiler treats these as trivia and omits them; ts-morph deliberately does
|
|
18
|
+
* not, which is useful everywhere else and is exactly what `linesOfCode` must
|
|
19
|
+
* undo. Measured: without this set a body of 4 code lines and 3 comment lines
|
|
20
|
+
* counted 7.
|
|
21
|
+
*/
|
|
22
|
+
const NON_CODE_KINDS = new Set([
|
|
23
|
+
SyntaxKind.SingleLineCommentTrivia,
|
|
24
|
+
SyntaxKind.MultiLineCommentTrivia,
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* Count the lines of a node that actually carry code.
|
|
28
|
+
*
|
|
29
|
+
* Physical source lines, excluding comments and blank lines. A line holding only
|
|
30
|
+
* `}` still counts — it is a source line; this is not a statement count.
|
|
31
|
+
*
|
|
32
|
+
* **Why not the span.**
|
|
33
|
+
* [Bug 0170](../../../../work/bugs/0170-linesofcode-counts-comments-so-documentation-reads-as-size.md):
|
|
34
|
+
* this was `end - start + 1`, which measures documentation as size. In this repo
|
|
35
|
+
* that put two rules in direct conflict — `eess/jsdoc-on-public-methods` requires
|
|
36
|
+
* a doc block on every public method, and `eess/max-class-lines` then counted
|
|
37
|
+
* those blocks, so satisfying the first rule broke the second. Measured across
|
|
38
|
+
* this source, six of nine class findings and two of four method findings were
|
|
39
|
+
* comment lines alone.
|
|
40
|
+
*
|
|
41
|
+
* The old docstring justified the span by saying it "avoids the fragility of
|
|
42
|
+
* text-based comment stripping". That reason is sound and it is why this counts
|
|
43
|
+
* TOKENS rather than matching comment syntax in text: comments are trivia, so
|
|
44
|
+
* they are never tokens, and they drop out structurally. Nothing is stripped.
|
|
45
|
+
*
|
|
46
|
+
* Comments have to be skipped by hand even so: ts-morph does not hide them the
|
|
47
|
+
* way the compiler's own tree does — `getChildren()` hands back
|
|
48
|
+
* `SingleLineCommentTrivia` and `MultiLineCommentTrivia` as ordinary leaves, and
|
|
49
|
+
* JSDoc as a child node. JSDoc is the sharpest of the three, because
|
|
50
|
+
* `getStartLineNumber()` excludes it while `getChildren()` returns it, so
|
|
51
|
+
* counting it made an element measure LARGER than its own span —
|
|
52
|
+
* `complexity.test.ts` pins against that as a corpus-wide invariant.
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* Character offset of the first character of each line, ascending.
|
|
56
|
+
*
|
|
57
|
+
* Measured, this is the whole performance story. Walking every token in this
|
|
58
|
+
* repo's source costs 99ms and reading their POSITIONS costs 21ms — but asking
|
|
59
|
+
* ts-morph for their line NUMBERS costs 523ms, five times the walk. `getStart()`
|
|
60
|
+
* returns a number the AST already holds; `getStartLineNumber()` resolves it
|
|
61
|
+
* against the file's text on every call.
|
|
62
|
+
*
|
|
63
|
+
* So positions come from the AST and the offset-to-line mapping is done here,
|
|
64
|
+
* against a table built once per file. That mapping is pure arithmetic over
|
|
65
|
+
* newline offsets — it is not text-based comment detection, which would be
|
|
66
|
+
* genuinely fragile (a regex literal containing `//` cannot be told from a
|
|
67
|
+
* comment without parsing). Deciding what is a comment stays the AST's job.
|
|
68
|
+
*/
|
|
69
|
+
let lineStartsByFile = new WeakMap();
|
|
70
|
+
function lineStartsOf(sourceFile) {
|
|
71
|
+
const cached = lineStartsByFile.get(sourceFile);
|
|
72
|
+
if (cached !== undefined)
|
|
73
|
+
return cached;
|
|
74
|
+
const text = sourceFile.getFullText();
|
|
75
|
+
const starts = [0];
|
|
76
|
+
for (let i = 0; i < text.length; i++) {
|
|
77
|
+
if (text.charCodeAt(i) === NEWLINE)
|
|
78
|
+
starts.push(i + 1);
|
|
79
|
+
}
|
|
80
|
+
lineStartsByFile.set(sourceFile, starts);
|
|
81
|
+
return starts;
|
|
82
|
+
}
|
|
83
|
+
const NEWLINE = 10;
|
|
84
|
+
/**
|
|
85
|
+
* The 1-based line holding a character offset.
|
|
86
|
+
*
|
|
87
|
+
* The count of line starts at or before the offset IS the line number, because
|
|
88
|
+
* the table begins with 0 for line 1.
|
|
89
|
+
*/
|
|
90
|
+
function lineAt(lineStarts, pos) {
|
|
91
|
+
return countUpTo(lineStarts, pos);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Every line of a source file that carries at least one token, ascending.
|
|
95
|
+
*
|
|
96
|
+
* Computed once per file and cached. Per-subject walking re-visited a method's
|
|
97
|
+
* tokens for every enclosing rule — `maxClassLines` walks the class, then
|
|
98
|
+
* `maxMethodLines` walks each method inside it.
|
|
99
|
+
*
|
|
100
|
+
* Dropped when the file is modified, via the listener in {@link watchOnce}.
|
|
101
|
+
* **Object identity is not enough here and never was.** A `SourceFile`'s
|
|
102
|
+
* identity SURVIVES an edit — `module-edges.ts` measured it, `descendant-cache.ts`
|
|
103
|
+
* records the same trap one level down, and the first cut of this index asserted
|
|
104
|
+
* the opposite and shipped the third instance of it.
|
|
105
|
+
*
|
|
106
|
+
* The failure is not "returns the previous number". Positions come from the AST
|
|
107
|
+
* and stay fresh while the table goes stale, so the two are read against each
|
|
108
|
+
* other and the answer corresponds to nothing: measured, a class that grew from
|
|
109
|
+
* 5 code lines to 8 reported 6.
|
|
110
|
+
*/
|
|
111
|
+
let codeLinesByFile = new WeakMap();
|
|
112
|
+
const watched = new WeakSet();
|
|
113
|
+
/**
|
|
114
|
+
* Join `resetProjectCache()`, the documented consumer escape hatch.
|
|
115
|
+
*
|
|
116
|
+
* **This registration is UNPROVEN, and saying so is the point.** Measured:
|
|
117
|
+
* emptying this callback leaves all 3,523 `packages/ts` tests green. That is not
|
|
118
|
+
* an oversight to fix with a cleverer test — it follows from what the
|
|
119
|
+
* registration is FOR. Correctness is already carried by the per-file
|
|
120
|
+
* `onModified` listener in {@link watchOnce}, which fires on every mutation path
|
|
121
|
+
* (and which IS proven — removing it reddens two rows in `complexity.test.ts`).
|
|
122
|
+
* What this adds is **memory reclamation on an explicit reset**: a consumer done
|
|
123
|
+
* with a large project can drop the tables without waiting for the `WeakMap` keys
|
|
124
|
+
* to become unreachable.
|
|
125
|
+
*
|
|
126
|
+
* A property with no observable correctness signature cannot have a break class,
|
|
127
|
+
* and this file's own rule two functions down — "a redundant guard is an
|
|
128
|
+
* unprovable one" — is why that is recorded here rather than left to look
|
|
129
|
+
* tested. Do not add a test that calls `resetProjectCache()` and asserts the next
|
|
130
|
+
* measurement is correct: it is correct either way, and such a row would pass
|
|
131
|
+
* over a deleted callback, which is worse than no row at all.
|
|
132
|
+
*/
|
|
133
|
+
registerCacheReset(() => {
|
|
134
|
+
lineStartsByFile = new WeakMap();
|
|
135
|
+
codeLinesByFile = new WeakMap();
|
|
136
|
+
});
|
|
137
|
+
/**
|
|
138
|
+
* Register the per-file invalidation listener, once.
|
|
139
|
+
*
|
|
140
|
+
* Not once per cache miss: a watch session re-evaluating rules would otherwise
|
|
141
|
+
* accumulate a listener per rule execution. Both maps drop together, because the
|
|
142
|
+
* same edit invalidates both.
|
|
143
|
+
*
|
|
144
|
+
* The closure reads `lineStartsByFile` / `codeLinesByFile` as **live bindings**
|
|
145
|
+
* rather than capturing them, which is what keeps invalidation working after
|
|
146
|
+
* `registerCacheReset` replaces the maps — `descendant-cache.ts` records that
|
|
147
|
+
* capturing by value made a post-reset edit invisible and passed the suite.
|
|
148
|
+
*
|
|
149
|
+
* `onModified` fires on every mutation path that matters here — measured:
|
|
150
|
+
* `addMethod`, `replaceWithText`, and `createSourceFile(path, text,
|
|
151
|
+
* { overwrite: true })`, which is the fixture shape this repo's own guidance
|
|
152
|
+
* prescribes and the one that returned a wrong number for every case after the
|
|
153
|
+
* first.
|
|
154
|
+
*/
|
|
155
|
+
function watchOnce(sourceFile) {
|
|
156
|
+
if (watched.has(sourceFile))
|
|
157
|
+
return;
|
|
158
|
+
watched.add(sourceFile);
|
|
159
|
+
sourceFile.onModified(() => {
|
|
160
|
+
lineStartsByFile.delete(sourceFile);
|
|
161
|
+
codeLinesByFile.delete(sourceFile);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function codeLinesOf(sourceFile) {
|
|
165
|
+
const cached = codeLinesByFile.get(sourceFile);
|
|
166
|
+
if (cached !== undefined)
|
|
167
|
+
return cached;
|
|
168
|
+
const lineStarts = lineStartsOf(sourceFile);
|
|
169
|
+
const lines = new Set();
|
|
170
|
+
const visit = (current) => {
|
|
171
|
+
if (NON_CODE_KINDS.has(current.getKind()))
|
|
172
|
+
return;
|
|
173
|
+
// JSDoc spans many kinds; the prefix is what they share.
|
|
174
|
+
if (current.getKindName().startsWith('JSDoc'))
|
|
175
|
+
return;
|
|
176
|
+
const children = current.getChildren();
|
|
177
|
+
if (children.length === 0) {
|
|
178
|
+
addTokenLines(lines, lineStarts, current);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
for (const child of children)
|
|
182
|
+
visit(child);
|
|
183
|
+
};
|
|
184
|
+
visit(sourceFile);
|
|
185
|
+
const sorted = [...lines].sort((a, b) => a - b);
|
|
186
|
+
codeLinesByFile.set(sourceFile, sorted);
|
|
187
|
+
return sorted;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Mark every line a leaf token occupies. Multi-line tokens exist — a template
|
|
191
|
+
* literal, a long string — and every line they cover is code.
|
|
192
|
+
*/
|
|
193
|
+
function addTokenLines(lines, lineStarts, token) {
|
|
194
|
+
const first = lineAt(lineStarts, token.getStart());
|
|
195
|
+
// `getEnd()` is exclusive, so the last character is one before it. Clamped,
|
|
196
|
+
// because a zero-width node has `getEnd() === getStart()`.
|
|
197
|
+
const last = lineAt(lineStarts, Math.max(token.getStart(), token.getEnd() - 1));
|
|
198
|
+
for (let line = first; line <= last; line++)
|
|
199
|
+
lines.add(line);
|
|
200
|
+
}
|
|
201
|
+
/** How many entries of an ascending array are `<= value`. */
|
|
202
|
+
function countUpTo(sorted, value) {
|
|
203
|
+
let low = 0;
|
|
204
|
+
let high = sorted.length;
|
|
205
|
+
while (low < high) {
|
|
206
|
+
const mid = (low + high) >>> 1;
|
|
207
|
+
// `?? -Infinity` satisfies noUncheckedIndexedAccess without a non-null
|
|
208
|
+
// assertion (ADR-005); `mid` is always in range, so it never applies.
|
|
209
|
+
if ((sorted[mid] ?? -Infinity) <= value)
|
|
210
|
+
low = mid + 1;
|
|
211
|
+
else
|
|
212
|
+
high = mid;
|
|
213
|
+
}
|
|
214
|
+
return low;
|
|
215
|
+
}
|
|
216
|
+
export function countCodeLines(node) {
|
|
217
|
+
const sourceFile = node.getSourceFile();
|
|
218
|
+
// ONE registration, here rather than in each accessor. Both maps drop on the
|
|
219
|
+
// same event, so a call in either accessor made the other's redundant — and a
|
|
220
|
+
// redundant guard is an unprovable one: removing either alone left the suite
|
|
221
|
+
// green. At the single entry, removing it reddens the invalidation tests.
|
|
222
|
+
watchOnce(sourceFile);
|
|
223
|
+
const lineStarts = lineStartsOf(sourceFile);
|
|
224
|
+
const lines = codeLinesOf(sourceFile);
|
|
225
|
+
const first = lineAt(lineStarts, node.getStart());
|
|
226
|
+
const last = lineAt(lineStarts, Math.max(node.getStart(), node.getEnd() - 1));
|
|
227
|
+
return countUpTo(lines, last) - countUpTo(lines, first - 1);
|
|
228
|
+
}
|
|
229
|
+
//# 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/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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createViolation, enclosingScopeName, getElementName } from './violation.js';
|
|
2
|
+
/**
|
|
3
|
+
* A finding whose message states a **measurement** — bug 0012.
|
|
4
|
+
*
|
|
5
|
+
* Metric conditions write the measured value into the message:
|
|
6
|
+
*
|
|
7
|
+
* Big has 10 methods (max: 5) — consider splitting into focused classes
|
|
8
|
+
*
|
|
9
|
+
* `hashViolation` identifies a violation by its message, so the identity moved
|
|
10
|
+
* whenever the measurement moved — **in either direction**. Baseline a class at
|
|
11
|
+
* 10 methods, delete two, and the finding was reported as new:
|
|
12
|
+
*
|
|
13
|
+
* 10 → 10 green ✓
|
|
14
|
+
* 10 → 12 red ✓ (worse)
|
|
15
|
+
* 10 → 8 RED ✗ (better — the defect)
|
|
16
|
+
* 10 → 5 green ✓ (under the threshold)
|
|
17
|
+
*
|
|
18
|
+
* Paying down the debt failed CI, and kept failing on every incremental step
|
|
19
|
+
* until the class dropped under the threshold entirely. A team that split four
|
|
20
|
+
* methods out of an 87-method service got a red build for its trouble. The
|
|
21
|
+
* external audit that motivated this recommends adopting these rules "behind a
|
|
22
|
+
* ratchet (accept today's god objects, block new regressions)" and records them
|
|
23
|
+
* at **zero uses** — the ratchet they were told to use did not work.
|
|
24
|
+
*
|
|
25
|
+
* ## Why identity alone cannot fix it
|
|
26
|
+
*
|
|
27
|
+
* Bug 0010 added `identity` for messages that state a derived population, and
|
|
28
|
+
* applying it naively here trades one failure for a worse one:
|
|
29
|
+
*
|
|
30
|
+
* | identity contains | improving to 8 | regressing to 12 |
|
|
31
|
+
* | ----------------- | -------------- | ---------------- |
|
|
32
|
+
* | the count | **red** ✗ | red ✓ |
|
|
33
|
+
* | no count | green ✓ | **green** ✗ |
|
|
34
|
+
*
|
|
35
|
+
* Dropping the count turns the baseline into a mute button. Identity answers
|
|
36
|
+
* "is this the same finding?", and a metric needs "is it **worse** than what we
|
|
37
|
+
* accepted?" — a comparison, not an equality. So this carries both: a stable
|
|
38
|
+
* identity that finds the entry, and `measured`, which the baseline stores and
|
|
39
|
+
* compares. See `Baseline.isKnown`.
|
|
40
|
+
*
|
|
41
|
+
* **Ten sites produce these, not the eight the bug enumerated.** That table was
|
|
42
|
+
* built by grepping the `has N <noun>` message shape, which misses the two
|
|
43
|
+
* complexity conditions — `has cyclomatic complexity N` puts the number last.
|
|
44
|
+
* Both were left on `createViolation` in the first cut of this fix while the
|
|
45
|
+
* docs already claimed complexity was ratcheted, so a reader would have removed
|
|
46
|
+
* their CI escape hatch for a gate that still fired on every improvement. Found
|
|
47
|
+
* by review; a mechanical enumeration by *shape* is not one by *behaviour*.
|
|
48
|
+
*/
|
|
49
|
+
export function metricViolation(node, options, context) {
|
|
50
|
+
const base = createViolation(node, options.message, context);
|
|
51
|
+
return {
|
|
52
|
+
...base,
|
|
53
|
+
// The qualified name reaches `element` too, not only `identity` — bug 0068's
|
|
54
|
+
// first consequence. `createViolation` derives it with `getElementName`,
|
|
55
|
+
// which resolves an unnamed node up to its nearest named ancestor, so a
|
|
56
|
+
// finding ABOUT an object-literal function was labelled with the ENCLOSING
|
|
57
|
+
// function's name while its own message named it correctly. `element` is
|
|
58
|
+
// what the terminal prints, what the JSON reports, and one of the three
|
|
59
|
+
// fields string-form `.excluding()` matches by exact membership
|
|
60
|
+
// (`execute-rule.ts`), so the disagreement also made an exclusion written
|
|
61
|
+
// against the printed name silently miss.
|
|
62
|
+
element: options.qualifiedName ?? base.element,
|
|
63
|
+
// File, element and metric — never the value. The value is the thing being
|
|
64
|
+
// ratcheted, so putting it here makes every change a new finding, which is
|
|
65
|
+
// the bug. Leaving the FILE out is the other half, and it was shipped once:
|
|
66
|
+
// two classes named `Big` in different files produced one identity, one
|
|
67
|
+
// hash, and `withBaseline`'s last-write-wins picked whichever ceiling came
|
|
68
|
+
// last — measured, a real 10 → 15 regression was silently accepted while
|
|
69
|
+
// the sibling sat at 20. That is bug 0028's shape recreated inside bug
|
|
70
|
+
// 0012's fix, and `ArchViolation.identity`'s own contract forbids it: "two
|
|
71
|
+
// distinct violations sharing one identity are one violation to the
|
|
72
|
+
// baseline, and accepting either accepts both."
|
|
73
|
+
//
|
|
74
|
+
// A path here is portable: `hashViolation` scrubs identity through
|
|
75
|
+
// `normalizeIdentityText(text, root)`, which is what that scrub is for.
|
|
76
|
+
identity: `${node.getSourceFile().getFilePath()}::${identityName(node, options.qualifiedName)}::${options.metric}`,
|
|
77
|
+
measured: options.measured,
|
|
78
|
+
// Defaults to the metric's own name: for `methods` or `parameters` the name
|
|
79
|
+
// IS the unit, and only a metric that can change what it counts under a
|
|
80
|
+
// stable name needs to say so explicitly.
|
|
81
|
+
measuredUnit: options.unit ?? options.metric,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The name segment of a metric identity: the subject's own name, **prefixed by the
|
|
86
|
+
* name of whatever encloses it**, so that two subjects sharing a name in one file
|
|
87
|
+
* are still two identities.
|
|
88
|
+
*
|
|
89
|
+
* Measured, across every function shape — neither name alone is sufficient:
|
|
90
|
+
*
|
|
91
|
+
* | shape | own name | enclosing scope | identity segment |
|
|
92
|
+
* | ------------------------------------ | ------------------- | --------------- | ------------------------- |
|
|
93
|
+
* | two factories returning `{build}` | `build`, `build` | `makeBeta`, `makeGamma` | `makeBeta.build`, … |
|
|
94
|
+
* | an arrow inside a named function | `errorResponseBuilder` | `makeAlpha` | `makeAlpha.errorResponseBuilder` |
|
|
95
|
+
* | a top-level `function takesFive` | `takesFive` | none | `takesFive` — unchanged |
|
|
96
|
+
* | a class method via `functions()` | `Repo.save` | `Repo` | `Repo.save` — already carries it |
|
|
97
|
+
*
|
|
98
|
+
* Two mistakes are recorded here because both shipped and both were found by
|
|
99
|
+
* review rather than by reasoning:
|
|
100
|
+
*
|
|
101
|
+
* 1. **The own name alone** (bug 0068's first fix) moved the collision instead of
|
|
102
|
+
* closing it: `owningBindingName` deliberately declines to prefix a literal
|
|
103
|
+
* returned from a factory, so both `build`s are just `build`.
|
|
104
|
+
* 2. **`getElementName` is not a scope.** It returns the node's OWN name when the
|
|
105
|
+
* node has one and only walks ancestors otherwise — so for method shorthand
|
|
106
|
+
* (`{ build() {} }`, a `MethodDeclaration`) it returned `build`, the prefix was
|
|
107
|
+
* skipped, and the fix worked for the arrow spelling of the same code and not
|
|
108
|
+
* for this one. The scope now comes from `enclosingScopeName`, which always
|
|
109
|
+
* walks from the parent.
|
|
110
|
+
*
|
|
111
|
+
* There is deliberately **no `own === scope` short-circuit**: a nested function
|
|
112
|
+
* whose name equals its enclosing function's (`function save() { return { save:
|
|
113
|
+
* … } }`) is exactly the case that needs the prefix, and equality of strings
|
|
114
|
+
* cannot tell "the scope is me" from "the scope happens to share my name".
|
|
115
|
+
*
|
|
116
|
+
* Known limit, stated rather than papered over: a literal in a **call argument**
|
|
117
|
+
* at module level (`register({ handler: … })`) has no enclosing named
|
|
118
|
+
* declaration, so two of them in one file still share an identity. Nothing stable
|
|
119
|
+
* distinguishes them — that is bug 0067's territory ("there is no right name
|
|
120
|
+
* yet"), not this one's.
|
|
121
|
+
*/
|
|
122
|
+
function identityName(node, qualifiedName) {
|
|
123
|
+
const own = qualifiedName ?? getElementName(node);
|
|
124
|
+
const scope = enclosingScopeName(node);
|
|
125
|
+
if (scope === undefined)
|
|
126
|
+
return own;
|
|
127
|
+
// Already carries it — a class method's `Repo.save` under scope `Repo`.
|
|
128
|
+
if (own.startsWith(`${scope}.`) || own.endsWith(`.${scope}`))
|
|
129
|
+
return own;
|
|
130
|
+
return `${scope}.${own}`;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=metric-violation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metric-violation.js","sourceRoot":"","sources":["../../src/core/metric-violation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAU,EACV,OA6BC,EACD,OAMC;IAED,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC5D,OAAO;QACL,GAAG,IAAI;QACP,6EAA6E;QAC7E,yEAAyE;QACzE,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,wEAAwE;QACxE,gEAAgE;QAChE,0EAA0E;QAC1E,0CAA0C;QAC1C,OAAO,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO;QAC9C,2EAA2E;QAC3E,2EAA2E;QAC3E,4EAA4E;QAC5E,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,uEAAuE;QACvE,2EAA2E;QAC3E,oEAAoE;QACpE,gDAAgD;QAChD,EAAE;QACF,mEAAmE;QACnE,wEAAwE;QACxE,QAAQ,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,OAAO,CAAC,MAAM,EAAE;QAClH,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,4EAA4E;QAC5E,wEAAwE;QACxE,0CAA0C;QAC1C,YAAY,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM;KAC7C,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,SAAS,YAAY,CAAC,IAAU,EAAE,aAAiC;IACjE,MAAM,GAAG,GAAG,aAAa,IAAI,cAAc,CAAC,IAAI,CAAC,CAAA;IACjD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACtC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,GAAG,CAAA;IACnC,wEAAwE;IACxE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC;QAAE,OAAO,GAAG,CAAA;IACxE,OAAO,GAAG,KAAK,IAAI,GAAG,EAAE,CAAA;AAC1B,CAAC"}
|