Skip to content

feat(TextSegment): add WriteTo appendLine override, inline storage, and Count#267

Merged
skarllot merged 3 commits intomainfrom
feat/optimize-text-segment
Apr 4, 2026
Merged

feat(TextSegment): add WriteTo appendLine override, inline storage, and Count#267
skarllot merged 3 commits intomainfrom
feat/optimize-text-segment

Conversation

@skarllot
Copy link
Copy Markdown
Owner

@skarllot skarllot commented Apr 4, 2026

Summary

  • Adds WriteTo(SourceTextWriter, bool appendLine) overload to override the segment's stored AppendLine flag at write time
  • Replaces the internal dynamic array with 8 inline string? fields (_part0_part7) plus an overflow array, eliminating heap allocation for segments with ≤ 8 parts
  • Adds TextSegment.Collection partial exposing Count, a public indexer, and GetEnumerator over the inline storage
  • Adds Throws.IndexOutOfRangeIfInvalid helper for bounds checking in the new indexer
  • Adds TextSegmentTest.Collection tests covering Count, the indexer, and enumeration behaviors

Test plan

  • Run dotnet test — all existing and new tests pass
  • Verify zero-alloc fast path: segments with ≤ 8 parts produce no _additionalParts allocation
  • Verify fallback path: segments with > 8 parts still work correctly via the overflow array

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • TextSegment now supports collection-like operations: direct indexing to access individual elements, enumeration with foreach loops, and a Count property for segment size
    • Improved boundary validation with clearer error messages when accessing elements out of bounds
  • Chores

    • Version updated to 2.4

skarllot and others added 3 commits April 4, 2026 12:05
Add WriteTo(SourceTextWriter, bool) overload that lets callers suppress
or force a line terminator regardless of the segment's stored AppendLine
flag, with XML doc comment and theory tests covering all four override
combinations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…o-alloc fast path

Replaces single-array storage with 8 inline string fields (_part0–_part7)
plus an overflow _additionalParts array, eliminating heap allocation for
segments with ≤ 8 parts (the common case in source generators).

Adds indexer and enumerator to support collection access, with tests covering
inline/overflow boundary, null values, out-of-range guards, and Grow behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 4, 2026

📝 Walkthrough

Walkthrough

This pull request refactors TextSegment's internal storage from array-based to fixed inline slots (_part0_part7) with overflow handling, adds collection-like behavior via an indexer, Count property, and enumerator, introduces a bounds-validation helper method, and updates all tests accordingly. Version bumped to 2.4.

Changes

Cohort / File(s) Summary
Validation Helper
src/InterpolationCodeWriter/Internals/Throws.cs
Added IndexOutOfRangeIfInvalid method for bounds checking; reformatted MinMaxExceptionIf for consistency.
Storage Refactoring
src/InterpolationCodeWriter/TextSegment.cs, src/InterpolationCodeWriter/TextSegment.Interpolation.cs
Replaced array-based storage with inline slots plus overflow array. Updated initialization, append operations, growth logic, and enumeration. Added WriteTo(SourceTextWriter, bool appendLine) overload.
Collection Interface
src/InterpolationCodeWriter/TextSegment.Collection.cs
New partial file implementing indexer, Count property, GetEnumerator() method, and ref struct Enumerator for iteration.
Tests
tests/InterpolationCodeWriter.Tests/TextSegmentTest.Collection.cs, tests/InterpolationCodeWriter.Tests/TextSegmentTest.cs
Added comprehensive collection tests for indexing, enumeration, and bounds checking. Extended existing tests for growth behavior and new WriteTo overload.
Version
version.json
Bumped version from 2.3 to 2.4.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • PR #249 — Modifies Throws.cs utilities and TextSegment code paths; adds complementary exception helpers used by the collection bounds checking.
  • PR #221 — Updates the same InterpolationCodeWriter files and storage/exception infrastructure that this PR builds upon.

Suggested labels

enhancement

Suggested reviewers

  • fgodoy-lepaho

Poem

🐰 A rabbit's ode to a storage tale,
Eight slots inline, then overflow's pale,
Index and count, now enumerate with glee,
TextSegment grows up, collection-wild and free!
From bounded arrays to slots so fine,
Version two-four, the refactor's divine!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 64.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The pull request description covers the key changes (WriteTo overload, inline storage, collection support, new tests) and includes a test plan with verification steps, but lacks explicit checklist confirmation. Clarify whether the four checklist items in the template (branching from default, targeting default, unit tests included, local build successful) have been completed.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the three main changes: WriteTo appendLine override, inline storage optimization, and Count property addition.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/optimize-text-segment

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 4, 2026

