Revert "[clang-format] Add AlignConsecutiveShortCaseStatements"

This reverts commit 4ba00844174db562d2bd8b15dab6aac605eddf57.
This commit is contained in:
Owen Pan 2023-07-24 18:36:53 -07:00
parent 1a3da0bc1e
commit 87ad34ffdc
8 changed files with 19 additions and 569 deletions

View File

@ -789,104 +789,6 @@ the configuration (without a prefix: ``Auto``).
bbb >>= 2;
.. _AlignConsecutiveShortCaseStatements:
**AlignConsecutiveShortCaseStatements** (``ShortCaseStatementsAlignmentStyle``) :versionbadge:`clang-format 17` :ref:`¶ <AlignConsecutiveShortCaseStatements>`
Style of aligning consecutive short case labels.
Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``.
.. code-block:: yaml
# Example of usage:
AlignConsecutiveShortCaseStatements:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignCaseColons: false
Nested configuration flags:
Alignment options.
* ``bool Enabled`` Whether aligning is enabled.
.. code-block:: c++
true:
switch (level) {
case log::info: return "info:";
case log::warning: return "warning:";
default: return "";
}
false:
switch (level) {
case log::info: return "info:";
case log::warning: return "warning:";
default: return "";
}
* ``bool AcrossEmptyLines`` Whether to align across empty lines.
.. code-block:: c++
true:
switch (level) {
case log::info: return "info:";
case log::warning: return "warning:";
default: return "";
}
false:
switch (level) {
case log::info: return "info:";
case log::warning: return "warning:";
default: return "";
}
* ``bool AcrossComments`` Whether to align across comments.
.. code-block:: c++
true:
switch (level) {
case log::info: return "info:";
case log::warning: return "warning:";
/* A comment. */
default: return "";
}
false:
switch (level) {
case log::info: return "info:";
case log::warning: return "warning:";
/* A comment. */
default: return "";
}
* ``bool AlignCaseColons`` Whether aligned case labels are aligned on the colon, or on the
, or on the tokens after the colon.
.. code-block:: c++
true:
switch (level) {
case log::info : return "info:";
case log::warning: return "warning:";
default : return "";
}
false:
switch (level) {
case log::info: return "info:";
case log::warning: return "warning:";
default: return "";
}
.. _AlignEscapedNewlines:
**AlignEscapedNewlines** (``EscapedNewlineAlignmentStyle``) :versionbadge:`clang-format 5` :ref:`¶ <AlignEscapedNewlines>`

View File

@ -988,8 +988,6 @@ clang-format
- Add ``KeepEmptyLinesAtEOF`` to keep empty lines at end of file.
- Add ``RemoveParentheses`` to remove redundant parentheses.
- Add ``TypeNames`` to treat listed non-keyword identifiers as type names.
- Add ``AlignConsecutiveShortCaseStatements`` which can be used to align case
labels in conjunction with ``AllowShortCaseLabelsOnASingleLine``.
libclang
--------

View File

