Skip to content

jscpd sees the constructor + guard-prelude idiom as clones once statics strip the varying lines #452

Closed

Description

@Blind-Striker

jscpd reports the constructor + argument-guard idiom as clones once static conversions strip the lines that used to differ.

Finding

GEN-E3 PR 3 made the Ingestion/Projection policies static (P38, U7-30, U10-09). That removed GraphKeyBuilder, ErrorStyleClassifier and LiteralClassifier from the projector constructors.

Three projectors keep exactly one real collaborator, the injected SchemaProjector. What remains of each is the same idiom: a one-field constructor (_schemaProjector = schemaProjector ?? throw new ArgumentNullException(...)), followed by the next method's ArgumentNullException.ThrowIfNull(...) / ArgumentException.ThrowIfNullOrWhiteSpace(...) guard block. jscpd now sees two new windows, with no shared logic in either:

Pair Tokens
tools/OpenCode.Sdk.Tools/Generator/Ingestion/Projection/ObjectSchemaProjector.cs:10-23 ↔ PrefixItemsAdapter.cs:12-25 81
ObjectSchemaProjector.cs:12-23 ↔ UnionNormalizer.cs:23-34 63

Why they are baselined, not removed, in GEN-E3 PR 3

  • A helper that wraps the guards would be the slop the clone rules forbid. It would be an abstraction over two BCL calls, with no logic to own.
  • No planned step removes the windows. None of GEN-E3, GEN-E4 or GEN-E5 makes these three types static or removes their injected SchemaProjector, which is a real per-ingestion collaborator.

The PR baselines both pairs with this reason and names this issue as the change that removes them (docs/engineering/quality-gates.md, Clone gate).

Decision needed (structure or detector)

  1. Structure: the projectors could take SchemaProjector as a method argument instead of a constructor field, or become one composed unit. That has a design cost.
  2. Detector: teach the clone gate to ignore a constructor-assignment plus guard-prelude window, the way it already ignores using lines ([TST-E0] build: the clone gate ignores using directives and fails on stale baseline entries #410), with tests that a real body duplicate is still caught.

Whichever is chosen removes both baseline entries.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions