dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.02k stars 4.03k forks source link

Indentation broken for nested object initializers #21192

Open Pilchie opened 7 years ago

Pilchie commented 7 years ago

From: https://developercommunity.visualstudio.com/content/problem/86310/indentation-broken-for-nested-object-initializers.html

Steps to Reproduce: Given:

using System;
using System.Collections.Generic;

public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
    }
}

Copy and paste the below into the body of Main:

Account account = new Account
{
    Email = "james@example.com",
    Active = true,
    CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
    Roles = new List<string>
    {
        "User",
        "Admin"
    }
};

Expected Behavior: Nested object initializer to be indented correctly

Actual Behavior: It isn't. It isn't fixed by Format Document either.

Pilchie commented 7 years ago

Note that not working on Format Document is somewhat by design - we normally aren't prescriptive about where braces for object initializers go (some people indent them by 1 from the parent statement, and some don't).

However, we're supposed to adjust the indentation by the same relative amount that we adjust the containing statement. This goes wrong in this case because there is no leading whitespace in the paste - VS puts the caret in virtual space and paste doesn't move the first line in practice, though the indentation is different than when it is pasted.

Pilchie commented 7 years ago

@heejaechang Do you have a quick idea about where the fix for this would go?

heejaechang commented 7 years ago

I think it should be handled by special rule here. http://source.roslyn.io/#Microsoft.CodeAnalysis.CSharp.EditorFeatures/Formatting/Indentation/CSharpIndentationService.cs,109

but looks like rule for initializer is not there, so it probably currently handled by here. http://source.roslyn.io/#Microsoft.CodeAnalysis.CSharp.EditorFeatures/Formatting/Indentation/CSharpIndentationService.Indenter.cs,290

I think fix should be just adding new rule to http://source.roslyn.io/#Microsoft.CodeAnalysis.CSharp.EditorFeatures/Formatting/Indentation/CSharpIndentationService.cs,109 for initializer expression.

miloush commented 7 years ago

Also see #9702.

kendrahavens commented 5 years ago

Noting that we have additional users hitting this. https://twitter.com/Nick_Craver/status/1115052563668316160

Direct customer quote:

ಠ_ಠ If you format the whole document, that is what that line would do...it's just really weird to do or suggest 1 line at a time. So it is working...it just shouldn't suggest, probably.

Wow, I thought I was the only one. I spent friday tearing about VSCode styling rules to figure out why it was doing this. No such luck.

image image image