Index: cfe/trunk/lib/Format/UnwrappedLineParser.cpp =================================================================== --- cfe/trunk/lib/Format/UnwrappedLineParser.cpp +++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp @@ -715,6 +715,13 @@ return; bool PreviousMustBeValue = mustBeJSIdentOrValue(Keywords, Previous); + if (PreviousMustBeValue && Line && Line->Tokens.size() > 1) { + // If the token before the previous one is an '@', the previous token is an + // annotation and can precede another identifier/value. + const FormatToken *PrePrevious = std::next(Line->Tokens.rend(), 2)->Tok; + if (PrePrevious->is(tok::at)) + return; + } if (Next->is(tok::exclaim) && PreviousMustBeValue) addUnwrappedLine(); bool NextMustBeValue = mustBeJSIdentOrValue(Keywords, Next); Index: cfe/trunk/unittests/Format/FormatTestJS.cpp =================================================================== --- cfe/trunk/unittests/Format/FormatTestJS.cpp +++ cfe/trunk/unittests/Format/FormatTestJS.cpp @@ -686,6 +686,8 @@ verifyFormat("x instanceof String", "x\n" "instanceof\n" "String"); + verifyFormat("function f(@Foo bar) {}", "function f(@Foo\n" + " bar) {}"); } TEST_F(FormatTestJS, ClosureStyleCasts) {