C#: Fix MaybeAutoFormat no-op when SDK consumed via NuGet PackageReference#7192
Merged
knutwannheden merged 8 commits intomainfrom Mar 29, 2026
Conversation
…lizers Roslyn's Formatter.Format does not expand empty constructor bodies to Allman style when a constructor initializer (`: base(...)`) is present (dotnet/roslyn#82974). This means MaybeAutoFormat produces `Foo() : base() { }` instead of multi-line braces. Work around this in MinimumViableSpacingVisitor by inserting newlines into empty method body blocks that have a constructor initializer and Space.Empty prefix/end, so the printed source has multi-line braces that Roslyn can then indent correctly.
…rence AdhocWorkspace relies on Assembly.Load to discover Microsoft.CodeAnalysis.CSharp.Workspaces via the .NET dependency graph. When the OpenRewrite SDK is consumed with PrivateAssets="all", the dependency entries are absent from the consumer's .deps.json, so Assembly.Load fails silently and MEF cannot discover the C# formatting services — making Formatter.Format a no-op. Fix by explicitly providing the already-loaded Roslyn assemblies to MefHostServices.Create, bypassing the Assembly.Load discovery path.
…ces-no-indentation-in-local-rewritetest-non-rpc
…sumers Test dependencies (xunit, coverlet, Microsoft.NET.Test.Sdk, etc.) were flowing to NuGet package consumers because they lacked PrivateAssets="all". This could interfere with assembly resolution in consuming projects.
bc8c5aa to
430ecc7
Compare
…ces-no-indentation-in-local-rewritetest-non-rpc # Conflicts: # rewrite-csharp/csharp/OpenRewrite/OpenRewrite.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Three issues with
MaybeAutoFormatin the C# SDK:Formatter.Formatdoes not expandConstructor() : base(){}to Allman-style multi-line braces (dotnet/roslyn#82974)AdhocWorkspacecannot discoverMicrosoft.CodeAnalysis.CSharp.WorkspacesviaAssembly.Loadwhen consumed withPrivateAssets="all", making the Roslyn formatter a silent no-opWhitespaceReconcilerdetects a structural mismatch (e.g., recipe usesIdentifier("string")where the parser producesPrimitive), it silently returns the original tree, making formatting bugs extremely hard to diagnoseSummary
MinimumViableSpacingVisitorby inserting newlines into empty constructor body blocks that have a constructor initializer andSpace.Emptyprefix/endAdhocWorkspaceassembly discovery by explicitly providing already-loaded Roslyn assemblies toMefHostServices.Createxunit,coverlet,Microsoft.NET.Test.Sdk, etc.) asPrivateAssets="all"to prevent leaking to NuGet consumersWhitespaceReconciler: whenThrowOnMismatchDefaultis true (set byRewriteTest), collects up to 5 mismatches with property paths and throwsWhitespaceReconcileMismatchExceptionTest plan
AutoFormatEmptyConstructorBodyWithInitializer— Allman-style braces for constructors with initializersMaybeAutoFormatAtClassLevelWithSynthesizedConstructor— end-to-end recipe testFormatSpansReconcilerAppliesFormattingToSynthesizedNodes— direct FormatSpans pipeline testReconcilerMismatchReportsPropertyPath— verifies exception contains property path on type mismatch