r336521 - [clang-format/ObjC] Put ObjC method arguments into one line when they fit
Author: jolesiak Date: Mon Jul 9 00:08:45 2018 New Revision: 336521 URL: http://llvm.org/viewvc/llvm-project?rev=336521=rev Log: [clang-format/ObjC] Put ObjC method arguments into one line when they fit Reapply D47195: Currently BreakBeforeParameter is set to true everytime message receiver spans multiple lines, e.g.: ``` [[object block:^{ return 42; }] aa:42 bb:42]; ``` will be formatted: ``` [[object block:^{ return 42; }] aa:42 bb:42]; ``` even though arguments could fit into one line. This change fixes this behavior. Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=336521=336520=336521=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Mon Jul 9 00:08:45 2018 @@ -1398,6 +1398,30 @@ void ContinuationIndenter::moveStatePast (Current.is(tok::greater) && Current.is(TT_DictLiteral State.Stack.pop_back(); + // Reevaluate whether ObjC message arguments fit into one line. + // If a receiver spans multiple lines, e.g.: + // [[object block:^{ + // return 42; + // }] a:42 b:42]; + // BreakBeforeParameter is calculated based on an incorrect assumption + // (it is checked whether the whole expression fits into one line without + // considering a line break inside a message receiver). + // We check whether arguements fit after receiver scope closer (into the same + // line). + if (State.Stack.back().BreakBeforeParameter && Current.MatchingParen && + Current.MatchingParen->Previous) { +const FormatToken = *Current.MatchingParen->Previous; +if (CurrentScopeOpener.is(TT_ObjCMethodExpr) && +CurrentScopeOpener.MatchingParen) { + int NecessarySpaceInLine = + getLengthToMatchingParen(CurrentScopeOpener, State.Stack) + + CurrentScopeOpener.TotalLength - Current.TotalLength - 1; + if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <= + Style.ColumnLimit) +State.Stack.back().BreakBeforeParameter = false; +} + } + if (Current.is(tok::r_square)) { // If this ends the array subscript expr, reset the corresponding value. const FormatToken *NextNonComment = Current.getNextNonComment(); Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=336521=336520=336521=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Mon Jul 9 00:08:45 2018 @@ -820,6 +820,48 @@ TEST_F(FormatTestObjC, FormatObjCMethodE verifyFormat("aa = [aa aa:aa\n" " aa:aa];"); + // Message receiver taking multiple lines. + // Non-corner case. + verifyFormat("[[object block:^{\n" + " return 42;\n" + "}] a:42 b:42];"); + // Arguments just fit into one line. + verifyFormat("[[object block:^{\n" + " return 42;\n" + "}] aaa:42 b:42];"); + // Arguments just over a column limit. + verifyFormat("[[object block:^{\n" + " return 42;\n" + "}] aaa:42\n" + "bb:42];"); + // Arguments just fit into one line. + Style.ColumnLimit = 23; + verifyFormat("[[obj a:42\n" + " b:42\n" + " c:42\n" + " d:42] e:42 f:42];"); + + // Arguments do not fit into one line with a receiver. + Style.ColumnLimit = 20; + verifyFormat("[[obj a:42] a:42\n" + "b:42];"); + verifyFormat("[[obj a:42] a:42\n" + "b:42\n" + "c:42];"); + verifyFormat("[[obj aa:42\n" + " b:42]\n" + "cc:42\n" + " d:42];"); + + // Avoid breaking receiver expression. + Style.ColumnLimit = 30; + verifyFormat("fooo =\n" + "[[obj fooo] aaa:42\n" + "aaa:42];"); + verifyFormat("[[[obj foo] bar] aa:42\n" + " bb:42\n" + " cc:42];"); + Style.ColumnLimit = 70; verifyFormat( "void f() {\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r336520 - [clang-format/ObjC] Improve split priorities for ObjC methods
Author: jolesiak Date: Sun Jul 8 23:54:52 2018 New Revision: 336520 URL: http://llvm.org/viewvc/llvm-project?rev=336520=rev Log: [clang-format/ObjC] Improve split priorities for ObjC methods Reduce penalty for aligning ObjC method arguments using the colon alignment as this is the canonical way. Trying to fit a whole expression into one line should not force other line breaks (e.g. when ObjC method expression is a part of other expression). Modified: cfe/trunk/lib/Format/FormatToken.h cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/FormatToken.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=336520=336519=336520=diff == --- cfe/trunk/lib/Format/FormatToken.h (original) +++ cfe/trunk/lib/Format/FormatToken.h Sun Jul 8 23:54:52 2018 @@ -248,6 +248,11 @@ struct FormatToken { /// selector consist of. unsigned ObjCSelectorNameParts = 0; + /// The 0-based index of the parameter/argument. For ObjC it is set + /// for the selector name token. + /// For now calculated only for ObjC. + unsigned ParameterIndex = 0; + /// Stores the number of required fake parentheses and the /// corresponding operator precedence. /// Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=336520=336519=336520=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Sun Jul 8 23:54:52 2018 @@ -725,6 +725,8 @@ private: Contexts.back().LongestObjCSelectorName) Contexts.back().LongestObjCSelectorName = Tok->Previous->ColumnWidth; + Tok->Previous->ParameterIndex = + Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts; ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts; } } else if (Contexts.back().ColonIsForRangeExpr) { @@ -2142,8 +2144,20 @@ void TokenAnnotator::calculateFormatting // FIXME: Only calculate this if CanBreakBefore is true once static // initializers etc. are sorted out. // FIXME: Move magic numbers to a better place. -Current->SplitPenalty = 20 * Current->BindingStrength + -splitPenalty(Line, *Current, InFunctionDecl); + +// Reduce penalty for aligning ObjC method arguments using the colon +// alignment as this is the canonical way (still prefer fitting everything +// into one line if possible). Trying to fit a whole expression into one +// line should not force other line breaks (e.g. when ObjC method +// expression is a part of other expression). +Current->SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl); +if (Style.Language == FormatStyle::LK_ObjC && +Current->is(TT_SelectorName) && Current->ParameterIndex > 0) { + if (Current->ParameterIndex == 1) +Current->SplitPenalty += 5 * Current->BindingStrength; +} else { + Current->SplitPenalty += 20 * Current->BindingStrength; +} Current = Current->Next; } Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=336520=336519=336520=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Sun Jul 8 23:54:52 2018 @@ -678,6 +678,18 @@ TEST_F(FormatTestObjC, FormatObjCMethodE verifyFormat("[(id)foo bar:(id) ? baz : quux];"); verifyFormat("4 > 4 ? (id)a : (id)baz;"); + unsigned PreviousColumnLimit = Style.ColumnLimit; + Style.ColumnLimit = 50; + // Instead of: + // bool a = + // ([object a:42] == 0 || [object a:42 + //b:42] == 0); + verifyFormat("bool a = ([object a:42] == 0 ||\n" + " [object a:42 b:42] == 0);"); + Style.ColumnLimit = PreviousColumnLimit; + verifyFormat("bool a = ([ a] == a ||\n" + " [ a] == );"); + // This tests that the formatter doesn't break after "backing" but before ":", // which would be at 80 columns. verifyFormat( @@ -754,11 +766,10 @@ TEST_F(FormatTestObjC, FormatObjCMethodE "[self a:aaa, aaa, aaa,\n" "aaa, aaa, aaa,\n" "aaa, aaa];"); + verifyFormat("[self // break\n" " a:a\n" "aaa:aaa];"); - verifyFormat("bool a = ([ a] == a ||\n" - "
r336519 - [clang-format/ObjC] Prohibit breaking after a bracket opening ObjC method expression
Author: jolesiak Date: Sun Jul 8 23:04:58 2018 New Revision: 336519 URL: http://llvm.org/viewvc/llvm-project?rev=336519=rev Log: [clang-format/ObjC] Prohibit breaking after a bracket opening ObjC method expression Summary: Don't break after a "[" opening an ObjC method expression. Tests are added in D48719 where formatting is improved (to avoid adding and changing tests immediately). Reviewers: benhamilton, klimek Reviewed By: benhamilton Subscribers: acoomans, cfe-commits Differential Revision: https://reviews.llvm.org/D48718 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=336519=336518=336519=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Sun Jul 8 23:04:58 2018 @@ -321,6 +321,9 @@ bool ContinuationIndenter::canBreak(cons State.Stack.back().NoLineBreakInOperand) return false; + if (Previous.is(tok::l_square) && Previous.is(TT_ObjCMethodExpr)) +return false; + return !State.Stack.back().NoLineBreak; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r336518 - [clang-format/ObjC] Fix counting selector name parts for ObjC
Author: jolesiak Date: Sun Jul 8 22:58:51 2018 New Revision: 336518 URL: http://llvm.org/viewvc/llvm-project?rev=336518=rev Log: [clang-format/ObjC] Fix counting selector name parts for ObjC Summary: Counts selector parts also for method declarations and counts correctly for methods without arguments. This is an internal change and doesn't influence formatting on its own (at the current state). Its lack would be visible after applying D48719. Reviewers: benhamilton, klimek Reviewed By: benhamilton Subscribers: acoomans, cfe-commits Differential Revision: https://reviews.llvm.org/D48716 Modified: cfe/trunk/lib/Format/FormatToken.h cfe/trunk/lib/Format/TokenAnnotator.cpp Modified: cfe/trunk/lib/Format/FormatToken.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=336518=336517=336518=diff == --- cfe/trunk/lib/Format/FormatToken.h (original) +++ cfe/trunk/lib/Format/FormatToken.h Sun Jul 8 22:58:51 2018 @@ -243,8 +243,9 @@ struct FormatToken { /// e.g. because several of them are block-type. unsigned LongestObjCSelectorName = 0; - /// How many parts ObjC selector have (i.e. how many parameters method - /// has). + /// If this is the first ObjC selector name in an ObjC method + /// definition or call, this contains the number of parts that the whole + /// selector consist of. unsigned ObjCSelectorNameParts = 0; /// Stores the number of required fake parentheses and the Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=336518=336517=336518=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Sun Jul 8 22:58:51 2018 @@ -515,11 +515,23 @@ private: } Left->MatchingParen = CurrentToken; CurrentToken->MatchingParen = Left; +// FirstObjCSelectorName is set when a colon is found. This does +// not work, however, when the method has no parameters. +// Here, we set FirstObjCSelectorName when the end of the method call is +// reached, in case it was not set already. +if (!Contexts.back().FirstObjCSelectorName) { +FormatToken* Previous = CurrentToken->getPreviousNonComment(); +if (Previous && Previous->is(TT_SelectorName)) { + Previous->ObjCSelectorNameParts = 1; + Contexts.back().FirstObjCSelectorName = Previous; +} +} else { + Left->ParameterCount = + Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts; +} if (Contexts.back().FirstObjCSelectorName) { Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = Contexts.back().LongestObjCSelectorName; - Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts = - Left->ParameterCount; if (Left->BlockParameterCount > 1) Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0; } @@ -539,11 +551,6 @@ private: TT_DesignatedInitializerLSquare)) { Left->Type = TT_ObjCMethodExpr; StartsObjCMethodExpr = true; - // ParameterCount might have been set to 1 before expression was - // recognized as ObjCMethodExpr (as '1 + number of commas' formula is - // used for other expression types). Parameter counter has to be, - // therefore, reset to 0. - Left->ParameterCount = 0; Contexts.back().ColonIsObjCMethodExpr = true; if (Parent && Parent->is(tok::r_paren)) // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen. @@ -617,12 +624,12 @@ private: } void updateParameterCount(FormatToken *Left, FormatToken *Current) { +// For ObjC methods, the number of parameters is calculated differently as +// method declarations have a different structure (the parameters are not +// inside a bracket scope). if (Current->is(tok::l_brace) && Current->BlockKind == BK_Block) ++Left->BlockParameterCount; -if (Left->Type == TT_ObjCMethodExpr) { - if (Current->is(tok::colon)) -++Left->ParameterCount; -} else if (Current->is(tok::comma)) { +if (Current->is(tok::comma)) { ++Left->ParameterCount; if (!Left->Role) Left->Role.reset(new CommaSeparatedList(Style)); @@ -718,6 +725,7 @@ private: Contexts.back().LongestObjCSelectorName) Contexts.back().LongestObjCSelectorName = Tok->Previous->ColumnWidth; + ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts; } } else if (Contexts.back().ColonIsForRangeExpr) { Tok->Type = TT_RangeBasedForLoopColon;
r335338 - [clang-format] Add AlwaysBreakBeforeMultilineString tests
Author: jolesiak Date: Fri Jun 22 04:57:55 2018 New Revision: 335338 URL: http://llvm.org/viewvc/llvm-project?rev=335338=rev Log: [clang-format] Add AlwaysBreakBeforeMultilineString tests Summary: Followup to D47393. Reviewers: stephanemoore Reviewed By: stephanemoore Subscribers: benhamilton, cfe-commits Differential Revision: https://reviews.llvm.org/D48432 Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=335338=335337=335338=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Fri Jun 22 04:57:55 2018 @@ -1227,6 +1227,15 @@ TEST_F(FormatTestObjC, AlwaysBreakBefore " @\"\");"); verifyFormat("(qqq, @\"\"\n" " @\"\");"); + verifyFormat("[ :@\"\"\n" + " @\"\"];"); + verifyFormat(" = [ :@\"\"\n" + " @\"\"];"); + verifyFormat("[ :@\"\"\n" + " @\"\"\n" + "rr:42\n" + "ss:@\"ee\"\n" + " @\"f\"];"); } } // end namespace ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r333539 - Revert "[clang-format] Fix putting ObjC message arguments in one line for multiline receiver"
Author: jolesiak Date: Wed May 30 05:57:58 2018 New Revision: 333539 URL: http://llvm.org/viewvc/llvm-project?rev=333539=rev Log: Revert "[clang-format] Fix putting ObjC message arguments in one line for multiline receiver" Summary: This reverts commit db9e5e9a616d7fdd4d1ba4c3b2cd89d8a0238533 (rC333171). Mentioned change introduced unintended formatting of ObjC code due to split priorities inherited from C/C++, e.g.: ``` fooo = [ [obj fooo] aaa:42 aaa:42]; ``` instead of ``` fooo = [[obj fooo] aaa:42 aaa:42]; ``` when formatted with ColumnLimit = 30. Reviewers: krasimir Reviewed By: krasimir Subscribers: benhamilton, klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D47527 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=333539=333538=333539=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Wed May 30 05:57:58 2018 @@ -1387,29 +1387,6 @@ void ContinuationIndenter::moveStatePast (Current.is(tok::greater) && Current.is(TT_DictLiteral State.Stack.pop_back(); - // Reevaluate whether ObjC message arguments fit into one line. - // If a receiver spans multiple lines, e.g.: - // [[object block:^{ - // return 42; - // }] a:42 b:42]; - // BreakBeforeParameter is calculated based on an incorrect assumption - // (it is checked whether the whole expression fits into one line without - // considering a line break inside a message receiver). - // We check whether arguements fit after receiver scope closer (into the same - // line). - if (Current.MatchingParen && Current.MatchingParen->Previous) { -const FormatToken = *Current.MatchingParen->Previous; -if (CurrentScopeOpener.is(TT_ObjCMethodExpr) && -CurrentScopeOpener.MatchingParen) { - int NecessarySpaceInLine = - getLengthToMatchingParen(CurrentScopeOpener, State.Stack) + - CurrentScopeOpener.TotalLength - Current.TotalLength - 1; - if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <= - Style.ColumnLimit) -State.Stack.back().BreakBeforeParameter = false; -} - } - if (Current.is(tok::r_square)) { // If this ends the array subscript expr, reset the corresponding value. const FormatToken *NextNonComment = Current.getNextNonComment(); Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=333539=333538=333539=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Wed May 30 05:57:58 2018 @@ -796,41 +796,6 @@ TEST_F(FormatTestObjC, FormatObjCMethodE verifyFormat("[((Foo *)foo) bar];"); verifyFormat("[((Foo *)foo) bar:1 blech:2];"); - // Message receiver taking multiple lines. - Style.ColumnLimit = 20; - // Non-corner case. - verifyFormat("[[object block:^{\n" - " return 42;\n" - "}] a:42 b:42];"); - // Arguments just fit into one line. - verifyFormat("[[object block:^{\n" - " return 42;\n" - "}] aaa:42 b:42];"); - // Arguments just over a column limit. - verifyFormat("[[object block:^{\n" - " return 42;\n" - "}] aaa:42\n" - "bb:42];"); - // Arguments just fit into one line. - Style.ColumnLimit = 23; - verifyFormat("[[obj a:42\n" - " b:42\n" - " c:42\n" - " d:42] e:42 f:42];"); - - // Arguments do not fit into one line with a receiver. - Style.ColumnLimit = 20; - verifyFormat("[[obj a:42] a:42\n" - "b:42];"); - verifyFormat("[[obj a:42] a:42\n" - "b:42\n" - "c:42];"); - verifyFormat("[[obj aa:42\n" - " b:42]\n" - "cc:42\n" - " d:42];"); - - Style.ColumnLimit = 70; verifyFormat( "void f() {\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r333171 - [clang-format] Fix putting ObjC message arguments in one line for multiline receiver
Author: jolesiak Date: Thu May 24 03:50:36 2018 New Revision: 333171 URL: http://llvm.org/viewvc/llvm-project?rev=333171=rev Log: [clang-format] Fix putting ObjC message arguments in one line for multiline receiver Summary: Reapply reverted changes from D46879. Currently BreakBeforeParameter is set to true everytime message receiver spans multiple lines, e.g.: ``` [[object block:^{ return 42; }] aa:42 bb:42]; ``` will be formatted: ``` [[object block:^{ return 42; }] aa:42 bb:42]; ``` even though arguments could fit into one line. This change fixes this behavior. Test Plan: make -j12 FormatTests && tools/clang/unittests/Format/FormatTests Reviewers: benhamilton, krasimir Reviewed By: benhamilton, krasimir Subscribers: djasper, klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D47195 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=333171=333170=333171=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Thu May 24 03:50:36 2018 @@ -1387,6 +1387,29 @@ void ContinuationIndenter::moveStatePast (Current.is(tok::greater) && Current.is(TT_DictLiteral State.Stack.pop_back(); + // Reevaluate whether ObjC message arguments fit into one line. + // If a receiver spans multiple lines, e.g.: + // [[object block:^{ + // return 42; + // }] a:42 b:42]; + // BreakBeforeParameter is calculated based on an incorrect assumption + // (it is checked whether the whole expression fits into one line without + // considering a line break inside a message receiver). + // We check whether arguements fit after receiver scope closer (into the same + // line). + if (Current.MatchingParen && Current.MatchingParen->Previous) { +const FormatToken = *Current.MatchingParen->Previous; +if (CurrentScopeOpener.is(TT_ObjCMethodExpr) && +CurrentScopeOpener.MatchingParen) { + int NecessarySpaceInLine = + getLengthToMatchingParen(CurrentScopeOpener, State.Stack) + + CurrentScopeOpener.TotalLength - Current.TotalLength - 1; + if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <= + Style.ColumnLimit) +State.Stack.back().BreakBeforeParameter = false; +} + } + if (Current.is(tok::r_square)) { // If this ends the array subscript expr, reset the corresponding value. const FormatToken *NextNonComment = Current.getNextNonComment(); Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=333171=333170=333171=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Thu May 24 03:50:36 2018 @@ -796,6 +796,41 @@ TEST_F(FormatTestObjC, FormatObjCMethodE verifyFormat("[((Foo *)foo) bar];"); verifyFormat("[((Foo *)foo) bar:1 blech:2];"); + // Message receiver taking multiple lines. + Style.ColumnLimit = 20; + // Non-corner case. + verifyFormat("[[object block:^{\n" + " return 42;\n" + "}] a:42 b:42];"); + // Arguments just fit into one line. + verifyFormat("[[object block:^{\n" + " return 42;\n" + "}] aaa:42 b:42];"); + // Arguments just over a column limit. + verifyFormat("[[object block:^{\n" + " return 42;\n" + "}] aaa:42\n" + "bb:42];"); + // Arguments just fit into one line. + Style.ColumnLimit = 23; + verifyFormat("[[obj a:42\n" + " b:42\n" + " c:42\n" + " d:42] e:42 f:42];"); + + // Arguments do not fit into one line with a receiver. + Style.ColumnLimit = 20; + verifyFormat("[[obj a:42] a:42\n" + "b:42];"); + verifyFormat("[[obj a:42] a:42\n" + "b:42\n" + "c:42];"); + verifyFormat("[[obj aa:42\n" + " b:42]\n" + "cc:42\n" + " d:42];"); + + Style.ColumnLimit = 70; verifyFormat( "void f() {\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r332998 - Revert "[clang-format] Fix putting ObjC message arguments in one line for multiline receiver"
Author: jolesiak Date: Tue May 22 09:44:42 2018 New Revision: 332998 URL: http://llvm.org/viewvc/llvm-project?rev=332998=rev Log: Revert "[clang-format] Fix putting ObjC message arguments in one line for multiline receiver" Summary: Reverts D46879 Reviewers: benhamilton Reviewed By: benhamilton Subscribers: krasimir, klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D47205 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=332998=332997=332998=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Tue May 22 09:44:42 2018 @@ -1073,34 +1073,8 @@ unsigned ContinuationIndenter::moveState if (Current.isMemberAccess()) State.Stack.back().StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column; - if (Current.is(TT_SelectorName) && - !State.Stack.back().ObjCSelectorNameFound) { + if (Current.is(TT_SelectorName)) State.Stack.back().ObjCSelectorNameFound = true; - -// Reevaluate whether ObjC message arguments fit into one line. -// If a receiver spans multiple lines, e.g.: -// [[object block:^{ -// return 42; -// }] a:42 b:42]; -// BreakBeforeParameter is calculated based on an incorrect assumption -// (it is checked whether the whole expression fits into one line without -// considering a line break inside a message receiver). -if (Current.Previous && Current.Previous->closesScope() && -Current.Previous->MatchingParen && -Current.Previous->MatchingParen->Previous) { - const FormatToken = - *Current.Previous->MatchingParen->Previous; - if (CurrentScopeOpener.is(TT_ObjCMethodExpr) && - CurrentScopeOpener.MatchingParen) { -int NecessarySpaceInLine = -getLengthToMatchingParen(CurrentScopeOpener, State.Stack) + -CurrentScopeOpener.TotalLength - Current.TotalLength - 1; -if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <= -Style.ColumnLimit) - State.Stack.back().BreakBeforeParameter = false; - } -} - } if (Current.is(TT_CtorInitializerColon) && Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) { // Indent 2 from the column, so: Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=332998=332997=332998=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Tue May 22 09:44:42 2018 @@ -796,35 +796,6 @@ TEST_F(FormatTestObjC, FormatObjCMethodE verifyFormat("[((Foo *)foo) bar];"); verifyFormat("[((Foo *)foo) bar:1 blech:2];"); - // Message receiver taking multiple lines. - Style.ColumnLimit = 20; - // Non-corner case. - verifyFormat("[[object block:^{\n" - " return 42;\n" - "}] a:42 b:42];"); - // Arguments just fit into one line. - verifyFormat("[[object block:^{\n" - " return 42;\n" - "}] aaa:42 b:42];"); - // Arguments just over a column limit. - verifyFormat("[[object block:^{\n" - " return 42;\n" - "}] aaa:42\n" - "bb:42];"); - // Non-corner case. - verifyFormat("[[object aaa:42\n" - " b:42]\n" - "cc:42 d:42];"); - // Arguments just fit into one line. - verifyFormat("[[object aaa:42\n" - " b:42]\n" - "cc:42 d:42];"); - // Arguments just over a column limit. - verifyFormat("[[object aaa:42\n" - " b:42]\n" - "cc:42\n" - "dd:42];"); - Style.ColumnLimit = 70; verifyFormat( "void f() {\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r332582 - [clang-format] Fix putting ObjC message arguments in one line for multiline receiver
Author: jolesiak Date: Thu May 17 01:35:15 2018 New Revision: 332582 URL: http://llvm.org/viewvc/llvm-project?rev=332582=rev Log: [clang-format] Fix putting ObjC message arguments in one line for multiline receiver Summary: Currently BreakBeforeParameter is set to true everytime message receiver spans multiple lines, e.g.: ``` [[object block:^{ return 42; }] aa:42 bb:42]; ``` will be formatted: ``` [[object block:^{ return 42; }] aa:42 bb:42]; ``` even though arguments could fit into one line. This change fixes this behavior. Test Plan: make -j12 FormatTests && tools/clang/unittests/Format/FormatTests Reviewers: benhamilton, djasper Reviewed By: benhamilton Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D46879 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=332582=332581=332582=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Thu May 17 01:35:15 2018 @@ -1073,8 +1073,34 @@ unsigned ContinuationIndenter::moveState if (Current.isMemberAccess()) State.Stack.back().StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column; - if (Current.is(TT_SelectorName)) + if (Current.is(TT_SelectorName) && + !State.Stack.back().ObjCSelectorNameFound) { State.Stack.back().ObjCSelectorNameFound = true; + +// Reevaluate whether ObjC message arguments fit into one line. +// If a receiver spans multiple lines, e.g.: +// [[object block:^{ +// return 42; +// }] a:42 b:42]; +// BreakBeforeParameter is calculated based on an incorrect assumption +// (it is checked whether the whole expression fits into one line without +// considering a line break inside a message receiver). +if (Current.Previous && Current.Previous->closesScope() && +Current.Previous->MatchingParen && +Current.Previous->MatchingParen->Previous) { + const FormatToken = + *Current.Previous->MatchingParen->Previous; + if (CurrentScopeOpener.is(TT_ObjCMethodExpr) && + CurrentScopeOpener.MatchingParen) { +int NecessarySpaceInLine = +getLengthToMatchingParen(CurrentScopeOpener, State.Stack) + +CurrentScopeOpener.TotalLength - Current.TotalLength - 1; +if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <= +Style.ColumnLimit) + State.Stack.back().BreakBeforeParameter = false; + } +} + } if (Current.is(TT_CtorInitializerColon) && Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) { // Indent 2 from the column, so: Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=332582=332581=332582=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Thu May 17 01:35:15 2018 @@ -792,6 +792,35 @@ TEST_F(FormatTestObjC, FormatObjCMethodE " a = 42;\n" "}];"); + // Message receiver taking multiple lines. + Style.ColumnLimit = 20; + // Non-corner case. + verifyFormat("[[object block:^{\n" + " return 42;\n" + "}] a:42 b:42];"); + // Arguments just fit into one line. + verifyFormat("[[object block:^{\n" + " return 42;\n" + "}] aaa:42 b:42];"); + // Arguments just over a column limit. + verifyFormat("[[object block:^{\n" + " return 42;\n" + "}] aaa:42\n" + "bb:42];"); + // Non-corner case. + verifyFormat("[[object aaa:42\n" + " b:42]\n" + "cc:42 d:42];"); + // Arguments just fit into one line. + verifyFormat("[[object aaa:42\n" + " b:42]\n" + "cc:42 d:42];"); + // Arguments just over a column limit. + verifyFormat("[[object aaa:42\n" + " b:42]\n" + "cc:42\n" + "dd:42];"); + Style.ColumnLimit = 70; verifyFormat( "void f() {\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r325221 - [clang-format] Improve ObjC headers detection
Author: jolesiak Date: Thu Feb 15 00:47:56 2018 New Revision: 325221 URL: http://llvm.org/viewvc/llvm-project?rev=325221=rev Log: [clang-format] Improve ObjC headers detection Summary: Detect ObjC characteristic types when they start a line and add additional keywords. Reviewers: benhamilton Reviewed By: benhamilton Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D43124 Modified: cfe/trunk/lib/Format/Format.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=325221=325220=325221=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Thu Feb 15 00:47:56 2018 @@ -1440,7 +1440,9 @@ private: "NSAffineTransform", "NSArray", "NSAttributedString", +"NSBundle", "NSCache", +"NSCalendar", "NSCharacterSet", "NSCountedSet", "NSData", @@ -1466,6 +1468,7 @@ private: "NSMutableString", "NSNumber", "NSNumberFormatter", +"NSObject", "NSOrderedSet", "NSPoint", "NSPointerArray", @@ -1475,17 +1478,19 @@ private: "NSSet", "NSSize", "NSString", +"NSTimeZone", "NSUInteger", "NSURL", "NSURLComponents", "NSURLQueryItem", "NSUUID", +"NSValue", }; for (auto : AnnotatedLines) { - for (FormatToken *FormatTok = Line->First->Next; FormatTok; + for (FormatToken *FormatTok = Line->First; FormatTok; FormatTok = FormatTok->Next) { -if ((FormatTok->Previous->is(tok::at) && +if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) && (FormatTok->isObjCAtKeyword(tok::objc_interface) || FormatTok->isObjCAtKeyword(tok::objc_implementation) || FormatTok->isObjCAtKeyword(tok::objc_protocol) || Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=325221=325220=325221=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Thu Feb 15 00:47:56 2018 @@ -113,10 +113,6 @@ TEST(FormatTestObjCStyle, DetectsObjCInH ASSERT_TRUE((bool)Style); EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language); - Style = getStyle("{}", "a.h", "none", "extern NSString *kFoo;\n"); - ASSERT_TRUE((bool)Style); - EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); - Style = getStyle("{}", "a.h", "none", "typedef NS_ENUM(NSInteger, Foo) {};\n"); ASSERT_TRUE((bool)Style); @@ -126,10 +122,6 @@ TEST(FormatTestObjCStyle, DetectsObjCInH ASSERT_TRUE((bool)Style); EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language); - Style = getStyle("{}", "a.h", "none", "extern NSInteger Foo();\n"); - ASSERT_TRUE((bool)Style); - EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); - Style = getStyle("{}", "a.h", "none", "inline void Foo() { Log(@\"Foo\"); }\n"); ASSERT_TRUE((bool)Style); @@ -154,6 +146,23 @@ TEST(FormatTestObjCStyle, DetectsObjCInH "inline void Foo() { int foo[] = {1, 2, 3}; }\n"); ASSERT_TRUE((bool)Style); EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language); + + // ObjC characteristic types. + Style = getStyle("{}", "a.h", "none", "extern NSString *kFoo;\n"); + ASSERT_TRUE((bool)Style); + EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); + + Style = getStyle("{}", "a.h", "none", "extern NSInteger Foo();\n"); + ASSERT_TRUE((bool)Style); + EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); + + Style = getStyle("{}", "a.h", "none", "NSObject *Foo();\n"); + ASSERT_TRUE((bool)Style); + EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); + + Style = getStyle("{}", "a.h", "none", "NSSet *Foo();\n"); + ASSERT_TRUE((bool)Style); + EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); } TEST_F(FormatTestObjC, FormatObjCTryCatch) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r324469 - [clang-format] Fix ObjC message arguments formatting.
Author: jolesiak Date: Wed Feb 7 02:35:08 2018 New Revision: 324469 URL: http://llvm.org/viewvc/llvm-project?rev=324469=rev Log: [clang-format] Fix ObjC message arguments formatting. Summary: Fixes formatting of ObjC message arguments when inline block is a first argument. Having inline block as a first argument when method has multiple parameters is discouraged by Apple: "It’s best practice to use only one block argument to a method. If the method also needs other non-block arguments, the block should come last" (https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html#//apple_ref/doc/uid/TP40011210-CH8-SW7), it should be correctly formatted nevertheless. Current formatting: ``` [object blockArgument:^{ a = 42; } anotherArg:42]; ``` Fixed (colon alignment): ``` [object blockArgument:^{ a = 42; } anotherArg:42]; ``` Test Plan: make -j12 FormatTests && tools/clang/unittests/Format/FormatTests Reviewers: krasimir, benhamilton Reviewed By: krasimir, benhamilton Subscribers: benhamilton, klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D42493 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/FormatToken.h cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=324469=324468=324469=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Wed Feb 7 02:35:08 2018 @@ -266,6 +266,11 @@ bool ContinuationIndenter::mustBreak(con return true; if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection) return true; + if (Style.Language == FormatStyle::LK_ObjC && + Current.ObjCSelectorNameParts > 1 && + Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) { +return true; + } if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) || (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) && Style.isCpp() && Modified: cfe/trunk/lib/Format/FormatToken.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=324469=324468=324469=diff == --- cfe/trunk/lib/Format/FormatToken.h (original) +++ cfe/trunk/lib/Format/FormatToken.h Wed Feb 7 02:35:08 2018 @@ -240,6 +240,10 @@ struct FormatToken { /// e.g. because several of them are block-type. unsigned LongestObjCSelectorName = 0; + /// \brief How many parts ObjC selector have (i.e. how many parameters method + /// has). + unsigned ObjCSelectorNameParts = 0; + /// \brief Stores the number of required fake parentheses and the /// corresponding operator precedence. /// Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=324469=324468=324469=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Wed Feb 7 02:35:08 2018 @@ -411,6 +411,8 @@ private: if (Contexts.back().FirstObjCSelectorName) { Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = Contexts.back().LongestObjCSelectorName; + Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts = + Left->ParameterCount; if (Left->BlockParameterCount > 1) Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0; } @@ -424,6 +426,11 @@ private: TT_DesignatedInitializerLSquare)) { Left->Type = TT_ObjCMethodExpr; StartsObjCMethodExpr = true; + // ParameterCount might have been set to 1 before expression was + // recognized as ObjCMethodExpr (as '1 + number of commas' formula is + // used for other expression types). Parameter counter has to be, + // therefore, reset to 0. + Left->ParameterCount = 0; Contexts.back().ColonIsObjCMethodExpr = true; if (Parent && Parent->is(tok::r_paren)) Parent->Type = TT_CastRParen; @@ -498,7 +505,10 @@ private: void updateParameterCount(FormatToken *Left, FormatToken *Current) { if (Current->is(tok::l_brace) && Current->BlockKind == BK_Block) ++Left->BlockParameterCount; -if (Current->is(tok::comma)) { +if (Left->Type == TT_ObjCMethodExpr) { + if (Current->is(tok::colon)) +++Left->ParameterCount; +} else if (Current->is(tok::comma)) { ++Left->ParameterCount; if (!Left->Role) Left->Role.reset(new
r324338 - Test commit - fixing a comment.
Author: jolesiak Date: Tue Feb 6 04:12:00 2018 New Revision: 324338 URL: http://llvm.org/viewvc/llvm-project?rev=324338=rev Log: Test commit - fixing a comment. Summary: A test commit. Reviewers: krasimir, benhamilton Reviewed By: krasimir Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D42901 Modified: cfe/trunk/lib/Format/ContinuationIndenter.h Modified: cfe/trunk/lib/Format/ContinuationIndenter.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.h?rev=324338=324337=324338=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.h (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.h Tue Feb 6 04:12:00 2018 @@ -314,8 +314,8 @@ struct ParenState { /// the same token. bool HasMultipleNestedBlocks : 1; - // \brief The start of a nested block (e.g. lambda introducer in C++ or - // "function" in JavaScript) is not wrapped to a new line. + /// \brief The start of a nested block (e.g. lambda introducer in C++ or + /// "function" in JavaScript) is not wrapped to a new line. bool NestedBlockInlined : 1; bool operator<(const ParenState ) const { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits