Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang-format] change format for constructor init and switch/case indent #16701

Merged

Conversation

phunkyfish
Copy link
Contributor

@phunkyfish phunkyfish commented Oct 2, 2019

Description

Proposing a new format for constructor init lists. Colon on newline and break after comma for longer lines.

For Short lines is would look like this having everything on one line (a short line is defined by the ColumnLimit in .clang_format, current value is 100:

CPVRChannelGroupInternal::CPVRChannelGroupInternal(bool bRadio) : m_iHiddenChannels(0)
{
}

And for longer lines:

CPVRChannelGroup::CPVRChannelGroup(bool bRadio,
                                   int iGroupId,
                                   const std::string& strGroupName,
                                   const std::shared_ptr<CPVRChannelGroup>& allChannelsGroup)
    : m_bRadio(bRadio),
      m_iGroupId(iGroupId),
      m_strGroupName(strGroupName),
      m_allChannelsGroup(allChannelsGroup)
{
  OnInit();
}

Also proposing an indent for switch/case statements:

switch (m_vecCuts[i].action)
{
  case CUT:
    cutCount++;
    break;
  case MUTE:
    muteCount++;
    break;
  case COMM_BREAK:
    commBreakCount++;
    break;
}

Also updated wording for c++14 usage.

Motivation and Context

The current format does not read well and is a bit ugly.

E.g.:

CPVRChannelGroup::CPVRChannelGroup(bool bRadio,
                                   int iGroupId,
                                   const std::string& strGroupName,
                                   const std::shared_ptr<CPVRChannelGroup>& allChannelsGroup)
    : m_bRadio(bRadio)
    , m_iGroupId(iGroupId)
    , m_strGroupName(strGroupName)
    , m_allChannelsGroup(allChannelsGroup)
{
  OnInit();
}

Same goes for switch/case:

switch (m_vecCuts[i].action)
{
case CUT:
  cutCount++;
  break;
case MUTE:
  muteCount++;
  break;
case COMM_BREAK:
  commBreakCount++;
  break;
}

How Has This Been Tested?

Screenshots (if appropriate):

Types of change

  • Bug fix (non-breaking change which fixes an issue)
  • Clean up (non-breaking change which removes non-working, unmaintained functionality)
  • Improvement (non-breaking change which improves existing functionality)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that will cause existing functionality to change)
  • Cosmetic change (non-breaking change that doesn't touch code)
  • None of the above (please explain below)

Checklist:

  • My code follows the Code Guidelines of this project
  • My change requires a change to the documentation, either Doxygen or wiki
  • I have updated the documentation accordingly
  • I have read the Contributing document
  • I have added tests to cover my change
  • All new and existing tests passed

@phunkyfish phunkyfish requested review from Rechi and ksooo October 2, 2019 17:02
@phunkyfish phunkyfish changed the title [clang-format] change constructor init list to colon on newline, brea… [clang-format] change format for constructor init and switch/case indent Oct 4, 2019
@phunkyfish phunkyfish force-pushed the clang-format-constructor-init-list branch from f6e339b to b7825d1 Compare October 4, 2019 15:01
Copy link
Member

@ksooo ksooo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking this up.

docs/CODE_GUIDELINES.md Outdated Show resolved Hide resolved
docs/CODE_GUIDELINES.md Outdated Show resolved Hide resolved
@ksooo ksooo added Component: Build Documentation Type: Improvement non-breaking change which improves existing functionality v19 Matrix labels Oct 4, 2019
@ksooo ksooo added this to the Matrix 19.0-alpha 1 milestone Oct 4, 2019
@phunkyfish phunkyfish force-pushed the clang-format-constructor-init-list branch from b7825d1 to b3eea1f Compare October 4, 2019 17:34
@phunkyfish
Copy link
Contributor Author

Ok, updated as per review.

Copy link
Member

@ksooo ksooo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@phunkyfish phunkyfish force-pushed the clang-format-constructor-init-list branch from b3eea1f to 45470ae Compare October 4, 2019 19:51
@AlwinEsch AlwinEsch self-requested a review October 4, 2019 22:39
Copy link
Member

@AlwinEsch AlwinEsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks for me better too.

docs/CODE_GUIDELINES.md Outdated Show resolved Hide resolved
: m_bBoolArg(bBoolArg),
m_iIntegerArg(iIntegerArg),
m_strSomeText(strSomeText),
m_myOtherClass(myOtherClass)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I like the following style (BreakConstructorInitializers: BeforeComma) is that in most cases it doesn't touch the previous line to add a comma if another initializer is added. If the majority prefers to keep the comma on the previous line that's okay for me.

MyClass::CMyClass(bool bBoolArg,
                  int iIntegerArg,
                  const std::string& strSomeText,
                  const std::shared_ptr<CMyOtherClass>& myOtherClass)
  : m_bBoolArg(bBoolArg)
  , m_iIntegerArg(iIntegerArg)
  , m_strSomeText(strSomeText)
  , m_myOtherClass(myOtherClass)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is "doesn't touch the previous line to add a comma if another initializer is added" really worth this very special formatting style? My personal opinion: It's not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is it "very special"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only my personal feeling, which got inspired from other C++ projects I know.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Rechi has a good point about keeping line history clean. However, I'm also with ksooo on this specific case, where I feel the leading comma is ugly enough to warrant an exception to the clean line mantra.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I strongly prefer the leading comma because it provides much cleaner diffs.

docs/CODE_GUIDELINES.md Outdated Show resolved Hide resolved
@Paxxi
Copy link
Member

Paxxi commented Oct 5, 2019

The original clang-format was designed to minimize the formatting changes it would do to existing code.
If we're ok with larger changes being made then I don't see any real issue with these changes.

I personally prefer the comma before format as it lines up nicely with the colon. It also has the nice property of not touching the previous line when changing something.

If there's consensus on this style then go for it 😀

@ksooo
Copy link
Member

ksooo commented Oct 5, 2019

If we're ok with larger changes being made then I don't see any real issue with these changes.

👍

@phunkyfish
Copy link
Contributor Author

I can also update for guidelines for cpp14 as we support since #13034, right?

@phunkyfish phunkyfish force-pushed the clang-format-constructor-init-list branch from 45470ae to 268e698 Compare October 5, 2019 15:06
@phunkyfish
Copy link
Contributor Author

phunkyfish commented Oct 5, 2019

Changed wording around c++14 usage and updated additional review points raised.

docs/CODE_GUIDELINES.md Outdated Show resolved Hide resolved
@Paxxi
Copy link
Member

Paxxi commented Oct 5, 2019

BTW did you know that git blame has an ignore revision option? I found this out recently and I think it could help getting over the reluctance to clean up the whole repos formatting.

It could be done manually or we could add a file that lists cosmetic revisions that one can point to to ignore them

@phunkyfish
Copy link
Contributor Author

@Paxxi if the git blame option could be set on a repo level that would be cool.

@phunkyfish phunkyfish force-pushed the clang-format-constructor-init-list branch from 268e698 to c6e1ff6 Compare October 5, 2019 17:21
@Paxxi
Copy link
Member

Paxxi commented Oct 5, 2019

It can't afaik. Best we can do is include a file with the commits and then tell people to make an alias or manually use

--ignore-revs-file <file>
Ignore revisions listed in file, which must be in the same format as an fsck.skipList. This option may be repeated, and these files will be processed after any files specified with the blame.ignoreRevsFile config option. An empty file name, "", will clear the list of revs from previously processed files.

## 10. Other conventions
### 11.6. Constructor Initialzation Lists

For lines up to length `ColumnLimit` (in `.clang-format`) everything will be on one line, excluding the braces which must be on the following lines.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now one has to open another file to get the value of ColumnLimit. Why not add the maximum line length to the code guidelines?
From where to where is the number of characters actually counted to compare with ColumnLimit?
Will the maximum line length be only used to decide if the everything goes into one line for constructors and ignored everywhere else?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it matter to spend effort on the coding guidelines that touches formatting?

Nobody should have to care about reading it or thinking about the formatting.

The columnlimit is currently 100. I find it's a decent line length while still fitting two editors side by side on a 1080p screen for diffs. It does cause issues with trailing comments because clang-format doesn't know how to break a comment and does unnatural formatting to fit the comment.

The columnlimit is from 0-100, it doesn't care about indentation and such and is applied everywhere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could state in Section 1 what the columnlimit is and where it's applied. Then the constructor section can remain clean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, definition of line length at start of formatting section now.

@phunkyfish phunkyfish force-pushed the clang-format-constructor-init-list branch from c6e1ff6 to 1eeec97 Compare October 6, 2019 08:11
Copy link
Member

@yol yol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mostly indifferent. The current style is (in the cited points) not inferior to me, but I won't stand in the way if people have a strong opinion/preference.

A thing I don't particularly like is the putting everything on one line thing. It makes it a tiny bit harder to see that a constructor initialization is taking place (since it is at the end of the line some times and in the next line other times).

@phunkyfish
Copy link
Contributor Author

That’s a fair point. This is what I aimed for initially however it’s doesn’t appear to be possible with the current version of clang-format.

@ksooo
Copy link
Member

ksooo commented Oct 6, 2019

The current style is (in the cited points) not inferior to me, but I won't stand in the way if people have a strong opinion/preference.

Thanks for that.

A thing I don't particularly like is the putting everything on one line thing.

Same here, but as @phunkyfish said currently not possible with clang-format.

@phunkyfish
Copy link
Contributor Author

Will merge this tomorrow night unless there are any objections.

@phunkyfish phunkyfish merged commit 2be8b24 into xbmc:master Oct 9, 2019
@phunkyfish phunkyfish deleted the clang-format-constructor-init-list branch October 9, 2019 12:53
@garbear
Copy link
Member

garbear commented Oct 10, 2019

I think this PR is the right approach. Thanks @phunkyfish!

@AlwinEsch
Copy link
Member

AlwinEsch commented Oct 19, 2019

One thing I have to say, unfortunately, which brings a little confused.
Is about value setting in single line. In the context of the example given above, full OK (if one value is set).

Only at the moment clang-format jumps pretty much back and forth between the lines.

e.g.:

MyClass::CMyClass(bool bBoolArg,
                  int iIntegerArg,
                  const std::string& strSomeText,
                  const std::shared_ptr<CMyOtherClass>& myOtherClass)
  : m_bBoolArg(bBoolArg),
    m_iIntegerArg(iIntegerArg),
    m_strSomeText(strSomeText),
    m_myOtherClass(myOtherClass)
{
}

becomes by one value removal, changed to:

MyClass::CMyClass(bool bBoolArg,
                  int iIntegerArg,
                  const std::string& strSomeText,
                  const std::shared_ptr<CMyOtherClass>& myOtherClass)
  : m_bBoolArg(bBoolArg), m_iIntegerArg(iIntegerArg), m_strSomeText(strSomeText)
{
}

Would the one-line also refer to the fact that it is only one value and is together with the rest in a row, would be OK (thats why accepted before).

MyClass::CMyClass(bool bBoolArg) : m_bArg(bBoolArg)
{
}

Only with more than one would be always better like this:

MyClass::CMyClass(bool bBoolArg, int iIntegerArg) 
  : m_bArg(bBoolArg), 
    m_iArg(iIntegerArg)
{
}

@Rechi
Copy link
Member

Rechi commented Nov 24, 2019

@AlwinEsch clang-format 9 and newer have a new option, AllowAllConstructorInitializersOnNextLine, which makes your expected style possible.
see https://clang.llvm.org/docs/ClangFormatStyleOptions.html

@phunkyfish
Copy link
Contributor Author

phunkyfish commented Nov 24, 2019

This is a good improvement. However something like this would still be possible:

MyClass::CMyClass(bool bBoolArg, int iIntegerArg) : m_bArg(bArg), m_iArg(iArg)
{
}

Happy to PR this tomorrow. No changes would be required to the docs as this addition will make what's in the doc true always.

Nice find @Rechi.

@phunkyfish
Copy link
Contributor Author

PR: #16962

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Build Documentation Type: Improvement non-breaking change which improves existing functionality v19 Matrix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants