Skip to content

fix(analyzers): report partial members once and add partial-shape fixtures - #157

Merged
e128 merged 1 commit into
mainfrom
fix/partial-member-duplicate-reports
Nov 12, 2026
Merged

e128 merged 1 commit into
mainfrom
fix/partial-member-duplicate-reports

Conversation

@e128

@e128 e128 commented Nov 12, 2026

Copy link
Copy Markdown
Owner

Executive Summary

A symbol action receives the defining symbol and the implementing symbol of a partial member as separate events, so member-level rules reported the same diagnostic twice for one logical member. MidNameUnderscoreAnalyzer reproduced the duplicate for a partial property. The new PartialMembers.IsImplementationPart helper detects the implementing source symbol through PartialDefinitionPart, and the four member-level symbol rules skip that event, so a partial member reports once, at its defining part.

The same session audited the two analyzer roadmap items raised by the pugworks GeneratedRegexAnalyzer silence in 2.9.7. At the Roslyn version this repository pins, no silently-dead registration reproduces: attribute node actions fire on partial declarations with and without an implementation part, across files, and with a generated implementation part. Every analyzer that ships a code fix registers that fix for each rule id it reports; the audit found and closed one missing fixture (the E128108 shape of LowValueTestCodeFixProvider).

Code Changes

  • src/E128.Analyzers/PartialMembers.cs: new shared helper. IsImplementationPart classifies the implementing source symbol of a partial method, partial property, or a parameter of one.
  • Four analyzers call the helper first and skip the implementing event: MidNameUnderscoreAnalyzer, ByteSizeForDataSizeAnalyzer, TimeSpanForDurationAnalyzer, and MutableCollectionExposureAnalyzer (method and property callbacks). TimeSpanForDurationAnalyzer also extracts a GetDetails switch to stay inside the complexity ceiling.
  • Partial-shape fixtures for five attribute rules: ObsoleteWithoutMessageAnalyzer (E128169), UnjustifiedSuppressionAttributeAnalyzer (E128173), DynamicallyAccessedMembersGuardAnalyzer (E128049), AggressiveOptimizationAnalyzer (E128116), and DllImportToLibraryImportAnalyzer (E128117). Each proves the rule fires on a partial declaration, the source-generator shape. MissingTraitCategoryAnalyzer and UntrackedSkipAnalyzer stay out of scope: a partial test method is not a real-world shape.
  • LowValueTestCodeFixTests gains the missing E128108 fix fixture.
  • Analyzer version 2.9.7 to 2.9.8; README install snippet updated. No rule ids, severities, categories, or code-fix offerings changed, so AnalyzerReleases.Unshipped.md stays empty and analyzer-promote.sh reported empty.

Tests and Tooling

scripts/check.sh --all passes: shell lint, format check, build, and tests. Full suite: 2903 tests, 2901 passed, 0 failed, 2 skipped (both predate this change). Lode files updated: analyzers/authoring.md records the probed partial-declaration behavior and the helper contract, shared-helpers.md lists the helper, release-tracking.md records the release, and plans/roadmap.md records both audit outcomes.

Review Guide

Start with PartialMembers.cs (29 lines), then the four early-return call sites. Each partial-shape fixture names its expected single diagnostic span. The analyzer-release-check.sh and readme-table-diff.sh --analyzer outputs are clean.

Rollback

Revert the single commit. No data, schema, or configuration migration involved.

Links

Roadmap item source: the 2.9.7 GeneratedRegexAnalyzer detection audit recorded in plans/roadmap.md.

🤖 Generated with Claude Code

@e128
e128 merged commit c8c8905 into main Nov 12, 2026
2 checks passed
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