kbilsted / StatePrinter

Automating unit testing and ToString() coding
Apache License 2.0
93 stars 32 forks source link

Output valid C# #54

Open mikechamberlain opened 6 years ago

mikechamberlain commented 6 years ago

This would be so useful to me... if only it could output valid C# code! Currently, I have to print the object and then mess around with it to get it to compile. This would be such an awesome feature. Obviously cycles could not be supported.

kbilsted commented 6 years ago

Sure. Just create your own output format. The project is quite extensible out of the box.

mikechamberlain commented 6 years ago

Hi Kasper, after your advice I've tried my best to implement a strict C# syntax output formatter but seem to have hit a blocker. I've managed to get it to correctly serialize collections and most other cases, but am stuck with object initializers.

Here is my commit, and if you run the unit tests on my fork you will see the problem:

https://github.com/mikechamberlain/StatePrinter

https://github.com/kbilsted/StatePrinter/pull/55/files

The problem is I can't see how to properly position the comma after an object initializer without looking ahead to the next token. When we initialize the object with default properties, the comma must appear straight after the (),. But, if we need to initialize some fields/properties, then the comma must appear after those inititializations {...},.

Here's the erroneous output I've managed so far - you'll see it's not valid C#.

    steeringWheel = new SteeringWheel(),
// incorrect                           ^
    {
        Size = 3,
        Grip = new FoamGrip(),
        {
            Material = ""Plastic"",
        },
        Weight = 525,
    },
//   ^ correct

I can't think how to make this work without some kind of lookahead. I'm sure I'm doing it wrong so hopefully you can advise me on a better way.

Also there are a couple of obvious hacks in there, and I'm not even sure if strict C# formatting is a suitable goal of your project. Let's discuss this too.

Look forward to working with you.

kbilsted commented 6 years ago

Hi Mike

Great that you took upon yourself the challenge of creating said functionality. Perhaps it is beneficial to change the code such that it needs a look behind instead.

The idea is to never create the separator automatically, instead tell the generator the previous state and then if an element has been generated in an initializer, append a comma and a new line as the first thing.

Let me know if it makes any sense

mikechamberlain commented 6 years ago

Could I perhaps apply a similar strategy to JsonStyle's OptionalComma, which seems to look ahead to the next token before deciding whether to append a comma? Would that make sense here?

https://github.com/kbilsted/StatePrinter/blob/master/StatePrinter/OutputFormatters/JsonStyle.cs#L215

kbilsted commented 6 years ago

Give it a whack;)

kbilsted commented 6 years ago

@mikechamberlain any luck?

mikechamberlain commented 5 years ago

55

kbilsted commented 5 years ago

55 is unfortunatly not finished. Anyone wants to continue from here?