@ -299,103 +299,6 @@ struct FormatStyle {
/// \version 3.8
AlignConsecutiveStyle AlignConsecutiveDeclarations;
/// Alignment options.
///
struct ShortCaseStatementsAlignmentStyle {
/// Whether aligning is enabled.
/// \code
/// true:
/// switch (level) {
/// case log::info: return "info:";
/// case log::warning: return "warning:";
/// default: return "";
/// }
///
/// false:
/// switch (level) {
/// case log::info: return "info:";
/// case log::warning: return "warning:";
/// default: return "";
/// }
/// \endcode
bool Enabled;
/// Whether to align across empty lines.
/// \code
/// true:
/// switch (level) {
/// case log::info: return "info:";
/// case log::warning: return "warning:";
///
/// default: return "";
/// }
///
/// false:
/// switch (level) {
/// case log::info: return "info:";
/// case log::warning: return "warning:";
///
/// default: return "";
/// }
/// \endcode
bool AcrossEmptyLines;
/// Whether to align across comments.
/// \code
/// true:
/// switch (level) {
/// case log::info: return "info:";
/// case log::warning: return "warning:";
/// /* A comment. */
/// default: return "";
/// }
///
/// false:
/// switch (level) {
/// case log::info: return "info:";
/// case log::warning: return "warning:";
/// /* A comment. */
/// default: return "";
/// }
/// \endcode
bool AcrossComments;
/// Whether aligned case labels are aligned on the colon, or on the
/// , or on the tokens after the colon.
/// \code
/// true:
/// switch (level) {
/// case log::info : return "info:";
/// case log::warning: return "warning:";
/// default : return "";
/// }
///
/// false:
/// switch (level) {
/// case log::info: return "info:";
/// case log::warning: return "warning:";
/// default: return "";
/// }
/// \endcode
bool AlignCaseColons;
bool operator==(const ShortCaseStatementsAlignmentStyle &R) const {
return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines &&
AcrossComments == R.AcrossComments &&
AlignCaseColons == R.AlignCaseColons;
}
};
/// Style of aligning consecutive short case labels.
/// Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``.
///
/// \code{.yaml}
/// # Example of usage:
/// AlignConsecutiveShortCaseStatements:
/// Enabled: true
/// AcrossEmptyLines: true
/// AcrossComments: true
/// AlignCaseColons: false
/// \endcode
/// \version 17
ShortCaseStatementsAlignmentStyle AlignConsecutiveShortCaseStatements;
/// Different styles for aligning escaped newlines.
enum EscapedNewlineAlignmentStyle : int8_t {
/// Don't align escaped newlines.
@ -4454,8 +4357,6 @@ struct FormatStyle {
AlignConsecutiveBitFields == R.AlignConsecutiveBitFields &&
AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations &&
AlignConsecutiveMacros == R.AlignConsecutiveMacros &&
AlignConsecutiveShortCaseStatements ==
R.AlignConsecutiveShortCaseStatements &&
AlignEscapedNewlines == R.AlignEscapedNewlines &&
AlignOperands == R.AlignOperands &&
AlignTrailingComments == R.AlignTrailingComments &&

View File

@ -111,17 +111,6 @@ template <> struct MappingTraits<FormatStyle::AlignConsecutiveStyle> {
}
};
template <>
struct MappingTraits<FormatStyle::ShortCaseStatementsAlignmentStyle> {
static void mapping(IO &IO,
FormatStyle::ShortCaseStatementsAlignmentStyle &Value) {
IO.mapOptional("Enabled", Value.Enabled);
IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);
IO.mapOptional("AcrossComments", Value.AcrossComments);
IO.mapOptional("AlignCaseColons", Value.AlignCaseColons);
}
};
template <>
struct ScalarEnumerationTraits<FormatStyle::AttributeBreakingStyle> {
static void enumeration(IO &IO, FormatStyle::AttributeBreakingStyle &Value) {
@ -868,8 +857,6 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("AlignConsecutiveDeclarations",
Style.AlignConsecutiveDeclarations);
IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
IO.mapOptional("AlignConsecutiveShortCaseStatements",
Style.AlignConsecutiveShortCaseStatements);
IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
IO.mapOptional("AlignOperands", Style.AlignOperands);
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
@ -1346,7 +1333,6 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AlignConsecutiveBitFields = {};
LLVMStyle.AlignConsecutiveDeclarations = {};
LLVMStyle.AlignConsecutiveMacros = {};
LLVMStyle.AlignConsecutiveShortCaseStatements = {};
LLVMStyle.AlignTrailingComments = {};
LLVMStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Always;
LLVMStyle.AlignTrailingComments.OverEmptyLines = 0;

View File

@ -102,7 +102,6 @@ const tooling::Replacements &WhitespaceManager::generateReplacements() {
llvm::sort(Changes, Change::IsBeforeInFile(SourceMgr));
calculateLineBreakInformation();
alignConsecutiveMacros();
alignConsecutiveShortCaseStatements();
alignConsecutiveDeclarations();
alignConsecutiveBitFields();
alignConsecutiveAssignments();
@ -676,12 +675,14 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
//
// We need to adjust the StartOfTokenColumn of each Change that is on a line
// containing any matching token to be aligned and located after such token.
static void AlignMatchingTokenSequence(
static void AlignMacroSequence(
unsigned &StartOfSequence, unsigned &EndOfSequence, unsigned &MinColumn,
std::function<bool(const WhitespaceManager::Change &C)> Matches,
unsigned &MaxColumn, bool &FoundMatchOnLine,
std::function<bool(const WhitespaceManager::Change &C)> AlignMacrosMatches,
SmallVector<WhitespaceManager::Change, 16> &Changes) {
if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) {
bool FoundMatchOnLine = false;
FoundMatchOnLine = false;
int Shift = 0;
for (unsigned I = StartOfSequence; I != EndOfSequence; ++I) {
@ -692,8 +693,8 @@ static void AlignMatchingTokenSequence(
// If this is the first matching token to be aligned, remember by how many
// spaces it has to be shifted, so the rest of the changes on the line are
// shifted by the same amount.
if (!FoundMatchOnLine && Matches(Changes[I])) {
// shifted by the same amount
if (!FoundMatchOnLine && AlignMacrosMatches(Changes[I])) {
FoundMatchOnLine = true;
Shift = MinColumn - Changes[I].StartOfTokenColumn;
Changes[I].Spaces += Shift;
@ -707,6 +708,7 @@ static void AlignMatchingTokenSequence(
}
MinColumn = 0;
MaxColumn = UINT_MAX;
StartOfSequence = 0;
EndOfSequence = 0;
}
@ -745,6 +747,7 @@ void WhitespaceManager::alignConsecutiveMacros() {
};
unsigned MinColumn = 0;
unsigned MaxColumn = UINT_MAX;
// Start and end of the token sequence we're processing.
unsigned StartOfSequence = 0;
@ -772,8 +775,8 @@ void WhitespaceManager::alignConsecutiveMacros() {
!(LineIsComment && Style.AlignConsecutiveMacros.AcrossComments);
if (EmptyLineBreak || NoMatchBreak) {
AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
AlignMacrosMatches, Changes);
AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
FoundMatchOnLine, AlignMacrosMatches, Changes);
}
// A new line starts, re-initialize line status tracking bools.
@ -793,12 +796,18 @@ void WhitespaceManager::alignConsecutiveMacros() {
StartOfSequence = I;
unsigned ChangeMinColumn = Changes[I].StartOfTokenColumn;
int LineLengthAfter = -Changes[I].Spaces;
for (unsigned j = I; j != E && Changes[j].NewlinesBefore == 0; ++j)
LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength;
unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
MinColumn = std::max(MinColumn, ChangeMinColumn);
MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
}
EndOfSequence = I;
AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
AlignMacrosMatches, Changes);
AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
FoundMatchOnLine, AlignMacrosMatches, Changes);
}
void WhitespaceManager::alignConsecutiveAssignments() {
@ -854,110 +863,6 @@ void WhitespaceManager::alignConsecutiveBitFields() {
Changes, /*StartAt=*/0, Style.AlignConsecutiveBitFields);
}
void WhitespaceManager::alignConsecutiveShortCaseStatements() {
if (!Style.AlignConsecutiveShortCaseStatements.Enabled ||
!Style.AllowShortCaseLabelsOnASingleLine) {
return;
}
auto Matches = [&](const Change &C) {
if (Style.AlignConsecutiveShortCaseStatements.AlignCaseColons)
return C.Tok->is(TT_CaseLabelColon);
// Ignore 'IsInsideToken' to allow matching trailing comments which
// need to be reflowed as that causes the token to appear in two
// different changes, which will cause incorrect alignment as we'll
// reflow early due to detecting multiple aligning tokens per line.
return !C.IsInsideToken && C.Tok->Previous &&
C.Tok->Previous->is(TT_CaseLabelColon);
};
unsigned MinColumn = 0;
// Empty case statements don't break the alignment, but don't necessarily
// match our predicate, so we need to track their column so they can push out
// our alignment.
unsigned MinEmptyCaseColumn = 0;
// Start and end of the token sequence we're processing.
unsigned StartOfSequence = 0;
unsigned EndOfSequence = 0;
// Whether a matching token has been found on the current line.
bool FoundMatchOnLine = false;
bool LineIsComment = true;
bool LineIsEmptyCase = false;
unsigned I = 0;
for (unsigned E = Changes.size(); I != E; ++I) {
if (Changes[I].NewlinesBefore != 0) {
// Whether to break the alignment sequence because of an empty line.
bool EmptyLineBreak =
(Changes[I].NewlinesBefore > 1) &&
!Style.AlignConsecutiveShortCaseStatements.AcrossEmptyLines;
// Whether to break the alignment sequence because of a line without a
// match.
bool NoMatchBreak =
!FoundMatchOnLine &&
!(LineIsComment &&
Style.AlignConsecutiveShortCaseStatements.AcrossComments) &&
!LineIsEmptyCase;
if (EmptyLineBreak || NoMatchBreak) {
AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
Matches, Changes);
MinEmptyCaseColumn = 0;
}
// A new line starts, re-initialize line status tracking bools.
FoundMatchOnLine = false;
LineIsComment = true;
LineIsEmptyCase = false;
}
if (Changes[I].Tok->isNot(tok::comment))
LineIsComment = false;
if (Changes[I].Tok->is(TT_CaseLabelColon)) {
LineIsEmptyCase =
!Changes[I].Tok->Next || Changes[I].Tok->Next->isTrailingComment();
if (LineIsEmptyCase) {
if (Style.AlignConsecutiveShortCaseStatements.AlignCaseColons) {
MinEmptyCaseColumn =
std::max(MinEmptyCaseColumn, Changes[I].StartOfTokenColumn);
} else {
MinEmptyCaseColumn =
std::max(MinEmptyCaseColumn, Changes[I].StartOfTokenColumn + 2);
}
}
}
if (!Matches(Changes[I]))
continue;
if (LineIsEmptyCase)
continue;
FoundMatchOnLine = true;
if (StartOfSequence == 0)
StartOfSequence = I;
EndOfSequence = I + 1;
MinColumn = std::max(MinColumn, Changes[I].StartOfTokenColumn);
// Allow empty case statements to push out our alignment.
MinColumn = std::max(MinColumn, MinEmptyCaseColumn);
}
AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
Changes);
}
void WhitespaceManager::alignConsecutiveDeclarations() {
if (!Style.AlignConsecutiveDeclarations.Enabled)
return;

View File

@ -232,9 +232,6 @@ private:
/// Align consecutive declarations over all \c Changes.
void alignChainedConditionals();
/// Align consecutive short case statements over all \c Changes.
void alignConsecutiveShortCaseStatements();
/// Align trailing comments over all \c Changes.
void alignTrailingComments();

View File

@ -195,11 +195,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
CHECK_PARSE_BOOL(VerilogBreakBetweenInstancePorts);
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, Enabled);
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements,
AcrossEmptyLines);
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AcrossComments);
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseColons);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterEnum);

