Skip to content

[Feature]: Inline suppression for LCOM4 class cohesion #36

Description

@fummicc1

Feature Summary

Extend the // swift-complexity:disable inline suppression comment (added in #35 for cyclomatic/cognitive complexity) to also cover LCOM4 class cohesion checks, e.g. // swift-complexity:disable lcom4 placed directly above a class/struct/actor declaration.

Motivation

PR #35 added per-function suppression for cyclomatic and cognitive metrics, but deliberately left LCOM4 out of scope:

  • LCOM4 is a type-level metric (class/struct/actor), not a per-function one, so suppression needs to attach to a type declaration's leading trivia rather than a function/initializer/deinitializer/accessor's, as SuppressionParser currently does inside FunctionDetector.
  • LCOM4 is detected by a completely separate visitor, NominalTypeDetector, and computed through a different pipeline (SemanticLCOMCalculator, which requires IndexStore-DB via --lcom4 --index-store-path), unlike the pure-AST cyclomatic/cognitive calculators.

Without this, a team that has a legitimately low-cohesion type (e.g. a legacy God object being incrementally refactored) has no way to exempt it from --lcom4 threshold checks short of excluding the whole file via --exclude.

Proposed Solution

  • Add the same leading-trivia scan (SuppressionParser, or a small variant of it) to NominalTypeDetector's visit methods for class/struct/actor declarations.
  • Recognize a new lcom4 token for SuppressedMetric (or a parallel type-level enum, depending on how cleanly it composes with the existing per-function SuppressedMetric).
  • Thread a suppression flag through ClassCohesion, mirroring how FunctionComplexity.suppressedMetrics works: the LCOM4 value stays visible in every output format, only the threshold judgment (cohesionLevel == .low gating in createCohesionDiagnostic/cohesionResults) is skipped.
  • Keep the same fail-closed parsing behavior as the function-level suppression: an unrecognized token suppresses nothing.

Feature Category

Other

Usage Examples

# swift-complexity:disable lcom4
class LegacyOrderManager {
    // ... many loosely related methods/properties, refactor tracked separately
}

Alternative Solutions

--exclude <pattern> already allows suppressing an entire file, but that also hides cyclomatic/cognitive violations in the same file, which is too coarse when only the class-level cohesion check should be exempted.

Priority

Low (nice to have)

Implementation

  • I'm willing to submit a pull request for this feature

Additional Context

Follow-up from #35 (see that PR's description and docs/user-guide/usage.md / README.md, both of which currently state "LCOM4 class cohesion has no suppression mechanism yet, since it is a type-level metric rather than a per-function one.").

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or improvement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions