This is an archive of the discontinued LLVM Phabricator instance.

[clang-format] Add DefinitionBlockSpacing option
Needs ReviewPublic

Authored by alecto on Aug 19 2022, 11:24 AM.

Details

Summary

Fixes https://github.com/llvm/llvm-project/issues/57180

Given configuration:

SeparateDefinitionBlocks: Always
DefinitionBlockSpacing: 2

Two spaces will be inserted between definition blocks. Code before
formatting:

/// f is a function
void f() {
    // Some code
    // More code
    return;
}
/// g is another function
void g() {
    // Some other code
}

Versus code after formatting:

/// f is a function
void f() {
    // Some code
    // More code
    return;
}
​
​
/// g is another function
void g() {
    // Some other code
}

Note: two zero width spaces were inserted into the commit message in
order to prevent git from removing the additional lines inside the
commit. These will not appear in formatted code.

Diff Detail

Event Timeline

alecto created this revision.Aug 19 2022, 11:24 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 19 2022, 11:24 AM
alecto requested review of this revision.Aug 19 2022, 11:24 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 19 2022, 11:24 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
HazardyKnusperkeks added a project: Restricted Project.

Please run clang/docs/tools/dump_format_style.py.

clang/include/clang/Format/Format.h
3201

This isn't going to land in 15.

3202

Please sort alphabetically.

clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
609
610

Do we want to define the behavior of MaxEmptyLinesToKeep < DefinitionBlockSpacing? Then we need tests for that!
Tests with MaxEmptyLinesToKeep < DefinitionBlockSpacing and initially more than DefinitionBlockSpacing should definitely be there.

alecto updated this revision to Diff 454343.EditedAug 21 2022, 5:22 PM

Revise based on feedback from Björn Schäpers

We updated the version tag to 16 and positioned the DefinitionBLockSpacing field alphabetically. We also updated the documentation with clang/docs/tools/dump_format_style.py

alecto added a comment.EditedAug 21 2022, 5:25 PM

Do we want to define the behavior of MaxEmptyLinesToKeep < DefinitionBlockSpacing? Then we need tests for that!
Tests with MaxEmptyLinesToKeep < DefinitionBlockSpacing and initially more than DefinitionBlockSpacing should definitely be there.

Hello! To clarify, do you mean there should be unit tests for this behavior, or do you mean that there should be checks in clang-format itself that will alert the user if MaxEmptyLinesToKeep < DefinitionBlockSpacing?

Also, is the code in the clang-format examples hand-aligned or is there some tool or script used to align/generate it?

alecto marked 2 inline comments as done.Aug 21 2022, 10:23 PM

Do we want to define the behavior of MaxEmptyLinesToKeep < DefinitionBlockSpacing? Then we need tests for that!
Tests with MaxEmptyLinesToKeep < DefinitionBlockSpacing and initially more than DefinitionBlockSpacing should definitely be there.

Hello! To clarify, do you mean there should be unit tests for this behavior, or do you mean that there should be checks in clang-format itself that will alert the user if MaxEmptyLinesToKeep < DefinitionBlockSpacing?

I ask the open question if the behavior should be defined (in howsoever), then there have to be tests, so we can ensure the behavior doesn't regress. Or if it should be undefined, then we don't need tests, because it can do anything.
I don't know if we can actually warn about such things, but we can error out.

I have no opinion on either variant, I just want it to be discussed.

Also, is the code in the clang-format examples hand-aligned or is there some tool or script used to align/generate it?

You can always just write the code and run the tests, and then take a look at the formatted code and copy-paste it, if it is what you want. That's the way I develop. But the code in the strings has to be put somewhat manually there.

If possible I would like to error out if MaxEmptyLinesToKeep < DefinitionBlockSpacing, because that case is probably a mistake on the part of the user, and a failure would be better than clang-format silently doing something unexpected, but I'm not sure where to put the logic for failure.

Where does clang-format handle style/input validation, and what method does it use for handling errors? (Does it rely on exceptions, or returning a "failure" state of some kind?)

If possible I would like to error out if MaxEmptyLinesToKeep < DefinitionBlockSpacing, because that case is probably a mistake on the part of the user, and a failure would be better than clang-format silently doing something unexpected, but I'm not sure where to put the logic for failure.

Where does clang-format handle style/input validation, and what method does it use for handling errors? (Does it rely on exceptions, or returning a "failure" state of some kind?)

Take a look at https://github.com/llvm/llvm-project/blob/2b8f722e630d0fdf1ca267361866a27c8d4c9387/clang/lib/Format/Format.cpp#L1696

MyDeveloperDay added inline comments.Sep 2 2022, 3:34 AM
clang/docs/ClangFormatStyleOptions.rst
2429

Can you write this not in terms of the code variables and enumerated but in terms of what they put in the .clang-format file

Cloud you include a test that contains multiple levels of nested scope, I'm assuming we won't add an additonal line at every {} level (or will we?)