Skip to content

Optimize TextEditorModel's InvalidLineRange from class to struct, add comprehensive test coverage, fix exception handling for TokenizeViewPort#577

Open
udlose wants to merge 4 commits intoAvaloniaUI:masterfrom
udlose:performance/optimization-texteditormodel
Open

Optimize TextEditorModel's InvalidLineRange from class to struct, add comprehensive test coverage, fix exception handling for TokenizeViewPort#577
udlose wants to merge 4 commits intoAvaloniaUI:masterfrom
udlose:performance/optimization-texteditormodel

Conversation

@udlose
Copy link
Copy Markdown
Contributor

@udlose udlose commented Apr 5, 2026

PR Classification

Code cleanup and test enhancement to improve resource management, thread-safety, and test coverage for TextEditorModel.

PR Summary

Refactored TextEditorModel for safer disposal and better testability, and significantly expanded unit tests for edge cases and internal behaviors.

  • TextEditorModel.cs: Added thread-safe disposal, converted InvalidLineRange to a struct, improved event handler safety, and refactored tokenization logic.
  • ReflectionTestHelper.cs: Introduced a utility for invoking private/internal members in tests.
  • TextEditorModelTests.cs: Added comprehensive tests for disposal, event handling, edge cases, and internal logic using the new reflection helper.

Test Coverage

image

udlose added 4 commits April 5, 2026 14:27
Added extensive new unit tests to TextEditorModelTests.cs, covering line counting, content, insert/remove/replace operations, batch updates, disposal idempotency, event handler resilience, exception handling, InvalidLineRange logic, DocumentSnapshot consistency, and edge cases (including CRLF/mixed endings and viewport/tokenization logic). Tests use Avalonia headless infrastructure and reflection helpers for thorough coverage. Existing tests were reorganized and some replaced with more comprehensive versions. This greatly improves confidence in TextEditorModel's correctness and robustness.
- Add thread-safe disposal checks using Volatile.Read/Write and _isDisposed
- Change InvalidLineRange from class to readonly struct to reduce allocations
- Refactor invalid range merging to return new struct instead of mutating
- Early-exit event handlers if disposed to prevent invalid operations
- Refactor TokenizeViewPort to use Dispatcher.UIThread.Post and extract core logic for testability
- Improve XML documentation and code clarity
- Use C# 8 index-from-end operator (^) for cleaner list access
- Add ThrowIfDisposed for consistent disposal checks
- Update property/field declarations for consistency
Refactored LinkElementGenerator and MailLinkElementGenerator to use C# source-generated regular expressions via the [GeneratedRegex] attribute. This replaces static Regex field initializations, improving performance and reducing allocations. Public API and logic remain unchanged.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would be possible to avoid using reflection here for testing?

I think it's worth using InternalsVisibleTo or just making internal methods XXXForTesting rather than using reflection what is quite bad in terms of maintainability.

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