forked from OSchip/llvm-project
[clang-format] Do not break Objective-C string literals inside array literals
Summary: Concatenating Objective-C string literals inside an array literal raises the warning -Wobjc-string-concatenation (which is enabled by default). clang-format currently splits and concatenates string literals like the following: NSArray *myArray = @[ @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ]; into: NSArray *myArray = @[ @"aaaaaaaaaaaaaaaaaaaaaaaaaaaa" @"aaaaaaaaa" ]; which raises the warning. This is https://bugs.llvm.org/show_bug.cgi?id=36153 . The options I can think of to fix this are: 1) Have clang-format disable Wobjc-string-concatenation by emitting pragmas around the formatted code 2) Have clang-format wrap the string literals in a macro (which disables the warning) 3) Disable string splitting for Objective-C string literals inside array literals I think 1) has no precedent, and I couldn't find a good identity() macro for 2). So, this diff implements 3). Test Plan: make -j12 FormatTests && ./tools/clang/unittests/Format/FormatTests Reviewers: jolesiak, stephanemoore, djasper Reviewed By: jolesiak Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D42704 llvm-svn: 324618
This commit is contained in:
parent
976f317f0c
commit
09051f2925
|
@ -1285,6 +1285,9 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
|
|||
State.Stack.back().NestedBlockIndent = NestedBlockIndent;
|
||||
State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
|
||||
State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
|
||||
State.Stack.back().IsInsideObjCArrayLiteral =
|
||||
Current.is(TT_ArrayInitializerLSquare) && Current.Previous &&
|
||||
Current.Previous->is(tok::at);
|
||||
}
|
||||
|
||||
void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
|
||||
|
@ -1578,6 +1581,11 @@ std::unique_ptr<BreakableToken> ContinuationIndenter::createBreakableToken(
|
|||
// likely want to terminate the string before any line breaking is done.
|
||||
if (Current.IsUnterminatedLiteral)
|
||||
return nullptr;
|
||||
// Don't break string literals inside Objective-C array literals (doing so
|
||||
// raises the warning -Wobjc-string-concatenation).
|
||||
if (State.Stack.back().IsInsideObjCArrayLiteral) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StringRef Text = Current.TokenText;
|
||||
StringRef Prefix;
|
||||
|
|
|
@ -208,7 +208,8 @@ struct ParenState {
|
|||
NoLineBreakInOperand(false), LastOperatorWrapped(true),
|
||||
ContainsLineBreak(false), ContainsUnwrappedBuilder(false),
|
||||
AlignColons(true), ObjCSelectorNameFound(false),
|
||||
HasMultipleNestedBlocks(false), NestedBlockInlined(false) {}
|
||||
HasMultipleNestedBlocks(false), NestedBlockInlined(false),
|
||||
IsInsideObjCArrayLiteral(false) {}
|
||||
|
||||
/// \brief The position to which a specific parenthesis level needs to be
|
||||
/// indented.
|
||||
|
@ -318,6 +319,10 @@ struct ParenState {
|
|||
/// "function" in JavaScript) is not wrapped to a new line.
|
||||
bool NestedBlockInlined : 1;
|
||||
|
||||
/// \brief \c true if the current \c ParenState represents an Objective-C
|
||||
/// array literal.
|
||||
bool IsInsideObjCArrayLiteral : 1;
|
||||
|
||||
bool operator<(const ParenState &Other) const {
|
||||
if (Indent != Other.Indent)
|
||||
return Indent < Other.Indent;
|
||||
|
|
|
@ -975,6 +975,12 @@ TEST_F(FormatTestObjC, ObjCArrayLiterals) {
|
|||
verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
|
||||
" NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
|
||||
"]];");
|
||||
Style.ColumnLimit = 20;
|
||||
// We can't break string literals inside NSArray literals
|
||||
// (that raises -Wobjc-string-concatenation).
|
||||
verifyFormat("NSArray *foo = @[\n"
|
||||
" @\"aaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
|
||||
"];\n");
|
||||
}
|
||||
} // end namespace
|
||||
} // end namespace format
|
||||
|
|
Loading…
Reference in New Issue