Skip to content

Keep the enclosing indent on multi-line expression bodies - #114

Merged
matt-edmondson merged 4 commits into
mainfrom
fix/splice-multiline-expression-bodies
Sep 26, 2026
Merged

matt-edmondson merged 4 commits into
mainfrom
fix/splice-multiline-expression-bodies

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #112

What was wrong

PropertyTemplate.ExpressionBodyFactory and AccessorKind.Expression rendered the expression fragment and passed it to Write as one string. IndentedTextWriter only indents at the start of a write, so every line after the first landed at the fragment's own indent instead of the enclosing one. Switch expressions, collection expressions and initializers all came out mis-indented. A factory that ended with WriteLine also left the ; alone on its own line.

Change

  • Adds TemplateRendering.WriteExpressionBody, which both expression paths now call:
    • It writes => and keeps the first line on the declaration line.
    • It splices the remaining lines at the current indent, the same way SpliceFragment does for block bodies.
    • It puts the ; on the last line that has content.
  • Single-line expression bodies render exactly as before, and the existing tests pin that.

Tests

  • AMultiLineExpressionBodiedPropertyKeepsTheEnclosingIndent: the switch-expression reproduction from the issue, nested in a class.
  • AMultiLineExpressionBodiedAccessorKeepsTheEnclosingIndent: a collection-expression getter nested in a class.
  • AnExpressionBodyEndingInALineTerminatorKeepsItsSemicolonOnTheLastLine: a factory that ends with WriteLine.
  • With the fix reverted, all 3 new tests fail. With it applied, the full suite passes (174/174).
  • A local Sonar build reports only the pre-existing S8969 in DocComment.cs.

This stands alone on main. It touches TemplateRendering.cs, as #113 does, but in separate methods.

🤖 Generated with Claude Code

https://claude.ai/code/session_019StKk4VdpfAZ5cdW5X685e


Generated by Claude Code

PropertyTemplate.ExpressionBodyFactory and AccessorKind.Expression wrote
the rendered expression as one string, and IndentedTextWriter only
indents at the start of a write, so every line after the first lost the
enclosing indent. A factory ending in WriteLine also left the semicolon
alone on its own line.

Both paths now go through TemplateRendering.WriteExpressionBody. It
keeps the first line after the arrow, splices the rest at the current
indent, and puts the semicolon on the last line that has content.

Fixes #112

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019StKk4VdpfAZ5cdW5X685e
Groups the two body writers together, and keeps this change from
touching the same lines as the string-literal escaping in #113.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019StKk4VdpfAZ5cdW5X685e
SonarCloud's coverage gate (80% on new code) flagged these two branches
as untested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019StKk4VdpfAZ5cdW5X685e
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 8d2b3b8 into main Sep 26, 2026
12 checks passed
@matt-edmondson
matt-edmondson deleted the fix/splice-multiline-expression-bodies branch September 26, 2026 11:50
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.

Multi-line expression bodies (ExpressionBodyFactory / AccessorKind.Expression) lose indentation on every line after the first

2 participants