From: Daniel Jasper Date: Mon, 11 May 2015 15:15:48 +0000 (+0000) Subject: clang-format: Support aligning ObjC string literals. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2bfdd4f5d5994237b4c6fbde34bf038e63358af4;p=clang clang-format: Support aligning ObjC string literals. Before: NSString s = @"aaaa" @"bbbb"; After: NSString s = @"aaaa" @"bbbb"; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237000 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index 1c262c2be9..54b8c510d7 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -542,7 +542,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { if (Current.is(tok::identifier) && Current.Next && Current.Next->is(TT_DictLiteral)) return State.Stack.back().Indent; - if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0) + if ((NextNonComment->isStringLiteral() || + NextNonComment->is(TT_ObjCStringLiteral)) && + State.StartOfStringLiteral != 0) return State.StartOfStringLiteral; if (NextNonComment->is(tok::lessless) && State.Stack.back().FirstLessLess != 0) @@ -690,7 +692,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, moveStatePastScopeCloser(State); moveStatePastFakeRParens(State); - if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) { + if ((Current.isStringLiteral() || Current.is(TT_ObjCStringLiteral)) && + State.StartOfStringLiteral == 0) { State.StartOfStringLiteral = State.Column; } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) && !Current.isStringLiteral()) { diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h index 85e5eb2ceb..0fc20de3c8 100644 --- a/lib/Format/FormatToken.h +++ b/lib/Format/FormatToken.h @@ -63,6 +63,7 @@ enum TokenType { TT_ObjCMethodExpr, TT_ObjCMethodSpecifier, TT_ObjCProperty, + TT_ObjCStringLiteral, TT_OverloadedOperator, TT_OverloadedOperatorLParen, TT_PointerOrReference, diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 67a66fcbd4..58ce7aef74 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -915,17 +915,21 @@ private: if (rParenEndsCast(Current)) Current.Type = TT_CastRParen; } else if (Current.is(tok::at) && Current.Next) { - switch (Current.Next->Tok.getObjCKeywordID()) { - case tok::objc_interface: - case tok::objc_implementation: - case tok::objc_protocol: - Current.Type = TT_ObjCDecl; - break; - case tok::objc_property: - Current.Type = TT_ObjCProperty; - break; - default: - break; + if (Current.Next->isStringLiteral()) { + Current.Type = TT_ObjCStringLiteral; + } else { + switch (Current.Next->Tok.getObjCKeywordID()) { + case tok::objc_interface: + case tok::objc_implementation: + case tok::objc_protocol: + Current.Type = TT_ObjCDecl; + break; + case tok::objc_property: + Current.Type = TT_ObjCProperty; + break; + default: + break; + } } } else if (Current.is(tok::period)) { FormatToken *PreviousNoComment = Current.getPreviousNonComment(); @@ -1980,8 +1984,10 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, return Left.BlockKind != BK_BracedInit && Left.isNot(TT_CtorInitializerColon) && (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline); - if (Right.Previous->isTrailingComment() || - (Right.isStringLiteral() && Right.Previous->isStringLiteral())) + if (Left.isTrailingComment()) + return true; + if (Left.isStringLiteral() && + (Right.isStringLiteral() || Right.is(TT_ObjCStringLiteral))) return true; if (Right.Previous->IsUnterminatedLiteral) return true; diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 9098d2b9bf..91540d4f2d 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -4715,11 +4715,16 @@ TEST_F(FormatTest, AlignsStringLiterals) { " \"jkl\");"); verifyFormat("f(L\"a\"\n" - " L\"b\")"); + " L\"b\");"); verifyFormat("#define A(X) \\\n" " L\"aaaaa\" #X L\"bbbbbb\" \\\n" " L\"ccccc\"", getLLVMStyleWithColumns(25)); + + verifyFormat("f(@\"a\"\n" + " @\"b\");"); + verifyFormat("NSString s = @\"a\"\n" + " @\"b\";"); } TEST_F(FormatTest, AlwaysBreakAfterDefinitionReturnType) { @@ -4817,9 +4822,9 @@ TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { // Exempt ObjC strings for now. EXPECT_EQ("NSString *const kString = @\"aaaa\"\n" - " \"bbbb\";", + " @\"bbbb\";", format("NSString *const kString = @\"aaaa\"\n" - "\"bbbb\";", + "@\"bbbb\";", Break)); Break.ColumnLimit = 0;