Skip to content

C#: Fix AutoFormat corrupting whitespace outside target subtree#7179

Merged
knutwannheden merged 1 commit intomainfrom
fix-autoformat-corrupting-whitespace-in-base-type-lists-and-async-modifiers
Mar 27, 2026
Merged

C#: Fix AutoFormat corrupting whitespace outside target subtree#7179
knutwannheden merged 1 commit intomainfrom
fix-autoformat-corrupting-whitespace-in-base-type-lists-and-async-modifiers

Conversation

@knutwannheden
Copy link
Copy Markdown
Contributor

Motivation

When CSharpTemplate.Rewrite() or AutoFormatVisitor formats a specific subtree (e.g., replacing [Fact] with [Test]), the RoslynFormatter.Format() method corrupts whitespace in unrelated parts of the file. For example:

  • Base type lists: IComparable<TestObj?>, IEquatable<TestObj?>IComparable<TestObj?> , IEquatable<TestObj?>
  • Async modifiers: async Task<RunSummary>async Task<RunSummary>

This happens because MinimumViableSpacingVisitor (MVS) adds spacing artifacts to ensure parseable output, and when reconciling whitespace back, those artifacts leak into nodes outside the formatting target.

Summary

  • Root cause: Format() overwrote cu with the MVS result, so whitespace reconciliation used the MVS-modified tree as the "original" — leaking MVS artifacts into non-target nodes
  • Fix: Save originalCu before MVS, use mvsCu only for printing/Roslyn formatting, reconcile against originalCu. This matches the pattern already used in FormatSpans()
  • Changed file: RoslynFormatter.cs — the Format(cu, targetSubtree, stopAfter) overload

Test plan

  • Added FormatSubtreeDoesNotCorruptUnrelatedWhitespace test with base type lists (nullable generics) and async methods
  • Test exercises both FormatSubtree and Format code paths
  • Asserts full character-level equality (not just substring checks)
  • All 20 AutoFormatTests pass
  • All 50 format-related tests pass

RoslynFormatter.Format() applied MinimumViableSpacingVisitor (MVS) and
overwrote `cu`, so MVS artifacts on nodes outside the target subtree
leaked into the final result during whitespace reconciliation.

Save the original CU before MVS and reconcile against it, matching the
pattern already used in FormatSpans().
@github-project-automation github-project-automation bot moved this to In Progress in OpenRewrite Mar 27, 2026
@knutwannheden knutwannheden changed the title C#: Fix AutoFormat corrupting whitespace outside target subtree C#: Fix AutoFormat corrupting whitespace outside target subtree Mar 27, 2026
@knutwannheden knutwannheden merged commit 00a99a4 into main Mar 27, 2026
1 check passed
@knutwannheden knutwannheden deleted the fix-autoformat-corrupting-whitespace-in-base-type-lists-and-async-modifiers branch March 27, 2026 17:30
@github-project-automation github-project-automation bot moved this from In Progress to Done in OpenRewrite Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant