Skip to content

S3776: reduce cognitive complexity in seven methods - #167

Merged
matt-edmondson merged 1 commit into
mainfrom
chore/sonar-cognitive-complexity
Aug 14, 2026
Merged

S3776: reduce cognitive complexity in seven methods#167
matt-edmondson merged 1 commit into
mainfrom
chore/sonar-cognitive-complexity

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Clears all seven open S3776 cognitive-complexity findings. Pure extraction into named helpers — no logic changes anywhere.

Sites

File Method Complexity Approach
QuantitiesGenerator.cs CollectAllOperators 43 → split per relationship kind, then again per form
QuantitiesGenerator.cs CollectAllProducts 42 → same shape
QuantitiesGenerator.cs GenerateInner 22 → Phase B loop body + overload loop extracted
DimensionsMetadata.cs Validate 37 → four-level split by what's being validated
UnitsGenerator.cs GenerateInner 23 → three builders
PropertyTemplate.cs WriteTo 17 → guard clauses; predicate and accessor branches extracted
Chord.cs ConsumeModifiers 17 → split by modifier group

All are now under the 15 threshold.

Notes for review

The generated sources under Generated/ are byte-identical. Four of the five files (QuantitiesGenerator, UnitsGenerator, DimensionsMetadata, PropertyTemplate) exist only to produce that emitted code, so zero drift is direct proof those extractions preserved behavior — stronger than test coverage alone. Chord.cs is the one resting on tests instead.

Chord.ConsumeModifiers is a destructive parse and its consumption order is load-bearing — omissions, then the flat sixth (before any bare 6), then the altered tensions (multi-character tokens before bare numbers), then the fifth alteration, then add9. The split preserves that order exactly.

The new TakeEither(ref body, ascii, unicode) helper keeps the original Take(a) || Take(b) short-circuit, so a body containing both spellings of a token still loses only the ASCII one. That is existing behavior, preserved deliberately rather than "fixed" — if it's a latent bug it deserves its own change with its own test.

Chord.cs was a seventh site not on the original worklist (which had six, all in Semantics.SourceGenerators). It's in Semantics.Music, which the local Sonar setup can't reach, so it's the one site verified only by CI.

Verification

  • 8-TFM build clean, 0 warnings, 0 errors
  • 1095/1095 tests pass
  • No drift under Generated/
  • Local Sonar analyzers (.sonarlint/sonar-local.props, with S3776 enabled at warning) report zero remaining S3776 in Semantics.SourceGenerators

🤖 Generated with Claude Code

https://claude.ai/code/session_01AgFo81FUAF3qx6o5ifnAwq

Splits the seven methods SonarCloud flags for cognitive complexity into
named helpers. Pure extraction — no logic changes. The generated sources
under Generated/ are byte-identical, which is the load-bearing check for
four of the five files.

Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs
  CollectAllOperators (43) and CollectAllProducts (42) each split per
  relationship kind, with the innermost per-form body extracted again:
  CollectIntegralOperators/CollectDerivativeOperators + Add*OpsForForm,
  CollectDotProducts/CollectCrossProducts + AddDotProductForForm and
  AddCrossProduct. GenerateInner (22) hands its Phase B loop body to
  EmitDimensionTypes and the overload loop to EmitOverloadTypes.

Semantics.SourceGenerators/Models/DimensionsMetadata.cs
  Validate (37) -> ValidateDimension -> ValidateAvailableUnits and
  ValidateVectorForms -> ValidateVectorForm. The two seen-name sets stay
  threaded through so duplicates are still detected document-wide, and
  the issue ordering is unchanged.

Semantics.SourceGenerators/Generators/UnitsGenerator.cs
  GenerateInner (23) -> BuildUnitToDimensionsMap, BuildUnitClass,
  BuildUnitsCatalogue.

Semantics.SourceGenerators/Templates/PropertyTemplate.cs
  WriteTo (17) uses guard-clause returns; the long auto-accessor
  predicate becomes CanUseShorthand and the duplicated getter/setter
  branches collapse into one WriteAccessor helper.

Semantics.Music/Chord.cs
  ConsumeModifiers (17) -> ConsumeOmissions, ConsumeTensions,
  ConsumeFifthAlteration, plus TakeEither for the ASCII/Unicode token
  pairs. Consumption order is load-bearing (the parse is destructive)
  and is preserved exactly; TakeEither keeps the original short-circuit,
  so only one spelling of a token is ever consumed.

Verified: 8-TFM build clean (0 warnings), 1095/1095 tests pass, no drift
under Generated/, and the local Sonar analyzers report no remaining
S3776 in Semantics.SourceGenerators.
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 1ad67b0 into main Aug 14, 2026
6 checks passed
@matt-edmondson
matt-edmondson deleted the chore/sonar-cognitive-complexity branch August 14, 2026 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant