diff options
Diffstat (limited to 'unittests/Format/FormatTestObjC.cpp')
| -rw-r--r-- | unittests/Format/FormatTestObjC.cpp | 513 |
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 |
