Skip to content

BRO1108: Parameters should be on the same line or on separate lines

Parameters and arguments are either all on one line or each on its own line. Replaces StyleCop SA1117.

Example

Before

public class Mailer
{
    public void Send(string to, string subject,
        string body)
    {
    }

    public void Welcome(string to)
    {
        Send(
            to,
            "Welcome", "Thanks for signing up.");
    }
}

After

public class Mailer
{
    public void Send(
        string to,
        string subject,
        string body)
    {
    }

    public void Welcome(string to)
    {
        Send(
            to,
            "Welcome",
            "Thanks for signing up.");
    }
}

Why

A list that is half on one line and half on separate lines is hard to scan: you can't tell at a glance how many items there are or which is which. Either layout is fine; mixing them isn't.

What is reported

Like StyleCop, the first two items decide which layout was meant:

  • The first two start on the same line: every item has to start on that line. The first one that doesn't is reported.
  • The first two start on different lines: no item may start on the line where the previous one ends. The first one that does is reported.

An item that spans several lines, like a lambda or a nested call, counts by the line it starts and ends on: M(1, 2, N( then 3)) is fine, since N(...) starts on the first line. An empty () split over lines counts as joined when BRO1116 is on (its fix joins it): N( then ), M(5, 6) is all on one line.

How the fix works

Every item goes on its own line, starting on the line after the opening parenthesis, one level deeper than the line with the parenthesis. The indentation comes from .editorconfig (indent_style, indent_size, tab_width) and defaults to four spaces. Items that already start their line keep their indentation. A moved item's later lines (a lambda's block body) move with it, by the same amount.

The fix never joins lines: a list that spans lines because one item does can't be put on one line, and a list that was split on purpose is usually long.

With stylebro_split_list_first_item = same_line (see BRO1107), or with BRO1107 off (stylebro-migrate init turns it off for code that mixes both forms), a first item on the opening parenthesis's line stays there, and the moved items are indented like the first item that already starts a line (else one level deeper than the line with the parenthesis).

The lists checked are the same as for BRO1107.

Configuration

[*.cs]
# false (default, like StyleCop): a call whose first argument spans lines gets one argument per line.
# true: a first argument that is a multi-line lambda, anonymous method or anonymous object, with the other arguments
# on its closing line, stays as it is (BRO1107 doesn't report it either).
stylebro_allow_leading_multiline_lambda = false

With true, this layout is fine:

context.RegisterSymbolAction(ctx =>
{
    Check(ctx);
}, SymbolKind.Field);

The first argument has to start on the ( line and every other argument on its last line; any other layout of the same call is still reported and fixed as usual. stylebro-migrate init writes true when the repository's code writes such calls (at least 3, all of them below 10, 75 % from 10 on); the migration from StyleCop doesn't (SA1116 and SA1117 report it).

Not reported

  • A comment or directive between the parenthesis and an item, or between items. The fix rewrites exactly those gaps, so it would have to move or drop the comment.
  • Lists with syntax errors.
  • A list with an item that contains a multi-line string (verbatim, raw or interpolated): its text can't be reindented, and splitting Assert.Equal(@"line 1 / line 2", actual) around it scatters the call (found in spreadcheetah).

Compared with StyleCop

StyleCop has no stylebro_allow_leading_multiline_lambda option. With the default, same results as StyleCop, except that StyleCop reports lists with a multi-line string (no fix), and that StyleCop 1.2.0-beta.556 doesn't check record parameters, primary-constructor parameters or a primary constructor's base arguments. StyleCop has no working fix for SA1117; StyleBro's puts each item on its own line, and moves a lambda's block body along with the lambda (StyleCop's fixes leave it behind: #1620, #3183, open).