Style.AlwaysBreakTemplateDeclarations);
IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
Style.AlwaysBreakBeforeMultilineStrings);
+ IO.mapOptional("BreakBeforeBinaryOperators",
+ Style.BreakBeforeBinaryOperators);
+ IO.mapOptional("BreakConstructorInitializersBeforeComma",
+ Style.BreakConstructorInitializersBeforeComma);
IO.mapOptional("BinPackParameters", Style.BinPackParameters);
IO.mapOptional("ColumnLimit", Style.ColumnLimit);
IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
- LLVMStyle.AlwaysBreakTemplateDeclarations = false;
LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
+ LLVMStyle.AlwaysBreakTemplateDeclarations = false;
LLVMStyle.BinPackParameters = true;
+ LLVMStyle.BreakBeforeBinaryOperators = false;
+ LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
+ LLVMStyle.BreakConstructorInitializersBeforeComma = false;
LLVMStyle.ColumnLimit = 80;
LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
+ LLVMStyle.Cpp11BracedListStyle = false;
LLVMStyle.DerivePointerBinding = false;
LLVMStyle.ExperimentalAutoDetectBinPacking = false;
LLVMStyle.IndentCaseLabels = false;
+ LLVMStyle.IndentFunctionDeclarationAfterType = false;
+ LLVMStyle.IndentWidth = 2;
LLVMStyle.MaxEmptyLinesToKeep = 1;
LLVMStyle.ObjCSpaceBeforeProtocolList = true;
LLVMStyle.PointerBindsToType = false;
LLVMStyle.SpacesBeforeTrailingComments = 1;
- LLVMStyle.Cpp11BracedListStyle = false;
LLVMStyle.Standard = FormatStyle::LS_Cpp03;
- LLVMStyle.IndentWidth = 2;
LLVMStyle.UseTab = false;
- LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
- LLVMStyle.IndentFunctionDeclarationAfterType = false;
setDefaultPenalties(LLVMStyle);
LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
GoogleStyle.AllowAllParametersOfDeclarationOnNextLine = true;
GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
GoogleStyle.AllowShortLoopsOnASingleLine = true;
- GoogleStyle.AlwaysBreakTemplateDeclarations = true;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
+ GoogleStyle.AlwaysBreakTemplateDeclarations = true;
GoogleStyle.BinPackParameters = true;
+ GoogleStyle.BreakBeforeBinaryOperators = false;
+ GoogleStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
+ GoogleStyle.BreakConstructorInitializersBeforeComma = false;
GoogleStyle.ColumnLimit = 80;
GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
+ GoogleStyle.Cpp11BracedListStyle = true;
GoogleStyle.DerivePointerBinding = true;
GoogleStyle.ExperimentalAutoDetectBinPacking = false;
GoogleStyle.IndentCaseLabels = true;
+ GoogleStyle.IndentFunctionDeclarationAfterType = true;
+ GoogleStyle.IndentWidth = 2;
GoogleStyle.MaxEmptyLinesToKeep = 1;
GoogleStyle.ObjCSpaceBeforeProtocolList = false;
GoogleStyle.PointerBindsToType = true;
GoogleStyle.SpacesBeforeTrailingComments = 2;
- GoogleStyle.Cpp11BracedListStyle = true;
GoogleStyle.Standard = FormatStyle::LS_Auto;
- GoogleStyle.IndentWidth = 2;
GoogleStyle.UseTab = false;
- GoogleStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
- GoogleStyle.IndentFunctionDeclarationAfterType = true;
setDefaultPenalties(GoogleStyle);
GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
ChromiumStyle.BinPackParameters = false;
- ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
ChromiumStyle.DerivePointerBinding = false;
+ ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
return ChromiumStyle;
}
FormatStyle getWebKitStyle() {
FormatStyle Style = getLLVMStyle();
Style.ColumnLimit = 0;
- Style.IndentWidth = 4;
Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
+ Style.BreakBeforeBinaryOperators = true;
+ Style.BreakConstructorInitializersBeforeComma = true;
+ Style.IndentWidth = 4;
Style.PointerBindsToType = true;
return Style;
}
/// input's line breaking decisions.
void formatWithoutColumnLimit(LineState &State) {
while (State.NextToken != NULL) {
- bool Newline = State.NextToken->NewlinesBefore > 0;
+ bool Newline = mustBreak(State) ||
+ (canBreak(State) && State.NextToken->NewlinesBefore > 0);
addTokenToState(Newline, /*DryRun=*/false, State);
}
}
// : First(...), ...
// Next(...)
// ^ line up here.
- State.Stack.back().Indent = State.Column + 2;
+ if (!Style.BreakConstructorInitializersBeforeComma)
+ State.Stack.back().Indent = State.Column + 2;
if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
State.Stack.back().AvoidBinPacking = true;
State.Stack.back().BreakBeforeParameter = false;
// prec::Assignment) as those have different indentation rules. Indent
// other expression, unless the indentation needs to be skipped.
if (*I == prec::Conditional ||
- (!SkipFirstExtraIndent && *I > prec::Assignment))
+ (!SkipFirstExtraIndent && *I > prec::Assignment &&
+ !Style.BreakBeforeBinaryOperators))
NewParenState.Indent += 4;
if (Previous && !Previous->opensScope())
NewParenState.BreakBeforeParameter = false;
return true;
if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection)
return true;
+ if (Style.BreakConstructorInitializersBeforeComma) {
+ if (Previous.Type == TT_CtorInitializerComma)
+ return false;
+ if (Current.Type == TT_CtorInitializerComma)
+ return true;
+ }
if ((Previous.isOneOf(tok::comma, tok::semi) || Current.is(tok::question) ||
Current.Type == TT_ConditionalExpr) &&
State.Stack.back().BreakBeforeParameter &&
(Current.TokenText.find("\\\n") != StringRef::npos)))
return true;
- // If we need to break somewhere inside the LHS of a binary expression, we
- // should also break after the operator. Otherwise, the formatting would
- // hide the operator precedence, e.g. in:
- // if (aaaaaaaaaaaaaa ==
- // bbbbbbbbbbbbbb && c) {..
- // For comparisons, we only apply this rule, if the LHS is a binary
- // expression itself as otherwise, the line breaks seem superfluous.
- // We need special cases for ">>" which we have split into two ">" while
- // lexing in order to make template parsing easier.
- bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
- Previous.getPrecedence() == prec::Equality) &&
- Previous.Previous &&
- Previous.Previous->Type != TT_BinaryOperator; // For >>.
- bool LHSIsBinaryExpr =
- Previous.Previous && Previous.Previous->FakeRParens > 0;
- if (Previous.Type == TT_BinaryOperator &&
- (!IsComparison || LHSIsBinaryExpr) &&
- Current.Type != TT_BinaryOperator && // For >>.
- !Current.isTrailingComment() &&
- !Previous.isOneOf(tok::lessless, tok::question) &&
- Previous.getPrecedence() != prec::Assignment &&
- State.Stack.back().BreakBeforeParameter)
- return true;
+ if (!Style.BreakBeforeBinaryOperators) {
+ // If we need to break somewhere inside the LHS of a binary expression, we
+ // should also break after the operator. Otherwise, the formatting would
+ // hide the operator precedence, e.g. in:
+ // if (aaaaaaaaaaaaaa ==
+ // bbbbbbbbbbbbbb && c) {..
+ // For comparisons, we only apply this rule, if the LHS is a binary
+ // expression itself as otherwise, the line breaks seem superfluous.
+ // We need special cases for ">>" which we have split into two ">" while
+ // lexing in order to make template parsing easier.
+ //
+ // FIXME: We'll need something similar for styles that break before binary
+ // operators.
+ bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
+ Previous.getPrecedence() == prec::Equality) &&
+ Previous.Previous && Previous.Previous->Type !=
+ TT_BinaryOperator; // For >>.
+ bool LHSIsBinaryExpr =
+ Previous.Previous && Previous.Previous->FakeRParens > 0;
+ if (Previous.Type == TT_BinaryOperator &&
+ (!IsComparison || LHSIsBinaryExpr) &&
+ Current.Type != TT_BinaryOperator && // For >>.
+ !Current.isTrailingComment() &&
+ !Previous.isOneOf(tok::lessless, tok::question) &&
+ Previous.getPrecedence() != prec::Assignment &&
+ State.Stack.back().BreakBeforeParameter)
+ return true;
+ }
// Same as above, but for the first "<<" operator.
if (Current.is(tok::lessless) && State.Stack.back().BreakBeforeParameter &&
case tok::comma:
if (Contexts.back().FirstStartOfName)
Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
+ if (Contexts.back().InCtorInitializer)
+ Tok->Type = TT_CtorInitializerComma;
break;
default:
break;
LongestObjCSelectorName(0), ColonIsForRangeExpr(false),
ColonIsObjCDictLiteral(false), ColonIsObjCMethodExpr(false),
FirstObjCSelectorName(NULL), FirstStartOfName(NULL),
- IsExpression(IsExpression), CanBeExpression(true) {}
+ IsExpression(IsExpression), CanBeExpression(true),
+ InCtorInitializer(false) {}
tok::TokenKind ContextKind;
unsigned BindingStrength;
FormatToken *FirstStartOfName;
bool IsExpression;
bool CanBeExpression;
+ bool InCtorInitializer;
};
/// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime
} else if (Current.Previous &&
Current.Previous->Type == TT_CtorInitializerColon) {
Contexts.back().IsExpression = true;
+ Contexts.back().InCtorInitializer = true;
} else if (Current.is(tok::kw_new)) {
Contexts.back().CanBeExpression = false;
} else if (Current.is(tok::semi)) {
} else if (Current->Previous->ClosesTemplateDeclaration &&
Style.AlwaysBreakTemplateDeclarations) {
Current->MustBreakBefore = true;
+ } else if (Current->Type == TT_CtorInitializerComma &&
+ Style.BreakConstructorInitializersBeforeComma) {
+ Current->MustBreakBefore = true;
}
Current->CanBreakBefore =
Current->MustBreakBefore || canBreakBefore(Line, *Current);
// We only break before r_brace if there was a corresponding break before
// the l_brace, which is tracked by BreakBeforeClosingBrace.
- if (Right.isOneOf(tok::r_brace, tok::r_paren, tok::greater))
+ if (Right.isOneOf(tok::r_brace, tok::r_paren) ||
+ Right.Type == TT_TemplateCloser)
return false;
// Allow breaking after a trailing 'const', e.g. after a method declaration,
if (Left.is(tok::identifier) && Right.is(tok::string_literal))
return true;
- return (Left.isBinaryOperator() && Left.isNot(tok::lessless)) ||
+
+ if (Left.Type == TT_CtorInitializerComma &&
+ Style.BreakConstructorInitializersBeforeComma)
+ return false;
+ if (Right.isBinaryOperator() && Style.BreakBeforeBinaryOperators)
+ return true;
+ return (Left.isBinaryOperator() && Left.isNot(tok::lessless) &&
+ !Style.BreakBeforeBinaryOperators) ||
Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
tok::kw_class, tok::kw_struct) ||
Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon) ||
getLLVMStyleWithColumns(30));
}
+TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) {
+ // Not sure what the best system is here. Like this, the LHS can be found
+ // immediately above an operator (everything with the same or a higher
+ // indent). The RHS is aligned right of the operator and so compasses
+ // everything until something with the same indent as the operator is found.
+ // FIXME: Is this a good system?
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBinaryOperators = true;
+ verifyFormat(
+ "bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " > ccccccccccccccccccccccccccccccccccccccccc;",
+ Style);
+ verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " == bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}",
+ Style);
+ verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " == bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}",
+ Style);
+ verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}",
+ Style);
+ verifyFormat("if () {\n"
+ "} else if (aaaaa && bbbbb // break\n"
+ " > ccccc) {\n"
+ "}",
+ Style);
+}
+
TEST_F(FormatTest, ConstructorInitializers) {
verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}");
verifyFormat("Constructor() : Inttializer(FitsOnTheLine) {}",
CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations);
CHECK_PARSE_BOOL(BinPackParameters);
+ CHECK_PARSE_BOOL(BreakBeforeBinaryOperators);
+ CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma);
CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine);
CHECK_PARSE_BOOL(DerivePointerBinding);
CHECK_PARSE_BOOL(IndentCaseLabels);
// Constructor initializers are formatted one per line with the "," on the
// new line.
- // FIXME: This needs to be implemented.
- // verifyFormat("Constructor()\n"
- // " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
- // " , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
- // " aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
- // " , aaaaaaaaaaaaaaaaaaaaaaa() {}",
- // Style);
+ verifyFormat("Constructor()\n"
+ " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+ " , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaa, // break\n"
+ " aaaaaaaaaaaaaa)\n"
+ " , aaaaaaaaaaaaaaaaaaaaaaa()\n{\n}",
+ Style);
// Do not align comments.
// FIXME: Implement option to suppress comment alignment.