diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 8fb6932db9f66505653dae36a941ed5337c0495a..056376a4e28d0e4e6362d4e97154b16d569fccbb 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -53,6 +53,10 @@ struct TokenAnnotation { bool MustBreakBefore; }; +static prec::Level getPrecedence(const FormatToken &Tok) { + return getBinOpPrecedence(Tok.Tok.getKind(), true, true); +} + using llvm::MutableArrayRef; FormatStyle getLLVMStyle() { @@ -266,6 +270,10 @@ private: if (!DryRun) replaceWhitespace(Current, 0, Spaces); + // FIXME: Look into using this alignment at other ParenLevels. + if (ParenLevel == 0 && (getPrecedence(Previous) == prec::Assignment || + Previous.Tok.is(tok::kw_return))) + State.Indent[ParenLevel] = State.Column + Spaces; if (Previous.Tok.is(tok::l_paren) || Annotations[Index - 1].Type == TokenAnnotation::TT_TemplateOpener) State.Indent[ParenLevel] = State.Column; @@ -290,18 +298,20 @@ private: State.Column += Current.Tok.getLength(); - // If we encounter an opening (, [ or <, we add a level to our stacks to + // If we encounter an opening (, [, { or <, we add a level to our stacks to // prepare for the following tokens. if (Current.Tok.is(tok::l_paren) || Current.Tok.is(tok::l_square) || + Current.Tok.is(tok::l_brace) || Annotations[Index].Type == TokenAnnotation::TT_TemplateOpener) { State.Indent.push_back(4 + State.LastSpace.back()); State.LastSpace.push_back(State.LastSpace.back()); State.FirstLessLess.push_back(0); } - // If we encounter a closing ), ] or >, we can remove a level from our + // If we encounter a closing ), ], } or >, we can remove a level from our // stacks. if (Current.Tok.is(tok::r_paren) || Current.Tok.is(tok::r_square) || + (Current.Tok.is(tok::r_brace) && State.ConsumedTokens > 0) || Annotations[Index].Type == TokenAnnotation::TT_TemplateCloser) { State.Indent.pop_back(); State.LastSpace.pop_back(); @@ -328,8 +338,7 @@ private: if (Left.Tok.is(tok::l_paren)) return 2; - prec::Level Level = - getBinOpPrecedence(Line.Tokens[Index].Tok.getKind(), true, true); + prec::Level Level = getPrecedence(Line.Tokens[Index]); if (Level != prec::Unknown) return Level; @@ -742,7 +751,7 @@ private: TokenAnnotation &Annotation = Annotations[i]; const FormatToken &Tok = Line.Tokens[i]; - if (getBinOpPrecedence(Tok.Tok.getKind(), true, true) == prec::Assignment) + if (getPrecedence(Tok) == prec::Assignment) IsRHS = true; else if (Tok.Tok.is(tok::kw_return)) IsRHS = true; @@ -773,7 +782,7 @@ private: bool isBinaryOperator(const FormatToken &Tok) { // Comma is a binary operator, but does not behave as such wrt. formatting. - return getBinOpPrecedence(Tok.Tok.getKind(), true, true) > prec::Comma; + return getPrecedence(Tok) > prec::Comma; } TokenAnnotation::TokenType determineStarAmpUsage(unsigned Index, diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index dda1f82e8247ec4fcab83850cac9c8d0d932f33a..9a1cb9074681129155106189e687df4aae349ab1 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -451,9 +451,9 @@ TEST_F(FormatTest, BreaksDesireably) { // taking into account the StopAt value. verifyFormat( "return aaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaa ||\n" - " aaaaaaaaaaa(aaaaaaaaa) || aaaaaaaaaaaaaaaaaaaaaaa ||\n" - " aaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaa ||\n" - " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + " aaaaaaaaaaa(aaaaaaaaa) || aaaaaaaaaaaaaaaaaaaaaaa ||\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaa ||\n" + " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); } TEST_F(FormatTest, BreaksAccordingToOperatorPrecedence) { @@ -471,6 +471,34 @@ TEST_F(FormatTest, BreaksAccordingToOperatorPrecedence) { " ccccccccccccccccccccccccc) {\n}"); } +TEST_F(FormatTest, AlignsAfterAssignments) { + verifyFormat( + "int Result = aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa;"); + verifyFormat( + "Result += aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa;"); + verifyFormat( + "Result >>= aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa;"); + verifyFormat( + "int Result = (aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat( + "double LooooooooooooooooooooooooongResult =\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa;"); +} + +TEST_F(FormatTest, AlignsAfterReturn) { + verifyFormat( + "return aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa;"); + verifyFormat( + "return (aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa);"); +} + TEST_F(FormatTest, AlignsStringLiterals) { verifyFormat("loooooooooooooooooooooooooongFunction(\"short literal \"\n" " \"short literal\");");