dart-lang / dart_style

An opinionated formatter/linter for Dart code
https://pub.dev/packages/dart_style
BSD 3-Clause "New" or "Revised" License
645 stars 118 forks source link

Optional argument taking multiline closure is indented strangely #568

Closed nex3 closed 1 month ago

nex3 commented 7 years ago

The following code:

void main() {
  var controller = new StreamController<T>(sync: true, onCancel: () {
    return Future.wait(operationSet.map((operation) => operation.cancel()));
  });
}

is formatted as:

void main() {
  var controller = new StreamController<T>(
      sync: true,
      onCancel: () {
        return Future.wait(operationSet.map((operation) => operation.cancel()));
      });
}

This seems substantially worse than the input. Note that it has similar formatting no matter how long the onCancel callback is, which can lead to a lot of unnecessary indentation.

munificent commented 7 years ago

Hmm, this one is surprising. I would expect it to keep your original formatting.

munificent commented 7 years ago

This one is a little tricky. The formatter has special rules to handle functions in argument lists and make them more block-like, for cases like:

method(thing: () {
  ...
}, other: () {
  ...
});

But in some cases applying that style would produce weird output:

method(leadingNamed: arg, 
    another: arg,
    thing: () {
  ...
}, other: () {
  ...
},
    trailingNamed: arg);

Better would be:

method(leadingNamed: arg, 
    another: arg,
    thing: () {
      ...
    }, other: () {
      ...
    },
    trailingNamed: arg);

Ideally, it would decide whether to indent function bodies in cases like this based on whether or not the named arguments needed to split. Unfortunately, that's really hard with how the formatter's internal representation works.

Instead, it has some rules to try to avoid nasty cases like this. In particular, one rule is "if there are named arguments and at least one of them is not a function, don't do special block-like indentation for functions". That's what you're running into here.

I've tried tweaking that rule a few ways, but everything I tried made more code worse than it made better. Leaving this bug open for now.

munificent commented 1 month ago

The forthcoming tall style does a better job here and produces output the same as the original input code. :)