Codecov Report

❌ Patch coverage is 89.47368% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.29%. Comparing base (425e6ab) to head (efef775).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...terpolationCodeWriter/TextSegment.Interpolation.cs 75.51% 0 Missing and 12 partials ⚠️
src/InterpolationCodeWriter/Internals/Throws.cs 75.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #267      +/-   ##
==========================================
+ Coverage   88.88%   89.29%   +0.40%     
==========================================
  Files          19       20       +1     
  Lines        1332     1401      +69     
  Branches      101      109       +8     
==========================================
+ Hits         1184     1251      +67     
- Misses        104      107       +3     
+ Partials       44       43       -1     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (2)
src/InterpolationCodeWriter/TextSegment.Interpolation.cs (1)

519-528: Consider using HasValue for nullable struct check.

For nullable value types, using !value.HasValue is more idiomatic than value is null. The pattern matching approach works but involves unnecessary boxing.

♻️ Suggested change
     public void AppendFormatted(in TextSegment? value)
     {
-        if (value is null)
+        if (!value.HasValue)
         {
             return;
         }

         var underlyingValue = value.Value;
         AppendFormatted(in underlyingValue);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/InterpolationCodeWriter/TextSegment.Interpolation.cs` around lines 519 -
528, Replace the null-pattern check with the nullable struct HasValue check in
AppendFormatted to avoid boxing: in the AppendFormatted(in TextSegment? value)
method use if (!value.HasValue) return; then get var underlyingValue =
value.Value and call AppendFormatted(in underlyingValue); this updates the
nullability check for the nullable TextSegment to the idiomatic HasValue usage.
src/InterpolationCodeWriter/Internals/Throws.cs (1)

42-50: XML documentation references wrong exception type.

The <exception> tag at lines 48-50 states ArgumentOutOfRangeException is thrown, which is correct. However, the method name IndexOutOfRangeIfInvalid and the summary imply it throws IndexOutOfRangeException. The actual implementation throws ArgumentOutOfRangeException, which is the correct choice for parameter validation. Consider renaming the method to OutOfRangeIfInvalidIndex for consistency with other helpers in this class (e.g., OutOfRangeIfNegative, OutOfRangeIfGreaterThan).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/InterpolationCodeWriter/Internals/Throws.cs` around lines 42 - 50, The
XML docs and method name are inconsistent with the exception thrown: the method
IndexOutOfRangeIfInvalid actually throws ArgumentOutOfRangeException; rename the
method to OutOfRangeIfInvalidIndex (to match existing helpers like
OutOfRangeIfNegative and OutOfRangeIfGreaterThan), and update its XML <summary>
and any references to use the new name while keeping the <exception> tag as
ArgumentOutOfRangeException so the docs reflect the actual behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/InterpolationCodeWriter/Internals/Throws.cs`:
- Around line 42-50: The XML docs and method name are inconsistent with the
exception thrown: the method IndexOutOfRangeIfInvalid actually throws
ArgumentOutOfRangeException; rename the method to OutOfRangeIfInvalidIndex (to
match existing helpers like OutOfRangeIfNegative and OutOfRangeIfGreaterThan),
and update its XML <summary> and any references to use the new name while
keeping the <exception> tag as ArgumentOutOfRangeException so the docs reflect
the actual behavior.

In `@src/InterpolationCodeWriter/TextSegment.Interpolation.cs`:
- Around line 519-528: Replace the null-pattern check with the nullable struct
HasValue check in AppendFormatted to avoid boxing: in the AppendFormatted(in
TextSegment? value) method use if (!value.HasValue) return; then get var
underlyingValue = value.Value and call AppendFormatted(in underlyingValue); this
updates the nullability check for the nullable TextSegment to the idiomatic
HasValue usage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 84d51e17-9367-45e6-904c-ccc95998ec60

📥 Commits

Reviewing files that changed from the base of the PR and between 425e6ab and efef775.

📒 Files selected for processing (7)
  • src/InterpolationCodeWriter/Internals/Throws.cs
  • src/InterpolationCodeWriter/TextSegment.Collection.cs
  • src/InterpolationCodeWriter/TextSegment.Interpolation.cs
  • src/InterpolationCodeWriter/TextSegment.cs
  • tests/InterpolationCodeWriter.Tests/TextSegmentTest.Collection.cs
  • tests/InterpolationCodeWriter.Tests/TextSegmentTest.cs
  • version.json

@skarllot skarllot merged commit ee146b9 into main Apr 4, 2026
7 checks passed
@skarllot skarllot deleted the feat/optimize-text-segment branch April 4, 2026 18:10
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.

2 participants