From d1ceccab96915c2d8bd7d1a6343e71858b8dc97b Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Mon, 18 May 2015 09:47:22 +0000 Subject: [PATCH] clang-format: Support function annotations in macros. Before: DEPRECATED("Use NewClass::NewFunction instead.") string OldFunction(const string ¶meter) {} After: DEPRECATED("Use NewClass::NewFunction instead.") string OldFunction(const string ¶meter) {} git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237562 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/ContinuationIndenter.cpp | 11 +++++++++-- lib/Format/FormatToken.h | 1 + lib/Format/TokenAnnotator.cpp | 15 ++++++++++++++- unittests/Format/FormatTest.cpp | 8 ++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index 3baebed567..20626a622f 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -208,8 +208,13 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { return true; if (Current.NestingLevel == 0 && !Current.isTrailingComment()) { + // Always break after "template <...>" and leading annotations. This is only + // for cases where the entire line does not fit on a single line as a + // different LineFormatter would be used otherwise. if (Previous.ClosesTemplateDeclaration) return true; + if (Previous.is(TT_FunctionAnnotation) && Previous.is(tok::r_paren)) + return true; if (Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) && Current.isNot(TT_LeadingJavaAnnotation)) return true; @@ -487,7 +492,8 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, !PreviousNonComment->isOneOf(tok::comma, tok::semi) && (PreviousNonComment->isNot(TT_TemplateCloser) || Current.NestingLevel != 0) && - !PreviousNonComment->isOneOf(TT_BinaryOperator, TT_JavaAnnotation, + !PreviousNonComment->isOneOf(TT_BinaryOperator, TT_FunctionAnnotation, + TT_JavaAnnotation, TT_LeadingJavaAnnotation) && Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope()) State.Stack.back().BreakBeforeParameter = true; @@ -568,7 +574,8 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { return State.Stack.back().VariablePos; if ((PreviousNonComment && (PreviousNonComment->ClosesTemplateDeclaration || - PreviousNonComment->isOneOf(TT_AttributeParen, TT_JavaAnnotation, + PreviousNonComment->isOneOf(TT_AttributeParen, TT_FunctionAnnotation, + TT_JavaAnnotation, TT_LeadingJavaAnnotation))) || (!Style.IndentWrappedFunctionNames && NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h index 0fc20de3c8..c934398b1a 100644 --- a/lib/Format/FormatToken.h +++ b/lib/Format/FormatToken.h @@ -42,6 +42,7 @@ enum TokenType { TT_DesignatedInitializerPeriod, TT_DictLiteral, TT_ForEachMacro, + TT_FunctionAnnotation, TT_FunctionDeclarationName, TT_FunctionLBrace, TT_FunctionTypeLParen, diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 94de217eb8..abd9be6d22 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -493,7 +493,8 @@ private: if (Line.MustBeDeclaration && Contexts.size() == 1 && !Contexts.back().IsExpression && Line.First->isNot(TT_ObjCProperty) && (!Tok->Previous || - !Tok->Previous->isOneOf(tok::kw_decltype, TT_LeadingJavaAnnotation))) + !Tok->Previous->isOneOf(tok::kw_decltype, TT_LeadingJavaAnnotation, + TT_FunctionAnnotation))) Line.MightBeFunctionDecl = true; break; case tok::l_square: @@ -915,9 +916,16 @@ private: } else { Current.Type = TT_LineComment; } + } else if (Current.is(tok::l_paren) && Current.Previous && + Current.Previous->is(TT_FunctionAnnotation)) { + Current.Type = TT_FunctionAnnotation; } else if (Current.is(tok::r_paren)) { if (rParenEndsCast(Current)) Current.Type = TT_CastRParen; + if (Current.MatchingParen && + Current.MatchingParen->is(TT_FunctionAnnotation) && Current.Next && + !Current.Next->isOneOf(tok::semi, tok::colon)) + Current.Type = TT_FunctionAnnotation; } else if (Current.is(tok::at) && Current.Next) { if (Current.Next->isStringLiteral()) { Current.Type = TT_ObjCStringLiteral; @@ -968,6 +976,11 @@ private: TT_LeadingJavaAnnotation)) { Current.Type = Current.Previous->Type; } + } else if (Current.is(tok::identifier) && + Current.TokenText == Current.TokenText.upper() && + (!Current.Previous || + Current.Previous->ClosesTemplateDeclaration)) { + Current.Type = TT_FunctionAnnotation; } } diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index f7510c8618..5e69e05d4a 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -4040,6 +4040,14 @@ TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) { " aaaaaaaaaaaaaaaaaaaaaaaaa;"); } +TEST_F(FormatTest, FunctionAnnotations) { + verifyFormat("DEPRECATED(\"Use NewClass::NewFunction instead.\")\n" + "string OldFunction(const string ¶meter) {}"); + verifyFormat("template \n" + "DEPRECATED(\"Use NewClass::NewFunction instead.\")\n" + "string OldFunction(const string ¶meter) {}"); +} + TEST_F(FormatTest, BreaksDesireably) { verifyFormat("if (aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n" " aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n" -- 2.40.0