Skip to content

Comments

refactor: Introduce DiagnosticContext to replace Parser mutable state#57

Merged
DrBarnabus merged 2 commits intomainfrom
refactor/introduce-diagnostic-context
Feb 23, 2026
Merged

refactor: Introduce DiagnosticContext to replace Parser mutable state#57
DrBarnabus merged 2 commits intomainfrom
refactor/introduce-diagnostic-context

Conversation

@DrBarnabus
Copy link
Owner

@DrBarnabus DrBarnabus commented Feb 23, 2026

Summary

  • Introduces a DiagnosticContext class carrying CurrentLocation, a Diagnostics list, and the ReportDiagnostic method with existing fallback logic
  • Replaces the two mutable instance fields (_diagnostics and _location) on Parser, making diagnostic flow visible in method signatures instead of relying on closure capture
  • Updates Parser.Parse to return a (GenerationSpec?, ImmutableEquatableArray<DiagnosticInfo>) tuple, eliminating mutable state from the Parser instance entirely
  • Passes DiagnosticContext as an explicit parameter through ParseTemplateStringIntoKeyParts and its local functions (ToPropertyKeyPart, ToRepeatingPropertyKeyPart)

Closes #42

Summary by CodeRabbit

  • Tests

    • Added a comprehensive unit test suite validating diagnostic context behaviour, including fallback location logic, message formatting, multi-diagnostic accumulation and default states.
  • Refactor

    • Improved diagnostic collection and reporting during source generation; parsing now preserves and returns accumulated diagnostics alongside generation results for clearer error feedback.

Replace the two mutable instance fields (_diagnostics and _location) on
Parser with an explicit DiagnosticContext parameter, making diagnostic
flow visible in method signatures instead of relying on closure capture.

- Add DiagnosticContext class carrying CurrentLocation, Diagnostics list,
  and ReportDiagnostic method with existing fallback logic
- Update Parser.Parse to return (GenerationSpec?, Diagnostics) tuple,
  eliminating mutable state from the Parser instance entirely
- Pass DiagnosticContext through ParseTemplateStringIntoKeyParts and its
  local functions as an explicit parameter
- Simplify SourceGenerator to use Parse return tuple directly
- Add unit tests for DiagnosticContext covering location fallback,
  accumulation, and message arg passthrough
@coderabbitai
Copy link

coderabbitai bot commented Feb 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4498b2f and a1a2d41.

📒 Files selected for processing (1)
  • CLAUDE.md

Walkthrough

Replaces Parser's mutable parsing state with a new per-Parse DiagnosticContext; Parser.Parse now returns a tuple (GenerationSpec? GenerationSpec, ImmutableEquatableArray Diagnostics) and internal helpers propagate DiagnosticContext for diagnostic reporting. Adds unit tests for DiagnosticContext behaviour.

Changes

Cohort / File(s) Summary
DiagnosticContext
src/CompositeKey.SourceGeneration/DiagnosticContext.cs
New internal sealed class that holds a Compilation reference, exposes Location? CurrentLocation, accumulates DiagnosticInfo and implements ReportDiagnostic with fallback to CurrentLocation when given location is null or from an unknown syntax tree.
Parser refactor
src/CompositeKey.SourceGeneration/Parser.cs
Removes Parser instance mutable fields for diagnostics/location; Parse signature changed to return (GenerationSpec? GenerationSpec, ImmutableEquatableArray<DiagnosticInfo> Diagnostics). Internal helpers (ParseTemplateStringIntoKeyParts, ToPropertyKeyPart, ToRepeatingPropertyKeyPart) updated to accept and propagate DiagnosticContext and report via it.
SourceGenerator integration
src/CompositeKey.SourceGeneration/SourceGenerator.cs
Select/initialise flow simplified to return the tuple produced by Parser.Parse(...) directly (no intermediate local).
Unit tests
src/CompositeKey.SourceGeneration.UnitTests/DiagnosticContextTests.cs
New test suite validating ReportDiagnostic fallback logic, accumulation of multiple diagnostics, message-argument formatting, and default CurrentLocation/Diagnostics states.
Docs/meta
CLAUDE.md
Updated summary/notes to reflect file renames and the new DiagnosticContext/Parse result shape.

