From e9ab42df0cf305b8ff1f363cc5acd680f954ec16 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Fri, 31 Oct 2014 18:23:49 +0000 Subject: [PATCH] clang-format: [Java] Improve line breaks around annotations. Before: @SomeAnnotation("With some really looooooooooooooong text") private static final long something = 0L; void SomeFunction(@Nullable String something) {} After: @SomeAnnotation("With some really looooooooooooooong text") private static final long something = 0L; void SomeFunction(@Nullable String something) {} llvm-svn: 220984 --- clang/lib/Format/ContinuationIndenter.cpp | 9 ++++++--- clang/lib/Format/FormatToken.h | 1 + clang/lib/Format/TokenAnnotator.cpp | 16 +++++++++++++--- clang/unittests/Format/FormatTestJava.cpp | 6 ++++++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 0920137..b6dd9bd 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -464,6 +464,7 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, PreviousNonComment->Type != TT_TemplateCloser && PreviousNonComment->Type != TT_BinaryOperator && PreviousNonComment->Type != TT_JavaAnnotation && + PreviousNonComment->Type != TT_LeadingJavaAnnotation && Current.Type != TT_BinaryOperator && !PreviousNonComment->opensScope()) State.Stack.back().BreakBeforeParameter = true; @@ -538,9 +539,11 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { return State.Stack.back().QuestionColumn; if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0) return State.Stack.back().VariablePos; - if ((PreviousNonComment && (PreviousNonComment->ClosesTemplateDeclaration || - PreviousNonComment->Type == TT_AttributeParen || - PreviousNonComment->Type == TT_JavaAnnotation)) || + if ((PreviousNonComment && + (PreviousNonComment->ClosesTemplateDeclaration || + PreviousNonComment->Type == TT_AttributeParen || + PreviousNonComment->Type == TT_JavaAnnotation || + PreviousNonComment->Type == TT_LeadingJavaAnnotation)) || (!Style.IndentWrappedFunctionNames && (NextNonComment->is(tok::kw_operator) || NextNonComment->Type == TT_FunctionDeclarationName))) diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 425a7c8..aca5298 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -48,6 +48,7 @@ enum TokenType { TT_InlineASMColon, TT_JavaAnnotation, TT_LambdaLSquare, + TT_LeadingJavaAnnotation, TT_LineComment, TT_ObjCBlockLBrace, TT_ObjCBlockLParen, diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index f0ffdb6..c54b041 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -190,6 +190,8 @@ private: CurrentToken->Type = TT_AttributeParen; if (Left->Previous && Left->Previous->Type == TT_JavaAnnotation) CurrentToken->Type = TT_JavaAnnotation; + if (Left->Previous && Left->Previous->Type == TT_LeadingJavaAnnotation) + CurrentToken->Type = TT_LeadingJavaAnnotation; if (!HasMultipleLines) Left->PackingKind = PPK_Inconclusive; @@ -835,7 +837,12 @@ private: Current.Type = TT_TrailingAnnotation; } else if (Style.Language == FormatStyle::LK_Java && Current.Previous && Current.Previous->is(tok::at)) { - Current.Type = TT_JavaAnnotation; + const FormatToken& AtToken = *Current.Previous; + if (!AtToken.Previous || + AtToken.Previous->Type == TT_LeadingJavaAnnotation) + Current.Type = TT_LeadingJavaAnnotation; + else + Current.Type = TT_JavaAnnotation; } } } @@ -1460,6 +1467,9 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, return 150; } + if (Left.Type == TT_LeadingJavaAnnotation) + return 1; + if (Right.Type == TT_TrailingAnnotation && (!Right.Next || Right.Next->isNot(tok::l_paren))) { // Moving trailing annotations to the next line is fine for ObjC method @@ -1811,7 +1821,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, Left.Previous->is(tok::char_constant)) return true; } else if (Style.Language == FormatStyle::LK_Java) { - if (Left.Type == TT_JavaAnnotation && Right.isNot(tok::l_paren) && + if (Left.Type == TT_LeadingJavaAnnotation && Right.isNot(tok::l_paren) && Line.Last->is(tok::l_brace)) return true; if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next && @@ -1835,7 +1845,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, return false; if (Left.Tok.getObjCKeywordID() == tok::objc_interface) return false; - if (Left.Type == TT_JavaAnnotation) + if (Left.Type == TT_JavaAnnotation || Left.Type == TT_LeadingJavaAnnotation) return true; if (Right.Type == TT_StartOfName || Right.Type == TT_FunctionDeclarationName || Right.is(tok::kw_operator)) diff --git a/clang/unittests/Format/FormatTestJava.cpp b/clang/unittests/Format/FormatTestJava.cpp index c957589..4f9a3dc 100644 --- a/clang/unittests/Format/FormatTestJava.cpp +++ b/clang/unittests/Format/FormatTestJava.cpp @@ -84,9 +84,15 @@ TEST_F(FormatTestJava, Annotations) { " }\n" "});"); + verifyFormat("void SomeFunction(@Nullable String something) {\n" + "}"); + verifyFormat("@Partial @Mock DataLoader loader;"); verifyFormat("@SuppressWarnings(value = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\")\n" "public static int iiiiiiiiiiiiiiiiiiiiiiii;"); + + verifyFormat("@SomeAnnotation(\"With some really looooooooooooooong text\")\n" + "private static final long something = 0L;"); } TEST_F(FormatTestJava, Generics) { -- 2.7.4