feat(utilities): add Delta / SetDelta<T> set-difference for incremental diffing - #148
Conversation
…al diffing Delta.Difference(first, second) returns the relative complement (second \ first), preserving second's order; Delta.Compute(previous, current) returns a value-equatable SetDelta<T> carrying Added/Removed so a snapshot diff flows through the incremental generator cache. Overloads for ImmutableArray<T> and EquatableArray<T>; results are EquatableArray<T>. Fixes the doc/impl drift of the classic single-direction helper (documented filter-not-dedup semantics). 14 tests (order, duplicates, symmetry, overload agreement, record models, value equality). Verified: CI=true Release build (warnings-as-errors) green; 174 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Summary by CodeRabbit
WalkthroughIntroduces a ChangesDelta Utility and Tests
Estimated code review effort: 2 (Simple) | ~12 minutes Related PRs: None specified. Suggested reviewers: None specified. Note:
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error)
✅ Passed checks (7 passed)
Comment |
There was a problem hiding this comment.
Pull request overview
Adds a small diffing primitive to ANcpLua.Roslyn.Utilities to support incremental analyzer/generator snapshot comparisons, along with tests and a README entry documenting the new API.
Changes:
- Introduces
Delta.Difference(...)to compute the relative complement (second \ first) while preservingsecond’s order (and intentionally not deduplicating). - Introduces
Delta.Compute(...)returning a value-equatableSetDelta<T>(Added/Removed) suitable for incremental cache comparisons. - Adds xUnit test coverage for ordering, duplicates, default inputs, overload agreement, and
SetDelta<T>value equality; documents the utility inREADME.md.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/ANcpLua.Roslyn.Utilities/Delta.cs |
Adds Delta + SetDelta<T> APIs (ImmutableArray/EquatableArray overloads, XML docs, value equality + hash). |
tests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs |
Adds unit tests covering Difference/Compute semantics and SetDelta<T> equality/hash behavior. |
README.md |
Documents the new utility in the library feature list. |
.claude/TASK.md |
Adds an internal task/checklist document related to implementing and shipping the feature. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs`:
- Around line 12-85: Consolidate the repetitive Delta.Difference tests into a
single [Theory] with [MemberData] (or equivalent shared data source) instead of
multiple [Fact] methods. Keep the same coverage for the existing Difference_*
cases by parameterizing the inputs and expected outputs, and update the test
names/data setup around Delta.Difference, Eq, and AsImmutableArray so the
behavior assertions remain unchanged while removing duplication.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 178f1923-6f96-4e4c-acf6-04235aa0f9d5
⛔ Files ignored due to path filters (2)
.claude/TASK.mdis excluded by none and included by noneREADME.mdis excluded by none and included by none
📒 Files selected for processing (2)
src/ANcpLua.Roslyn.Utilities/Delta.cstests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: build (windows-latest)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: copilot-pull-request-reviewer
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx,js,jsx,cs,py}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Skip files whose first ~3 lines contain
// Ported from <upstream>,// Generated, or// Auto-generated— surface a one-line note instead of line-level findings
Files:
src/ANcpLua.Roslyn.Utilities/Delta.cstests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs
**/*.cs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
.NET code: enable nullable reference types, use central package management via
Directory.Packages.props, and treatVersion.propsas the single owner of versions — never edit<Version>lines directly
Files:
src/ANcpLua.Roslyn.Utilities/Delta.cstests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs
src/ANcpLua.Roslyn.Utilities/**/*.{cs,csproj}
📄 CodeRabbit inference engine (AGENTS.md)
Keep
ANCPLUA_ROSLYN_PUBLICcontrolled per-consumer; avoid bleeding API-visibility mode into source-only or internal package surfaces
Files:
src/ANcpLua.Roslyn.Utilities/Delta.cs
src/**/*.cs
📄 CodeRabbit inference engine (Custom checks)
src/**/*.cs: In C# public async methods, verify that every async method accepts and forwards a CancellationToken parameter
When adding a new injectable service class registered in dependency injection, verify that it registers an ActivitySource or Meter for OpenTelemetry instrumentation
Files:
src/ANcpLua.Roslyn.Utilities/Delta.cs
⚙️ CodeRabbit configuration file
src/**/*.cs: C# 14 / .NET 10 codebase. Review for: idiomatic modern C#, proper async/await (no sync-over-async, no fire-and-forget without justification), correct IDisposable/IAsyncDisposable, null safety (NRTs enabled), and adherence to existing patterns. Flag new public API surface that lacks XML doc comments. Check DI lifetime correctness (scoped vs singleton vs transient).
ARCHITECTURAL INVARIANTS — flag violations as blocking: 1. Every new injectable service must register OpenTelemetry instrumentation
(ActivitySource or Meter).
2. Every new DuckDB write path must handle backpressure (bounded channel or semaphore). 3. No hardcoded connection strings, paths, or magic strings — use IOptions or
IConfiguration.
4. No new dependencies on Sentry-specific types in core/ — Sentry is a comparison
target, not an identity.
5. CancellationToken must be threaded through all async public methods. 6. No sync-over-async (.Result, .GetAwaiter().GetResult()) outside of
well-documented infrastructure code.
Files:
src/ANcpLua.Roslyn.Utilities/Delta.cs
src/**/*.{cs,js,ts,py}
📄 CodeRabbit inference engine (Custom checks)
When adding new code paths that write to DuckDB, verify it uses a bounded channel or semaphore for backpressure handling
Files:
src/ANcpLua.Roslyn.Utilities/Delta.cs
**
⚙️ CodeRabbit configuration file
**: # ANcpLua.Roslyn.UtilitiesMinimal navigation for Claude/Codex agents. Keep policy in
AGENTS.md; keep findings in issues, PRs, or tests.Project Index
- AOT reflection generator
- AOT reflection attributes
- Discriminated union generator
- Extensible enum mirror generator
- Core Roslyn utilities
- Polyfills package
- Source-only package
- Testing utilities
- AOT testing utilities
Nearby Repos
- ANcpLua.NET.Sdk: shared SDK/version truth for the ANcpLua repos.
- ANcpLua.Analyzers: analyzer consumer of the source-only utilities.
- ANcpLua.Agents: successor location for agent workflow/test helpers; do not describe this repo as the MAF runtime home.
**:
999.9.9
10.0.203
latestMinor
<PropertyGroup Label="Roslyn"> <RoslynVersion>5.3.0</RoslynVersion> <RoslynAnalyzersVersion>5.3.0</RoslynAnalyzersVersion> </PropertyGroup> <!-- ═══════════════════════════════════════════════════════════════════════ ROSLYN ANALYZER TESTING Used by: Roslyn.Utilities.Testing, Analyzers.Tests ════════════════════════════════════════════════════════════════════...
Files:
src/ANcpLua.Roslyn.Utilities/Delta.cstests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs
src/ANcpLua.Roslyn.Utilities/**
⚙️ CodeRabbit configuration file
src/ANcpLua.Roslyn.Utilities/**: # ANcpLua.Roslyn.UtilitiesCore runtime and Roslyn utility package.
- Project: ANcpLua.Roslyn.Utilities.csproj
- Runtime helpers should stay usable without Roslyn dependencies where possible.
- Check existing helper types before adding another abstraction.
Files:
src/ANcpLua.Roslyn.Utilities/Delta.cs
tests/**/*.cs
⚙️ CodeRabbit configuration file
xUnit.v3 test projects using xunit.v3.mtp-v2 with AwesomeAssertions and NSubstitute. Follow Arrange-Act-Assert pattern. Use descriptive test names: MethodName_Scenario_ExpectedResult. Test async methods with async Task, not async void. Flag hardcoded test data that should come from the seeded DuckDB file (the single source of truth for demo/test data). Prefer [Theory] with [InlineData] or [MemberData] over duplicated [Fact] methods testing variations of the same behavior. Flag tests that depend on test execution order.
Files:
tests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs
🧠 Learnings (2)
📚 Learning: 2026-06-14T00:13:53.631Z
Learnt from: ANcpLua
Repo: ANcpLua/ANcpLua.Roslyn.Utilities PR: 144
File: tests/ANcpLua.Roslyn.Utilities.DiscriminatedUnion.Tests/IncrementalDiagnosticLocationTests.cs:63-67
Timestamp: 2026-06-14T00:13:53.631Z
Learning: When testing Roslyn incremental generator diagnostics, assert generator execution failures (e.g., CS8785 “generator-failed”) against `GeneratorDriverRunResult.Diagnostics` (use `driver.GetRunResult().Diagnostics`), not against `outputCompilation.GetDiagnostics()`. Checking `outputCompilation` for CS8785 is a silent no-op because that diagnostic is surfaced only in the driver run result.
Applied to files:
tests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs
📚 Learning: 2026-06-14T00:13:53.631Z
Learnt from: ANcpLua
Repo: ANcpLua/ANcpLua.Roslyn.Utilities PR: 144
File: tests/ANcpLua.Roslyn.Utilities.DiscriminatedUnion.Tests/IncrementalDiagnosticLocationTests.cs:63-67
Timestamp: 2026-06-14T00:13:53.631Z
Learning: In this repo’s test suite, the `Test<TGenerator>` harness and `GeneratorTestEngine.RunTwiceAsync` are not suitable for scenarios that require `ReplaceSyntaxTree` shrinking edits between two driver runs. If a test needs to reproduce regressions like dotnet/roslyn#82032 (incremental update with a smaller syntax tree), write the test with a hand-rolled `CSharpGeneratorDriver` and call `RunGenerators` on the modified compilation directly (i.e., don’t rely on `RunTwiceAsync`/`ReplaceSyntaxTree` shrinking across driver runs).
Applied to files:
tests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs
🔇 Additional comments (2)
src/ANcpLua.Roslyn.Utilities/Delta.cs (1)
1-175: LGTM!tests/ANcpLua.Roslyn.Utilities.Testing.Tests/DeltaTests.cs (1)
87-136: LGTM!
…l bumped) (#149) The Delta / SetDelta<T> task is fully complete: merged via #148, published as 2.2.29 (tagged, indexed on nuget.org), and qyl's global.json pins were bumped in qyl#456. Removing the task-state file so it is not mistaken for ongoing work. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
What
Adds a small, on-theme utility to
ANcpLua.Roslyn.Utilities: set difference for incremental "what changed between the previous and current snapshot" logic — the diffing primitive incremental generators/analyzers reach for constantly.Delta.Difference(first, second)→ relative complementsecond \ first, preservingsecond's order. Filters (does not deduplicate); documented and tested.Delta.Compute(previous, current)→ value-equatableSetDelta<T>carryingAdded(incurrent, notprevious) andRemoved(inprevious, notcurrent) — the "call it twice" idiom baked in.ImmutableArray<T>andEquatableArray<T>; results areEquatableArray<T>so a delta flows through the generator cache.SetDelta<T>is value-equatable (==,Equals,HashCombiner-basedGetHashCode), withIsEmpty/HasChanges.Follows repo conventions: dual-visibility (
ANCPLUA_ROSLYN_PUBLIC),HashCombiner, full XML docs.Why
Diffing two snapshots is a recurring need in incremental pipelines (added/removed models, usings, symbols, cache keys). This bakes the correct, allocation-conscious, cache-friendly version into the library and fixes the doc/impl drift of the classic single-direction helper.
Verification — complete & verified
CI=true dotnet build -c Release(warnings-as-errors) — green.DeltaTests: order, duplicates, symmetry, overload agreement, default-array inputs, record models, value equality).🤖 Generated with Claude Code