This is an archive of the discontinued LLVM Phabricator instance.

Extend format with AllowShortEnumsOnASingleLine option
Needs RevisionPublic

Authored by koalo on Nov 16 2018, 4:36 AM.

Details

Summary

Before, clang-format has tried to put enums on a single line whenever possible (unless in styles where the opening brace was put on a seperate line anyway).
AllowShortEnumsOnASingleLine that defaults to true (matching the conventional behaviour) can be set to false to force enums on multiple lines.

This feature is requested from time to time, e.g. here, and should be unobtrusive for users that do not set this option to false.

Diff Detail

Event Timeline

koalo created this revision.Nov 16 2018, 4:36 AM
MyDeveloperDay edited reviewers, added: MyDeveloperDay; removed: rsmith.Nov 12 2019, 12:39 PM
MyDeveloperDay added projects: Restricted Project, Restricted Project.

sorry searching through old issues, are you still interested in this patch?

koalo added a comment.Nov 13 2019, 7:27 AM

sorry searching through old issues, are you still interested in this patch?

Yes, would be nice to have either this or an equivalent possibility that implements the same feature.

I'm thinking this is the same as BraceWrapping.AfterEnum, if you think your use case is covered would you consider Abandoning this revision so we know this functionality exists already, if not let work out what is missing

if (Right.is(TT_InlineASMBrace))
  return Right.HasUnescapedNewline;
if (isAllmanBrace(Left) || isAllmanBrace(Right))
  return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) ||
         (Line.startsWith(tok::kw_typedef, tok::kw_enum) &&
          Style.BraceWrapping.AfterEnum) ||
         (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
         (Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct);
if (Left.is(TT_ObjCBlockLBrace) &&
    Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never)
  return true;
koalo added a comment.Nov 13 2019, 7:58 AM

The difference is that BraceWrapping.AfterEnum also wraps before the brace.

With AfterEnum we have the following

true:
enum X : int
{
  B
};

false:
enum X : int { B };

But what I want is this:

enum X : int {
  B
};

It feels like it should somehow be following BreakBeforeBraces style but understand it might not

koalo added a comment.Nov 13 2019, 8:13 AM

Yes it does not. Therefore, I have followed the same pattern as the the other AllowShort* options.

MyDeveloperDay added a comment.EditedNov 13 2019, 9:19 AM

Yes it does not. Therefore, I have followed the same pattern as the the other AllowShort* options.

I'm not completely sure, but I don't think its quite the same, the AllowShort* options are working on merging simple blocks with tryMergeSimpleBlock(), either small or empty blocks

I think what you are really adding here is "AlwaysBreakAfterEnum" but is there a use case for having

typedef enum Color { Red, Blue, Green }; on one line but
typedef enum Color { Red, Blue, Green, Orange, Purple, Magenta, Cyan, Yellow }; on multiple

i.e. what do we define as "Short" here?

With the following config

---
Language: Cpp
BaseOnStyle: LLVM
BreakBeforeBraces: Custom
BraceWrapping:
    AfterEnum: true

You get (which is the same as GNU and Allman style)

enum
{
  Red,
  Blue,
  Green
} Color;

enum Color
{
  Red,
  Blue,
  Green,
  Orange,
  Purple,
  Magenta,
  Cyan,
  Yellow
};

false, as you said will put them on one line..

If you want the brace cuddled with the enum, like below, then we need something else, either your option or perhaps changing the AfterEnum to be a enum of Alway=true,Never=false,Attach or something like that

enum {
  Red,
  Blue,
  Green
} Color;

It is the "Short" word that seems a little confusing unless we are going to define "Short" as being a certain number of enumerations etc.. and that feels a bit clunky.

For the Attach option, I think we have to tell this above clause to break only for isAllman(Left) and not isAllman(Right) so the newline comes after the { not before.

Could I suggest you rebase,first, then it would be easier to try some stuff out.

But I certainly think your request is really to add the BS_Attach capability to enums without having the entire enum on the same line

Again sorry you had to wait so long, I am trying to work my way through the backlog (but it's going to take some time unless I can get some others to help me especially in getting things reviewed we decide to fix ;-) )

Ironically the LLVM style guide says enumerators should be written out as you requested, but from what I can tell its not actually possible to get that format without this sort of change, do you agree?

koalo updated this revision to Diff 229298.Nov 14 2019, 6:20 AM

Rebased to current master

koalo added a comment.Nov 14 2019, 6:21 AM

Yes, that is at least my understanding. I just rebased to master.

In my understanding, "short" means "put it on a single line if it fits considering the current maximum line length".

Thanks for rebasing, I think this is a good idea I'm just not sure about how the option presents itself, would you consider changing it?

clang/lib/Format/TokenAnnotator.cpp
3109

would you be happy to consider this being something like this instead?

if (isAllmanBrace(Left) && Style.BraceWrapping.AfterEnum == FormatStyle::BWAE_Attach &...

There is now precedent for the BraceWrapping styles to be an enum (see work by @mitchell-stellar who did something similar for AfterControlStylement)

Yes, that is at least my understanding. I just rebased to master.

In my understanding, "short" means "put it on a single line if it fits considering the current maximum line length".

If you are going to use AllowShortEnumsOnASingleLine you need to test it being true and where AfterEnum = true

clang/lib/Format/TokenAnnotator.cpp
3109

I would not recommend making this option an enum. Style.BraceWrapping.AfterControlStatement is a special case since there was a potential readability issue for multi-line control statement conditions. Enums do not suffer from this. I think the option is in line with the other AllowShort*OnASingleLine options.

ok sounds good, @koalo do you have the tests to ensure AfterEnum=true and AllowShortEnumsOnASingleIne=true show on a single line? otherwise perhaps we are already good.

Nit: you should use a full context diff.

MyDeveloperDay requested changes to this revision.Dec 21 2019, 7:36 AM
This revision now requires changes to proceed.Dec 21 2019, 7:36 AM