Sequence Diagram(s)

sequenceDiagram
    participant SourceGenerator
    participant Parser
    participant DiagnosticContext
    participant Compilation
    SourceGenerator->>Parser: Parse(TypeDeclarationSyntax, SemanticModel, CancellationToken)
    Parser->>DiagnosticContext: new DiagnosticContext(compilation)
    Parser->>DiagnosticContext: set CurrentLocation (from target type)
    Parser->>DiagnosticContext: call ReportDiagnostic(descriptor, location?, args)
    DiagnosticContext->>Compilation: verify location.SourceTree ∈ Compilation? 
    alt location invalid or null
        DiagnosticContext-->>Parser: use CurrentLocation as fallback
    end
    DiagnosticContext-->>Parser: record DiagnosticInfo
    Parser-->>SourceGenerator: (GenerationSpec?, Diagnostics)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I nibble bits of code at night,
Diagnostics now march in sight.
No more hidden mutable stew,
Context holds the clues we knew.
Hop, report, and then compile — delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarises the main change: introducing DiagnosticContext to replace Parser's mutable state fields.
Linked Issues check ✅ Passed All coding requirements from issue #42 are met: DiagnosticContext created with CurrentLocation, Diagnostics, and ReportDiagnostic; Parser.Parse updated to return tuple with diagnostics; DiagnosticContext threaded through Parse, ParseTemplateStringIntoKeyParts, and local functions; fallback logic preserved.
Out of Scope Changes check ✅ Passed All changes align with issue #42 objectives: DiagnosticContext introduction, Parser refactoring, diagnostic flow making explicit, and call site adjustments. No extraneous modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/introduce-diagnostic-context

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/CompositeKey.SourceGeneration.UnitTests/DiagnosticContextTests.cs`:
- Around line 8-139: The test class DiagnosticContextTests is declared static
which prevents xUnit discovery; change the class declaration to a non-static
public class (remove the static modifier from DiagnosticContextTests) while
leaving individual [Fact] methods as static or instance methods as desired so
xUnit can run the tests; update any references relying on the class being static
if necessary.

In `@src/CompositeKey.SourceGeneration/DiagnosticContext.cs`:
- Around line 16-21: The method ReportDiagnostic currently relies on
Debug.Assert(CurrentLocation != null) which is removed in Release; add a runtime
guard that throws (e.g., InvalidOperationException or ArgumentNullException) if
CurrentLocation is null before falling back to using it, so callers can't
silently emit diagnostics without a location. Update the guard in
DiagnosticContext.ReportDiagnostic to check CurrentLocation and throw a clear
exception message (referencing CurrentLocation and ReportDiagnostic) before the
existing logic that substitutes location = CurrentLocation when location is null
or invalid.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fcb18e9 and 4498b2f.

📒 Files selected for processing (4)
  • src/CompositeKey.SourceGeneration.UnitTests/DiagnosticContextTests.cs
  • src/CompositeKey.SourceGeneration/DiagnosticContext.cs
  • src/CompositeKey.SourceGeneration/Parser.cs
  • src/CompositeKey.SourceGeneration/SourceGenerator.cs

@DrBarnabus DrBarnabus merged commit 0d64e64 into main Feb 23, 2026
2 checks passed
@DrBarnabus DrBarnabus deleted the refactor/introduce-diagnostic-context branch February 23, 2026 21:47
@codecov
Copy link

codecov bot commented Feb 23, 2026

Codecov Report

❌ Patch coverage is 76.31579% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.77%. Comparing base (fcb18e9) to head (a1a2d41).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/CompositeKey.SourceGeneration/Parser.cs 66.66% 6 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #57      +/-   ##
==========================================
+ Coverage   87.66%   87.77%   +0.11%     
==========================================
  Files          35       36       +1     
  Lines        2099     2103       +4     
  Branches      344      344              
==========================================
+ Hits         1840     1846       +6     
+ Misses        157      156       -1     
+ Partials      102      101       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

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.

refactor: Introduce DiagnosticContext to replace Parser mutable state

1 participant