summaryrefslogtreecommitdiff
path: root/unittests/Format/FormatTestObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Format/FormatTestObjC.cpp')
-rw-r--r--unittests/Format/FormatTestObjC.cpp513
1 files changed, 493 insertions, 20 deletions
diff --git a/unittests/Format/FormatTestObjC.cpp b/unittests/Format/FormatTestObjC.cpp
index 4220b44b4c47..e56df6d130d2 100644
--- a/unittests/Format/FormatTestObjC.cpp
+++ b/unittests/Format/FormatTestObjC.cpp
@@ -40,8 +40,8 @@ protected:
std::string format(llvm::StringRef Code,
StatusCheck CheckComplete = SC_ExpectComplete) {
- DEBUG(llvm::errs() << "---\n");
- DEBUG(llvm::errs() << Code << "\n\n");
+ LLVM_DEBUG(llvm::errs() << "---\n");
+ LLVM_DEBUG(llvm::errs() << Code << "\n\n");
std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
FormattingAttemptStatus Status;
tooling::Replacements Replaces =
@@ -53,11 +53,12 @@ protected:
}
auto Result = applyAllReplacements(Code, Replaces);
EXPECT_TRUE(static_cast<bool>(Result));
- DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+ LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
return *Result;
}
void verifyFormat(StringRef Code) {
+ EXPECT_EQ(Code.str(), format(Code)) << "Expected code is not stable";
EXPECT_EQ(Code.str(), format(test::messUp(Code)));
}
@@ -94,6 +95,75 @@ TEST(FormatTestObjCStyle, DetectsObjCInHeaders) {
Style = getStyle("LLVM", "a.h", "none", "void f() {}");
ASSERT_TRUE((bool)Style);
EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
+
+ Style = getStyle("{}", "a.h", "none", "@interface Foo\n@end\n");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
+ Style = getStyle("{}", "a.h", "none",
+ "const int interface = 1;\nconst int end = 2;\n");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
+
+ Style = getStyle("{}", "a.h", "none", "@protocol Foo\n@end\n");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
+ Style = getStyle("{}", "a.h", "none",
+ "const int protocol = 1;\nconst int end = 2;\n");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
+
+ Style =
+ getStyle("{}", "a.h", "none", "typedef NS_ENUM(NSInteger, Foo) {};\n");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
+ Style = getStyle("{}", "a.h", "none", "enum Foo {};");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
+
+ Style =
+ getStyle("{}", "a.h", "none", "inline void Foo() { Log(@\"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);
+ EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
+
+ Style =
+ getStyle("{}", "a.h", "none", "inline void Foo() { id = @[1, 2, 3]; }\n");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
+ Style = getStyle("{}", "a.h", "none",
+ "inline void Foo() { id foo = @{1: 2, 3: 4, 5: 6}; }\n");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
+ Style = getStyle("{}", "a.h", "none",
+ "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) {
@@ -118,7 +188,8 @@ TEST_F(FormatTestObjC, FormatObjCAutoreleasepool) {
"@autoreleasepool {\n"
" f();\n"
"}\n");
- Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterControlStatement = true;
verifyFormat("@autoreleasepool\n"
"{\n"
" f();\n"
@@ -129,6 +200,36 @@ TEST_F(FormatTestObjC, FormatObjCAutoreleasepool) {
"}\n");
}
+TEST_F(FormatTestObjC, FormatObjCGenerics) {
+ Style.ColumnLimit = 40;
+ verifyFormat("int aaaaaaaaaaaaaaaa(\n"
+ " NSArray<aaaaaaaaaaaaaaaaaa *>\n"
+ " aaaaaaaaaaaaaaaaa);\n");
+ verifyFormat("int aaaaaaaaaaaaaaaa(\n"
+ " NSArray<aaaaaaaaaaaaaaaaaaa<\n"
+ " aaaaaaaaaaaaaaaa *> *>\n"
+ " aaaaaaaaaaaaaaaaa);\n");
+}
+
+TEST_F(FormatTestObjC, FormatObjCSynchronized) {
+ verifyFormat("@synchronized(self) {\n"
+ " f();\n"
+ "}\n"
+ "@synchronized(self) {\n"
+ " f();\n"
+ "}\n");
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterControlStatement = true;
+ verifyFormat("@synchronized(self)\n"
+ "{\n"
+ " f();\n"
+ "}\n"
+ "@synchronized(self)\n"
+ "{\n"
+ " f();\n"
+ "}\n");
+}
+
TEST_F(FormatTestObjC, FormatObjCInterface) {
verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
"@public\n"
@@ -155,6 +256,12 @@ TEST_F(FormatTestObjC, FormatObjCInterface) {
"@end");
verifyFormat("@interface Foo : Bar\n"
+ "@property(assign, readwrite) NSInteger bar;\n"
+ "+ (id)init;\n"
+ "@end");
+
+ verifyFormat("FOUNDATION_EXPORT NS_AVAILABLE_IOS(10.0) @interface Foo : Bar\n"
+ "@property(assign, readwrite) NSInteger bar;\n"
"+ (id)init;\n"
"@end");
@@ -192,6 +299,18 @@ TEST_F(FormatTestObjC, FormatObjCInterface) {
"+ (id)init;\n"
"@end");
+ verifyFormat("@interface Foo<Baz : Blech> : Bar <Baz, Quux> {\n"
+ " int _i;\n"
+ "}\n"
+ "+ (id)init;\n"
+ "@end");
+
+ verifyFormat("@interface Foo<Bar : Baz <Blech>> : Xyzzy <Corge> {\n"
+ " int _i;\n"
+ "}\n"
+ "+ (id)init;\n"
+ "@end");
+
verifyFormat("@interface Foo (HackStuff) {\n"
" int _i;\n"
"}\n"
@@ -209,9 +328,46 @@ TEST_F(FormatTestObjC, FormatObjCInterface) {
"}\n"
"+ (id)init;\n"
"@end");
+ verifyFormat("@interface Foo\n"
+ "- (void)foo {\n"
+ "}\n"
+ "@end\n"
+ "@implementation Bar\n"
+ "- (void)bar {\n"
+ "}\n"
+ "@end");
+ Style.ColumnLimit = 40;
+ verifyFormat("@interface ccccccccccccc () <\n"
+ " ccccccccccccc, ccccccccccccc,\n"
+ " ccccccccccccc, ccccccccccccc> {\n"
+ "}");
+ verifyFormat("@interface ccccccccccccc (ccccccccccc) <\n"
+ " ccccccccccccc> {\n"
+ "}");
+ Style.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
+ verifyFormat("@interface ddddddddddddd () <\n"
+ " ddddddddddddd,\n"
+ " ddddddddddddd,\n"
+ " ddddddddddddd,\n"
+ " ddddddddddddd> {\n"
+ "}");
+
+ Style.BinPackParameters = false;
+ Style.ObjCBinPackProtocolList = FormatStyle::BPS_Auto;
+ verifyFormat("@interface eeeeeeeeeeeee () <\n"
+ " eeeeeeeeeeeee,\n"
+ " eeeeeeeeeeeee,\n"
+ " eeeeeeeeeeeee,\n"
+ " eeeeeeeeeeeee> {\n"
+ "}");
+ Style.ObjCBinPackProtocolList = FormatStyle::BPS_Always;
+ verifyFormat("@interface fffffffffffff () <\n"
+ " fffffffffffff, fffffffffffff,\n"
+ " fffffffffffff, fffffffffffff> {\n"
+ "}");
Style = getGoogleStyle(FormatStyle::LK_ObjC);
- verifyFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
+ verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
" @public\n"
" int field1;\n"
" @protected\n"
@@ -223,19 +379,22 @@ TEST_F(FormatTestObjC, FormatObjCInterface) {
"}\n"
"+ (id)init;\n"
"@end");
- verifyFormat("@interface Foo : Bar<Baz, Quux>\n"
+ verifyFormat("@interface Foo : Bar <Baz, Quux>\n"
"+ (id)init;\n"
"@end");
- verifyFormat("@interface Foo (HackStuff)<MyProtocol>\n"
+ verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"
"+ (id)init;\n"
"@end");
- Style.BinPackParameters = false;
- Style.ColumnLimit = 80;
- verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n"
- " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
- " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
- " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
- " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
+ Style.ColumnLimit = 40;
+ // BinPackParameters should be true by default.
+ verifyFormat("void eeeeeeee(int eeeee, int eeeee,\n"
+ " int eeeee, int eeeee);\n");
+ // ObjCBinPackProtocolList should be BPS_Never by default.
+ verifyFormat("@interface fffffffffffff () <\n"
+ " fffffffffffff,\n"
+ " fffffffffffff,\n"
+ " fffffffffffff,\n"
+ " fffffffffffff> {\n"
"}");
}
@@ -334,6 +493,10 @@ TEST_F(FormatTestObjC, FormatObjCProtocol) {
"@protocol Bar\n"
"@end");
+ verifyFormat("FOUNDATION_EXPORT NS_AVAILABLE_IOS(10.0) @protocol Foo\n"
+ "@property(assign, readwrite) NSInteger bar;\n"
+ "@end");
+
verifyFormat("@protocol myProtocol\n"
"- (void)mandatoryWithInt:(int)i;\n"
"@optional\n"
@@ -354,7 +517,7 @@ TEST_F(FormatTestObjC, FormatObjCProtocol) {
"@end");
Style = getGoogleStyle(FormatStyle::LK_ObjC);
- verifyFormat("@protocol MyProtocol<NSObject>\n"
+ verifyFormat("@protocol MyProtocol <NSObject>\n"
"- (NSUInteger)numberOfThings;\n"
"@end");
}
@@ -374,6 +537,7 @@ TEST_F(FormatTestObjC, FormatObjCMethodDeclarations) {
" evenLongerKeyword:(float)theInterval\n"
" error:(NSError **)theError {\n"
"}");
+ verifyFormat("+ (instancetype)new;\n");
Style.ColumnLimit = 60;
verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n"
" y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n"
@@ -381,12 +545,26 @@ TEST_F(FormatTestObjC, FormatObjCMethodDeclarations) {
verifyFormat("- (void)drawRectOn:(id)surface\n"
" ofSize:(size_t)height\n"
" :(size_t)width;");
+ Style.ColumnLimit = 40;
+ // Make sure selectors with 0, 1, or more arguments are indented when wrapped.
+ verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa;\n");
+ verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;\n");
+ verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;\n");
+ verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;\n");
+ verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;\n");
// Continuation indent width should win over aligning colons if the function
// name is long.
Style = getGoogleStyle(FormatStyle::LK_ObjC);
Style.ColumnLimit = 40;
- Style.IndentWrappedFunctionNames = true;
verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
" dontAlignNamef:(NSRect)theRect {\n"
"}");
@@ -478,6 +656,9 @@ TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"
"}");
verifyFormat("[self aaaaa:MACRO(a, b:, c:)];");
+ verifyFormat("[self aaaaa:MACRO(a, b:c:, d:e:)];");
+ verifyFormat("[self aaaaa:MACRO(a, b:c:d:, e:f:g:)];");
+ verifyFormat("int XYMyFoo(int a, int b) NS_SWIFT_NAME(foo(self:scale:));");
verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];");
verifyFormat("[self aaaaa:(Type)a bbbbb:3];");
@@ -497,6 +678,18 @@ TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
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 = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
+ " [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
+
// This tests that the formatter doesn't break after "backing" but before ":",
// which would be at 80 columns.
verifyFormat(
@@ -573,17 +766,101 @@ TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
"[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];");
+
verifyFormat("[self // break\n"
" a:a\n"
" aaa:aaa];");
- verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
- " [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
// Formats pair-parameters.
verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
verifyFormat("[I drawRectOn:surface //\n"
- " ofSize:aa:bbb\n"
- " atOrigin:cc:dd];");
+ " ofSize:aa:bbb\n"
+ " atOrigin:cc:dd];");
+
+ // Inline block as a first argument.
+ verifyFormat("[object justBlock:^{\n"
+ " a = 42;\n"
+ "}];");
+ verifyFormat("[object\n"
+ " justBlock:^{\n"
+ " a = 42;\n"
+ " }\n"
+ " notBlock:42\n"
+ " a:42];");
+ verifyFormat("[object\n"
+ " firstBlock:^{\n"
+ " a = 42;\n"
+ " }\n"
+ " blockWithLongerName:^{\n"
+ " a = 42;\n"
+ " }];");
+ verifyFormat("[object\n"
+ " blockWithLongerName:^{\n"
+ " a = 42;\n"
+ " }\n"
+ " secondBlock:^{\n"
+ " a = 42;\n"
+ " }];");
+ verifyFormat("[object\n"
+ " firstBlock:^{\n"
+ " a = 42;\n"
+ " }\n"
+ " notBlock:42\n"
+ " secondBlock:^{\n"
+ " a = 42;\n"
+ " }];");
+
+ // Space between cast rparen and selector name component.
+ verifyFormat("[((Foo *)foo) bar];");
+ verifyFormat("[((Foo *)foo) bar:1 blech:2];");
+
+ Style.ColumnLimit = 20;
+ verifyFormat("aaaaa = [a aa:aa\n"
+ " aa:aa];");
+ verifyFormat("aaaaaa = [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"
+ "}] aaaaaaa:42 b:42];");
+ // Arguments just over a column limit.
+ verifyFormat("[[object block:^{\n"
+ " return 42;\n"
+ "}] aaaaaaa: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 aaaaaa:42\n"
+ " b:42]\n"
+ " cc:42\n"
+ " d:42];");
+
+ // Avoid breaking receiver expression.
+ Style.ColumnLimit = 30;
+ verifyFormat("fooooooo =\n"
+ " [[obj fooo] aaa:42\n"
+ " aaa:42];");
+ verifyFormat("[[[obj foo] bar] aa:42\n"
+ " bb:42\n"
+ " cc:42];");
Style.ColumnLimit = 70;
verifyFormat(
@@ -616,6 +893,26 @@ TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
" backing:NSBackingStoreBuffered\n"
" defer:NO]);\n"
"}");
+
+ // Respect continuation indent and colon alignment (e.g. when object name is
+ // short, and first selector is the longest one)
+ Style = getLLVMStyle();
+ Style.Language = FormatStyle::LK_ObjC;
+ Style.ContinuationIndentWidth = 8;
+ verifyFormat("[self performSelectorOnMainThread:@selector(loadAccessories)\n"
+ " withObject:nil\n"
+ " waitUntilDone:false];");
+ verifyFormat("[self performSelector:@selector(loadAccessories)\n"
+ " withObjectOnMainThread:nil\n"
+ " waitUntilDone:false];");
+ verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " performSelectorOnMainThread:@selector(loadAccessories)\n"
+ " withObject:nil\n"
+ " waitUntilDone:false];");
+ verifyFormat("[self // force wrapping\n"
+ " performSelectorOnMainThread:@selector(loadAccessories)\n"
+ " withObject:nil\n"
+ " waitUntilDone:false];");
}
TEST_F(FormatTestObjC, ObjCAt) {
@@ -652,6 +949,15 @@ TEST_F(FormatTestObjC, ObjCAt) {
verifyFormat("@ /*foo*/ interface");
}
+TEST_F(FormatTestObjC, ObjCBlockTypesAndVariables) {
+ verifyFormat("void DoStuffWithBlockType(int (^)(char));");
+ verifyFormat("int (^foo)(char, float);");
+ verifyFormat("int (^foo[10])(char, float);");
+ verifyFormat("int (^foo[kNumEntries])(char, float);");
+ verifyFormat("int (^foo[kNumEntries + 10])(char, float);");
+ verifyFormat("int (^foo[(kNumEntries + 10)])(char, float);");
+}
+
TEST_F(FormatTestObjC, ObjCSnippets) {
verifyFormat("@autoreleasepool {\n"
" foo();\n"
@@ -676,6 +982,14 @@ TEST_F(FormatTestObjC, ObjCSnippets) {
verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");
verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
+ Style.ColumnLimit = 50;
+ verifyFormat("@interface Foo\n"
+ "- (void)doStuffWithFoo:(id)name\n"
+ " bar:(id)bar\n"
+ " baz:(id)baz\n"
+ " NS_SWIFT_NAME(doStuff(withFoo:bar:baz:));\n"
+ "@end");
+
Style = getMozillaStyle();
verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
verifyFormat("@property BOOL editable;");
@@ -700,6 +1014,88 @@ TEST_F(FormatTestObjC, ObjCForIn) {
" foo(n);\n"
" }\n"
"}");
+ verifyFormat("for (Foo *x in bar) {\n}");
+ verifyFormat("for (Foo *x in [bar baz]) {\n}");
+ verifyFormat("for (Foo *x in [bar baz:blech]) {\n}");
+ verifyFormat("for (Foo *x in [bar baz:blech, 1, 2, 3, 0]) {\n}");
+ verifyFormat("for (Foo *x in [bar baz:^{\n"
+ " [uh oh];\n"
+ " }]) {\n}");
+}
+
+TEST_F(FormatTestObjC, ObjCCxxKeywords) {
+ verifyFormat("+ (instancetype)new {\n"
+ " return nil;\n"
+ "}\n");
+ verifyFormat("+ (instancetype)myNew {\n"
+ " return [self new];\n"
+ "}\n");
+ verifyFormat("SEL NewSelector(void) { return @selector(new); }\n");
+ verifyFormat("SEL MacroSelector(void) { return MACRO(new); }\n");
+ verifyFormat("+ (instancetype)delete {\n"
+ " return nil;\n"
+ "}\n");
+ verifyFormat("+ (instancetype)myDelete {\n"
+ " return [self delete];\n"
+ "}\n");
+ verifyFormat("SEL DeleteSelector(void) { return @selector(delete); }\n");
+ verifyFormat("SEL MacroSelector(void) { return MACRO(delete); }\n");
+ verifyFormat("MACRO(new:)\n");
+ verifyFormat("MACRO(delete:)\n");
+ verifyFormat("foo = @{MACRO(new:) : MACRO(delete:)}\n");
+ verifyFormat("@implementation Foo\n"
+ "// Testing\n"
+ "- (Class)class {\n"
+ "}\n"
+ "- (void)foo {\n"
+ "}\n"
+ "@end\n");
+ verifyFormat("@implementation Foo\n"
+ "- (Class)class {\n"
+ "}\n"
+ "- (void)foo {\n"
+ "}\n"
+ "@end");
+ verifyFormat("@implementation Foo\n"
+ "+ (Class)class {\n"
+ "}\n"
+ "- (void)foo {\n"
+ "}\n"
+ "@end");
+ verifyFormat("@implementation Foo\n"
+ "- (Class)class:(Class)klass {\n"
+ "}\n"
+ "- (void)foo {\n"
+ "}\n"
+ "@end");
+ verifyFormat("@implementation Foo\n"
+ "+ (Class)class:(Class)klass {\n"
+ "}\n"
+ "- (void)foo {\n"
+ "}\n"
+ "@end");
+
+ verifyFormat("@interface Foo\n"
+ "// Testing\n"
+ "- (Class)class;\n"
+ "- (void)foo;\n"
+ "@end\n");
+ verifyFormat("@interface Foo\n"
+ "- (Class)class;\n"
+ "- (void)foo;\n"
+ "@end");
+ verifyFormat("@interface Foo\n"
+ "+ (Class)class;\n"
+ "- (void)foo;\n"
+ "@end");
+ verifyFormat("@interface Foo\n"
+ "- (Class)class:(Class)klass;\n"
+ "- (void)foo;\n"
+ "@end");
+ verifyFormat("@interface Foo\n"
+ "+ (Class)class:(Class)klass;\n"
+ "- (void)foo;\n"
+ "@end");
}
TEST_F(FormatTestObjC, ObjCLiterals) {
@@ -776,6 +1172,30 @@ TEST_F(FormatTestObjC, ObjCDictLiterals) {
" (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n"
" (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n"
"};");
+ Style.ColumnLimit = 40;
+ verifyFormat("int Foo() {\n"
+ " a12345 = @{a12345 : a12345};\n"
+ "}");
+ verifyFormat("int Foo() {\n"
+ " a12345 = @{a12345 : @(a12345)};\n"
+ "}");
+ verifyFormat("int Foo() {\n"
+ " a12345 = @{(Foo *)a12345 : @(a12345)};\n"
+ "}");
+ verifyFormat("int Foo() {\n"
+ " a12345 = @{@(a12345) : a12345};\n"
+ "}");
+ verifyFormat("int Foo() {\n"
+ " a12345 = @{@(a12345) : @YES};\n"
+ "}");
+ Style.SpacesInContainerLiterals = false;
+ verifyFormat("int Foo() {\n"
+ " b12345 = @{b12345: b12345};\n"
+ "}");
+ verifyFormat("int Foo() {\n"
+ " b12345 = @{(Foo *)b12345: @(b12345)};\n"
+ "}");
+ Style.SpacesInContainerLiterals = true;
Style = getGoogleStyle(FormatStyle::LK_ObjC);
verifyFormat(
@@ -831,7 +1251,60 @@ TEST_F(FormatTestObjC, ObjCArrayLiterals) {
verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
" NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
"]];");
+ Style.ColumnLimit = 40;
+ verifyFormat("int Foo() {\n"
+ " a12345 = @[ a12345, a12345 ];\n"
+ "}");
+ verifyFormat("int Foo() {\n"
+ " a123 = @[ (Foo *)a12345, @(a12345) ];\n"
+ "}");
+ Style.SpacesInContainerLiterals = false;
+ verifyFormat("int Foo() {\n"
+ " b12345 = @[b12345, b12345];\n"
+ "}");
+ verifyFormat("int Foo() {\n"
+ " b12345 = @[(Foo *)b12345, @(b12345)];\n"
+ "}");
+ Style.SpacesInContainerLiterals = true;
+ Style.ColumnLimit = 20;
+ // We can't break string literals inside NSArray literals
+ // (that raises -Wobjc-string-concatenation).
+ verifyFormat("NSArray *foo = @[\n"
+ " @\"aaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
+ "];\n");
+}
+
+TEST_F(FormatTestObjC, BreaksCallStatementWhereSemiJustOverTheLimit) {
+ Style.ColumnLimit = 60;
+ // If the statement starting with 'a = ...' is put on a single line, the ';'
+ // is at line 61.
+ verifyFormat("int f(int a) {\n"
+ " a = [self aaaaaaaaaa:bbbbbbbbb\n"
+ " ccccccccc:dddddddd\n"
+ " ee:fddd];\n"
+ "}");
}
+
+TEST_F(FormatTestObjC, AlwaysBreakBeforeMultilineStrings) {
+ Style = getGoogleStyle(FormatStyle::LK_ObjC);
+ Style.ColumnLimit = 40;
+ verifyFormat("aaaa = @\"bbbb\"\n"
+ " @\"cccc\";");
+ verifyFormat("aaaa(@\"bbbb\"\n"
+ " @\"cccc\");");
+ verifyFormat("aaaa(qqq, @\"bbbb\"\n"
+ " @\"cccc\");");
+ verifyFormat("[aaaa qqqq:@\"bbbb\"\n"
+ " @\"cccc\"];");
+ verifyFormat("aaaa = [aaaa qqqq:@\"bbbb\"\n"
+ " @\"cccc\"];");
+ verifyFormat("[aaaa qqqq:@\"bbbb\"\n"
+ " @\"cccc\"\n"
+ " rr:42\n"
+ " ssssss:@\"ee\"\n"
+ " @\"fffff\"];");
+}
+
} // end namespace
} // end namespace format
} // end namespace clang