View File

@ -19261,240 +19261,6 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
BracedAlign);
}
TEST_F(FormatTest, AlignConsecutiveShortCaseStatements) {
FormatStyle Alignment = getLLVMStyle();
Alignment.AllowShortCaseLabelsOnASingleLine = true;
Alignment.AlignConsecutiveShortCaseStatements.Enabled = true;
verifyFormat("switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning: return \"warning\";\n"
"default: return \"default\";\n"
"}",
Alignment);
verifyFormat("switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning: return \"warning\";\n"
"}",
"switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning:\n"
" return \"warning\";\n"
"}",
Alignment);
// Empty case statements push out the alignment, but non-short case labels
// don't.
verifyFormat("switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::critical:\n"
"case log::warning:\n"
"case log::severe: return \"severe\";\n"
"case log::extra_severe:\n"
" // comment\n"
" return \"extra_severe\";\n"
"}",
Alignment);
// Verify comments and empty lines break the alignment.
verifyNoChange("switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning: return \"warning\";\n"
"// comment\n"
"case log::critical: return \"critical\";\n"
"default: return \"default\";\n"
"\n"
"case log::severe: return \"severe\";\n"
"}",
Alignment);
// Empty case statements don't break the alignment, and potentially push it
// out.
verifyFormat("switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning:\n"
"case log::critical:\n"
"default: return \"default\";\n"
"}",
Alignment);
// Implicit fallthrough cases can be aligned with either a comment or
// [[fallthrough]]
verifyFormat("switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning: // fallthrough\n"
"case log::error: return \"error\";\n"
"case log::critical: /*fallthrough*/\n"
"case log::severe: return \"severe\";\n"
"case log::diag: [[fallthrough]];\n"
"default: return \"default\";\n"
"}",
Alignment);
// Verify trailing comment that needs a reflow also gets aligned properly.
verifyFormat("switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning: // fallthrough\n"
"case log::error: return \"error\";\n"
"}",
"switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning: //fallthrough\n"
"case log::error: return \"error\";\n"
"}",
Alignment);
// Verify adjacent non-short case statements don't change the alignment, and
// properly break the set of consecutive statements.
verifyFormat("switch (level) {\n"
"case log::critical:\n"
" // comment\n"
" return \"critical\";\n"
"case log::info: return \"info\";\n"
"case log::warning: return \"warning\";\n"
"default:\n"
" // comment\n"
" return \"\";\n"
"case log::error: return \"error\";\n"
"case log::severe: return \"severe\";\n"
"case log::extra_critical:\n"
" // comment\n"
" return \"extra critical\";\n"
"}",
Alignment);
Alignment.SpaceBeforeCaseColon = true;
verifyFormat("switch (level) {\n"
"case log::info : return \"info\";\n"
"case log::warning : return \"warning\";\n"
"default : return \"default\";\n"
"}",
Alignment);
Alignment.SpaceBeforeCaseColon = false;
// Make sure we don't incorrectly align correctly across nested switch cases.
verifyFormat("switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning: return \"warning\";\n"
"case log::other:\n"
" switch (sublevel) {\n"
" case log::info: return \"info\";\n"
" case log::warning: return \"warning\";\n"
" }\n"
" break;\n"
"case log::error: return \"error\";\n"
"default: return \"default\";\n"
"}",
"switch (level) {\n"
"case log::info: return \"info\";\n"
"case log::warning: return \"warning\";\n"
"case log::other: switch (sublevel) {\n"
" case log::info: return \"info\";\n"
" case log::warning: return \"warning\";\n"
"}\n"
"break;\n"
"case log::error: return \"error\";\n"
"default: return \"default\";\n"
"}",
Alignment);
Alignment.AlignConsecutiveShortCaseStatements.AcrossEmptyLines = true;
verifyFormat("switch (level) {\n"
"case log::info: return \"info\";\n"
"\n"
"case log::warning: return \"warning\";\n"
"}",
"switch (level) {\n"
"case log::info: return \"info\";\n"
"\n"
"case log::warning: return \"warning\";\n"
"}",
Alignment);
Alignment.AlignConsecutiveShortCaseStatements.AcrossComments = true;
verifyNoChange("switch (level) {\n"
"case log::info: return \"info\";\n"
"\n"
"/* block comment */\n"
"\n"
"// line comment\n"
"case log::warning: return \"warning\";\n"
"}",
Alignment);
Alignment.AlignConsecutiveShortCaseStatements.AcrossEmptyLines = false;
verifyFormat("switch (level) {\n"
"case log::info: return \"info\";\n"
"//\n"
"case log::warning: return \"warning\";\n"
"}",
Alignment);
Alignment.AlignConsecutiveShortCaseStatements.AlignCaseColons = true;
verifyFormat("switch (level) {\n"
"case log::info : return \"info\";\n"
"case log::warning: return \"warning\";\n"
"default : return \"default\";\n"
"}",
Alignment);
// With AlignCaseColons, empty case statements don't break alignment of
// consecutive case statements (and are aligned).
verifyFormat("switch (level) {\n"
"case log::info : return \"info\";\n"
"case log::warning :\n"
"case log::critical:\n"
"default : return \"default\";\n"
"}",
Alignment);
// Final non-short case labels shouldn't have their colon aligned
verifyFormat("switch (level) {\n"
"case log::info : return \"info\";\n"
"case log::warning :\n"
"case log::critical:\n"
"case log::severe : return \"severe\";\n"
"default:\n"
" // comment\n"
" return \"default\";\n"
"}",
Alignment);
// Verify adjacent non-short case statements break the set of consecutive
// alignments and aren't aligned with adjacent non-short case statements if
// AlignCaseColons is set.
verifyFormat("switch (level) {\n"
"case log::critical:\n"
" // comment\n"
" return \"critical\";\n"
"case log::info : return \"info\";\n"
"case log::warning: return \"warning\";\n"
"default:\n"
" // comment\n"
" return \"\";\n"
"case log::error : return \"error\";\n"
"case log::severe: return \"severe\";\n"
"case log::extra_critical:\n"
" // comment\n"
" return \"extra critical\";\n"
"}",
Alignment);
Alignment.SpaceBeforeCaseColon = true;
verifyFormat("switch (level) {\n"
"case log::info : return \"info\";\n"
"case log::warning : return \"warning\";\n"
"case log::error :\n"
"default : return \"default\";\n"
"}",
Alignment);
}
TEST_F(FormatTest, AlignWithLineBreaks) {
auto Style = getLLVMStyleWithColumns(120);