format icon indicating copy to clipboard operation
format copied to clipboard

Whitespace formatter flags no-op changes

Open corngood opened this issue 3 years ago • 3 comments

Program.cs

namespace A {

	public class B {
		object a = new();

#if !X
#endif

		public void A() {
		foo();
		}
	}
}

.editorconfig

root = true

[*.cs]
indent_style = tab
csharp_new_line_before_open_brace = none
csharp_new_line_before_else = false
csharp_new_line_before_catch = false
csharp_new_line_before_finally = false

If I run a master build of dotnet-format on this file using whitespace --verify-no-changes, I get this:

Program.cs(4,20): error WHITESPACE: Fix whitespace formatting. Replace 2 characters with '\n\n'. [/home/david/src/golf/tmp/tmp.csproj]
Program.cs(8,1): error WHITESPACE: Fix whitespace formatting. Replace 3 characters with '\n\t\t'. [/home/david/src/golf/tmp/tmp.csproj]
Program.cs(10,3): error WHITESPACE: Fix whitespace formatting. Insert '\t'. [/home/david/src/golf/tmp/tmp.csproj]

If I fix the indentation of foo, I get no errors. The extra errors always seem to indicate no changes.

corngood avatar Oct 18 '22 15:10 corngood

The no-op changes seem to come from roslyn. This change suppresses them for me:

diff --git a/src/Formatters/WhitespaceFormatter.cs b/src/Formatters/WhitespaceFormatter.cs
index b7fecac..57abfe5 100644
--- a/src/Formatters/WhitespaceFormatter.cs
+++ b/src/Formatters/WhitespaceFormatter.cs
@@ -55,7 +55,8 @@ private static async Task<SourceText> GetFormattedDocumentWithDetailedChanges(Do
         {
             var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
             // Since we've already checked that formatable documents support syntax tree, we know the `root` is not null.
-            var formattingTextChanges = Formatter.GetFormattedTextChanges(root!, document.Project.Solution.Workspace, optionSet, cancellationToken);
+            var formattingTextChanges = Formatter.GetFormattedTextChanges(root!, document.Project.Solution.Workspace, optionSet, cancellationToken)
+                .Where(change => sourceText.ToString(change.Span) != change.NewText);
 
             return sourceText.WithChanges(formattingTextChanges);
         }

I'm not sure where the responsibility for this should be.

corngood avatar Oct 18 '22 16:10 corngood

I have exactly the same issue.

airaolagoitia avatar Sep 27 '23 21:09 airaolagoitia

Same here.

jakoblover avatar Nov 09 '23 09:11 jakoblover