Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -1698,7 +1698,12 @@ return 110; if (InFunctionDecl && Right.NestingLevel == 0) return Style.PenaltyReturnTypeOnItsOwnLine; - return 200; + unsigned penalty = 200; + if(Right.is(TT_StartOfName)) { + // Apply the break penalty for objective-c methods with with no parameters. + penalty = std::max(penalty, Style.PenaltyBreakBeforeFirstCallParameter); + } + return penalty; } if (Right.is(TT_PointerOrReference)) return 190; @@ -1745,8 +1750,15 @@ // In Objective-C method expressions, prefer breaking before "param:" over // breaking after it. - if (Right.is(TT_SelectorName)) + if (Right.is(TT_SelectorName)) { + // While we prefer breaking before "param:", if this is the first paramater + // apply PenaltyBreakBeforeFirstCallParameter + if (Right.LongestObjCSelectorName != 0) { + return Style.PenaltyBreakBeforeFirstCallParameter; + } return 0; + } + if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr)) return Line.MightBeFunctionDecl ? 50 : 500; Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -7323,6 +7323,29 @@ " aaa:aaa];"); verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n" " [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);"); + + // Allow PenaltyBreakBeforeFirstCallParameter to stop us from breaking before + // the first selector name. + FormatStyle selectorBreakStyle = getGoogleStyleWithColumns(60); + selectorBreakStyle.PenaltyBreakBeforeFirstCallParameter = 10000; + verifyFormat("[self function1:[OtherType function2:longParamaterName1\n" + " param:longParameterName2]];", + selectorBreakStyle); + + // But don't break if the callee is an expression + /*TODO: This is what it should ideally look like. + verifyFormat( + "[[self foo] function:[OtherType function2:longParamaterName\n" + " param:longParameterName2]];", + selectorBreakStyle); + */ + + // TODO: logic in ContinuationIndenter::moveStatePastFakeLParens adds more + // spaces than expected to second line. + verifyFormat("[[self foo] function:\n" + " [OtherType function2:longParamaterName\n" + " param:longParameterName2]];", + selectorBreakStyle); } TEST_F(FormatTest, ObjCAt) {