Skip to content

Conversation

@YoelDruxman
Copy link

@YoelDruxman YoelDruxman commented Jan 14, 2026

Respect .editorconfig end_of_line and charset in generated code

Description

Generated mapper files (.g.cs) now respect .editorconfig settings for line endings and character encoding.

Problem

Generated code always used CRLF (\r\n) line endings and UTF-8 without BOM, regardless of the project's .editorconfig configuration. This caused issues for projects configured with different line endings.

Solution

Read end_of_line and charset settings from the source file's .editorconfig via AnalyzerConfigOptionsProvider and apply them to the generated output.

Supported settings:

  • end_of_line: lf, crlf, cr (defaults to crlf)
  • charset: utf-8, utf-8-bom, utf-16be, utf-16le (defaults to utf-8 without BOM)

Known Limitation

Due to a Roslyn limitation, editorconfig settings are read from the source file containing the mapper declaration, not from generated .g.cs files. This means [*.g.cs] patterns in .editorconfig will not be applied. Users should configure settings in [*.cs] or [*] sections.

Files changed:

  • LineEndingTextWriter.cs - Streaming line ending replacement
  • IncrementalValuesProviderExtensions.cs - Read editorconfig settings and apply encoding
  • MapperNode.cs - Store EndOfLine and Charset properties
  • MapperGenerator.cs - Pass settings from source file to output

Addresses this discussion

Checklist

  • The existing code style is followed
  • The commit message follows our guidelines
  • Performed a self-review of my code
  • Hard-to-understand areas of my code are commented
  • The documentation is updated (as applicable)
  • Unit tests are added/updated
  • Integration tests are added/updated (as applicable)

@YoelDruxman YoelDruxman force-pushed the feat/editorconfig-settings branch 6 times, most recently from 4199944 to 3194a3e Compare January 14, 2026 15:30
@latonz
Copy link
Contributor

latonz commented Jan 14, 2026

Thank you for this contribution. Before I start the review, I’d like to clarify a few open questions:

  • How do other source generators handle this? It seems like a challenge all source generators face.
  • What is the performance impact?
  • Would it make more sense to emit the correct line feeds directly in the syntax emitters instead of replacing them afterward? This would probably reduce the performance impact.

@YoelDruxman
Copy link
Author

YoelDruxman commented Jan 14, 2026

Thank you @latonz! I am still working on this. Let me consider your feedback and update the PR or at least report back.

@YoelDruxman YoelDruxman changed the title Respect .editorconfig end_of_line and charset in generated code Respect .editorconfig end_of_line and charset in generated code Jan 15, 2026
@YoelDruxman
Copy link
Author

@latonz I think this is ready for your review. Your thoughtful questions led to changing the implementation for the better:

  1. It seems that this is an unsolved problem.
  2. The performance has been improved to what I believe is almost transparent.
  3. This seems like more effort and difficulty than it is worth.

Here is a report I created with Claude that delves a little deeper.

Please let me know what you think. Any feedback is welcome! Thank you for this wonderful library!

YoelDruxman and others added 6 commits January 19, 2026 19:34
Generated mapper files (.g.cs) now honor .editorconfig settings:
- end_of_line: supports lf, crlf, cr (defaults to crlf)
- charset: supports utf-8, utf-8-bom, utf-16be, utf-16le (defaults to utf-8 without BOM)

This allows generated code to match the project's line ending and encoding
preferences, avoiding git diffs and post-processing requirements.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Use the mapper source file path (.cs) instead of trying to create a
synthetic tree with the generated file path (.g.cs). This provides
reliable editorconfig support with a documented limitation.

Note: [*.g.cs] patterns are not supported due to a Roslyn limitation.
Users should configure settings in [*.cs] or [*] sections.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Instead of GetText().ToString().Replace() which creates 2 string
allocations for non-CRLF line endings, use SyntaxNode.WriteTo()
with a custom LineEndingTextWriter that replaces CRLF on-the-fly.

This reduces allocations from 2 to 1 for LF/CR configurations while
maintaining the fast path (no replacement) for CRLF (default).

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Clarifies that settings are read from the source file containing
the mapper declaration, not from generated files.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@YoelDruxman YoelDruxman force-pushed the feat/editorconfig-settings branch from 72bed81 to 76d8d14 Compare January 20, 2026 00:34
@YoelDruxman YoelDruxman marked this pull request as ready for review January 20, 2026 00:34
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