[clang] e811150 - [clang-format] use spaces for alignment with UT_ForContinuationAndIndentation
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 13 07:14:50 PDT 2020
Author: mydeveloperday
Date: 2020-04-13T15:14:26+01:00
New Revision: e8111502d8696896241132865c7a44c6f84f93c1
URL: https://github.com/llvm/llvm-project/commit/e8111502d8696896241132865c7a44c6f84f93c1
DIFF: https://github.com/llvm/llvm-project/commit/e8111502d8696896241132865c7a44c6f84f93c1.diff
LOG: [clang-format] use spaces for alignment with UT_ForContinuationAndIndentation
Summary:
Use spaces instead of tabs for alignment with UT_ForContinuationAndIndentation to make the code aligned for any tab/indent width.
Fixes https://bugs.llvm.org/show_bug.cgi?id=38381
Reviewed By: MyDeveloperDay
Patch By: fickert
Tags: #clang-format
Differential Revision: https://reviews.llvm.org/D75034
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/include/clang/Format/Format.h
clang/lib/Format/BreakableToken.cpp
clang/lib/Format/ContinuationIndenter.cpp
clang/lib/Format/ContinuationIndenter.h
clang/lib/Format/Format.cpp
clang/lib/Format/UnwrappedLineFormatter.cpp
clang/lib/Format/WhitespaceManager.cpp
clang/lib/Format/WhitespaceManager.h
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 1c1d0142930f..6d486224e3c2 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2534,7 +2534,11 @@ the configuration (without a prefix: ``Auto``).
Use tabs only for indentation.
* ``UT_ForContinuationAndIndentation`` (in configuration: ``ForContinuationAndIndentation``)
- Use tabs only for line continuation and indentation.
+ Fill all leading whitespace with tabs, and use spaces for alignment that
+ appears within a line (e.g. consecutive assignments and declarations).
+
+ * ``UT_AlignWithSpaces`` (in configuration: ``AlignWithSpaces``)
+ Use tabs for line continuation and indentation, and spaces for alignment.
* ``UT_Always`` (in configuration: ``Always``)
Use tabs whenever we need to fill whitespace that spans at least from
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index d4f76c87c14e..2b2edc4adc11 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2129,8 +2129,12 @@ struct FormatStyle {
UT_Never,
/// Use tabs only for indentation.
UT_ForIndentation,
- /// Use tabs only for line continuation and indentation.
+ /// Fill all leading whitespace with tabs, and use spaces for alignment that
+ /// appears within a line (e.g. consecutive assignments and declarations).
UT_ForContinuationAndIndentation,
+ /// Use tabs for line continuation and indentation, and spaces for
+ /// alignemnt.
+ UT_AlignWithSpaces,
/// Use tabs whenever we need to fill whitespace that spans at least from
/// one tab stop to the next one.
UT_Always
diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp
index 4294c2a653fa..15fbe3b6515d 100644
--- a/clang/lib/Format/BreakableToken.cpp
+++ b/clang/lib/Format/BreakableToken.cpp
@@ -863,7 +863,8 @@ void BreakableLineCommentSection::reflow(unsigned LineIndex,
// tokens by the empty string.
Whitespaces.replaceWhitespace(
*Tokens[LineIndex], /*Newlines=*/0, /*Spaces=*/0,
- /*StartOfTokenColumn=*/StartColumn, /*InPPDirective=*/false);
+ /*StartOfTokenColumn=*/StartColumn, /*IsAligned=*/true,
+ /*InPPDirective=*/false);
} else if (LineIndex > 0) {
// In case we're reflowing after the '\' in:
//
@@ -931,6 +932,7 @@ void BreakableLineCommentSection::adaptStartOfLine(
/*Newlines=*/1,
/*Spaces=*/LineColumn,
/*StartOfTokenColumn=*/LineColumn,
+ /*IsAligned=*/true,
/*InPPDirective=*/false);
}
if (OriginalPrefix[LineIndex] != Prefix[LineIndex]) {
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 2dda5d89a3ac..e70ae7efb0c3 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -642,8 +642,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign &&
!State.Stack.back().IsCSharpGenericTypeConstraint &&
Previous.opensScope() && Previous.isNot(TT_ObjCMethodExpr) &&
- (Current.isNot(TT_LineComment) || Previous.BlockKind == BK_BracedInit))
+ (Current.isNot(TT_LineComment) || Previous.BlockKind == BK_BracedInit)) {
State.Stack.back().Indent = State.Column + Spaces;
+ State.Stack.back().IsAligned = true;
+ }
if (State.Stack.back().AvoidBinPacking && startsNextParameter(Current, Style))
State.Stack.back().NoLineBreak = true;
if (startsSegmentOfBuilderTypeCall(Current) &&
@@ -858,6 +860,7 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
bool ContinuePPDirective =
State.Line->InPPDirective && State.Line->Type != LT_ImportStatement;
Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,
+ State.Stack.back().IsAligned,
ContinuePPDirective);
}
diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h
index ab116d5468e8..5ad4548529d7 100644
--- a/clang/lib/Format/ContinuationIndenter.h
+++ b/clang/lib/Format/ContinuationIndenter.h
@@ -202,14 +202,14 @@ struct ParenState {
ParenState(const FormatToken *Tok, unsigned Indent, unsigned LastSpace,
bool AvoidBinPacking, bool NoLineBreak)
: Tok(Tok), Indent(Indent), LastSpace(LastSpace),
- NestedBlockIndent(Indent), BreakBeforeClosingBrace(false),
- AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
- NoLineBreak(NoLineBreak), NoLineBreakInOperand(false),
- LastOperatorWrapped(true), ContainsLineBreak(false),
- ContainsUnwrappedBuilder(false), AlignColons(true),
- ObjCSelectorNameFound(false), HasMultipleNestedBlocks(false),
- NestedBlockInlined(false), IsInsideObjCArrayLiteral(false),
- IsCSharpGenericTypeConstraint(false) {}
+ NestedBlockIndent(Indent), IsAligned(false),
+ BreakBeforeClosingBrace(false), AvoidBinPacking(AvoidBinPacking),
+ BreakBeforeParameter(false), NoLineBreak(NoLineBreak),
+ NoLineBreakInOperand(false), LastOperatorWrapped(true),
+ ContainsLineBreak(false), ContainsUnwrappedBuilder(false),
+ AlignColons(true), ObjCSelectorNameFound(false),
+ HasMultipleNestedBlocks(false), NestedBlockInlined(false),
+ IsInsideObjCArrayLiteral(false), IsCSharpGenericTypeConstraint(false) {}
/// \brief The token opening this parenthesis level, or nullptr if this level
/// is opened by fake parenthesis.
@@ -265,6 +265,9 @@ struct ParenState {
/// Used to align further variables if necessary.
unsigned VariablePos = 0;
+ /// Whether this block's indentation is used for alignment.
+ bool IsAligned : 1;
+
/// Whether a newline needs to be inserted before the block's closing
/// brace.
///
@@ -341,6 +344,8 @@ struct ParenState {
return NestedBlockIndent < Other.NestedBlockIndent;
if (FirstLessLess != Other.FirstLessLess)
return FirstLessLess < Other.FirstLessLess;
+ if (IsAligned != Other.IsAligned)
+ return IsAligned;
if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
return BreakBeforeClosingBrace;
if (QuestionColumn != Other.QuestionColumn)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 031312bd16d8..4a5626d42209 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -93,6 +93,7 @@ template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
IO.enumCase(Value, "ForContinuationAndIndentation",
FormatStyle::UT_ForContinuationAndIndentation);
+ IO.enumCase(Value, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);
}
};
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index a81d480c8e64..c16c16c4f26a 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -888,7 +888,8 @@ class LineFormatter {
if (!DryRun) {
Whitespaces->replaceWhitespace(
*Child->First, /*Newlines=*/0, /*Spaces=*/1,
- /*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective);
+ /*StartOfTokenColumn=*/State.Column, /*IsAligned=*/false,
+ State.Line->InPPDirective);
}
Penalty +=
formatLine(*Child, State.Column + 1, /*FirstStartColumn=*/0, DryRun);
@@ -1320,6 +1321,7 @@ void UnwrappedLineFormatter::formatFirstToken(
Indent = 0;
Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent,
+ /*IsAligned=*/false,
Line.InPPDirective &&
!RootToken.HasUnescapedNewline);
}
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 5a44500d355f..bc71a89fc92b 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -30,13 +30,13 @@ WhitespaceManager::Change::Change(const FormatToken &Tok,
int Spaces, unsigned StartOfTokenColumn,
unsigned NewlinesBefore,
StringRef PreviousLinePostfix,
- StringRef CurrentLinePrefix,
+ StringRef CurrentLinePrefix, bool IsAligned,
bool ContinuesPPDirective, bool IsInsideToken)
: Tok(&Tok), CreateReplacement(CreateReplacement),
OriginalWhitespaceRange(OriginalWhitespaceRange),
StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
PreviousLinePostfix(PreviousLinePostfix),
- CurrentLinePrefix(CurrentLinePrefix),
+ CurrentLinePrefix(CurrentLinePrefix), IsAligned(IsAligned),
ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces),
IsInsideToken(IsInsideToken), IsTrailingComment(false), TokenLength(0),
PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
@@ -45,13 +45,13 @@ WhitespaceManager::Change::Change(const FormatToken &Tok,
void WhitespaceManager::replaceWhitespace(FormatToken &Tok, unsigned Newlines,
unsigned Spaces,
unsigned StartOfTokenColumn,
- bool InPPDirective) {
+ bool IsAligned, bool InPPDirective) {
if (Tok.Finalized)
return;
Tok.Decision = (Newlines > 0) ? FD_Break : FD_Continue;
Changes.push_back(Change(Tok, /*CreateReplacement=*/true, Tok.WhitespaceRange,
Spaces, StartOfTokenColumn, Newlines, "", "",
- InPPDirective && !Tok.IsFirst,
+ IsAligned, InPPDirective && !Tok.IsFirst,
/*IsInsideToken=*/false));
}
@@ -62,7 +62,7 @@ void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
Changes.push_back(Change(Tok, /*CreateReplacement=*/false,
Tok.WhitespaceRange, /*Spaces=*/0,
Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
- InPPDirective && !Tok.IsFirst,
+ /*IsAligned=*/false, InPPDirective && !Tok.IsFirst,
/*IsInsideToken=*/false));
}
@@ -82,7 +82,8 @@ void WhitespaceManager::replaceWhitespaceInToken(
Change(Tok, /*CreateReplacement=*/true,
SourceRange(Start, Start.getLocWithOffset(ReplaceChars)), Spaces,
std::max(0, Spaces), Newlines, PreviousPostfix, CurrentPrefix,
- InPPDirective && !Tok.IsFirst, /*IsInsideToken=*/true));
+ /*IsAligned=*/true, InPPDirective && !Tok.IsFirst,
+ /*IsInsideToken=*/true));
}
const tooling::Replacements &WhitespaceManager::generateReplacements() {
@@ -761,9 +762,9 @@ void WhitespaceManager::generateChanges() {
C.EscapedNewlineColumn);
else
appendNewlineText(ReplacementText, C.NewlinesBefore);
- appendIndentText(ReplacementText, C.Tok->IndentLevel,
- std::max(0, C.Spaces),
- C.StartOfTokenColumn - std::max(0, C.Spaces));
+ appendIndentText(
+ ReplacementText, C.Tok->IndentLevel, std::max(0, C.Spaces),
+ C.StartOfTokenColumn - std::max(0, C.Spaces), C.IsAligned);
ReplacementText.append(C.CurrentLinePrefix);
storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
}
@@ -809,7 +810,8 @@ void WhitespaceManager::appendEscapedNewlineText(
void WhitespaceManager::appendIndentText(std::string &Text,
unsigned IndentLevel, unsigned Spaces,
- unsigned WhitespaceStartColumn) {
+ unsigned WhitespaceStartColumn,
+ bool IsAligned) {
switch (Style.UseTab) {
case FormatStyle::UT_Never:
Text.append(Spaces, ' ');
@@ -838,28 +840,39 @@ void WhitespaceManager::appendIndentText(std::string &Text,
case FormatStyle::UT_ForIndentation:
if (WhitespaceStartColumn == 0) {
unsigned Indentation = IndentLevel * Style.IndentWidth;
- // This happens, e.g. when a line in a block comment is indented less than
- // the first one.
- if (Indentation > Spaces)
- Indentation = Spaces;
- if (Style.TabWidth) {
- unsigned Tabs = Indentation / Style.TabWidth;
- Text.append(Tabs, '\t');
- Spaces -= Tabs * Style.TabWidth;
- }
+ Spaces = appendTabIndent(Text, Spaces, Indentation);
}
Text.append(Spaces, ' ');
break;
case FormatStyle::UT_ForContinuationAndIndentation:
- if (WhitespaceStartColumn == 0 && Style.TabWidth) {
- unsigned Tabs = Spaces / Style.TabWidth;
- Text.append(Tabs, '\t');
- Spaces -= Tabs * Style.TabWidth;
+ if (WhitespaceStartColumn == 0)
+ Spaces = appendTabIndent(Text, Spaces, Spaces);
+ Text.append(Spaces, ' ');
+ break;
+ case FormatStyle::UT_AlignWithSpaces:
+ if (WhitespaceStartColumn == 0) {
+ unsigned Indentation =
+ IsAligned ? IndentLevel * Style.IndentWidth : Spaces;
+ Spaces = appendTabIndent(Text, Spaces, Indentation);
}
Text.append(Spaces, ' ');
break;
}
}
+unsigned WhitespaceManager::appendTabIndent(std::string &Text, unsigned Spaces,
+ unsigned Indentation) {
+ // This happens, e.g. when a line in a block comment is indented less than the
+ // first one.
+ if (Indentation > Spaces)
+ Indentation = Spaces;
+ if (Style.TabWidth) {
+ unsigned Tabs = Indentation / Style.TabWidth;
+ Text.append(Tabs, '\t');
+ Spaces -= Tabs * Style.TabWidth;
+ }
+ return Spaces;
+}
+
} // namespace format
} // namespace clang
diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h
index f47bf40204b3..a9f83920801f 100644
--- a/clang/lib/Format/WhitespaceManager.h
+++ b/clang/lib/Format/WhitespaceManager.h
@@ -49,7 +49,7 @@ class WhitespaceManager {
/// this replacement. It is needed for determining how \p Spaces is turned
/// into tabs and spaces for some format styles.
void replaceWhitespace(FormatToken &Tok, unsigned Newlines, unsigned Spaces,
- unsigned StartOfTokenColumn,
+ unsigned StartOfTokenColumn, bool isAligned = false,
bool InPPDirective = false);
/// Adds information about an unchangeable token's whitespace.
@@ -109,7 +109,7 @@ class WhitespaceManager {
SourceRange OriginalWhitespaceRange, int Spaces,
unsigned StartOfTokenColumn, unsigned NewlinesBefore,
StringRef PreviousLinePostfix, StringRef CurrentLinePrefix,
- bool ContinuesPPDirective, bool IsInsideToken);
+ bool IsAligned, bool ContinuesPPDirective, bool IsInsideToken);
// The kind of the token whose whitespace this change replaces, or in which
// this change inserts whitespace.
@@ -125,6 +125,7 @@ class WhitespaceManager {
unsigned NewlinesBefore;
std::string PreviousLinePostfix;
std::string CurrentLinePrefix;
+ bool IsAligned;
bool ContinuesPPDirective;
// The number of spaces in front of the token or broken part of the token.
@@ -204,7 +205,10 @@ class WhitespaceManager {
unsigned PreviousEndOfTokenColumn,
unsigned EscapedNewlineColumn);
void appendIndentText(std::string &Text, unsigned IndentLevel,
- unsigned Spaces, unsigned WhitespaceStartColumn);
+ unsigned Spaces, unsigned WhitespaceStartColumn,
+ bool IsAligned);
+ unsigned appendTabIndent(std::string &Text, unsigned Spaces,
+ unsigned Indentation);
SmallVector<Change, 16> Changes;
const SourceManager &SourceMgr;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index ece7c61a999c..69a2001cd995 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -10151,17 +10151,18 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
" \t \t comment */",
Tab));
EXPECT_EQ("{\n"
- " /*\n"
- " * Comment\n"
- " */\n"
- " int i;\n"
+ " /*\n"
+ " * Comment\n"
+ " */\n"
+ " int i;\n"
"}",
format("{\n"
"\t/*\n"
"\t * Comment\n"
"\t */\n"
"\t int i;\n"
- "}"));
+ "}",
+ Tab));
Tab.UseTab = FormatStyle::UT_ForContinuationAndIndentation;
Tab.TabWidth = 8;
@@ -10332,15 +10333,245 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
"\t*/\n"
"}",
Tab));
+ EXPECT_EQ("/* some\n"
+ " comment */",
+ format(" \t \t /* some\n"
+ " \t \t comment */",
+ Tab));
+ EXPECT_EQ("int a; /* some\n"
+ " comment */",
+ format(" \t \t int a; /* some\n"
+ " \t \t comment */",
+ Tab));
+ EXPECT_EQ("int a; /* some\n"
+ "comment */",
+ format(" \t \t int\ta; /* some\n"
+ " \t \t comment */",
+ Tab));
+ EXPECT_EQ("f(\"\t\t\"); /* some\n"
+ " comment */",
+ format(" \t \t f(\"\t\t\"); /* some\n"
+ " \t \t comment */",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\t * Comment\n"
+ "\t */\n"
+ "\tint i;\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ "\t * Comment\n"
+ "\t */\n"
+ "\t int i;\n"
+ "}",
+ Tab));
+ Tab.TabWidth = 2;
+ Tab.IndentWidth = 2;
+ EXPECT_EQ("{\n"
+ "\t/* aaaa\n"
+ "\t\t bbbb */\n"
+ "}",
+ format("{\n"
+ "/* aaaa\n"
+ "\t bbbb */\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\t\taaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t\tbbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "/*\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "*/\n"
+ "}",
+ Tab));
+ Tab.AlignConsecutiveAssignments = true;
+ Tab.AlignConsecutiveDeclarations = true;
+ Tab.TabWidth = 4;
+ Tab.IndentWidth = 4;
+ verifyFormat("class Assign {\n"
+ "\tvoid f() {\n"
+ "\t\tint x = 123;\n"
+ "\t\tint random = 4;\n"
+ "\t\tstd::string alphabet =\n"
+ "\t\t\t\"abcdefghijklmnopqrstuvwxyz\";\n"
+ "\t}\n"
+ "};",
+ Tab);
+
+ Tab.UseTab = FormatStyle::UT_AlignWithSpaces;
+ Tab.TabWidth = 8;
+ Tab.IndentWidth = 8;
+ EXPECT_EQ("if (aaaaaaaa && // q\n"
+ " bb) // w\n"
+ "\t;",
+ format("if (aaaaaaaa &&// q\n"
+ "bb)// w\n"
+ ";",
+ Tab));
+ EXPECT_EQ("if (aaa && bbb) // w\n"
+ "\t;",
+ format("if(aaa&&bbb)// w\n"
+ ";",
+ Tab));
+ verifyFormat("class X {\n"
+ "\tvoid f() {\n"
+ "\t\tsomeFunction(parameter1,\n"
+ "\t\t parameter2);\n"
+ "\t}\n"
+ "};",
+ Tab);
+ verifyFormat("#define A \\\n"
+ "\tvoid f() { \\\n"
+ "\t\tsomeFunction( \\\n"
+ "\t\t parameter1, \\\n"
+ "\t\t parameter2); \\\n"
+ "\t}",
+ Tab);
+ Tab.TabWidth = 4;
+ Tab.IndentWidth = 8;
+ verifyFormat("class TabWidth4Indent8 {\n"
+ "\t\tvoid f() {\n"
+ "\t\t\t\tsomeFunction(parameter1,\n"
+ "\t\t\t\t parameter2);\n"
+ "\t\t}\n"
+ "};",
+ Tab);
+ Tab.TabWidth = 4;
+ Tab.IndentWidth = 4;
+ verifyFormat("class TabWidth4Indent4 {\n"
+ "\tvoid f() {\n"
+ "\t\tsomeFunction(parameter1,\n"
+ "\t\t parameter2);\n"
+ "\t}\n"
+ "};",
+ Tab);
+ Tab.TabWidth = 8;
+ Tab.IndentWidth = 4;
+ verifyFormat("class TabWidth8Indent4 {\n"
+ " void f() {\n"
+ "\tsomeFunction(parameter1,\n"
+ "\t parameter2);\n"
+ " }\n"
+ "};",
+ Tab);
+ Tab.TabWidth = 8;
+ Tab.IndentWidth = 8;
EXPECT_EQ("/*\n"
- "\t a\t\tcomment\n"
- "\t in multiple lines\n"
+ " a\t\tcomment\n"
+ " in multiple lines\n"
" */",
format(" /*\t \t \n"
" \t \t a\t\tcomment\t \t\n"
" \t \t in multiple lines\t\n"
" \t */",
Tab));
+ verifyFormat("{\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "};",
+ Tab);
+ verifyFormat("enum AA {\n"
+ "\ta1, // Force multiple lines\n"
+ "\ta2,\n"
+ "\ta3\n"
+ "};",
+ Tab);
+ EXPECT_EQ("if (aaaaaaaa && // q\n"
+ " bb) // w\n"
+ "\t;",
+ format("if (aaaaaaaa &&// q\n"
+ "bb)// w\n"
+ ";",
+ Tab));
+ verifyFormat("class X {\n"
+ "\tvoid f() {\n"
+ "\t\tsomeFunction(parameter1,\n"
+ "\t\t parameter2);\n"
+ "\t}\n"
+ "};",
+ Tab);
+ verifyFormat("{\n"
+ "\tQ(\n"
+ "\t {\n"
+ "\t\t int a;\n"
+ "\t\t someFunction(aaaaaaaa,\n"
+ "\t\t bbbbbbb);\n"
+ "\t },\n"
+ "\t p);\n"
+ "}",
+ Tab);
+ EXPECT_EQ("{\n"
+ "\t/* aaaa\n"
+ "\t bbbb */\n"
+ "}",
+ format("{\n"
+ "/* aaaa\n"
+ " bbbb */\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "/*\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "*/\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t// bbbbbbbbbbbbb\n"
+ "}",
+ format("{\n"
+ "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ "\n"
+ "\t*/\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ " asdf\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ " asdf\n"
+ "\t*/\n"
+ "}",
+ Tab));
EXPECT_EQ("/* some\n"
" comment */",
format(" \t \t /* some\n"
@@ -10362,17 +10593,41 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
" \t \t comment */",
Tab));
EXPECT_EQ("{\n"
- " /*\n"
- " * Comment\n"
- " */\n"
- " int i;\n"
+ "\t/*\n"
+ "\t * Comment\n"
+ "\t */\n"
+ "\tint i;\n"
"}",
format("{\n"
"\t/*\n"
"\t * Comment\n"
"\t */\n"
"\t int i;\n"
- "}"));
+ "}",
+ Tab));
+ Tab.TabWidth = 2;
+ Tab.IndentWidth = 2;
+ EXPECT_EQ("{\n"
+ "\t/* aaaa\n"
+ "\t bbbb */\n"
+ "}",
+ format("{\n"
+ "/* aaaa\n"
+ " bbbb */\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "/*\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "*/\n"
+ "}",
+ Tab));
Tab.AlignConsecutiveAssignments = true;
Tab.AlignConsecutiveDeclarations = true;
Tab.TabWidth = 4;
@@ -10443,6 +10698,23 @@ TEST_F(FormatTest, ZeroTabWidth) {
"};",
Tab));
+ Tab.UseTab = FormatStyle::UT_AlignWithSpaces;
+ EXPECT_EQ("void a(){\n"
+ " // line starts with '\t'\n"
+ "};",
+ format("void a(){\n"
+ "\t// line starts with '\t'\n"
+ "};",
+ Tab));
+
+ EXPECT_EQ("void a(){\n"
+ " // line starts with '\t'\n"
+ "};",
+ format("void a(){\n"
+ "\t\t// line starts with '\t'\n"
+ "};",
+ Tab));
+
Tab.UseTab = FormatStyle::UT_Always;
EXPECT_EQ("void a(){\n"
"// line starts with '\t'\n"
@@ -12843,6 +13115,8 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
CHECK_PARSE("UseTab: ForContinuationAndIndentation", UseTab,
FormatStyle::UT_ForContinuationAndIndentation);
+ CHECK_PARSE("UseTab: AlignWithSpaces", UseTab,
+ FormatStyle::UT_AlignWithSpaces);
// For backward compatibility:
CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never);
CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always);
More information about the cfe-commits
mailing list